diff options
author | Campbell Barton <campbell@blender.org> | 2022-04-20 05:06:03 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-04-20 05:16:11 +0300 |
commit | 6d9268c2c7362ec772a3ff956ee888e877682a01 (patch) | |
tree | afa457b0bace94befad94e96a955145d0d3b88b0 | |
parent | 16afff2ddc4580cfe3a952c3e60e0950ae0487b6 (diff) |
PyAPI: utility functions for parsing typed RNA arguments
These functions can be used with PyArg_ParseTupleAndKeywords
(and related functions) to take typed RNA arguments without
having to extract and type-check them separately.
No functional changes, extracted from D13126.
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 44 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 27 |
2 files changed, 71 insertions, 0 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 5db66405403..11b584b692d 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -7872,6 +7872,50 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e return srna; } +const PointerRNA *pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna) +{ + BPy_StructRNA *bpy_srna = (BPy_StructRNA *)py_obj; + if (!BPy_StructRNA_Check(py_obj) || !RNA_struct_is_a(bpy_srna->ptr.type, srna)) { + PyErr_Format(PyExc_TypeError, + "Expected a \"bpy.types.%.200s\" not a \"%.200s\"", + RNA_struct_identifier(srna), + Py_TYPE(py_obj)->tp_name); + return NULL; + } + PYRNA_STRUCT_CHECK_OBJ(bpy_srna); + return &bpy_srna->ptr; +} + +const PointerRNA *pyrna_struct_as_ptr_or_null(PyObject *py_obj, const StructRNA *srna) +{ + if (py_obj == Py_None) { + return &PointerRNA_NULL; + } + return pyrna_struct_as_ptr(py_obj, srna); +} + +int pyrna_struct_as_ptr_parse(PyObject *o, void *p) +{ + struct BPy_StructRNA_Parse *srna_parse = p; + BLI_assert(srna_parse->type != NULL); + srna_parse->ptr = pyrna_struct_as_ptr(o, srna_parse->type); + if (srna_parse->ptr == NULL) { + return 0; + } + return 1; +} + +int pyrna_struct_as_ptr_or_null_parse(PyObject *o, void *p) +{ + struct BPy_StructRNA_Parse *srna_parse = p; + BLI_assert(srna_parse->type != NULL); + srna_parse->ptr = pyrna_struct_as_ptr_or_null(o, srna_parse->type); + if (srna_parse->ptr == NULL) { + return 0; + } + return 1; +} + /* Orphan functions, not sure where they should go. */ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) { diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 573daac6e95..91fa0ea2c8d 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -187,6 +187,33 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); int pyrna_deferred_register_class(struct StructRNA *srna, PyTypeObject *py_class); +const PointerRNA *pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna); +const PointerRNA *pyrna_struct_as_ptr_or_null(PyObject *py_obj, const StructRNA *srna); + +/** + * Struct used for RNA argument parsing functions: + * - #pyrna_struct_as_ptr_parse + * - #pyrna_struct_as_ptr_or_null_parse + */ +struct BPy_StructRNA_Parse { + /** The struct RNA must match this type. */ + StructRNA *type; + /** Result, may be `PointerRNA_NULL` if #pyrna_struct_as_ptr_or_null_parse is used. */ + const PointerRNA *ptr; +}; + +/** + * Sets #BPy_StructRNA_Parse.ptr to the value in the #BPy_StructRNA.ptr (from `o`) + * or raise an error if the type isn't a #BPy_StructRNA. + * + * Use with #PyArg_ParseTuple's `O&` formatting. + */ +int pyrna_struct_as_ptr_parse(PyObject *o, void *p); +/** + * A version of #pyrna_struct_as_ptr_parse that maps Python's `None` to #PointerRNA_NULL. + */ +int pyrna_struct_as_ptr_or_null_parse(PyObject *o, void *p); + void pyrna_struct_type_extend_capi(struct StructRNA *srna, struct PyMethodDef *py_method, struct PyGetSetDef *py_getset); |