| 
									
										
										
										
											2022-02-11 09:07:11 +11:00
										 |  |  | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup pythonintern | 
					
						
							| 
									
										
										
										
											2011-11-05 08:21:12 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * This file is the main interface between Python and Blender's data api (RNA), | 
					
						
							|  |  |  |  * exposing RNA to Python so blender data can be accessed in a Python like way. | 
					
						
							| 
									
										
										
										
											2011-11-05 08:21:12 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * The two main types are #BPy_StructRNA and #BPy_PropertyRNA - the base | 
					
						
							|  |  |  |  * classes for most of the data Python accesses in blender. | 
					
						
							| 
									
										
										
										
											2011-02-27 20:10:08 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | #include <Python.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include <float.h> /* FLT_MIN/MAX */
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include <stddef.h>
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 16:56:48 +02:00
										 |  |  | #include "RNA_path.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "RNA_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 19:34:42 +01:00
										 |  |  | #include "BLI_bitmap.h"
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | #include "BLI_dynstr.h"
 | 
					
						
							|  |  |  | #include "BLI_listbase.h"
 | 
					
						
							|  |  |  | #include "BLI_math_rotation.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_string.h"
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 01:52:28 +00:00
										 |  |  | #include "BPY_extern.h"
 | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  | #include "BPY_extern_clog.h"
 | 
					
						
							| 
									
										
										
										
											2012-09-15 01:52:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "bpy_capi_utils.h"
 | 
					
						
							|  |  |  | #include "bpy_intern_string.h"
 | 
					
						
							|  |  |  | #include "bpy_props.h"
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | #include "bpy_rna.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "bpy_rna_anim.h"
 | 
					
						
							| 
									
										
										
										
											2010-02-27 13:27:06 +00:00
										 |  |  | #include "bpy_rna_callback.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 06:56:21 +00:00
										 |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2012-09-15 01:52:28 +00:00
										 |  |  | #  include "BLI_ghash.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "RNA_access.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "RNA_define.h" /* RNA_def_property_free_identifier */
 | 
					
						
							|  |  |  | #include "RNA_enum_types.h"
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:54:46 +01:00
										 |  |  | #include "RNA_prototypes.h"
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  | #include "CLG_log.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 19:18:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-19 19:03:38 +00:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | #include "BKE_global.h" /* evil G.* */
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "BKE_idprop.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  | #include "BKE_idtype.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BKE_main.h"
 | 
					
						
							|  |  |  | #include "BKE_report.h"
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Only for types. */ | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | #include "BKE_node.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-25 10:13:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 12:24:26 +02:00
										 |  |  | #include "DEG_depsgraph_query.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #include "../generic/idprop_py_api.h" /* For IDprop lookups. */
 | 
					
						
							| 
									
										
											  
											
												Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
 - `as_dict`: Returns a dictionary of the property's UI data.
 - `clear`: Removes the property's UI data.
 - `update_from`: Copy UI data between properties,
   even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
											
										 
											2021-08-27 08:27:24 -05:00
										 |  |  | #include "../generic/idprop_py_ui_api.h"
 | 
					
						
							| 
									
										
										
										
											2021-09-01 16:30:47 +10:00
										 |  |  | #include "../generic/py_capi_rna.h"
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | #include "../generic/py_capi_utils.h"
 | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  | #include "../generic/python_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | #define USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  | #define USE_MATHUTILS
 | 
					
						
							|  |  |  | #define USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2010-02-21 14:48:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 21:21:18 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * This _must_ be enabled to support Python 3.10's postponed annotations, | 
					
						
							|  |  |  |  * `from __future__ import annotations`. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This has the disadvantage of evaluating strings at run-time, in the future we might be able to | 
					
						
							|  |  |  |  * reinstate the older, more efficient logic using descriptors, see: pep-0649 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define USE_POSTPONED_ANNOTATIONS
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 18:12:03 +11:00
										 |  |  | /* Unfortunately Python needs to hold a global reference to the context.
 | 
					
						
							|  |  |  |  * If we remove this is means `bpy.context` won't be usable from some parts of the code: | 
					
						
							|  |  |  |  * `bpy.app.handler` callbacks for example. | 
					
						
							|  |  |  |  * Even though this is arguably "correct", it's going to cause problems for existing scripts, | 
					
						
							|  |  |  |  * so accept having this for the time being. */ | 
					
						
							| 
									
										
										
										
											2019-02-23 18:29:03 +11:00
										 |  |  | BPy_StructRNA *bpy_context_module = NULL; /* for fast access */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | static PyObject *pyrna_struct_Subtype(PointerRNA *ptr); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  | static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class); | 
					
						
							|  |  |  | static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-05 05:44:52 +00:00
										 |  |  | #define BPY_DOC_ID_PROP_TYPE_NOTE \
 | 
					
						
							|  |  |  |   "   .. note::\n" \ | 
					
						
							|  |  |  |   "\n" \ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   "      Only the :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \ | 
					
						
							| 
									
										
										
										
											2011-10-09 02:24:51 +00:00
										 |  |  |   "      :class:`bpy.types.PoseBone` classes support custom properties.\n" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | int pyrna_struct_validity_check(BPy_StructRNA *pysrna) | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (pysrna->ptr.type) { | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |   PyErr_Format( | 
					
						
							|  |  |  |       PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | int pyrna_prop_validity_check(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (self->ptr.type) { | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |   PyErr_Format(PyExc_ReferenceError, | 
					
						
							|  |  |  |                "PropertyRNA of type %.200s.%.200s has been removed", | 
					
						
							|  |  |  |                Py_TYPE(self)->tp_name, | 
					
						
							|  |  |  |                RNA_property_identifier(self->prop)); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-26 10:33:57 +00:00
										 |  |  | void pyrna_invalidate(BPy_DummyPointerRNA *self) | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-11-01 15:56:42 +00:00
										 |  |  |   RNA_POINTER_INVALIDATE(&self->ptr); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | #ifdef USE_PYRNA_INVALIDATE_GC
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | #  define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1))
 | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Only for sizeof(). */ | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | struct gc_generation { | 
					
						
							|  |  |  |   PyGC_Head head; | 
					
						
							|  |  |  |   int threshold; | 
					
						
							|  |  |  |   int count; | 
					
						
							|  |  |  | } gc_generation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void id_release_gc(struct ID *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  |   uint j; | 
					
						
							|  |  |  |   // uint i = 0;
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   for (j = 0; j < 3; j++) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j)); | 
					
						
							|  |  |  |     PyGC_Head *g = gen->gc.gc_next; | 
					
						
							|  |  |  |     while ((g = g->gc.gc_next) != gen) { | 
					
						
							|  |  |  |       PyObject *ob = FROM_GC(g); | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |       if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || | 
					
						
							|  |  |  |           PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob; | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |         if (ob_ptr->ptr.owner_id == id) { | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  |           pyrna_invalidate(ob_ptr); | 
					
						
							|  |  |  |           // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
 | 
					
						
							|  |  |  |           // i++;
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // printf("id_release_gc freed '%s': %d\n", id->name, i);
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | //#define DEBUG_RNA_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2011-03-02 16:56:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | struct GHash *id_weakref_pool = NULL; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyMethodDef id_free_weakref_cb_def = { | 
					
						
							|  |  |  |     "id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL}; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 17:52:36 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Only used when there are values left on exit (causing memory leaks). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void id_weakref_pool_free_value_fn(void *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GHash *weakinfo_hash = p; | 
					
						
							|  |  |  |   BLI_ghash_free(weakinfo_hash, NULL, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Adds a reference to the list, remember to decref. */ | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | static GHash *id_weakref_pool_get(ID *id) | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-08-11 17:29:26 +10:00
										 |  |  |   GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (weakinfo_hash == NULL) { | 
					
						
							| 
									
										
										
										
											2021-08-11 17:29:26 +10:00
										 |  |  |     /* This could be a set, values are used to keep a reference back to the ID
 | 
					
						
							|  |  |  |      * (all of them are the same). */ | 
					
						
							| 
									
										
										
										
											2012-05-16 00:51:36 +00:00
										 |  |  |     weakinfo_hash = BLI_ghash_ptr_new("rna_id"); | 
					
						
							| 
									
										
										
										
											2015-05-11 12:39:39 +10:00
										 |  |  |     BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |   return weakinfo_hash; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject(). */ | 
					
						
							| 
									
										
										
										
											2013-07-21 16:40:34 +00:00
										 |  |  | static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna) | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PyObject *weakref; | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |   PyObject *weakref_capsule; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  |   PyObject *weakref_cb_py; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |   /* Create a new function instance and insert the list as 'self'
 | 
					
						
							|  |  |  |    * so we can remove ourself from it. */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   GHash *weakinfo_hash = id_weakref_pool_get(id); /* New or existing. */ | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule); | 
					
						
							|  |  |  |   Py_DECREF(weakref_capsule); | 
					
						
							| 
									
										
										
										
											2011-03-02 06:56:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Add weakref to weakinfo_hash list. */ | 
					
						
							| 
									
										
										
										
											2011-03-02 16:56:13 +00:00
										 |  |  |   weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   Py_DECREF(weakref_cb_py); /* Function owned by the weakref now. */ | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Important to add at the end of the hash, since first removal looks at the end. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Using a hash table as a set, all 'id's are the same. */ | 
					
						
							|  |  |  |   BLI_ghash_insert(weakinfo_hash, weakref, id); | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |   /* weakinfo_hash owns the weakref */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Workaround to get the last id without a lookup. */ | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | static ID *_id_tmp_ptr; | 
					
						
							|  |  |  | static void value_id_set(void *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   _id_tmp_ptr = (ID *)id; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash); | 
					
						
							| 
									
										
										
										
											2020-09-07 18:09:09 +02:00
										 |  |  | static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref) | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Important to search backwards. */ | 
					
						
							| 
									
										
										
										
											2020-09-07 18:09:09 +02:00
										 |  |  |   GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_pair, NULL); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-15 23:36:11 +11:00
										 |  |  |   if (BLI_ghash_len(weakinfo_hash) > 1) { | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |     BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   else { /* Get the last id and free it. */ | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |     BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set); | 
					
						
							|  |  |  |     id_release_weakref_list(_id_tmp_ptr, weakinfo_hash); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Py_DECREF(weakref); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash) | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |   GHashIterator weakinfo_hash_iter; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |   BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-31 04:43:26 +00:00
										 |  |  | #  ifdef DEBUG_RNA_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2018-02-15 23:36:11 +11:00
										 |  |  |   fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_len(weakinfo_hash)); | 
					
						
							| 
									
										
										
										
											2011-03-31 04:43:26 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-08 12:58:11 +00:00
										 |  |  |   while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter); | 
					
						
							|  |  |  |     PyObject *item = PyWeakref_GET_OBJECT(weakref); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (item != Py_None) { | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-31 04:43:26 +00:00
										 |  |  | #  ifdef DEBUG_RNA_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |       PyC_ObSpit("id_release_weakref item ", item); | 
					
						
							| 
									
										
										
										
											2011-03-31 04:43:26 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       pyrna_invalidate((BPy_DummyPointerRNA *)item); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(weakref); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BLI_ghashIterator_step(&weakinfo_hash_iter); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL); | 
					
						
							|  |  |  |   BLI_ghash_free(weakinfo_hash, NULL, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void id_release_weakref(struct ID *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (weakinfo_hash) { | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  |     id_release_weakref_list(id, weakinfo_hash); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
 | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void BPY_id_release(struct ID *id) | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | #ifdef USE_PYRNA_INVALIDATE_GC
 | 
					
						
							|  |  |  |   id_release_gc(id); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2021-08-11 17:29:26 +10:00
										 |  |  |   /* Check for NULL since this may run before Python has been started. */ | 
					
						
							|  |  |  |   if (id_weakref_pool != NULL) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-31 04:43:26 +00:00
										 |  |  |     id_release_weakref(id); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-31 04:43:26 +00:00
										 |  |  |     PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   (void)id; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | static bool rna_disallow_writes = false; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   ID *id = ptr->owner_id; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (id) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     const short idcode = GS(id->name); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* May need more ID types added here. */ | 
					
						
							|  |  |  |     if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  |       const char *idtype = BKE_idtype_idcode_to_name(idcode); | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |       const char *pyname; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (key && PyUnicode_Check(key)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |         pyname = PyUnicode_AsUTF8(key); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         pyname = "<UNKNOWN>"; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Make a nice string error. */ | 
					
						
							| 
									
										
										
										
											2011-01-09 15:12:08 +00:00
										 |  |  |       BLI_assert(idtype != NULL); | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "Writing to ID classes in this context is not allowed: " | 
					
						
							|  |  |  |                    "%.200s, %.200s datablock, error setting %.200s.%.200s", | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |                    id->name + 2, | 
					
						
							|  |  |  |                    idtype, | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                    pyname); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |       return true; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-01 00:32:50 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | bool pyrna_write_check(void) | 
					
						
							| 
									
										
										
										
											2011-02-01 00:32:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   return !rna_disallow_writes; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-06-07 16:08:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | void pyrna_write_set(bool val) | 
					
						
							| 
									
										
										
										
											2011-06-07 16:08:49 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   rna_disallow_writes = !val; | 
					
						
							| 
									
										
										
										
											2011-06-07 16:08:49 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #else  /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | bool pyrna_write_check(void) | 
					
						
							| 
									
										
										
										
											2011-02-01 00:32:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2011-02-01 00:32:50 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | void pyrna_write_set(bool UNUSED(val)) | 
					
						
							| 
									
										
										
										
											2011-06-07 16:08:49 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* pass */ | 
					
						
							| 
									
										
										
										
											2011-06-07 16:08:49 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self); | 
					
						
							|  |  |  | static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self); | 
					
						
							|  |  |  | static int pyrna_py_to_prop( | 
					
						
							|  |  |  |     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix); | 
					
						
							|  |  |  | static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #  include "../mathutils/mathutils.h" /* So we can have mathutils callbacks. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                                   PointerRNA *ptr, | 
					
						
							|  |  |  |                                                   PropertyRNA *prop, | 
					
						
							|  |  |  |                                                   Py_ssize_t start, | 
					
						
							|  |  |  |                                                   Py_ssize_t stop, | 
					
						
							|  |  |  |                                                   Py_ssize_t length); | 
					
						
							|  |  |  | static short pyrna_rotation_euler_order_get(PointerRNA *ptr, | 
					
						
							|  |  |  |                                             const short order_fallback, | 
					
						
							|  |  |  |                                             PropertyRNA **r_prop_eul_order); | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-01 12:24:06 +11:00
										 |  |  | /* `bpyrna` vector/euler/quaternion callbacks. */ | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  | static uchar mathutils_rna_array_cb_index = -1; /* Index for our callbacks. */ | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-01 12:24:06 +11:00
										 |  |  | /* Sub-type not used much yet. */ | 
					
						
							| 
									
										
										
										
											2010-02-20 19:49:04 +00:00
										 |  |  | #  define MATHUTILS_CB_SUBTYPE_EUL 0
 | 
					
						
							|  |  |  | #  define MATHUTILS_CB_SUBTYPE_VEC 1
 | 
					
						
							|  |  |  | #  define MATHUTILS_CB_SUBTYPE_QUAT 2
 | 
					
						
							| 
									
										
										
										
											2010-08-15 12:03:49 +00:00
										 |  |  | #  define MATHUTILS_CB_SUBTYPE_COLOR 3
 | 
					
						
							| 
									
										
										
										
											2010-02-20 19:49:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  | static int mathutils_rna_generic_check(BaseMathObject *bmo) | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |   return self->prop ? 0 : -1; | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  | static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype) | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  |   RNA_property_float_get_array(&self->ptr, self->prop, bmo->data); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Euler order exception. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { | 
					
						
							|  |  |  |     EulerObject *eul = (EulerObject *)bmo; | 
					
						
							|  |  |  |     PropertyRNA *prop_eul_order = NULL; | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |     eul->order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order); | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  | static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype) | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |   float min, max; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #  endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-30 12:27:34 +00:00
										 |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy_prop \"%.200s.%.200s\" is read-only", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop)); | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2010-08-30 12:27:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |   RNA_property_float_range(&self->ptr, self->prop, &min, &max); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-07 19:49:38 +00:00
										 |  |  |   if (min != -FLT_MAX || max != FLT_MAX) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     int i, len = RNA_property_array_length(&self->ptr, self->prop); | 
					
						
							|  |  |  |     for (i = 0; i < len; i++) { | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  |       CLAMP(bmo->data[i], min, max); | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  |   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_update_check(self->prop)) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     RNA_property_update(BPY_context_get(), &self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Euler order exception. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { | 
					
						
							|  |  |  |     EulerObject *eul = (EulerObject *)bmo; | 
					
						
							|  |  |  |     PropertyRNA *prop_eul_order = NULL; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (order != eul->order) { | 
					
						
							| 
									
										
										
										
											2010-04-27 07:50:31 +00:00
										 |  |  |       RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (RNA_property_update_check(prop_eul_order)) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |         RNA_property_update(BPY_context_get(), &self->ptr, prop_eul_order); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-04-27 07:50:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  | static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index) | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index); | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  | static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index) | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #  endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-30 12:27:34 +00:00
										 |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy_prop \"%.200s.%.200s\" is read-only", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop)); | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2010-08-30 12:27:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  |   RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]); | 
					
						
							|  |  |  |   RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_update_check(self->prop)) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     RNA_property_update(BPY_context_get(), &self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 18:42:41 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static Mathutils_Callback mathutils_rna_array_cb = { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |     (BaseMathCheckFunc)mathutils_rna_generic_check, | 
					
						
							|  |  |  |     (BaseMathGetFunc)mathutils_rna_vector_get, | 
					
						
							|  |  |  |     (BaseMathSetFunc)mathutils_rna_vector_set, | 
					
						
							|  |  |  |     (BaseMathGetIndexFunc)mathutils_rna_vector_get_index, | 
					
						
							| 
									
										
										
										
											2019-01-19 13:21:18 +11:00
										 |  |  |     (BaseMathSetIndexFunc)mathutils_rna_vector_set_index, | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | /* bpyrna matrix callbacks */ | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  | static uchar mathutils_rna_matrix_cb_index = -1; /* Index for our callbacks. */ | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  | static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype)) | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							| 
									
										
										
										
											2011-02-28 21:06:09 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  |   RNA_property_float_get_array(&self->ptr, self->prop, bmo->data); | 
					
						
							| 
									
										
										
										
											2011-02-28 21:06:09 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  | static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype)) | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							| 
									
										
										
										
											2011-02-28 21:06:09 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							| 
									
										
										
										
											2011-02-28 21:06:09 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #  endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-30 12:27:34 +00:00
										 |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy_prop \"%.200s.%.200s\" is read-only", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop)); | 
					
						
							| 
									
										
										
										
											2011-02-28 21:06:09 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2010-08-30 12:27:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Can ignore clamping here. */ | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  |   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_update_check(self->prop)) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     RNA_property_update(BPY_context_get(), &self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-28 21:06:09 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static Mathutils_Callback mathutils_rna_matrix_cb = { | 
					
						
							| 
									
										
										
										
											2010-04-27 19:21:36 +00:00
										 |  |  |     mathutils_rna_generic_check, | 
					
						
							|  |  |  |     mathutils_rna_matrix_get, | 
					
						
							|  |  |  |     mathutils_rna_matrix_set, | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-01-19 13:21:18 +11:00
										 |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static short pyrna_rotation_euler_order_get(PointerRNA *ptr, | 
					
						
							|  |  |  |                                             const short order_fallback, | 
					
						
							|  |  |  |                                             PropertyRNA **r_prop_eul_order) | 
					
						
							| 
									
										
										
										
											2010-02-27 15:28:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Attempt to get order. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |   if (*r_prop_eul_order == NULL) { | 
					
						
							|  |  |  |     *r_prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode"); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |   if (*r_prop_eul_order) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const short order = RNA_property_enum_get(ptr, *r_prop_eul_order); | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |     /* Could be quaternion or axis-angle. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |     if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) { | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  |       return order; | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-27 15:28:34 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  |   return order_fallback; | 
					
						
							| 
									
										
										
										
											2010-02-27 15:28:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_MATHUTILS */
 | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Note that #PROP_NONE is included as a vector subtype. this is because it is handy to | 
					
						
							|  |  |  |  * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | #define PROP_ALL_VECTOR_SUBTYPES \
 | 
					
						
							| 
									
										
										
										
											2012-06-06 14:48:39 +00:00
										 |  |  |   PROP_COORDS: \ | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |   case PROP_TRANSLATION: \ | 
					
						
							|  |  |  |   case PROP_DIRECTION: \ | 
					
						
							|  |  |  |   case PROP_VELOCITY: \ | 
					
						
							|  |  |  |   case PROP_ACCELERATION: \ | 
					
						
							|  |  |  |   case PROP_XYZ: \ | 
					
						
							|  |  |  |   case PROP_XYZ_LENGTH | 
					
						
							| 
									
										
										
										
											2010-01-04 13:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *ret = NULL; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							| 
									
										
										
										
											2009-11-24 20:15:24 +00:00
										 |  |  |   int subtype, totdim; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |   int len; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const int flag = RNA_property_flag(prop); | 
					
						
							| 
									
										
										
										
											2014-08-25 23:53:34 +10:00
										 |  |  |   const int type = RNA_property_type(prop); | 
					
						
							|  |  |  |   const bool is_thick = (flag & PROP_THICK_WRAP) != 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-24 20:15:24 +00:00
										 |  |  |   /* disallow dynamic sized arrays to be wrapped since the size could change
 | 
					
						
							|  |  |  |    * to a size mathutils does not support */ | 
					
						
							| 
									
										
										
										
											2014-08-25 23:53:34 +10:00
										 |  |  |   if (flag & PROP_DYNAMIC) { | 
					
						
							| 
									
										
										
										
											2009-11-24 20:15:24 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2014-08-25 23:53:34 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   len = RNA_property_array_length(ptr, prop); | 
					
						
							| 
									
										
										
										
											2014-08-25 23:53:34 +10:00
										 |  |  |   if (type == PROP_FLOAT) { | 
					
						
							|  |  |  |     /* pass */ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (type == PROP_INT) { | 
					
						
							|  |  |  |     if (is_thick) { | 
					
						
							|  |  |  |       goto thick_wrap_slice; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   subtype = RNA_property_subtype(prop); | 
					
						
							|  |  |  |   totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |   if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) { | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (!is_thick) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Owned by the mathutils PyObject. */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       ret = pyrna_prop_CreatePyObject(ptr, prop); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-18 08:50:06 +00:00
										 |  |  |     switch (subtype) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_ALL_VECTOR_SUBTYPES: | 
					
						
							|  |  |  |         if (len >= 2 && len <= 4) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |             ret = Vector_CreatePyObject(NULL, len, NULL); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |             PyObject *vec_cb = Vector_CreatePyObject_cb( | 
					
						
							|  |  |  |                 ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             Py_DECREF(ret); /* The vector owns 'ret' now. */ | 
					
						
							|  |  |  |             ret = vec_cb;   /* Return the vector instead. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2009-12-28 22:59:09 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case PROP_MATRIX: | 
					
						
							|  |  |  |         if (len == 16) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |             ret = Matrix_CreatePyObject(NULL, 4, 4, NULL); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |             PyObject *mat_cb = Matrix_CreatePyObject_cb( | 
					
						
							|  |  |  |                 ret, 4, 4, mathutils_rna_matrix_cb_index, 0); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             Py_DECREF(ret); /* The matrix owns 'ret' now. */ | 
					
						
							|  |  |  |             ret = mat_cb;   /* Return the matrix instead. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2009-12-28 22:59:09 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         else if (len == 9) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |             ret = Matrix_CreatePyObject(NULL, 3, 3, NULL); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |             PyObject *mat_cb = Matrix_CreatePyObject_cb( | 
					
						
							|  |  |  |                 ret, 3, 3, mathutils_rna_matrix_cb_index, 0); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             Py_DECREF(ret); /* The matrix owns 'ret' now. */ | 
					
						
							|  |  |  |             ret = mat_cb;   /* Return the matrix instead. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2009-12-28 22:59:09 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case PROP_EULER: | 
					
						
							|  |  |  |       case PROP_QUATERNION: | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         if (len == 3) { /* Euler. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (is_thick) { | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |             /* Attempt to get order,
 | 
					
						
							|  |  |  |              * only needed for thick types since wrapped with update via callbacks. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             PropertyRNA *prop_eul_order = NULL; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |             const short order = pyrna_rotation_euler_order_get( | 
					
						
							|  |  |  |                 ptr, EULER_ORDER_XYZ, &prop_eul_order); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |             ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO: get order from RNA. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Order will be updated from callback on use. */ | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |             /* TODO: get order from RNA. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |             PyObject *eul_cb = Euler_CreatePyObject_cb( | 
					
						
							|  |  |  |                 ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             Py_DECREF(ret); /* The euler owns 'ret' now. */ | 
					
						
							|  |  |  |             ret = eul_cb;   /* Return the euler instead. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2009-12-28 22:59:09 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         else if (len == 4) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |             ret = Quaternion_CreatePyObject(NULL, NULL); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |             PyObject *quat_cb = Quaternion_CreatePyObject_cb( | 
					
						
							|  |  |  |                 ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             Py_DECREF(ret); /* The quat owns 'ret' now. */ | 
					
						
							|  |  |  |             ret = quat_cb;  /* Return the quat instead. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2010-04-11 14:22:27 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case PROP_COLOR: | 
					
						
							|  |  |  |       case PROP_COLOR_GAMMA: | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         if (len == 3) { /* Color. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (is_thick) { | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |             ret = Color_CreatePyObject(NULL, NULL); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |             PyObject *col_cb = Color_CreatePyObject_cb( | 
					
						
							|  |  |  |                 ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             Py_DECREF(ret); /* The color owns 'ret' now. */ | 
					
						
							|  |  |  |             ret = col_cb;   /* Return the color instead. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2010-04-11 14:22:27 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       default: | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (ret == NULL) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (is_thick) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* This is an array we can't reference (since it is not thin wrappable)
 | 
					
						
							|  |  |  |        * and cannot be coerced into a mathutils type, so return as a list. */ | 
					
						
							| 
									
										
										
										
											2014-08-25 23:53:34 +10:00
										 |  |  |     thick_wrap_slice: | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len); | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       ret = pyrna_prop_CreatePyObject(ptr, prop); /* Owned by the mathutils PyObject. */ | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #else  /* USE_MATHUTILS */
 | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  |   (void)ptr; | 
					
						
							|  |  |  |   (void)prop; | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_MATHUTILS */
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 14:18:18 +10:00
										 |  |  | /* NOTE(@campbellbarton): Regarding comparison `__cmp__`:
 | 
					
						
							| 
									
										
										
										
											2012-01-15 12:35:40 +00:00
										 |  |  |  * checking the 'ptr->data' matches works in almost all cases, | 
					
						
							|  |  |  |  * however there are a few RNA properties that are fake sub-structs and | 
					
						
							|  |  |  |  * share the pointer with the parent, in those cases this happens 'a.b == a' | 
					
						
							|  |  |  |  * see: r43352 for example. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * So compare the 'ptr->type' as well to avoid this problem. | 
					
						
							|  |  |  |  * It's highly unlikely this would happen that 'ptr->data' and 'ptr->prop' would match, | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |  * but _not_ 'ptr->type' but include this check for completeness. */ | 
					
						
							| 
									
										
										
										
											2012-01-15 12:35:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b) | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |   return (((a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ? 0 : -1); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |   return (((a->prop == b->prop) && (a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ? | 
					
						
							|  |  |  |               0 : | 
					
						
							|  |  |  |               -1); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op) | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  |   PyObject *res; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   int ok = -1; /* Zero is true. */ | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   switch (op) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case Py_NE: | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |       ok = !ok; | 
					
						
							| 
									
										
										
										
											2017-05-20 14:01:03 +10:00
										 |  |  |       ATTR_FALLTHROUGH; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case Py_EQ: | 
					
						
							|  |  |  |       res = ok ? Py_False : Py_True; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case Py_LT: | 
					
						
							|  |  |  |     case Py_LE: | 
					
						
							|  |  |  |     case Py_GT: | 
					
						
							|  |  |  |     case Py_GE: | 
					
						
							|  |  |  |       res = Py_NotImplemented; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       PyErr_BadArgument(); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  |   return Py_INCREF_RET(res); | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op) | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  |   PyObject *res; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   int ok = -1; /* Zero is true. */ | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   switch (op) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case Py_NE: | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |       ok = !ok; | 
					
						
							| 
									
										
										
										
											2017-05-20 14:01:03 +10:00
										 |  |  |       ATTR_FALLTHROUGH; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case Py_EQ: | 
					
						
							|  |  |  |       res = ok ? Py_False : Py_True; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case Py_LT: | 
					
						
							|  |  |  |     case Py_LE: | 
					
						
							|  |  |  |     case Py_GT: | 
					
						
							|  |  |  |     case Py_GE: | 
					
						
							|  |  |  |       res = Py_NotImplemented; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       PyErr_BadArgument(); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  |   return Py_INCREF_RET(res); | 
					
						
							| 
									
										
										
										
											2009-01-29 09:38:52 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | /*----------------------repr--------------------------------------------*/ | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static PyObject *pyrna_struct_str(BPy_StructRNA *self) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *name; | 
					
						
							| 
									
										
										
										
											2020-09-13 15:37:01 +10:00
										 |  |  |   const char *extra_info = ""; | 
					
						
							| 
									
										
										
										
											2009-03-23 13:28:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (!PYRNA_STRUCT_IS_VALID(self)) { | 
					
						
							| 
									
										
										
										
											2012-11-01 17:16:24 +00:00
										 |  |  |     return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 15:37:01 +10:00
										 |  |  |   ID *id = self->ptr.owner_id; | 
					
						
							|  |  |  |   if (id && id != DEG_get_original_id(id)) { | 
					
						
							|  |  |  |     extra_info = ", evaluated"; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Print name if available.
 | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Always include the pointer address since it can help identify unique data, | 
					
						
							|  |  |  |    * or when data is re-allocated internally. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (name) { | 
					
						
							| 
									
										
										
										
											2020-09-13 15:37:01 +10:00
										 |  |  |     ret = PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\") at %p%s>", | 
					
						
							|  |  |  |                                RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                                name, | 
					
						
							|  |  |  |                                self->ptr.data, | 
					
						
							|  |  |  |                                extra_info); | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |     MEM_freeN((void *)name); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2009-03-23 13:28:42 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 15:37:01 +10:00
										 |  |  |   return PyUnicode_FromFormat("<bpy_struct, %.200s at %p%s>", | 
					
						
							|  |  |  |                               RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                               self->ptr.data, | 
					
						
							|  |  |  |                               extra_info); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  | static PyObject *pyrna_struct_repr(BPy_StructRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   ID *id = self->ptr.owner_id; | 
					
						
							| 
									
										
										
										
											2011-08-22 18:13:37 +00:00
										 |  |  |   PyObject *tmp_str; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 15:37:01 +10:00
										 |  |  |   if (id == NULL || !PYRNA_STRUCT_IS_VALID(self) || (DEG_get_original_id(id) != id)) { | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     /* fallback */ | 
					
						
							|  |  |  |     return pyrna_struct_str(self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   tmp_str = PyUnicode_FromString(id->name + 2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 15:37:01 +10:00
										 |  |  |   if (RNA_struct_is_ID(self->ptr.type) && (id->flag & LIB_EMBEDDED_DATA) == 0) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = PyUnicode_FromFormat( | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  |         "bpy.data.%s[%R]", BKE_idtype_idcode_to_name_plural(GS(id->name)), tmp_str); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |     const char *path; | 
					
						
							| 
									
										
										
										
											2019-09-02 18:37:55 +02:00
										 |  |  |     ID *real_id = NULL; | 
					
						
							|  |  |  |     path = RNA_path_from_real_ID_to_struct(G_MAIN, &self->ptr, &real_id); | 
					
						
							| 
									
										
										
										
											2019-10-04 12:24:26 +02:00
										 |  |  |     if (path != NULL) { | 
					
						
							| 
									
										
										
										
											2019-10-10 10:25:46 +11:00
										 |  |  |       /* 'real_id' may be NULL in some cases, although the only valid one is evaluated data,
 | 
					
						
							|  |  |  |        * which should have already been caught above. | 
					
						
							| 
									
										
										
										
											2019-10-04 12:24:26 +02:00
										 |  |  |        * So assert, but handle it without crashing for release builds. */ | 
					
						
							|  |  |  |       BLI_assert(real_id != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (real_id != NULL) { | 
					
						
							| 
									
										
										
										
											2019-09-02 18:37:55 +02:00
										 |  |  |         Py_DECREF(tmp_str); | 
					
						
							|  |  |  |         tmp_str = PyUnicode_FromString(real_id->name + 2); | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  |         ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s", | 
					
						
							|  |  |  |                                    BKE_idtype_idcode_to_name_plural(GS(real_id->name)), | 
					
						
							|  |  |  |                                    tmp_str, | 
					
						
							|  |  |  |                                    path); | 
					
						
							| 
									
										
										
										
											2019-10-04 12:24:26 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         /* Can't find the path, print something useful as a fallback. */ | 
					
						
							|  |  |  |         ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  |                                    BKE_idtype_idcode_to_name_plural(GS(id->name)), | 
					
						
							| 
									
										
										
										
											2019-10-04 12:24:26 +02:00
										 |  |  |                                    tmp_str, | 
					
						
							|  |  |  |                                    RNA_struct_identifier(self->ptr.type)); | 
					
						
							| 
									
										
										
										
											2012-04-10 16:37:05 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |       MEM_freeN((void *)path); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     else { | 
					
						
							|  |  |  |       /* Can't find the path, print something useful as a fallback. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  |                                  BKE_idtype_idcode_to_name_plural(GS(id->name)), | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |                                  tmp_str, | 
					
						
							|  |  |  |                                  RNA_struct_identifier(self->ptr.type)); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 18:13:37 +00:00
										 |  |  |   Py_DECREF(tmp_str); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 18:13:37 +00:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2009-03-23 13:28:42 +00:00
										 |  |  |   PointerRNA ptr; | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *name; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const char *type_id = NULL; | 
					
						
							|  |  |  |   char type_fmt[64] = ""; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   int type; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   type = RNA_property_type(self->prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 13:49:52 +11:00
										 |  |  |   if (RNA_enum_id_from_value(rna_enum_property_type_items, type, &type_id) == 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Should never happen. */ | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   /* This should never fail. */ | 
					
						
							|  |  |  |   int len = -1; | 
					
						
							|  |  |  |   char *c = type_fmt; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   while ((*c++ = tolower(*type_id++))) { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (type == PROP_COLLECTION) { | 
					
						
							|  |  |  |     len = pyrna_prop_collection_length(self); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (RNA_property_array_check(self->prop)) { | 
					
						
							|  |  |  |     len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (len != -1) { | 
					
						
							|  |  |  |     sprintf(--c, "[%d]", len); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* If a pointer, try to print name of pointer target too. */ | 
					
						
							| 
									
										
										
										
											2011-11-15 11:56:54 +00:00
										 |  |  |   if (type == PROP_POINTER) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ptr = RNA_property_pointer_get(&self->ptr, self->prop); | 
					
						
							|  |  |  |     name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (name) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |                                  type_fmt, | 
					
						
							|  |  |  |                                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                                  RNA_property_identifier(self->prop), | 
					
						
							|  |  |  |                                  name); | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |       MEM_freeN((void *)name); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |       return ret; | 
					
						
							| 
									
										
										
										
											2009-03-23 13:28:42 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-11-15 11:56:54 +00:00
										 |  |  |   if (type == PROP_COLLECTION) { | 
					
						
							| 
									
										
										
										
											2011-02-14 03:15:55 +00:00
										 |  |  |     PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |       return PyUnicode_FromFormat( | 
					
						
							|  |  |  |           "<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type)); | 
					
						
							| 
									
										
										
										
											2011-02-14 03:15:55 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |   return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>", | 
					
						
							|  |  |  |                               type_fmt, | 
					
						
							|  |  |  |                               RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                               RNA_property_identifier(self->prop)); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-28 22:23:39 +10:00
										 |  |  | static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, const int index) | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   ID *id = self->ptr.owner_id; | 
					
						
							| 
									
										
										
										
											2011-08-22 18:13:37 +00:00
										 |  |  |   PyObject *tmp_str; | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *path; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (id == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Fallback. */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     return pyrna_prop_str(self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   tmp_str = PyUnicode_FromString(id->name + 2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-02 18:37:55 +02:00
										 |  |  |   /* Note that using G_MAIN is absolutely not ideal, but we have no access to actual Main DB from
 | 
					
						
							|  |  |  |    * here. */ | 
					
						
							|  |  |  |   ID *real_id = NULL; | 
					
						
							|  |  |  |   path = RNA_path_from_real_ID_to_property_index( | 
					
						
							|  |  |  |       G_MAIN, &self->ptr, self->prop, index_dim, index, &real_id); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (path) { | 
					
						
							| 
									
										
										
										
											2019-09-02 18:37:55 +02:00
										 |  |  |     if (real_id != id) { | 
					
						
							|  |  |  |       Py_DECREF(tmp_str); | 
					
						
							|  |  |  |       tmp_str = PyUnicode_FromString(real_id->name + 2); | 
					
						
							| 
									
										
										
										
											2012-04-10 16:37:05 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-02 18:37:55 +02:00
										 |  |  |     const char *data_delim = (path[0] == '[') ? "" : "."; | 
					
						
							|  |  |  |     ret = PyUnicode_FromFormat("bpy.data.%s[%R]%s%s", | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  |                                BKE_idtype_idcode_to_name_plural(GS(real_id->name)), | 
					
						
							| 
									
										
										
										
											2019-09-02 18:37:55 +02:00
										 |  |  |                                tmp_str, | 
					
						
							|  |  |  |                                data_delim, | 
					
						
							|  |  |  |                                path); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |     MEM_freeN((void *)path); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   else { | 
					
						
							|  |  |  |     /* Can't find the path, print something useful as a fallback. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", | 
					
						
							| 
									
										
										
										
											2020-03-19 19:37:00 +01:00
										 |  |  |                                BKE_idtype_idcode_to_name_plural(GS(id->name)), | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |                                tmp_str, | 
					
						
							|  |  |  |                                RNA_property_identifier(self->prop)); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 18:13:37 +00:00
										 |  |  |   Py_DECREF(tmp_str); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-28 22:23:39 +10:00
										 |  |  | static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return pyrna_prop_repr_ex(self, 0, -1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_array_repr(BPy_PropertyArrayRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return pyrna_prop_repr_ex((BPy_PropertyRNA *)self, self->arraydim, self->arrayoffset); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_func_repr(BPy_FunctionRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |   return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>", | 
					
						
							|  |  |  |                               Py_TYPE(self)->tp_name, | 
					
						
							|  |  |  |                               RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                               RNA_function_identifier(self->func)); | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-26 17:20:36 +00:00
										 |  |  | static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:36:35 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  |   return _Py_HashPointer(self->ptr.data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* From Python's meth_hash v3.1.2. */ | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  | static long pyrna_prop_hash(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |   long x, y; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (self->ptr.data == NULL) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     x = 0; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     x = _Py_HashPointer(self->ptr.data); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (x == -1) { | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   y = _Py_HashPointer((void *)(self->prop)); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (y == -1) { | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  |   x ^= y; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (x == -1) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     x = -2; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  |   return x; | 
					
						
							| 
									
										
										
										
											2008-12-02 14:36:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							|  |  |  | static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Py_VISIT(self->reference); | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int pyrna_struct_clear(BPy_StructRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Py_CLEAR(self->reference); | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Use our own dealloc so we can free a property if we use one. */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | static void pyrna_struct_dealloc(BPy_StructRNA *self) | 
					
						
							| 
									
										
										
										
											2008-12-29 03:24:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-05 16:29:38 +00:00
										 |  |  | #ifdef PYRNA_FREE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2009-01-08 15:29:09 +00:00
										 |  |  |   if (self->freeptr && self->ptr.data) { | 
					
						
							| 
									
										
										
										
											2010-01-29 14:49:21 +00:00
										 |  |  |     IDP_FreeProperty(self->ptr.data); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     self->ptr.data = NULL; | 
					
						
							| 
									
										
										
										
											2008-12-29 03:24:13 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-05 16:29:38 +00:00
										 |  |  | #endif /* PYRNA_FREE_SUPPORT */
 | 
					
						
							| 
									
										
										
										
											2008-12-29 03:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |   if (self->in_weakreflist != NULL) { | 
					
						
							|  |  |  |     PyObject_ClearWeakRefs((PyObject *)self); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (self->reference) { | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     pyrna_struct_clear(self); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  |   Py_TYPE(self)->tp_free(self); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							|  |  |  | static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (self->reference) { | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     Py_CLEAR(self->reference); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Reference is now NULL. */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (reference) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     self->reference = reference; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  |     Py_INCREF(reference); | 
					
						
							| 
									
										
										
										
											2022-09-28 16:09:12 +10:00
										 |  |  |     BLI_assert(!PyObject_GC_IsTracked((PyObject *)self)); | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  |     PyObject_GC_Track(self); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Use our own dealloc so we can free a property if we use one. */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | static void pyrna_prop_dealloc(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |   if (self->in_weakreflist != NULL) { | 
					
						
							|  |  |  |     PyObject_ClearWeakRefs((PyObject *)self); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  |   Py_TYPE(self)->tp_free(self); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |   if (self->in_weakreflist != NULL) { | 
					
						
							|  |  |  |     PyObject_ClearWeakRefs((PyObject *)self); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */ | 
					
						
							| 
									
										
										
										
											2009-03-16 15:54:43 +00:00
										 |  |  |   Py_TYPE(self)->tp_free(self); | 
					
						
							| 
									
										
										
										
											2008-12-29 03:24:13 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 17:05:21 +00:00
										 |  |  | static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) | 
					
						
							| 
									
										
										
										
											2008-12-25 10:48:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-18 15:07:26 +11:00
										 |  |  |   const EnumPropertyItem *item; | 
					
						
							| 
									
										
										
										
											2010-12-03 17:05:21 +00:00
										 |  |  |   const char *result; | 
					
						
							| 
									
										
										
										
											2014-01-04 18:08:43 +11:00
										 |  |  |   bool free = false; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |   RNA_property_enum_items(BPY_context_get(), ptr, prop, &item, NULL, &free); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (item) { | 
					
						
							| 
									
										
										
										
											2021-09-01 16:50:48 +10:00
										 |  |  |     result = pyrna_enum_repr(item); | 
					
						
							| 
									
										
										
										
											2009-07-13 19:33:59 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     result = ""; | 
					
						
							| 
									
										
										
										
											2009-07-13 19:33:59 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 15:07:26 +11:00
										 |  |  |   if (free) { | 
					
						
							|  |  |  |     MEM_freeN((void *)item); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												RNA
* Enums can now be dynamically created in the _itemf callback,
  using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
  for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
  for operators. This doesn't fit design well at all, needed to do
  some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
  _itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
  (unselected, deselect), to make them consistent with other ops.
											
										 
											2009-07-10 19:56:13 +00:00
										 |  |  |   return result; | 
					
						
							| 
									
										
										
										
											2008-12-25 10:48:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 14:36:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static int pyrna_string_to_enum( | 
					
						
							|  |  |  |     PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *r_value, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:00:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *param = PyUnicode_AsUTF8(item); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (param == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2011-12-29 14:46:26 +00:00
										 |  |  |                  "%.200s expected a string enum, not %.200s", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |   if (!RNA_property_enum_value(BPY_context_get(), ptr, prop, param, r_value)) { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     const char *enum_str = pyrna_enum_as_string(ptr, prop); | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s enum \"%.200s\" not found in (%s)", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  param, | 
					
						
							|  |  |  |                  enum_str); | 
					
						
							|  |  |  |     MEM_freeN((void *)enum_str); | 
					
						
							|  |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:00:39 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-29 14:46:26 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:00:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static int pyrna_prop_to_enum_bitfield( | 
					
						
							|  |  |  |     PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-18 15:07:26 +11:00
										 |  |  |   const EnumPropertyItem *item; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  |   int ret; | 
					
						
							| 
									
										
										
										
											2014-01-04 18:08:43 +11:00
										 |  |  |   bool free = false; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   *r_value = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-25 17:01:33 +00:00
										 |  |  |   if (!PyAnySet_Check(value)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s, %.200s.%.200s expected a set, not a %.200s", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                  RNA_property_identifier(prop), | 
					
						
							|  |  |  |                  Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |   RNA_property_enum_items(BPY_context_get(), ptr, prop, &item, NULL, &free); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (item) { | 
					
						
							| 
									
										
										
										
											2021-09-01 16:50:48 +10:00
										 |  |  |     ret = pyrna_enum_bitfield_from_set(item, value, r_value, error_prefix); | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (PySet_GET_SIZE(value)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%.200s: empty enum \"%.200s\" could not have any values assigned", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    RNA_property_identifier(prop)); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = -1; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = 0; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 15:07:26 +11:00
										 |  |  |   if (free) { | 
					
						
							|  |  |  |     MEM_freeN((void *)item); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  | static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *item, *ret = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  |     const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = PySet_New(NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     if (RNA_property_enum_bitflag_identifiers(BPY_context_get(), ptr, prop, val, identifier)) { | 
					
						
							| 
									
										
										
										
											2009-12-07 02:20:55 +00:00
										 |  |  |       int index; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       for (index = 0; identifier[index]; index++) { | 
					
						
							|  |  |  |         item = PyUnicode_FromString(identifier[index]); | 
					
						
							| 
									
										
										
										
											2009-12-07 02:20:55 +00:00
										 |  |  |         PySet_Add(ret, item); | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2008-12-02 14:36:35 +00:00
										 |  |  |     const char *identifier; | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     if (RNA_property_enum_identifier(BPY_context_get(), ptr, prop, val, &identifier)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = PyUnicode_FromString(identifier); | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  |       /* Static, no need to free. */ | 
					
						
							|  |  |  |       const EnumPropertyItem *enum_item; | 
					
						
							|  |  |  |       bool free_dummy; | 
					
						
							|  |  |  |       RNA_property_enum_items_ex(NULL, ptr, prop, true, &enum_item, NULL, &free_dummy); | 
					
						
							|  |  |  |       BLI_assert(!free_dummy); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |       /* Do not print warning in case of DummyRNA_NULL_items,
 | 
					
						
							|  |  |  |        * this one will never match any value... */ | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  |       if (enum_item != DummyRNA_NULL_items) { | 
					
						
							|  |  |  |         const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Prefer not to fail silently in case of API errors, maybe disable it later. */ | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  |         CLOG_WARN(BPY_LOG_RNA, | 
					
						
							|  |  |  |                   "current value '%d' " | 
					
						
							|  |  |  |                   "matches no enum in '%s', '%s', '%s'", | 
					
						
							|  |  |  |                   val, | 
					
						
							|  |  |  |                   RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                   ptr_name, | 
					
						
							|  |  |  |                   RNA_property_identifier(prop)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #if 0 /* Gives Python decoding errors while generating docs :( */
 | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  |         char error_str[256]; | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |         BLI_snprintf(error_str, | 
					
						
							|  |  |  |                      sizeof(error_str), | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  |                      "RNA Warning: Current value \"%d\" " | 
					
						
							|  |  |  |                      "matches no enum in '%s', '%s', '%s'", | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |                      val, | 
					
						
							|  |  |  |                      RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                      ptr_name, | 
					
						
							|  |  |  |                      RNA_property_identifier(prop)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  |         PyErr_Warn(PyExc_RuntimeWarning, error_str); | 
					
						
							| 
									
										
										
										
											2009-11-12 15:46:45 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         if (ptr_name) { | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  |           MEM_freeN((void *)ptr_name); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-07-08 09:23:49 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |       ret = PyUnicode_FromString(""); | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-02 08:29:16 +00:00
										 |  |  | PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const int type = RNA_property_type(prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-14 10:28:18 +00:00
										 |  |  |   if (RNA_property_array_check(prop)) { | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  |     return pyrna_py_from_array(ptr, prop); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* See if we can coerce into a Python type - 'PropertyType'. */ | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  |   switch (type) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |     case PROP_BOOLEAN: | 
					
						
							|  |  |  |       ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PROP_INT: | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |       ret = PyLong_FromLong(RNA_property_int_get(ptr, prop)); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case PROP_FLOAT: | 
					
						
							|  |  |  |       ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PROP_STRING: { | 
					
						
							|  |  |  |       const int subtype = RNA_property_subtype(prop); | 
					
						
							|  |  |  |       const char *buf; | 
					
						
							|  |  |  |       int buf_len; | 
					
						
							|  |  |  |       char buf_fixed[32]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len); | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2022-09-16 18:13:19 +10:00
										 |  |  |       /* Only file paths get special treatment, they may contain non UTF-8 chars. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  |         ret = PyBytes_FromStringAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-07-20 01:30:29 +10:00
										 |  |  |       else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         ret = PyC_UnicodeFromByteAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         ret = PyUnicode_FromStringAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #else  /* USE_STRING_COERCE */
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  |         ret = PyBytes_FromStringAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         ret = PyUnicode_FromStringAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_STRING_COERCE */
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       if (buf_fixed != buf) { | 
					
						
							|  |  |  |         MEM_freeN((void *)buf); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2011-09-01 09:47:21 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |     case PROP_ENUM: { | 
					
						
							|  |  |  |       ret = pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop)); | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |     case PROP_POINTER: { | 
					
						
							|  |  |  |       PointerRNA newptr; | 
					
						
							|  |  |  |       newptr = RNA_property_pointer_get(ptr, prop); | 
					
						
							|  |  |  |       if (newptr.data) { | 
					
						
							|  |  |  |         ret = pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         ret = Py_None; | 
					
						
							|  |  |  |         Py_INCREF(ret); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |     case PROP_COLLECTION: | 
					
						
							|  |  |  |       ret = pyrna_prop_CreatePyObject(ptr, prop); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)", | 
					
						
							|  |  |  |                    type); | 
					
						
							|  |  |  |       ret = NULL; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | int pyrna_pydict_to_props(PointerRNA *ptr, | 
					
						
							|  |  |  |                           PyObject *kw, | 
					
						
							|  |  |  |                           const bool all_args, | 
					
						
							|  |  |  |                           const char *error_prefix) | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   int error_val = 0; | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |   int totkw; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const char *arg_name = NULL; | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |   PyObject *item; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |   totkw = kw ? PyDict_Size(kw) : 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |   RNA_STRUCT_BEGIN (ptr, prop) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     arg_name = RNA_property_identifier(prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-10 06:18:03 +00:00
										 |  |  |     if (STREQ(arg_name, "rna_type")) { | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if (kw == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%.200s: no keywords, expected \"%.200s\"", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    arg_name ? arg_name : "<UNKNOWN>"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       error_val = -1; | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-22 10:42:32 -07:00
										 |  |  |     item = PyDict_GetItemString(kw, arg_name); /* Won't set an error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |     if (item == NULL) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (all_args) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%.200s: keyword \"%.200s\" missing", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      arg_name ? arg_name : "<UNKNOWN>"); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         error_val = -1; /* pyrna_py_to_prop sets the error. */ | 
					
						
							| 
									
										
										
										
											2009-07-30 01:52:00 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  |       if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         error_val = -1; | 
					
						
							| 
									
										
										
										
											2009-07-30 01:52:00 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       totkw--; | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-24 21:27:10 +00:00
										 |  |  |   RNA_STRUCT_END; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   if (error_val == 0 && totkw > 0) { /* Some keywords were given that were not used :/. */ | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |     PyObject *key, *value; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     Py_ssize_t pos = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |     while (PyDict_Next(kw, &pos, &key, &value)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |       arg_name = PyUnicode_AsUTF8(key); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (RNA_struct_find_property(ptr, arg_name) == NULL) { | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       arg_name = NULL; | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s: keyword \"%.200s\" unrecognized", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  arg_name ? arg_name : "<UNKNOWN>"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     error_val = -1; | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |   return error_val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 06:58:19 +00:00
										 |  |  | static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func) | 
					
						
							| 
									
										
										
										
											2009-04-09 17:31:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |   BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *)PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   pyfunc->ptr = *ptr; | 
					
						
							|  |  |  |   pyfunc->func = func; | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  |   return (PyObject *)pyfunc; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static int pyrna_py_to_prop( | 
					
						
							|  |  |  |     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* XXX hard limits should be checked here. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const int type = RNA_property_type(prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-14 10:28:18 +00:00
										 |  |  |   if (RNA_property_array_check(prop)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Done getting the length. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) { | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Normal Property (not an array). */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* See if we can coerce into a Python type - 'PropertyType'. */ | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |     switch (type) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_BOOLEAN: { | 
					
						
							|  |  |  |         int param; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Prefer not to have an exception here
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |          * however so many poll functions return None or a valid Object. | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |          * It's a hassle to convert these into a bool before returning. */ | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |         if (RNA_parameter_flag(prop) & PARM_OUTPUT) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           param = PyObject_IsTrue(value); | 
					
						
							| 
									
										
										
										
											2012-12-20 03:08:27 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2017-08-20 15:44:54 +10:00
										 |  |  |           param = PyC_Long_AsI32(value); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           if (UNLIKELY(param & ~1)) { /* Only accept 0/1. */ | 
					
						
							|  |  |  |             param = -1;               /* Error out below. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-12-20 03:08:27 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-20 03:08:27 +00:00
										 |  |  |         if (param == -1) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                        "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s", | 
					
						
							|  |  |  |                        error_prefix, | 
					
						
							|  |  |  |                        RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                        RNA_property_identifier(prop), | 
					
						
							|  |  |  |                        Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (data) { | 
					
						
							|  |  |  |           *((bool *)data) = param; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           RNA_property_boolean_set(ptr, prop, param); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_INT: { | 
					
						
							|  |  |  |         int overflow; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |         const long param = PyLong_AsLongAndOverflow(value, &overflow); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         if (overflow || (param > INT_MAX) || (param < INT_MIN)) { | 
					
						
							|  |  |  |           PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                        "%.200s %.200s.%.200s value not in 'int' range " | 
					
						
							|  |  |  |                        "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")", | 
					
						
							|  |  |  |                        error_prefix, | 
					
						
							|  |  |  |                        RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                        RNA_property_identifier(prop)); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |         if (param == -1 && PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                        "%.200s %.200s.%.200s expected an int type, not %.200s", | 
					
						
							|  |  |  |                        error_prefix, | 
					
						
							|  |  |  |                        RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                        RNA_property_identifier(prop), | 
					
						
							|  |  |  |                        Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         int param_i = (int)param; | 
					
						
							|  |  |  |         if (data) { | 
					
						
							|  |  |  |           RNA_property_int_clamp(ptr, prop, ¶m_i); | 
					
						
							|  |  |  |           *((int *)data) = param_i; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           RNA_property_int_set(ptr, prop, param_i); | 
					
						
							| 
									
										
										
										
											2012-05-11 10:25:12 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_FLOAT: { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |         const float param = PyFloat_AsDouble(value); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         if (PyErr_Occurred()) { | 
					
						
							|  |  |  |           PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                        "%.200s %.200s.%.200s expected a float type, not %.200s", | 
					
						
							|  |  |  |                        error_prefix, | 
					
						
							|  |  |  |                        RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                        RNA_property_identifier(prop), | 
					
						
							|  |  |  |                        Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (data) { | 
					
						
							|  |  |  |           RNA_property_float_clamp(ptr, prop, (float *)¶m); | 
					
						
							|  |  |  |           *((float *)data) = param; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           RNA_property_float_set(ptr, prop, param); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_STRING: { | 
					
						
							|  |  |  |         const int subtype = RNA_property_subtype(prop); | 
					
						
							|  |  |  |         const char *param; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-30 16:11:39 +11:00
										 |  |  |         if (value == Py_None) { | 
					
						
							|  |  |  |           if ((RNA_property_flag(prop) & PROP_NEVER_NULL) == 0) { | 
					
						
							|  |  |  |             if (data) { | 
					
						
							| 
									
										
										
										
											2019-09-06 16:26:10 +03:00
										 |  |  |               if (RNA_property_flag(prop) & PROP_THICK_WRAP) { | 
					
						
							|  |  |  |                 *(char *)data = 0; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else { | 
					
						
							|  |  |  |                 *((char **)data) = (char *)NULL; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2018-10-30 16:11:39 +11:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               RNA_property_string_set(ptr, prop, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-10-30 16:11:39 +11:00
										 |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             PyC_Err_Format_Prefix(PyExc_TypeError, | 
					
						
							|  |  |  |                                   "%.200s %.200s.%.200s doesn't support None from string types", | 
					
						
							|  |  |  |                                   error_prefix, | 
					
						
							|  |  |  |                                   RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                                   RNA_property_identifier(prop)); | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-10-30 16:11:39 +11:00
										 |  |  |         } | 
					
						
							|  |  |  |         else if (subtype == PROP_BYTESTRING) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Byte String. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           param = PyBytes_AsString(value); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (param == NULL) { | 
					
						
							|  |  |  |             if (PyBytes_Check(value)) { | 
					
						
							|  |  |  |               /* there was an error assigning a string type,
 | 
					
						
							|  |  |  |                * rather than setting a new error, prefix the existing one | 
					
						
							|  |  |  |                */ | 
					
						
							|  |  |  |               PyC_Err_Format_Prefix(PyExc_TypeError, | 
					
						
							|  |  |  |                                     "%.200s %.200s.%.200s error assigning bytes", | 
					
						
							|  |  |  |                                     error_prefix, | 
					
						
							|  |  |  |                                     RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                                     RNA_property_identifier(prop)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                            "%.200s %.200s.%.200s expected a bytes type, not %.200s", | 
					
						
							|  |  |  |                            error_prefix, | 
					
						
							|  |  |  |                            RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                            RNA_property_identifier(prop), | 
					
						
							|  |  |  |                            Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           if (data) { | 
					
						
							|  |  |  |             if (RNA_property_flag(prop) & PROP_THICK_WRAP) { | 
					
						
							|  |  |  |               BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |               *((char **)data) = (char *)param; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           else { | 
					
						
							|  |  |  |             RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value)); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Unicode String. */ | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           PyObject *value_coerce = NULL; | 
					
						
							| 
									
										
										
										
											2014-07-20 01:30:29 +10:00
										 |  |  |           if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |             /* TODO: get size. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             param = PyC_UnicodeAsByte(value, &value_coerce); | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           else { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |             param = PyUnicode_AsUTF8(value); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #else  /* USE_STRING_COERCE */
 | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |           param = PyUnicode_AsUTF8(value); | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_STRING_COERCE */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (param == NULL) { | 
					
						
							|  |  |  |             if (PyUnicode_Check(value)) { | 
					
						
							|  |  |  |               /* there was an error assigning a string type,
 | 
					
						
							|  |  |  |                * rather than setting a new error, prefix the existing one | 
					
						
							|  |  |  |                */ | 
					
						
							|  |  |  |               PyC_Err_Format_Prefix(PyExc_TypeError, | 
					
						
							|  |  |  |                                     "%.200s %.200s.%.200s error assigning string", | 
					
						
							|  |  |  |                                     error_prefix, | 
					
						
							|  |  |  |                                     RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                                     RNA_property_identifier(prop)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                            "%.200s %.200s.%.200s expected a string type, not %.200s", | 
					
						
							|  |  |  |                            error_prefix, | 
					
						
							|  |  |  |                            RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                            RNA_property_identifier(prop), | 
					
						
							|  |  |  |                            Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           /* Same as bytes. */ | 
					
						
							|  |  |  |           /* XXX, this is suspect, but needed for function calls,
 | 
					
						
							|  |  |  |            * need to see if there's a better way. */ | 
					
						
							|  |  |  |           if (data) { | 
					
						
							|  |  |  |             if (RNA_property_flag(prop) & PROP_THICK_WRAP) { | 
					
						
							|  |  |  |               BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |               *((char **)data) = (char *)param; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           else { | 
					
						
							|  |  |  |             RNA_property_string_set(ptr, prop, param); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           Py_XDECREF(value_coerce); | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_STRING_COERCE */
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_ENUM: { | 
					
						
							|  |  |  |         int val = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Type checking is done by each function. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Set of enum items, concatenate all values with OR. */ | 
					
						
							| 
									
										
										
										
											2013-01-10 15:22:19 +00:00
										 |  |  |           if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Simple enum string. */ | 
					
						
							| 
									
										
										
										
											2013-01-10 15:22:19 +00:00
										 |  |  |           if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         if (data) { | 
					
						
							|  |  |  |           *((int *)data) = val; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_enum_set(ptr, prop, val); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-09-24 03:48:26 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_POINTER: { | 
					
						
							|  |  |  |         PyObject *value_new = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop); | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |         const int flag = RNA_property_flag(prop); | 
					
						
							|  |  |  |         const int flag_parameter = RNA_parameter_flag(prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* This is really nasty! Done so we can fake the operator having direct properties, eg:
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |          * layout.prop(self, "filepath") | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |          * ... which in fact should be: | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |          * layout.prop(self.properties, "filepath") | 
					
						
							|  |  |  |          * | 
					
						
							|  |  |  |          * we need to do this trick. | 
					
						
							| 
									
										
										
										
											2019-09-30 17:06:28 +10:00
										 |  |  |          * if the prop is not an operator type and the PyObject is an operator, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |          * use its properties in place of itself. | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |          * | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |          * This is so bad that it is almost a good reason to do away with fake | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |          * 'self.properties -> self' | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |          * class mixing. If this causes problems in the future it should be removed. | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |          */ | 
					
						
							| 
									
										
										
										
											2022-10-07 22:52:53 +11:00
										 |  |  |         if ((ptr_type == &RNA_AnyType) && BPy_StructRNA_Check(value)) { | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |           const StructRNA *base_type = RNA_struct_base_child_of( | 
					
						
							|  |  |  |               ((const BPy_StructRNA *)value)->ptr.type, NULL); | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  |           if (ELEM(base_type, &RNA_Operator, &RNA_Gizmo)) { | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |             value = PyObject_GetAttr(value, bpy_intern_str_properties); | 
					
						
							|  |  |  |             value_new = value; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  |         /* if property is an OperatorProperties/GizmoProperties pointer and value is a map,
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |          * forward back to pyrna_pydict_to_props */ | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |         if (PyDict_Check(value)) { | 
					
						
							|  |  |  |           const StructRNA *base_type = RNA_struct_base_child_of(ptr_type, NULL); | 
					
						
							|  |  |  |           if (base_type == &RNA_OperatorProperties) { | 
					
						
							|  |  |  |             PointerRNA opptr = RNA_property_pointer_get(ptr, prop); | 
					
						
							|  |  |  |             return pyrna_pydict_to_props(&opptr, value, false, error_prefix); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           if (base_type == &RNA_GizmoProperties) { | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |             PointerRNA opptr = RNA_property_pointer_get(ptr, prop); | 
					
						
							|  |  |  |             return pyrna_pydict_to_props(&opptr, value, false, error_prefix); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-18 16:31:15 -05:00
										 |  |  |         /* Another exception, allow passing a collection as an RNA property. */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           PointerRNA c_ptr; | 
					
						
							|  |  |  |           BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value; | 
					
						
							|  |  |  |           if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) { | 
					
						
							|  |  |  |             value = pyrna_struct_CreatePyObject(&c_ptr); | 
					
						
							|  |  |  |             value_new = value; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                          "%.200s %.200s.%.200s collection has no type, " | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                          "can't be used as a %.200s type", | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |                          error_prefix, | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                          RNA_property_identifier(prop), | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr_type)); | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |         BPy_StructRNA *param; | 
					
						
							|  |  |  |         if (value == Py_None) { | 
					
						
							|  |  |  |           if (flag & PROP_NEVER_NULL) { | 
					
						
							|  |  |  |             PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                          "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type", | 
					
						
							|  |  |  |                          error_prefix, | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                          RNA_property_identifier(prop), | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr_type)); | 
					
						
							|  |  |  |             Py_XDECREF(value_new); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           param = NULL; | 
					
						
							| 
									
										
										
										
											2010-08-24 03:02:27 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |         else { | 
					
						
							|  |  |  |           if (!BPy_StructRNA_Check(value)) { | 
					
						
							|  |  |  |             PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                          "%.200s %.200s.%.200s expected a %.200s type, not %.200s", | 
					
						
							|  |  |  |                          error_prefix, | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                          RNA_property_identifier(prop), | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr_type), | 
					
						
							|  |  |  |                          Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |             Py_XDECREF(value_new); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           param = (BPy_StructRNA *)value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           const ID *value_owner_id = ((BPy_StructRNA *)value)->ptr.owner_id; | 
					
						
							|  |  |  |           if (value_owner_id != NULL) { | 
					
						
							|  |  |  |             if ((flag & PROP_ID_SELF_CHECK) && (ptr->owner_id == value_owner_id)) { | 
					
						
							|  |  |  |               PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                            "%.200s %.200s.%.200s ID type does not support assignment to itself", | 
					
						
							|  |  |  |                            error_prefix, | 
					
						
							|  |  |  |                            RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                            RNA_property_identifier(prop)); | 
					
						
							|  |  |  |               Py_XDECREF(value_new); | 
					
						
							|  |  |  |               return -1; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-03-09 01:01:31 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (value_owner_id->tag & LIB_TAG_TEMP_MAIN) { | 
					
						
							|  |  |  |               /* Allow passing temporary ID's to functions, but not attribute assignment. */ | 
					
						
							|  |  |  |               if (ptr->type != &RNA_Function) { | 
					
						
							|  |  |  |                 PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                              "%.200s %.200s.%.200s ID type assignment is temporary, can't assign", | 
					
						
							|  |  |  |                              error_prefix, | 
					
						
							|  |  |  |                              RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                              RNA_property_identifier(prop)); | 
					
						
							|  |  |  |                 Py_XDECREF(value_new); | 
					
						
							|  |  |  |                 return -1; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2009-04-16 13:21:18 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |         bool raise_error = false; | 
					
						
							|  |  |  |         if (data) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (flag_parameter & PARM_RNAPTR) { | 
					
						
							|  |  |  |             if (flag & PROP_THICK_WRAP) { | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |               if (param == NULL) { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |                 memset(data, 0, sizeof(PointerRNA)); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							|  |  |  |                 *((PointerRNA *)data) = param->ptr; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2012-11-01 15:56:42 +00:00
										 |  |  |               else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |                 raise_error = true; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |               /* For function calls, we sometimes want to pass the 'ptr' directly,
 | 
					
						
							|  |  |  |                * but watch out that it remains valid! | 
					
						
							|  |  |  |                * We could possibly support this later if needed. */ | 
					
						
							|  |  |  |               BLI_assert(value_new == NULL); | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |               if (param == NULL) { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |                 *((void **)data) = NULL; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							|  |  |  |                 *((PointerRNA **)data) = ¶m->ptr; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else { | 
					
						
							|  |  |  |                 raise_error = true; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |           else if (param == NULL) { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |             *((void **)data) = NULL; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							|  |  |  |             *((void **)data) = param->ptr.data; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2009-06-07 13:09:18 +00:00
										 |  |  |           else { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |             raise_error = true; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           /* Data == NULL, assign to RNA. */ | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |           if ((param == NULL) || RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |             ReportList reports; | 
					
						
							|  |  |  |             BKE_reports_init(&reports, RPT_STORE); | 
					
						
							|  |  |  |             RNA_property_pointer_set( | 
					
						
							| 
									
										
										
										
											2021-03-03 14:57:52 +11:00
										 |  |  |                 ptr, prop, (param == NULL) ? PointerRNA_NULL : param->ptr, &reports); | 
					
						
							| 
									
										
										
										
											2022-10-07 22:52:53 +11:00
										 |  |  |             const int err = BPy_reports_to_error(&reports, PyExc_RuntimeError, true); | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |             if (err == -1) { | 
					
						
							|  |  |  |               Py_XDECREF(value_new); | 
					
						
							|  |  |  |               return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           else { | 
					
						
							|  |  |  |             raise_error = true; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |         if (raise_error) { | 
					
						
							|  |  |  |           if (pyrna_struct_validity_check(param) == -1) { | 
					
						
							|  |  |  |             /* Error set. */ | 
					
						
							| 
									
										
										
										
											2009-04-16 13:21:18 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |           else { | 
					
						
							|  |  |  |             PointerRNA tmp; | 
					
						
							|  |  |  |             RNA_pointer_create(NULL, ptr_type, NULL, &tmp); | 
					
						
							|  |  |  |             PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                          "%.200s %.200s.%.200s expected a %.200s type, not %.200s", | 
					
						
							|  |  |  |                          error_prefix, | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                          RNA_property_identifier(prop), | 
					
						
							|  |  |  |                          RNA_struct_identifier(tmp.type), | 
					
						
							|  |  |  |                          RNA_struct_identifier(param->ptr.type)); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           Py_XDECREF(value_new); | 
					
						
							|  |  |  |           return -1; | 
					
						
							| 
									
										
										
										
											2009-04-16 13:21:18 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         Py_XDECREF(value_new); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_COLLECTION: { | 
					
						
							|  |  |  |         Py_ssize_t seq_len, i; | 
					
						
							|  |  |  |         PyObject *item; | 
					
						
							|  |  |  |         PointerRNA itemptr; | 
					
						
							|  |  |  |         ListBase *lb; | 
					
						
							|  |  |  |         CollectionPointerLink *link; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         lb = (data) ? (ListBase *)data : NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Convert a sequence of dict's into a collection. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         if (!PySequence_Check(value)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |           PyErr_Format( | 
					
						
							|  |  |  |               PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |               "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s", | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |               error_prefix, | 
					
						
							|  |  |  |               RNA_struct_identifier(ptr->type), | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |               RNA_property_identifier(prop), | 
					
						
							|  |  |  |               Py_TYPE(value)->tp_name); | 
					
						
							| 
									
										
										
										
											2010-03-16 17:19:42 +00:00
										 |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         seq_len = PySequence_Size(value); | 
					
						
							|  |  |  |         for (i = 0; i < seq_len; i++) { | 
					
						
							|  |  |  |           item = PySequence_GetItem(value, i); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (item == NULL) { | 
					
						
							|  |  |  |             PyErr_Format( | 
					
						
							|  |  |  |                 PyExc_TypeError, | 
					
						
							|  |  |  |                 "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection", | 
					
						
							|  |  |  |                 error_prefix, | 
					
						
							|  |  |  |                 RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                 RNA_property_identifier(prop), | 
					
						
							|  |  |  |                 i); | 
					
						
							|  |  |  |             Py_XDECREF(item); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (PyDict_Check(item) == 0) { | 
					
						
							|  |  |  |             PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                          "%.200s %.200s.%.200s expected a each sequence " | 
					
						
							|  |  |  |                          "member to be a dict for an RNA collection, not %.200s", | 
					
						
							|  |  |  |                          error_prefix, | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                          RNA_property_identifier(prop), | 
					
						
							|  |  |  |                          Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |             Py_XDECREF(item); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (lb) { | 
					
						
							|  |  |  |             link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink"); | 
					
						
							|  |  |  |             link->ptr = itemptr; | 
					
						
							|  |  |  |             BLI_addtail(lb, link); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |           else { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             RNA_property_collection_add(ptr, prop, &itemptr); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |           if (pyrna_pydict_to_props( | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                   &itemptr, item, true, "Converting a Python list to an RNA collection") == -1) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             PyObject *msg = PyC_ExceptionBuffer(); | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |             const char *msg_char = PyUnicode_AsUTF8(msg); | 
					
						
							| 
									
										
										
										
											2022-05-03 17:54:37 +10:00
										 |  |  |             PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                          "%.200s %.200s.%.200s error converting a member of a collection " | 
					
						
							|  |  |  |                          "from a dicts into an RNA collection, failed with: %s", | 
					
						
							|  |  |  |                          error_prefix, | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                          RNA_property_identifier(prop), | 
					
						
							|  |  |  |                          msg_char); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             Py_DECREF(item); | 
					
						
							|  |  |  |             Py_DECREF(msg); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
											
												PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
											
										 
											2009-06-05 12:48:58 +00:00
										 |  |  |           Py_DECREF(item); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                      "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                      RNA_property_identifier(prop)); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Run RNA property functions. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_update_check(prop)) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     RNA_property_update(BPY_context_get(), ptr, prop); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |   return pyrna_py_from_array_index(self, &self->ptr, self->prop, index); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value) | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   int ret = 0; | 
					
						
							|  |  |  |   PointerRNA *ptr = &self->ptr; | 
					
						
							|  |  |  |   PropertyRNA *prop = self->prop; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const int totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |   if (totdim > 1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     // char error_str[512];
 | 
					
						
							| 
									
										
										
										
											2011-06-17 02:22:38 +00:00
										 |  |  |     if (pyrna_py_to_array_index( | 
					
						
							|  |  |  |             &self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Error is set. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = -1; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* See if we can coerce into a Python type - 'PropertyType'. */ | 
					
						
							| 
									
										
										
										
											2011-01-11 02:30:01 +00:00
										 |  |  |     switch (RNA_property_type(prop)) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_BOOLEAN: { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |         const int param = PyC_Long_AsBool(value); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 15:44:54 +10:00
										 |  |  |         if (param == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Error is set. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           ret = -1; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |           RNA_property_boolean_set_index(ptr, prop, index, param); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_INT: { | 
					
						
							| 
									
										
										
										
											2017-08-20 15:44:54 +10:00
										 |  |  |         int param = PyC_Long_AsI32(value); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         if (param == -1 && PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |           PyErr_SetString(PyExc_TypeError, "expected an int type"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           ret = -1; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2010-02-21 14:48:28 +00:00
										 |  |  |           RNA_property_int_clamp(ptr, prop, ¶m); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |           RNA_property_int_set_index(ptr, prop, index, param); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_FLOAT: { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         float param = PyFloat_AsDouble(value); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |         if (PyErr_Occurred()) { | 
					
						
							|  |  |  |           PyErr_SetString(PyExc_TypeError, "expected a float type"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           ret = -1; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2010-02-21 14:48:28 +00:00
										 |  |  |           RNA_property_float_clamp(ptr, prop, ¶m); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  |           RNA_property_float_set_index(ptr, prop, index, param); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       default: | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_AttributeError, "not an array type"); | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Run RNA property functions. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_update_check(prop)) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     RNA_property_update(BPY_context_get(), ptr, prop); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | /* ---------------sequence------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self) | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1) { | 
					
						
							| 
									
										
										
										
											2009-09-09 19:40:46 +00:00
										 |  |  |     return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return RNA_property_array_length(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |   return RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  | /* bool functions are for speed, so we can avoid getting the length
 | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  |  * of 1000's of items in a linked list for eg. */ | 
					
						
							|  |  |  | static int pyrna_prop_array_bool(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  |   return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 20:07:54 +11:00
										 |  |  |   return !RNA_property_collection_is_empty(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-11 05:45:59 +00:00
										 |  |  | /* notice getting the length of the collection is avoided unless negative
 | 
					
						
							|  |  |  |  * index is used or to detect internal error with a valid index. | 
					
						
							|  |  |  |  * This is done for faster lookups. */ | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (keynum < 0) { \ | 
					
						
							| 
									
										
										
										
											2012-07-03 10:32:10 +00:00
										 |  |  |     keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \ | 
					
						
							|  |  |  |     if (keynum_abs < 0) { \ | 
					
						
							|  |  |  |       PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum); \ | 
					
						
							|  |  |  |       return ret_err; \ | 
					
						
							|  |  |  |     } \ | 
					
						
							| 
									
										
										
										
											2012-05-27 20:13:59 +00:00
										 |  |  |   } \ | 
					
						
							|  |  |  |   (void)0 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 22:56:54 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \param result: The result of calling a subscription operation on a collection (never NULL). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int pyrna_prop_collection_subscript_is_valid_or_error(const PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (value != Py_None) { | 
					
						
							|  |  |  |     BLI_assert(BPy_StructRNA_Check(value)); | 
					
						
							|  |  |  |     const BPy_StructRNA *value_pyrna = (const BPy_StructRNA *)value; | 
					
						
							|  |  |  |     if (UNLIKELY(value_pyrna->ptr.type == NULL)) { | 
					
						
							|  |  |  |       /* It's important to use a `TypeError` as that is what's returned when `__getitem__` is
 | 
					
						
							|  |  |  |        * called on an object that doesn't support item access. */ | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "'%.200s' object is not subscriptable (only iteration is supported)", | 
					
						
							|  |  |  |                    Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Internal use only. */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PointerRNA newptr; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   Py_ssize_t keynum_abs = keynum; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |   PYRNA_PROP_COLLECTION_ABS_INDEX(NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 22:56:54 +10:00
										 |  |  |   if (RNA_property_collection_lookup_int_has_fn(self->prop)) { | 
					
						
							|  |  |  |     if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) { | 
					
						
							|  |  |  |       return pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* No callback defined, just iterate and find the nth item. */ | 
					
						
							| 
									
										
										
										
											2022-08-24 10:18:35 +10:00
										 |  |  |     const int key = (int)keynum_abs; | 
					
						
							| 
									
										
										
										
											2022-08-23 22:56:54 +10:00
										 |  |  |     PyObject *result = NULL; | 
					
						
							|  |  |  |     bool found = false; | 
					
						
							|  |  |  |     CollectionPropertyIterator iter; | 
					
						
							|  |  |  |     RNA_property_collection_begin(&self->ptr, self->prop, &iter); | 
					
						
							|  |  |  |     for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) { | 
					
						
							|  |  |  |       if (i == key) { | 
					
						
							|  |  |  |         result = pyrna_struct_CreatePyObject(&iter.ptr); | 
					
						
							|  |  |  |         found = true; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* It's important to end the iterator after `result` has been created
 | 
					
						
							|  |  |  |      * so iterators may optionally invalidate items that were iterated over, see: T100286. */ | 
					
						
							|  |  |  |     RNA_property_collection_end(&iter); | 
					
						
							|  |  |  |     if (found) { | 
					
						
							|  |  |  |       if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) { | 
					
						
							|  |  |  |         Py_DECREF(result); | 
					
						
							|  |  |  |         result = NULL; /* The exception has been set. */ | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return result; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   const int len = RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							|  |  |  |   if (keynum_abs >= len) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_IndexError, | 
					
						
							|  |  |  |                  "bpy_prop_collection[index]: " | 
					
						
							|  |  |  |                  "index %d out of range, size %d", | 
					
						
							|  |  |  |                  keynum, | 
					
						
							|  |  |  |                  len); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                  "bpy_prop_collection[index]: internal error, " | 
					
						
							|  |  |  |                  "valid index %d given in %d sized collection, but value not found", | 
					
						
							|  |  |  |                  keynum_abs, | 
					
						
							|  |  |  |                  len); | 
					
						
							| 
									
										
										
										
											2010-05-16 10:09:07 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Values type must have been already checked. */ | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                    Py_ssize_t keynum, | 
					
						
							|  |  |  |                                                    PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   Py_ssize_t keynum_abs = keynum; | 
					
						
							|  |  |  |   const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr; | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_COLLECTION_ABS_INDEX(-1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     const int len = RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (keynum_abs >= len) { | 
					
						
							| 
									
										
										
										
											2011-10-11 05:45:59 +00:00
										 |  |  |       PyErr_Format(PyExc_IndexError, | 
					
						
							|  |  |  |                    "bpy_prop_collection[index] = value: " | 
					
						
							|  |  |  |                    "index %d out of range, size %d", | 
					
						
							|  |  |  |                    keynum, | 
					
						
							|  |  |  |                    len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-11 05:45:59 +00:00
										 |  |  |       PyErr_Format(PyExc_IndexError, | 
					
						
							|  |  |  |                    "bpy_prop_collection[index] = value: " | 
					
						
							|  |  |  |                    "failed assignment (unknown reason)", | 
					
						
							|  |  |  |                    keynum); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   int len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   len = pyrna_prop_array_length(self); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (keynum < 0) { | 
					
						
							|  |  |  |     keynum += len; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (keynum >= 0 && keynum < len) { | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |     return pyrna_prop_array_to_py_index(self, keynum); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:51:45 +00:00
										 |  |  |   PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PointerRNA newptr; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 22:56:54 +10:00
										 |  |  |   if (RNA_property_collection_lookup_string_has_fn(self->prop)) { | 
					
						
							|  |  |  |     if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { | 
					
						
							|  |  |  |       return pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* No callback defined, just iterate and find the nth item. */ | 
					
						
							|  |  |  |     const int keylen = strlen(keyname); | 
					
						
							|  |  |  |     char name[256]; | 
					
						
							|  |  |  |     int namelen; | 
					
						
							|  |  |  |     PyObject *result = NULL; | 
					
						
							|  |  |  |     bool found = false; | 
					
						
							|  |  |  |     CollectionPropertyIterator iter; | 
					
						
							|  |  |  |     RNA_property_collection_begin(&self->ptr, self->prop, &iter); | 
					
						
							|  |  |  |     for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) { | 
					
						
							|  |  |  |       PropertyRNA *nameprop = RNA_struct_name_property(iter.ptr.type); | 
					
						
							|  |  |  |       char *nameptr = RNA_property_string_get_alloc( | 
					
						
							|  |  |  |           &iter.ptr, nameprop, name, sizeof(name), &namelen); | 
					
						
							|  |  |  |       if ((keylen == namelen) && STREQ(nameptr, keyname)) { | 
					
						
							|  |  |  |         found = true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if ((char *)&name != nameptr) { | 
					
						
							|  |  |  |         MEM_freeN(nameptr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (found) { | 
					
						
							|  |  |  |         result = pyrna_struct_CreatePyObject(&iter.ptr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* It's important to end the iterator after `result` has been created
 | 
					
						
							|  |  |  |      * so iterators may optionally invalidate items that were iterated over, see: T100286. */ | 
					
						
							|  |  |  |     RNA_property_collection_end(&iter); | 
					
						
							|  |  |  |     if (found) { | 
					
						
							|  |  |  |       if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) { | 
					
						
							|  |  |  |         Py_DECREF(result); | 
					
						
							|  |  |  |         result = NULL; /* The exception has been set. */ | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return result; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |   PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | // static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname)
 | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Special case: `bpy.data.objects["some_id_name", "//some_lib_name.blend"]` | 
					
						
							|  |  |  |  * also for:     `bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)` | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |  * \note | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * error codes since this is not to be called directly from Python, | 
					
						
							|  |  |  |  * this matches Python's `__contains__` values C-API. | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |  * - -1: exception set | 
					
						
							|  |  |  |  * -  0: not found | 
					
						
							|  |  |  |  * -  1: found | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                             PyObject *key, | 
					
						
							|  |  |  |                                                             const char *err_prefix, | 
					
						
							|  |  |  |                                                             const short err_not_found, | 
					
						
							|  |  |  |                                                             PointerRNA *r_ptr) | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-27 00:21:23 +10:00
										 |  |  |   const char *keyname; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* First validate the args, all we know is that they are a tuple. */ | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   if (PyTuple_GET_SIZE(key) != 2) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                  "%s: tuple key must be a pair, not size %d", | 
					
						
							|  |  |  |                  err_prefix, | 
					
						
							|  |  |  |                  PyTuple_GET_SIZE(key)); | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (self->ptr.type != &RNA_BlendData) { | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |     PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                  "%s: is only valid for bpy.data collections, not %.200s", | 
					
						
							|  |  |  |                  err_prefix, | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type)); | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   if ((keyname = PyUnicode_AsUTF8(PyTuple_GET_ITEM(key, 0))) == NULL) { | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |     PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                  "%s: id must be a string, not %.200s", | 
					
						
							|  |  |  |                  err_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name); | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyObject *keylib = PyTuple_GET_ITEM(key, 1); | 
					
						
							|  |  |  |   Library *lib; | 
					
						
							|  |  |  |   bool found = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (keylib == Py_None) { | 
					
						
							|  |  |  |     lib = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyUnicode_Check(keylib)) { | 
					
						
							|  |  |  |     Main *bmain = self->ptr.data; | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |     const char *keylib_str = PyUnicode_AsUTF8(keylib); | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath)); | 
					
						
							|  |  |  |     if (lib == NULL) { | 
					
						
							|  |  |  |       if (err_not_found) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_KeyError, | 
					
						
							| 
									
										
										
										
											2021-03-30 19:29:59 +11:00
										 |  |  |                      "%s: lib filepath '%.1024s' " | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |                      "does not reference a valid library", | 
					
						
							|  |  |  |                      err_prefix, | 
					
						
							|  |  |  |                      keylib_str); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                  "%s: lib must be a string or None, not %.200s", | 
					
						
							|  |  |  |                  err_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(keylib)->tp_name); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   /* lib is either a valid pointer or NULL,
 | 
					
						
							|  |  |  |    * either way can do direct comparison with id.lib */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							|  |  |  |     ID *id = itemptr.data; /* Always an ID. */ | 
					
						
							| 
									
										
										
										
											2022-10-07 22:52:53 +11:00
										 |  |  |     if (id->lib == lib && STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2)) { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       found = true; | 
					
						
							|  |  |  |       if (r_ptr) { | 
					
						
							|  |  |  |         *r_ptr = itemptr; | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   /* We may want to fail silently as with collection.get(). */ | 
					
						
							|  |  |  |   if ((found == false) && err_not_found) { | 
					
						
							|  |  |  |     /* Only runs for getitem access so use fixed string. */ | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return found; /* 1 / 0, no exception. */ | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                               PyObject *key, | 
					
						
							|  |  |  |                                                               const char *err_prefix, | 
					
						
							|  |  |  |                                                               const bool err_not_found) | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr( | 
					
						
							|  |  |  |       self, key, err_prefix, err_not_found, &ptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |   if (contains == 1) { | 
					
						
							|  |  |  |     return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                        Py_ssize_t start, | 
					
						
							|  |  |  |                                                        Py_ssize_t stop) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   CollectionPropertyIterator rna_macro_iter; | 
					
						
							| 
									
										
										
										
											2013-05-10 22:05:47 +00:00
										 |  |  |   int count; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   PyObject *list; | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  |   PyObject *item; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   list = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Skip to start. */ | 
					
						
							| 
									
										
										
										
											2013-05-10 22:05:47 +00:00
										 |  |  |   RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); | 
					
						
							|  |  |  |   RNA_property_collection_skip(&rna_macro_iter, start); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Add items until stop. */ | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |   for (count = start; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr); | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |     PyList_APPEND(list, item); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  |     count++; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (count == stop) { | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  |   RNA_property_collection_end(&rna_macro_iter); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  |   return list; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-25 01:14:39 +11:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |  * TODO: dimensions | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * \note Could also use pyrna_prop_array_to_py_index(self, count) in a loop, but it's much slower | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |  * since at the moment it reads (and even allocates) the entire array for each index. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                                   PointerRNA *ptr, | 
					
						
							|  |  |  |                                                   PropertyRNA *prop, | 
					
						
							|  |  |  |                                                   Py_ssize_t start, | 
					
						
							|  |  |  |                                                   Py_ssize_t stop, | 
					
						
							|  |  |  |                                                   Py_ssize_t length) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |   int count, totdim; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   PyObject *tuple; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Isn't needed, internal use only. */ | 
					
						
							| 
									
										
										
										
											2014-08-25 23:53:34 +10:00
										 |  |  |   // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   tuple = PyTuple_New(stop - start); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |   if (totdim > 1) { | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     for (count = start; count < stop; count++) { | 
					
						
							| 
									
										
										
										
											2011-01-02 09:54:44 +00:00
										 |  |  |       PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count)); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     switch (RNA_property_type(prop)) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_FLOAT: { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |         float values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |         float *values; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         if (length > PYRNA_STACK_ARRAY) { | 
					
						
							|  |  |  |           values = PyMem_MALLOC(sizeof(float) * length); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           values = values_stack; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |         RNA_property_float_get_array(ptr, prop, values); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         for (count = start; count < stop; count++) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           PyTuple_SET_ITEM(tuple, count - start, PyFloat_FromDouble(values[count])); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |         if (values != values_stack) { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |           PyMem_FREE(values); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_BOOLEAN: { | 
					
						
							| 
									
										
										
										
											2018-07-01 15:47:09 +02:00
										 |  |  |         bool values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |         bool *values; | 
					
						
							|  |  |  |         if (length > PYRNA_STACK_ARRAY) { | 
					
						
							|  |  |  |           values = PyMem_MALLOC(sizeof(bool) * length); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           values = values_stack; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |         RNA_property_boolean_get_array(ptr, prop, values); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         for (count = start; count < stop; count++) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           PyTuple_SET_ITEM(tuple, count - start, PyBool_FromLong(values[count])); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |         if (values != values_stack) { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |           PyMem_FREE(values); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_INT: { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |         int values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |         int *values; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         if (length > PYRNA_STACK_ARRAY) { | 
					
						
							|  |  |  |           values = PyMem_MALLOC(sizeof(int) * length); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           values = values_stack; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |         RNA_property_int_get_array(ptr, prop, values); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         for (count = start; count < stop; count++) { | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |           PyTuple_SET_ITEM(tuple, count - start, PyLong_FromLong(values[count])); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |         if (values != values_stack) { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |           PyMem_FREE(values); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       default: | 
					
						
							| 
									
										
										
										
											2021-07-15 18:23:28 +10:00
										 |  |  |         BLI_assert_msg(0, "Invalid array type"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         PyErr_SetString(PyExc_TypeError, "not an array type"); | 
					
						
							|  |  |  |         Py_DECREF(tuple); | 
					
						
							|  |  |  |         tuple = NULL; | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-01-20 14:06:38 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-02 09:54:44 +00:00
										 |  |  |   return tuple; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |   if (PyUnicode_Check(key)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |     return pyrna_prop_collection_subscript_str(self, PyUnicode_AsUTF8(key)); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PyIndex_Check(key)) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2009-07-08 09:23:49 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     return pyrna_prop_collection_subscript_int(self, i); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PySlice_Check(key)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PySliceObject *key_slice = (PySliceObject *)key; | 
					
						
							|  |  |  |     Py_ssize_t step = 1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     if (step != 1) { | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  |       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     if (key_slice->start == Py_None && key_slice->stop == Py_None) { | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  |       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ | 
					
						
							|  |  |  |     if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     if (start < 0 || stop < 0) { | 
					
						
							|  |  |  |       /* Only get the length for negative values. */ | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |       const Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       if (start < 0) { | 
					
						
							|  |  |  |         start += len; | 
					
						
							| 
									
										
										
										
											2021-08-05 16:44:03 +10:00
										 |  |  |         CLAMP_MIN(start, 0); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       if (stop < 0) { | 
					
						
							|  |  |  |         stop += len; | 
					
						
							| 
									
										
										
										
											2021-08-05 16:44:03 +10:00
										 |  |  |         CLAMP_MIN(stop, 0); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (stop - start <= 0) { | 
					
						
							|  |  |  |       return PyList_New(0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pyrna_prop_collection_subscript_slice(self, start, stop); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PyTuple_Check(key)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Special case, for ID datablocks we. */ | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |     return pyrna_prop_collection_subscript_str_lib_pair( | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |         self, key, "bpy_prop_collection[id, lib]", true); | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                "bpy_prop_collection[key]: invalid key, " | 
					
						
							|  |  |  |                "must be a string or an int, not %.200s", | 
					
						
							|  |  |  |                Py_TYPE(key)->tp_name); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | /* generic check to see if a PyObject is compatible with a collection
 | 
					
						
							| 
									
										
										
										
											2011-10-17 06:39:13 +00:00
										 |  |  |  * -1 on failure, 0 on success, sets the error */ | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   StructRNA *prop_srna; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (value == Py_None) { | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |     if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |                    "bpy_prop_collection[key] = value: invalid, " | 
					
						
							| 
									
										
										
										
											2012-04-07 12:37:15 +00:00
										 |  |  |                    "this collection doesn't support None assignment"); | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; /* None is OK. */ | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (BPy_StructRNA_Check(value) == 0) { | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "bpy_prop_collection[key] = value: invalid, " | 
					
						
							|  |  |  |                  "expected a StructRNA type or None, not a %.200s", | 
					
						
							|  |  |  |                  Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type; | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |     if (RNA_struct_is_a(value_srna, prop_srna) == 0) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "bpy_prop_collection[key] = value: invalid, " | 
					
						
							|  |  |  |                    "expected a '%.200s' type or None, not a '%.200s'", | 
					
						
							|  |  |  |                    RNA_struct_identifier(prop_srna), | 
					
						
							|  |  |  |                    RNA_struct_identifier(value_srna)); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; /* OK, this is the correct type! */ | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |   PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                "bpy_prop_collection[key] = value: internal error, " | 
					
						
							|  |  |  |                "failed to get the collection type"); | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  | /* NOTE: currently this is a copy of 'pyrna_prop_collection_subscript' with
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:20:18 +00:00
										 |  |  |  * large blocks commented, we may support slice/key indices later */ | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                PyObject *key, | 
					
						
							|  |  |  |                                                PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Validate the assigned value. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (value == NULL) { | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (pyrna_prop_collection_type_check(self, value) == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     return -1; /* Exception is set. */ | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  |   if (PyUnicode_Check(key)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |     return pyrna_prop_collection_subscript_str(self, PyUnicode_AsUTF8(key)); | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   if (PyIndex_Check(key)) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |     return pyrna_prop_collection_ass_subscript_int(self, i, value); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  | #if 0 /* TODO: fake slice assignment. */
 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |   else if (PySlice_Check(key)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PySliceObject *key_slice = (PySliceObject *)key; | 
					
						
							|  |  |  |     Py_ssize_t step = 1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (step != 1) { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     else if (key_slice->start == Py_None && key_slice->stop == Py_None) { | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       } | 
					
						
							|  |  |  |       if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (start < 0 || stop < 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Only get the length for negative values. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |         if (start < 0) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |           start += len; | 
					
						
							| 
									
										
										
										
											2021-08-05 16:44:03 +10:00
										 |  |  |           CLAMP_MIN(start, 0); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (stop < 0) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |           stop += len; | 
					
						
							| 
									
										
										
										
											2021-08-05 16:44:03 +10:00
										 |  |  |           CLAMP_MIN(stop, 0); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  |       if (stop - start <= 0) { | 
					
						
							|  |  |  |         return PyList_New(0); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return pyrna_prop_collection_subscript_slice(self, start, stop); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                "bpy_prop_collection[key]: invalid key, " | 
					
						
							|  |  |  |                "must be a string or an int, not %.200s", | 
					
						
							|  |  |  |                Py_TYPE(key)->tp_name); | 
					
						
							|  |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  |   if (PyUnicode_Check(key)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |     return pyrna_prop_array_subscript_str(self, PyUnicode_AsUTF8(key)); | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |   else | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-07-08 09:23:49 +00:00
										 |  |  |   if (PyIndex_Check(key)) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2009-07-08 09:23:49 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-08-20 15:28:06 +10:00
										 |  |  |     return pyrna_prop_array_subscript_int(self, i); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PySlice_Check(key)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     Py_ssize_t step = 1; | 
					
						
							|  |  |  |     PySliceObject *key_slice = (PySliceObject *)key; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     if (step != 1) { | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  |       PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     if (key_slice->start == Py_None && key_slice->stop == Py_None) { | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |       /* NOTE: no significant advantage with optimizing [:] slice as with collections,
 | 
					
						
							| 
									
										
										
										
											2012-02-05 02:04:26 +00:00
										 |  |  |        * but include here for consistency with collection slice func */ | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |       const Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  |       return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const int len = pyrna_prop_array_length(self); | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     Py_ssize_t start, stop, slicelength; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (slicelength <= 0) { | 
					
						
							|  |  |  |       return PyTuple_New(0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int"); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Helpers for #prop_subscript_ass_array_slice | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, int length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *value_fast; | 
					
						
							|  |  |  |   if (!(value_fast = PySequence_Fast(value, | 
					
						
							|  |  |  |                                      "bpy_prop_array[slice] = value: " | 
					
						
							|  |  |  |                                      "element in assignment is not a sequence type"))) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PySequence_Fast_GET_SIZE(value_fast) != length) { | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |     Py_DECREF(value_fast); | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  |                     "bpy_prop_array[slice] = value: " | 
					
						
							|  |  |  |                     "re-sizing bpy_struct element in arrays isn't supported"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return value_fast; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int prop_subscript_ass_array_slice__float_recursive( | 
					
						
							|  |  |  |     PyObject **value_items, float *value, int totdim, const int dimsize[], const float range[2]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const int length = dimsize[0]; | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							|  |  |  |     int index = 0; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     for (i = 0; i != length; i++) { | 
					
						
							|  |  |  |       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]); | 
					
						
							|  |  |  |       if (UNLIKELY(subvalue == NULL)) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       index += prop_subscript_ass_array_slice__float_recursive( | 
					
						
							|  |  |  |           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       Py_DECREF(subvalue); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return index; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   BLI_assert(totdim == 1); | 
					
						
							|  |  |  |   const float min = range[0], max = range[1]; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   for (i = 0; i != length; i++) { | 
					
						
							|  |  |  |     float v = PyFloat_AsDouble(value_items[i]); | 
					
						
							|  |  |  |     CLAMP(v, min, max); | 
					
						
							|  |  |  |     value[i] = v; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   return i; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int prop_subscript_ass_array_slice__int_recursive( | 
					
						
							|  |  |  |     PyObject **value_items, int *value, int totdim, const int dimsize[], const int range[2]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const int length = dimsize[0]; | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							|  |  |  |     int index = 0; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     for (i = 0; i != length; i++) { | 
					
						
							|  |  |  |       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]); | 
					
						
							|  |  |  |       if (UNLIKELY(subvalue == NULL)) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       index += prop_subscript_ass_array_slice__int_recursive( | 
					
						
							|  |  |  |           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       Py_DECREF(subvalue); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return index; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   BLI_assert(totdim == 1); | 
					
						
							|  |  |  |   const int min = range[0], max = range[1]; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   for (i = 0; i != length; i++) { | 
					
						
							|  |  |  |     int v = PyLong_AsLong(value_items[i]); | 
					
						
							|  |  |  |     CLAMP(v, min, max); | 
					
						
							|  |  |  |     value[i] = v; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   return i; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items, | 
					
						
							| 
									
										
										
										
											2018-07-01 15:47:09 +02:00
										 |  |  |                                                           bool *value, | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |                                                           int totdim, | 
					
						
							|  |  |  |                                                           const int dimsize[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const int length = dimsize[0]; | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							|  |  |  |     int index = 0; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     for (i = 0; i != length; i++) { | 
					
						
							|  |  |  |       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]); | 
					
						
							|  |  |  |       if (UNLIKELY(subvalue == NULL)) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       index += prop_subscript_ass_array_slice__bool_recursive( | 
					
						
							|  |  |  |           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1]); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       Py_DECREF(subvalue); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return index; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   BLI_assert(totdim == 1); | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   for (i = 0; i != length; i++) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const int v = PyLong_AsLong(value_items[i]); | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     value[i] = v; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   return i; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */ | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | static int prop_subscript_ass_array_slice(PointerRNA *ptr, | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |                                           PropertyRNA *prop, | 
					
						
							|  |  |  |                                           int arraydim, | 
					
						
							|  |  |  |                                           int arrayoffset, | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |                                           int start, | 
					
						
							|  |  |  |                                           int stop, | 
					
						
							|  |  |  |                                           int length, | 
					
						
							|  |  |  |                                           PyObject *value_orig) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |   const int length_flat = RNA_property_array_length(ptr, prop); | 
					
						
							| 
									
										
										
										
											2010-01-04 20:53:52 +00:00
										 |  |  |   PyObject *value; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   void *values_alloc = NULL; | 
					
						
							|  |  |  |   int ret = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (value_orig == NULL) { | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |     PyErr_SetString( | 
					
						
							|  |  |  |         PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct"); | 
					
						
							| 
									
										
										
										
											2010-01-04 20:53:52 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (!(value = PySequence_Fast( | 
					
						
							|  |  |  |             value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) { | 
					
						
							| 
									
										
										
										
											2010-01-04 20:53:52 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |   if (PySequence_Fast_GET_SIZE(value) != stop - start) { | 
					
						
							| 
									
										
										
										
											2010-01-04 20:53:52 +00:00
										 |  |  |     Py_DECREF(value); | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2012-03-08 04:12:11 +00:00
										 |  |  |                     "bpy_prop_array[slice] = value: re-sizing bpy_struct arrays isn't supported"); | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |   int dimsize[3]; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const int totdim = RNA_property_array_dimension(ptr, prop, dimsize); | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |   if (totdim > 1) { | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |     BLI_assert(dimsize[arraydim] == length); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |   int span = 1; | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							|  |  |  |     for (int i = arraydim + 1; i < totdim; i++) { | 
					
						
							|  |  |  |       span *= dimsize[i]; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   PyObject **value_items = PySequence_Fast_ITEMS(value); | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |   switch (RNA_property_type(prop)) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       float values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       float *values = (length_flat > PYRNA_STACK_ARRAY) ? | 
					
						
							|  |  |  |                           (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) : | 
					
						
							|  |  |  |                           values_stack; | 
					
						
							|  |  |  |       if (start != 0 || stop != length) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Partial assignment? - need to get the array. */ | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |         RNA_property_float_get_array(ptr, prop, values); | 
					
						
							| 
									
										
										
										
											2010-02-21 14:48:28 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       float range[2]; | 
					
						
							|  |  |  |       RNA_property_float_range(ptr, prop, &range[0], &range[1]); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |       dimsize[arraydim] = stop - start; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       prop_subscript_ass_array_slice__float_recursive(value_items, | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |                                                       &values[arrayoffset + (start * span)], | 
					
						
							|  |  |  |                                                       totdim - arraydim, | 
					
						
							|  |  |  |                                                       &dimsize[arraydim], | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |                                                       range); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         RNA_property_float_set_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |     case PROP_INT: { | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |       int values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       int *values = (length_flat > PYRNA_STACK_ARRAY) ? | 
					
						
							|  |  |  |                         (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) : | 
					
						
							|  |  |  |                         values_stack; | 
					
						
							|  |  |  |       if (start != 0 || stop != length) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Partial assignment? - need to get the array. */ | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |         RNA_property_int_get_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       int range[2]; | 
					
						
							|  |  |  |       RNA_property_int_range(ptr, prop, &range[0], &range[1]); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |       dimsize[arraydim] = stop - start; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       prop_subscript_ass_array_slice__int_recursive(value_items, | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |                                                     &values[arrayoffset + (start * span)], | 
					
						
							|  |  |  |                                                     totdim - arraydim, | 
					
						
							|  |  |  |                                                     &dimsize[arraydim], | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |                                                     range); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         RNA_property_int_set_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |     case PROP_BOOLEAN: { | 
					
						
							| 
									
										
										
										
											2018-07-01 15:47:09 +02:00
										 |  |  |       bool values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |       bool *values = (length_flat > PYRNA_STACK_ARRAY) ? | 
					
						
							|  |  |  |                          (values_alloc = PyMem_MALLOC(sizeof(bool) * length_flat)) : | 
					
						
							|  |  |  |                          values_stack; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       if (start != 0 || stop != length) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Partial assignment? - need to get the array. */ | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |         RNA_property_boolean_get_array(ptr, prop, values); | 
					
						
							| 
									
										
										
										
											2010-02-21 14:48:28 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |       dimsize[arraydim] = stop - start; | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  |       prop_subscript_ass_array_slice__bool_recursive(value_items, | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |                                                      &values[arrayoffset + (start * span)], | 
					
						
							|  |  |  |                                                      totdim - arraydim, | 
					
						
							|  |  |  |                                                      &dimsize[arraydim]); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         RNA_property_boolean_set_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |     default: | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "not an array type"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = -1; | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-04 20:53:52 +00:00
										 |  |  |   Py_DECREF(value); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (values_alloc) { | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |     PyMem_FREE(values_alloc); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 17:33:44 +00:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                         Py_ssize_t keynum, | 
					
						
							|  |  |  |                                         PyObject *value) | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   int len = pyrna_prop_array_length(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (keynum < 0) { | 
					
						
							|  |  |  |     keynum += len; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (keynum >= 0 && keynum < len) { | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |     return pyrna_py_to_prop_array_index(self, keynum, value); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:51:45 +00:00
										 |  |  |   PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range"); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                           PyObject *key, | 
					
						
							|  |  |  |                                           PyObject *value) | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   // char *keyname = NULL; /* Not supported yet. */
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   int ret = -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only", | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop), | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type)); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = -1; | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 13:37:44 +00:00
										 |  |  |   else if (PyIndex_Check(key)) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							| 
									
										
										
										
											2010-04-19 13:37:44 +00:00
										 |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = -1; | 
					
						
							| 
									
										
										
										
											2010-04-19 13:37:44 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = prop_subscript_ass_array_int(self, i, value); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   else if (PySlice_Check(key)) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const Py_ssize_t len = pyrna_prop_array_length(self); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     Py_ssize_t start, stop, step, slicelength; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-05 13:48:42 +00:00
										 |  |  |     if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = -1; | 
					
						
							| 
									
										
										
										
											2010-04-19 13:37:44 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (slicelength <= 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       ret = 0; /* Do nothing. */ | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     else if (step == 1) { | 
					
						
							| 
									
										
										
										
											2016-03-08 21:19:35 +11:00
										 |  |  |       ret = prop_subscript_ass_array_slice( | 
					
						
							|  |  |  |           &self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = -1; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   else { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = -1; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (ret != -1) { | 
					
						
							|  |  |  |     if (RNA_property_update_check(self->prop)) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |       RNA_property_update(BPY_context_get(), &self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-19 13:37:44 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 13:37:44 +00:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* For slice only. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyMappingMethods pyrna_prop_array_as_mapping = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*mp_len*/ (lenfunc)pyrna_prop_array_length, | 
					
						
							|  |  |  |     /*mp_subscript*/ (binaryfunc)pyrna_prop_array_subscript, | 
					
						
							|  |  |  |     /*mp_ass_subscript*/ (objobjargproc)pyrna_prop_array_ass_subscript, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyMappingMethods pyrna_prop_collection_as_mapping = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*mp_len*/ (lenfunc)pyrna_prop_collection_length, | 
					
						
							|  |  |  |     /*mp_subscript*/ (binaryfunc)pyrna_prop_collection_subscript, | 
					
						
							|  |  |  |     /*mp_ass_subscript*/ (objobjargproc)pyrna_prop_collection_ass_subscript, | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Only for fast bool's, large structs, assign nb_bool on init. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyNumberMethods pyrna_prop_array_as_number = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*nb_add*/ NULL, | 
					
						
							|  |  |  |     /*nb_subtract*/ NULL, | 
					
						
							|  |  |  |     /*nb_multiply*/ NULL, | 
					
						
							|  |  |  |     /*nb_remainder*/ NULL, | 
					
						
							|  |  |  |     /*nb_divmod*/ NULL, | 
					
						
							|  |  |  |     /*nb_power*/ NULL, | 
					
						
							|  |  |  |     /*nb_negative*/ NULL, | 
					
						
							|  |  |  |     /*nb_positive*/ NULL, | 
					
						
							|  |  |  |     /*nb_absolute*/ NULL, | 
					
						
							|  |  |  |     /*nb_bool*/ (inquiry)pyrna_prop_array_bool, | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyNumberMethods pyrna_prop_collection_as_number = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*nb_add*/ NULL, | 
					
						
							|  |  |  |     /*nb_subtract*/ NULL, | 
					
						
							|  |  |  |     /*nb_multiply*/ NULL, | 
					
						
							|  |  |  |     /*nb_remainder*/ NULL, | 
					
						
							|  |  |  |     /*nb_divmod*/ NULL, | 
					
						
							|  |  |  |     /*nb_power*/ NULL, | 
					
						
							|  |  |  |     /*nb_negative*/ NULL, | 
					
						
							|  |  |  |     /*nb_positive*/ NULL, | 
					
						
							|  |  |  |     /*nb_absolute*/ NULL, | 
					
						
							|  |  |  |     /*nb_bool*/ (inquiry)pyrna_prop_collection_bool, | 
					
						
							|  |  |  |     /*nb_invert*/ NULL, | 
					
						
							|  |  |  |     /*nb_lshift*/ NULL, | 
					
						
							|  |  |  |     /*nb_rshift*/ NULL, | 
					
						
							|  |  |  |     /*nb_and*/ NULL, | 
					
						
							|  |  |  |     /*nb_xor*/ NULL, | 
					
						
							|  |  |  |     /*nb_or*/ NULL, | 
					
						
							|  |  |  |     /*nb_int*/ NULL, | 
					
						
							|  |  |  |     /*nb_reserved*/ NULL, | 
					
						
							|  |  |  |     /*nb_float*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_add*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_subtract*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_multiply*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_remainder*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_power*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_lshift*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_rshift*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_and*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_xor*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_or*/ NULL, | 
					
						
							|  |  |  |     /*nb_floor_divide*/ NULL, | 
					
						
							|  |  |  |     /*nb_true_divide*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_floor_divide*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_true_divide*/ NULL, | 
					
						
							|  |  |  |     /*nb_index*/ NULL, | 
					
						
							|  |  |  |     /*nb_matrix_multiply*/ NULL, | 
					
						
							|  |  |  |     /*nb_inplace_matrix_multiply*/ NULL, | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return pyrna_array_contains_py(&self->ptr, self->prop, value); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  | static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key) | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   PointerRNA newptr; /* Not used, just so RNA_property_collection_lookup_string runs. */ | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |   if (PyTuple_Check(key)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Special case, for ID data-blocks. */ | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |     return pyrna_prop_collection_subscript_str_lib_pair_ptr( | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |         self, key, "(id, lib) in bpy_prop_collection", false, NULL); | 
					
						
							| 
									
										
										
										
											2009-12-08 09:40:30 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   /* Key in dict style check. */ | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *keyname = PyUnicode_AsUTF8(key); | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (keyname == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_collection.__contains__: expected a string or a tuple of strings"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { | 
					
						
							|  |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-13 08:04:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *name = PyUnicode_AsUTF8(value); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |   if (!name) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string"); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties"); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   IDProperty *group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!group) { | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |   return IDP_GetPropertyFromGroup(group, name) ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PySequenceMethods pyrna_prop_array_as_sequence = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*sq_length*/ (lenfunc)pyrna_prop_array_length, | 
					
						
							|  |  |  |     /*sq_concat*/ NULL, | 
					
						
							|  |  |  |     /*sq_repeat*/ NULL, | 
					
						
							|  |  |  |     /* Only set this so `PySequence_Check()` returns True. */ | 
					
						
							|  |  |  |     /*sq_item*/ (ssizeargfunc)pyrna_prop_array_subscript_int, | 
					
						
							|  |  |  |     /*sq_slice*/ NULL, | 
					
						
							|  |  |  |     /*sq_ass_item*/ (ssizeobjargproc)prop_subscript_ass_array_int, | 
					
						
							|  |  |  |     /* was_sq_ass_slice */ NULL, /* DEPRECATED. */ | 
					
						
							|  |  |  |     /*sq_contains*/ (objobjproc)pyrna_prop_array_contains, | 
					
						
							|  |  |  |     /*sq_inplace_concat*/ NULL, | 
					
						
							|  |  |  |     /*sq_inplace_repeat*/ NULL, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PySequenceMethods pyrna_prop_collection_as_sequence = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*sq_length*/ (lenfunc)pyrna_prop_collection_length, | 
					
						
							|  |  |  |     /*sq_concat*/ NULL, | 
					
						
							|  |  |  |     /*sq_repeat*/ NULL, | 
					
						
							|  |  |  |     /* Only set this so PySequence_Check() returns True */ | 
					
						
							|  |  |  |     /*sq_item*/ (ssizeargfunc)pyrna_prop_collection_subscript_int, | 
					
						
							|  |  |  |     /*was_sq_slice*/ NULL, /* DEPRECATED. */ | 
					
						
							|  |  |  |     /* Let mapping take this one: #pyrna_prop_collection_ass_subscript_int */ | 
					
						
							|  |  |  |     /*sq_ass_item*/ NULL, | 
					
						
							|  |  |  |     /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */ | 
					
						
							|  |  |  |     /*sq_contains*/ (objobjproc)pyrna_prop_collection_contains, | 
					
						
							|  |  |  |     /*sq_inplace_concat*/ NULL, | 
					
						
							|  |  |  |     /*sq_inplace_repeat*/ NULL, | 
					
						
							| 
									
										
										
										
											2009-06-13 08:04:43 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PySequenceMethods pyrna_struct_as_sequence = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*sq_length*/ NULL, /* Can't set the len otherwise it can evaluate as false */ | 
					
						
							|  |  |  |     /*sq_concat*/ NULL, | 
					
						
							|  |  |  |     /*sq_repeat*/ NULL, | 
					
						
							|  |  |  |     /* Only set this so `PySequence_Check()` returns True. */ | 
					
						
							|  |  |  |     /*sq_item*/ NULL, | 
					
						
							|  |  |  |     /*was_sq_slice*/ NULL, /* DEPRECATED. */ | 
					
						
							|  |  |  |     /*sq_ass_item */ NULL, | 
					
						
							|  |  |  |     /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */ | 
					
						
							|  |  |  |     /*sq_contains*/ (objobjproc)pyrna_struct_contains, | 
					
						
							|  |  |  |     /*sq_inplace_concat*/ NULL, | 
					
						
							|  |  |  |     /*sq_inplace_repeat*/ NULL, | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-07-08 09:23:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key) | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Mostly copied from BPy_IDGroup_Map_GetItem. */ | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *name = PyUnicode_AsUTF8(key); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); | 
					
						
							| 
									
										
										
										
											2009-11-17 12:21:41 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (name == NULL) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_struct[key]: only strings are allowed as keys of ID properties"); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   IDProperty *group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (group == NULL) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   IDProperty *idprop = IDP_GetPropertyFromGroup(group, name); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (idprop == NULL) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value) | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   IDProperty *group = RNA_struct_idprops(&self->ptr, 1); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) { | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (group == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_struct[key] = val: id properties not supported for this type"); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-06 23:26:18 +10:00
										 |  |  |   if (value && BPy_StructRNA_Check(value)) { | 
					
						
							|  |  |  |     BPy_StructRNA *val = (BPy_StructRNA *)value; | 
					
						
							|  |  |  |     if (val && self->ptr.type && val->ptr.type) { | 
					
						
							|  |  |  |       if (!RNA_struct_idprops_datablock_allowed(self->ptr.type) && | 
					
						
							|  |  |  |           RNA_struct_idprops_contains_datablock(val->ptr.type)) { | 
					
						
							|  |  |  |         PyErr_SetString( | 
					
						
							|  |  |  |             PyExc_TypeError, | 
					
						
							|  |  |  |             "bpy_struct[key] = val: datablock id properties not supported for this type"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
											  
											
												Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
											
										 
											2017-04-13 12:30:03 +03:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-16 22:21:39 +00:00
										 |  |  |   return BPy_Wrap_SetMapItem(group, key, value); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyMappingMethods pyrna_struct_as_mapping = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*mp_length*/ (lenfunc)NULL, | 
					
						
							|  |  |  |     /*mp_subscript*/ (binaryfunc)pyrna_struct_subscript, | 
					
						
							|  |  |  |     /*mp_ass_subscript*/ (objobjargproc)pyrna_struct_ass_subscript, | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_keys_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: keys()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   Returns the keys of this objects custom properties (matches Python's\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   dictionary function of the same name).\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: custom property keys.\n" | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |              "   :rtype: :class:`idprop.type.IDPropertyGroupViewKeys`\n" | 
					
						
							| 
									
										
										
										
											2011-10-09 02:24:51 +00:00
										 |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties"); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |   /* `group` may be NULL. */ | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   IDProperty *group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |   return BPy_Wrap_GetKeys_View_WithID(self->ptr.owner_id, group); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_items_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: items()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   Returns the items of this objects custom properties (matches Python's\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   dictionary function of the same name).\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: custom property key, value pairs.\n" | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |              "   :rtype: :class:`idprop.type.IDPropertyGroupViewItems`\n" | 
					
						
							| 
									
										
										
										
											2011-10-09 02:24:51 +00:00
										 |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | static PyObject *pyrna_struct_items(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties"); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |   /* `group` may be NULL. */ | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   IDProperty *group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |   return BPy_Wrap_GetItems_View_WithID(self->ptr.owner_id, group); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_values_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: values()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   Returns the values of this objects custom properties (matches Python's\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   dictionary function of the same name).\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: custom property values.\n" | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |              "   :rtype: :class:`idprop.type.IDPropertyGroupViewValues`\n" | 
					
						
							| 
									
										
										
										
											2011-10-09 02:24:51 +00:00
										 |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | static PyObject *pyrna_struct_values(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_struct.values(): this type doesn't support IDProperties"); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |   /* `group` may be NULL. */ | 
					
						
							| 
									
										
										
										
											2021-08-31 10:19:31 -05:00
										 |  |  |   IDProperty *group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2021-05-11 09:40:41 +10:00
										 |  |  |   return BPy_Wrap_GetValues_View_WithID(self->ptr.owner_id, group); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_is_property_set_doc, | 
					
						
							| 
									
										
										
										
											2020-11-04 18:06:34 +11:00
										 |  |  |              ".. method:: is_property_set(property, ghost=True)\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   Check if a property is set, use for testing operator properties.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2020-11-04 18:06:34 +11:00
										 |  |  |              "   :arg ghost: Used for operators that re-run with previous settings.\n" | 
					
						
							|  |  |  |              "      In this case the property is not marked as set,\n" | 
					
						
							|  |  |  |              "      yet the value from the previous execution is used.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "      In rare cases you may want to set this option to false.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :type ghost: boolean\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "   :return: True when the property has been set.\n" | 
					
						
							| 
									
										
										
										
											2011-02-22 05:23:20 +00:00
										 |  |  |              "   :rtype: boolean\n"); | 
					
						
							| 
									
										
										
										
											2020-11-04 18:06:34 +11:00
										 |  |  | static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args, PyObject *kw) | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *name; | 
					
						
							| 
									
										
										
										
											2020-11-06 12:27:56 +01:00
										 |  |  |   bool use_ghost = true; | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-04 18:06:34 +11:00
										 |  |  |   static const char *_keywords[] = {"", "ghost", NULL}; | 
					
						
							| 
									
										
										
										
											2022-04-08 09:41:28 +10:00
										 |  |  |   static _PyArg_Parser _parser = { | 
					
						
							|  |  |  |       "s"  /* `name` (positional). */ | 
					
						
							|  |  |  |       "|$" /* Optional keyword only arguments. */ | 
					
						
							|  |  |  |       "O&" /* `ghost` */ | 
					
						
							|  |  |  |       ":is_property_set", | 
					
						
							|  |  |  |       _keywords, | 
					
						
							|  |  |  |       0, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2020-11-04 18:06:34 +11:00
										 |  |  |   if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &name, PyC_ParseBool, &use_ghost)) { | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.is_property_set(\"%.200s\") not found", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-04 18:06:34 +11:00
										 |  |  |   return PyBool_FromLong(RNA_property_is_set_ex(&self->ptr, prop, use_ghost)); | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_property_unset_doc, | 
					
						
							|  |  |  |              ".. method:: property_unset(property)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Unset a property, will use default value afterward.\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:property_unset", &name)) { | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.property_unset(\"%.200s\") not found", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_property_unset(&self->ptr, prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: is_property_hidden(property)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Check if a property is hidden.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: True when the property is hidden.\n" | 
					
						
							| 
									
										
										
										
											2011-02-22 05:23:20 +00:00
										 |  |  |              "   :rtype: boolean\n"); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args) | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *name; | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) { | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.is_property_hidden(\"%.200s\") not found", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN); | 
					
						
							| 
									
										
											  
											
												Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
  or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
  to .py files as well to make creating distributable configurations
  easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
  keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
  added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
											
										 
											2009-10-08 18:40:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_is_property_readonly_doc, | 
					
						
							|  |  |  |              ".. method:: is_property_readonly(property)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Check if a property is readonly.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: True when the property is readonly (not writable).\n" | 
					
						
							|  |  |  |              "   :rtype: boolean\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:is_property_readonly", &name)) { | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.is_property_readonly(\"%.200s\") not found", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return PyBool_FromLong(!RNA_property_editable(&self->ptr, prop)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_is_property_overridable_library_doc, | 
					
						
							|  |  |  |              ".. method:: is_property_overridable_library(property)\n" | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-09-24 14:51:24 +02:00
										 |  |  |              "   Check if a property is overridable.\n" | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-09-24 14:51:24 +02:00
										 |  |  |              "   :return: True when the property is overridable.\n" | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |              "   :rtype: boolean\n"); | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  | static PyObject *pyrna_struct_is_property_overridable_library(BPy_StructRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:is_property_overridable_library", &name)) { | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |                  "%.200s.is_property_overridable_library(\"%.200s\") not found", | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return PyBool_FromLong((long)RNA_property_overridable_get(&self->ptr, prop)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-24 14:51:24 +02:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_property_overridable_library_set_doc, | 
					
						
							|  |  |  |              ".. method:: property_overridable_library_set(property, overridable)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Define a property as overridable or not (only for custom properties!).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: True when the overridable status of the property was successfully set.\n" | 
					
						
							|  |  |  |              "   :rtype: boolean\n"); | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  | static PyObject *pyrna_struct_property_overridable_library_set(BPy_StructRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							|  |  |  |   int is_overridable; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "sp:property_overridable_library_set", &name, &is_overridable)) { | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |                  "%.200s.property_overridable_library_set(\"%.200s\") not found", | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return PyBool_FromLong( | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |       (long)RNA_property_overridable_library_set(&self->ptr, prop, (bool)is_overridable)); | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_path_resolve_doc, | 
					
						
							| 
									
										
										
										
											2010-08-23 05:36:21 +00:00
										 |  |  |              ".. method:: path_resolve(path, coerce=True)\n" | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2010-08-23 05:36:21 +00:00
										 |  |  |              "   Returns the property from the path, raise an exception when not found.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg path: path which this property resolves.\n" | 
					
						
							|  |  |  |              "   :type path: string\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   :arg coerce: optional argument, when True, the property will be converted\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "      into its Python representation.\n" | 
					
						
							| 
									
										
										
										
											2011-02-22 05:23:20 +00:00
										 |  |  |              "   :type coerce: boolean\n"); | 
					
						
							| 
									
										
										
										
											2010-08-23 05:36:21 +00:00
										 |  |  | static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2009-11-17 20:46:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *path; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *coerce = Py_True; | 
					
						
							| 
									
										
										
										
											2009-11-17 20:46:59 +00:00
										 |  |  |   PointerRNA r_ptr; | 
					
						
							|  |  |  |   PropertyRNA *r_prop; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   int index = -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce)) { | 
					
						
							| 
									
										
										
										
											2009-11-17 20:46:59 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-03 21:58:52 +10:00
										 |  |  |   if (RNA_path_resolve_full_maybe_null(&self->ptr, path, &r_ptr, &r_prop, &index)) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (r_prop) { | 
					
						
							|  |  |  |       if (index != -1) { | 
					
						
							|  |  |  |         if (index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:51:45 +00:00
										 |  |  |           PyErr_Format(PyExc_IndexError, | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |                        "%.200s.path_resolve(\"%.200s\") index out of range", | 
					
						
							|  |  |  |                        RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                        path); | 
					
						
							| 
									
										
										
										
											2010-09-23 02:12:33 +00:00
										 |  |  |           return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return pyrna_array_index(&r_ptr, r_prop, index); | 
					
						
							| 
									
										
										
										
											2010-08-30 09:18:21 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (coerce == Py_False) { | 
					
						
							|  |  |  |         return pyrna_prop_CreatePyObject(&r_ptr, r_prop); | 
					
						
							| 
									
										
										
										
											2010-08-30 09:18:21 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return pyrna_prop_to_py(&r_ptr, r_prop); | 
					
						
							| 
									
										
										
										
											2010-08-23 05:36:21 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return pyrna_struct_CreatePyObject(&r_ptr); | 
					
						
							| 
									
										
										
										
											2010-08-23 05:36:21 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                "%.200s.path_resolve(\"%.200s\") could not be resolved", | 
					
						
							|  |  |  |                RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                path); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2009-11-17 20:46:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_path_from_id_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: path_from_id(property=\"\")\n" | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   Returns the data path from the ID to this object (string).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   :arg property: Optional property name which can be used if the path is\n" | 
					
						
							|  |  |  |              "      to a property of this object.\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "   :type property: string\n" | 
					
						
							| 
									
										
										
										
											2011-10-13 00:52:09 +00:00
										 |  |  |              "   :return: The path from :class:`bpy.types.bpy_struct.id_data`\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "      to this struct and property (when given).\n" | 
					
						
							| 
									
										
										
										
											2011-02-22 05:23:20 +00:00
										 |  |  |              "   :rtype: str\n"); | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  | static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const char *name = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *path; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "|s:path_from_id", &name)) { | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (name) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     prop = RNA_struct_find_property(&self->ptr, name); | 
					
						
							|  |  |  |     if (prop == NULL) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:51:45 +00:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |                    "%.200s.path_from_id(\"%.200s\") not found", | 
					
						
							|  |  |  |                    RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                    name); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     path = RNA_path_from_ID_to_property(&self->ptr, prop); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     path = RNA_path_from_ID_to_struct(&self->ptr); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (path == NULL) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (name) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:51:45 +00:00
										 |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                    "%.200s.path_from_id(\"%s\") found, but does not support path creation", | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |                    RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                    name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:51:45 +00:00
										 |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |                    "%.200s.path_from_id() does not support path creation for this type", | 
					
						
							|  |  |  |                    RNA_struct_identifier(self->ptr.type)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   ret = PyUnicode_FromString(path); | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   MEM_freeN((void *)path); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_path_from_id_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: path_from_id()\n" | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "   Returns the data path from the ID to this property (string).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-10-13 00:52:09 +00:00
										 |  |  |              "   :return: The path from :class:`bpy.types.bpy_struct.id_data` to this property.\n" | 
					
						
							| 
									
										
										
										
											2011-02-22 05:23:20 +00:00
										 |  |  |              "   :rtype: str\n"); | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  | static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *path; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PropertyRNA *prop = self->prop; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   path = RNA_path_from_ID_to_property(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (path == NULL) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:51:45 +00:00
										 |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |                  "%.200s.%.200s.path_from_id() does not support path creation for this type", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(prop)); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   ret = PyUnicode_FromString(path); | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   MEM_freeN((void *)path); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_as_bytes_doc, | 
					
						
							|  |  |  |              ".. method:: as_bytes()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   Returns this string property as a byte rather than a Python string.\n" | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: The string as bytes.\n" | 
					
						
							|  |  |  |              "   :rtype: bytes\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_property_type(self->prop) != PROP_STRING) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.%.200s.as_bytes() must be a string", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop)); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   char buf_fixed[256], *buf; | 
					
						
							|  |  |  |   int buf_len; | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   buf = RNA_property_string_get_alloc( | 
					
						
							|  |  |  |       &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len); | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   ret = PyBytes_FromStringAndSize(buf, buf_len); | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (buf_fixed != buf) { | 
					
						
							|  |  |  |     MEM_freeN(buf); | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 04:24:36 +10:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_update_doc, | 
					
						
							|  |  |  |              ".. method:: update()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Execute the properties update callback.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   .. note::\n" | 
					
						
							|  |  |  |              "      This is called when assigning a property,\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "      however in rare cases it's useful to call explicitly.\n"); | 
					
						
							| 
									
										
										
										
											2015-09-11 04:24:36 +10:00
										 |  |  | static PyObject *pyrna_prop_update(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |   RNA_property_update(BPY_context_get(), &self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2015-09-11 04:24:36 +10:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_type_recast_doc, | 
					
						
							| 
									
										
										
										
											2010-08-25 01:51:38 +00:00
										 |  |  |              ".. method:: type_recast()\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   Return a new instance, this is needed because types\n" | 
					
						
							|  |  |  |              "   such as textures can be changed at runtime.\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: a new instance of this object with the type initialized again.\n" | 
					
						
							| 
									
										
										
										
											2011-10-13 00:52:09 +00:00
										 |  |  |              "   :rtype: subclass of :class:`bpy.types.bpy_struct`\n"); | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  | static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self) | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |   RNA_pointer_recast(&self->ptr, &r_ptr); | 
					
						
							|  |  |  |   return pyrna_struct_CreatePyObject(&r_ptr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2019-09-30 17:06:28 +10:00
										 |  |  |  * \note Return value is borrowed, caller must #Py_INCREF. | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  |  */ | 
					
						
							|  |  |  | static PyObject *pyrna_struct_bl_rna_find_subclass_recursive(PyObject *cls, const char *id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *ret_test = NULL; | 
					
						
							|  |  |  |   PyObject *subclasses = ((PyTypeObject *)cls)->tp_subclasses; | 
					
						
							|  |  |  |   if (subclasses) { | 
					
						
							|  |  |  |     /* Unfortunately we can't use the dict key because Python class names
 | 
					
						
							|  |  |  |      * don't match the bl_idname used internally. */ | 
					
						
							|  |  |  |     BLI_assert(PyDict_CheckExact(subclasses)); | 
					
						
							|  |  |  |     PyObject *key = NULL; | 
					
						
							|  |  |  |     Py_ssize_t pos = 0; | 
					
						
							|  |  |  |     PyObject *value = NULL; | 
					
						
							|  |  |  |     while (PyDict_Next(subclasses, &pos, &key, &value)) { | 
					
						
							|  |  |  |       BLI_assert(PyWeakref_CheckRef(value)); | 
					
						
							|  |  |  |       PyObject *subcls = PyWeakref_GET_OBJECT(value); | 
					
						
							|  |  |  |       if (subcls != Py_None) { | 
					
						
							|  |  |  |         BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)subcls)->tp_dict, | 
					
						
							|  |  |  |                                                                  bpy_intern_str_bl_rna); | 
					
						
							|  |  |  |         if (py_srna) { | 
					
						
							|  |  |  |           StructRNA *srna = py_srna->ptr.data; | 
					
						
							|  |  |  |           if (STREQ(id, RNA_struct_identifier(srna))) { | 
					
						
							|  |  |  |             ret_test = subcls; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         ret_test = pyrna_struct_bl_rna_find_subclass_recursive(subcls, id); | 
					
						
							|  |  |  |         if (ret_test) { | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return ret_test; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_py_doc, | 
					
						
							|  |  |  |              ".. classmethod:: bl_rna_get_subclass_py(id, default=None)\n" | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg id: The RNA type identifier.\n" | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |              "   :type id: string\n" | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  |              "   :return: The class or default when not found.\n" | 
					
						
							|  |  |  |              "   :rtype: type\n"); | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | static PyObject *pyrna_struct_bl_rna_get_subclass_py(PyObject *cls, PyObject *args) | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   char *id; | 
					
						
							|  |  |  |   PyObject *ret_default = Py_None; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass_py", &id, &ret_default)) { | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   PyObject *ret = pyrna_struct_bl_rna_find_subclass_recursive(cls, id); | 
					
						
							|  |  |  |   if (ret == NULL) { | 
					
						
							|  |  |  |     ret = ret_default; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Py_INCREF_RET(ret); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_doc, | 
					
						
							|  |  |  |              ".. classmethod:: bl_rna_get_subclass(id, default=None)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg id: The RNA type identifier.\n" | 
					
						
							|  |  |  |              "   :type id: string\n" | 
					
						
							|  |  |  |              "   :return: The RNA type or default when not found.\n" | 
					
						
							|  |  |  |              "   :rtype: :class:`bpy.types.Struct` subclass\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *id; | 
					
						
							|  |  |  |   PyObject *ret_default = Py_None; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass", &id, &ret_default)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |   const BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)cls)->tp_dict, | 
					
						
							|  |  |  |                                                                  bpy_intern_str_bl_rna); | 
					
						
							|  |  |  |   if (py_srna == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_ValueError, "Not a registered class"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const StructRNA *srna_base = py_srna->ptr.data; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   if (srna_base == &RNA_Node) { | 
					
						
							|  |  |  |     bNodeType *nt = nodeTypeFind(id); | 
					
						
							|  |  |  |     if (nt) { | 
					
						
							| 
									
										
										
										
											2020-04-03 18:24:08 +02:00
										 |  |  |       RNA_pointer_create(NULL, &RNA_Struct, nt->rna_ext.srna, &ptr); | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |       return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |     /* TODO: panels, menus etc. */ | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_ValueError, "Class type \"%.200s\" not supported", RNA_struct_identifier(srna_base)); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |   return Py_INCREF_RET(ret_default); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  | static void pyrna_dir_members_py__add_keys(PyObject *list, PyObject *dict) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *list_tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   list_tmp = PyDict_Keys(dict); | 
					
						
							|  |  |  |   PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp); | 
					
						
							|  |  |  |   Py_DECREF(list_tmp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | static void pyrna_dir_members_py(PyObject *list, PyObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *dict; | 
					
						
							|  |  |  |   PyObject **dict_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   dict_ptr = _PyObject_GetDictPtr((PyObject *)self); | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (dict_ptr && (dict = *dict_ptr)) { | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  |     pyrna_dir_members_py__add_keys(list, dict); | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   dict = ((PyTypeObject *)Py_TYPE(self))->tp_dict; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (dict) { | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  |     pyrna_dir_members_py__add_keys(list, dict); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Since this is least common case, handle it last. */ | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  |   if (BPy_PropertyRNA_Check(self)) { | 
					
						
							|  |  |  |     BPy_PropertyRNA *self_prop = (BPy_PropertyRNA *)self; | 
					
						
							| 
									
										
										
										
											2012-04-11 10:35:09 +00:00
										 |  |  |     if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) { | 
					
						
							|  |  |  |       PointerRNA r_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (RNA_property_collection_type_get(&self_prop->ptr, self_prop->prop, &r_ptr)) { | 
					
						
							|  |  |  |         PyObject *cls = pyrna_struct_Subtype(&r_ptr); /* borrows */ | 
					
						
							|  |  |  |         dict = ((PyTypeObject *)cls)->tp_dict; | 
					
						
							|  |  |  |         pyrna_dir_members_py__add_keys(list, dict); | 
					
						
							|  |  |  |         Py_DECREF(cls); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr) | 
					
						
							| 
									
										
										
										
											2008-11-30 14:00:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |   const char *idname; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 14:47:27 +10:00
										 |  |  |   /* For looping over attributes and functions. */ | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |   PointerRNA tptr; | 
					
						
							| 
									
										
										
										
											2009-04-09 16:52:18 +00:00
										 |  |  |   PropertyRNA *iterprop; | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |   { | 
					
						
							|  |  |  |     RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     iterprop = RNA_struct_find_property(&tptr, "functions"); | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |     RNA_PROP_BEGIN (&tptr, itemptr, iterprop) { | 
					
						
							| 
									
										
										
										
											2013-06-13 11:35:25 +00:00
										 |  |  |       FunctionRNA *func = itemptr.data; | 
					
						
							|  |  |  |       if (RNA_function_defined(func)) { | 
					
						
							|  |  |  |         idname = RNA_function_identifier(itemptr.data); | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |         PyList_APPEND(list, PyUnicode_FromString(idname)); | 
					
						
							| 
									
										
										
										
											2013-06-13 11:35:25 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2009-04-09 16:52:18 +00:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Collect RNA attributes | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  |     char name[256], *nameptr; | 
					
						
							| 
									
										
										
										
											2011-10-22 10:49:35 +00:00
										 |  |  |     int namelen; | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     iterprop = RNA_struct_iterator_property(ptr->type); | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |     RNA_PROP_BEGIN (ptr, itemptr, iterprop) { | 
					
						
							| 
									
										
										
										
											2021-04-23 17:05:41 +10:00
										 |  |  |       /* Custom-properties are exposed using `__getitem__`, exclude from `__dir__`. */ | 
					
						
							|  |  |  |       if (RNA_property_is_idprop(itemptr.data)) { | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							| 
									
										
										
										
											2009-06-24 14:03:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (nameptr) { | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |         PyList_APPEND(list, PyUnicode_FromStringAndSize(nameptr, namelen)); | 
					
						
							| 
									
										
										
										
											2009-11-13 16:08:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |         if (name != nameptr) { | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  |           MEM_freeN(nameptr); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-24 21:27:10 +00:00
										 |  |  |     RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2009-04-09 16:52:18 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-09 16:52:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | static PyObject *pyrna_struct_dir(BPy_StructRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2009-11-11 17:12:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Include this in case this instance is a subtype of a Python class
 | 
					
						
							|  |  |  |    * In these instances we may want to return a function or variable provided by the subtype. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!BPy_StructRNA_CheckExact(self)) { | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |     pyrna_dir_members_py(ret, (PyObject *)self); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   pyrna_dir_members_rna(ret, &self->ptr); | 
					
						
							| 
									
										
										
										
											2009-06-20 14:55:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (self->ptr.type == &RNA_Context) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ListBase lb = CTX_data_dir_get(self->ptr.data); | 
					
						
							| 
									
										
										
										
											2009-06-20 14:55:28 +00:00
										 |  |  |     LinkData *link; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     for (link = lb.first; link; link = link->next) { | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |       PyList_APPEND(ret, PyUnicode_FromString(link->data)); | 
					
						
							| 
									
										
										
										
											2009-06-20 14:55:28 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BLI_freelistN(&lb); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /* set(), this is needed to remove-doubles because the deferred
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |      * register-props will be in both the Python __dict__ and accessed as RNA */ | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *set = PySet_New(ret); | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(ret); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = PySequence_List(set); | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  |     Py_DECREF(set); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 10:51:28 -04:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_id_properties_ensure_doc, | 
					
						
							| 
									
										
										
										
											2021-07-23 16:50:10 -04:00
										 |  |  |              ".. method:: id_properties_ensure()\n\n" | 
					
						
							| 
									
										
										
										
											2021-07-14 10:51:28 -04:00
										 |  |  |              "   :return: the parent group for an RNA struct's custom IDProperties.\n" | 
					
						
							|  |  |  |              "   :rtype: :class:`bpy.types.IDPropertyGroup`\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_struct_id_properties_ensure(BPy_StructRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   IDProperty *idprops = RNA_struct_idprops(&self->ptr, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* This is a paranoid check that theoretically might not be necessary.
 | 
					
						
							|  |  |  |    * It allows the possibility that some structs can't ensure IDProperties. */ | 
					
						
							|  |  |  |   if (idprops == NULL) { | 
					
						
							|  |  |  |     return Py_None; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type); | 
					
						
							|  |  |  |   group->owner_id = self->ptr.owner_id; | 
					
						
							|  |  |  |   group->prop = idprops; | 
					
						
							|  |  |  |   group->parent = NULL; | 
					
						
							|  |  |  |   return (PyObject *)group; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
 - `as_dict`: Returns a dictionary of the property's UI data.
 - `clear`: Removes the property's UI data.
 - `update_from`: Copy UI data between properties,
   even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
											
										 
											2021-08-27 08:27:24 -05:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_id_properties_ui_doc, | 
					
						
							|  |  |  |              ".. method:: id_properties_ui(key)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: Return an object used to manage an IDProperty's UI data.\n" | 
					
						
							|  |  |  |              "   :arg key: String name of the property.\n" | 
					
						
							|  |  |  |              "   :rtype: :class:`bpy.types.IDPropertyUIManager`\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_struct_id_properties_ui(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const char *key; | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "s:ui_data", &key)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   IDProperty *parent_group = RNA_struct_idprops(&self->ptr, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* This is a paranoid check that theoretically might not be necessary.
 | 
					
						
							|  |  |  |    * It allows the possibility that some structs can't ensure IDProperties. */ | 
					
						
							|  |  |  |   if (parent_group == NULL) { | 
					
						
							|  |  |  |     return Py_None; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   IDProperty *property = IDP_GetPropertyFromGroup(parent_group, key); | 
					
						
							|  |  |  |   if (property == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_KeyError, "Property not found in IDProperty group"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!IDP_ui_data_supported(property)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, "IDProperty \"%s\" does not support UI data", property->name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BPy_IDPropertyUIManager *ui_manager = PyObject_New(BPy_IDPropertyUIManager, | 
					
						
							|  |  |  |                                                      &BPy_IDPropertyUIManager_Type); | 
					
						
							|  |  |  |   ui_manager->property = property; | 
					
						
							|  |  |  |   return (PyObject *)ui_manager; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 10:51:28 -04:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_id_properties_clear_doc, | 
					
						
							| 
									
										
										
										
											2021-07-23 16:50:10 -04:00
										 |  |  |              ".. method:: id_properties_clear()\n\n" | 
					
						
							| 
									
										
										
										
											2021-07-14 10:51:28 -04:00
										 |  |  |              "   :return: Remove the parent group for an RNA struct's custom IDProperties.\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_struct_id_properties_clear(BPy_StructRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   IDProperty **idprops = RNA_struct_idprops_p(&self->ptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (*idprops) { | 
					
						
							|  |  |  |     IDP_FreeProperty(*idprops); | 
					
						
							|  |  |  |     *idprops = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | /* ---------------getattr-------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *name = PyUnicode_AsUTF8(pyname); | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |   FunctionRNA *func; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (name == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-09 13:58:38 +00:00
										 |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = NULL; | 
					
						
							| 
									
										
										
										
											2010-09-09 13:58:38 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  |   else if ( | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* RNA can't start with a "_", so for __dict__ and similar we can skip using RNA lookups. */ | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |       name[0] == '_') { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Annoying exception, maybe we need to have different types for this... */ | 
					
						
							| 
									
										
										
										
											2019-04-10 09:36:06 +02:00
										 |  |  |     if (STR_ELEM(name, "__getitem__", "__setitem__") && | 
					
						
							|  |  |  |         !RNA_struct_idprops_check(self->ptr.type)) { | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |       PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-17 12:21:41 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2009-11-14 23:11:46 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   else if ((prop = RNA_struct_find_property(&self->ptr, name))) { | 
					
						
							|  |  |  |     ret = pyrna_prop_to_py(&self->ptr, prop); | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* RNA function only if callback is declared (no optional functions). */ | 
					
						
							| 
									
										
										
										
											2012-06-10 13:34:59 +00:00
										 |  |  |   else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = pyrna_func_to_py(&self->ptr, func); | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |   else if (self->ptr.type == &RNA_Context) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     bContext *C = self->ptr.data; | 
					
						
							|  |  |  |     if (C == NULL) { | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", | 
					
						
							|  |  |  |                    name); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = NULL; | 
					
						
							| 
									
										
										
										
											2010-01-27 10:54:11 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       PointerRNA newptr; | 
					
						
							|  |  |  |       ListBase newlb; | 
					
						
							| 
									
										
										
										
											2010-04-24 19:26:05 +00:00
										 |  |  |       short newtype; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-06 11:42:45 +10:00
										 |  |  |       /* An empty string is used to implement #CTX_data_dir_get,
 | 
					
						
							|  |  |  |        * without this check `getattr(context, "")` succeeds. */ | 
					
						
							|  |  |  |       eContextResult done; | 
					
						
							|  |  |  |       if (name[0]) { | 
					
						
							|  |  |  |         done = CTX_data_get(C, name, &newptr, &newlb, &newtype); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         /* Fall through to built-in `getattr`. */ | 
					
						
							|  |  |  |         done = CTX_RESULT_MEMBER_NOT_FOUND; | 
					
						
							|  |  |  |         BLI_listbase_clear(&newlb); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Cleanup: Use enum for return values in context callbacks
Define enum `eContextResult` and use its values for returns, instead of
just returning 1, 0, or -1 (and always having some comment that explains
what -1 means).
This also cleans up the mixup between returning `0` and `false`, and `1`
and `true`. An inconsistency was discovered during this cleanup, and
marked with `TODO(sybren)`. It's not fixed here, as it would consititute
a functional change.
The enum isn't used everywhere, as enums in C and C++ can have different
storage sizes. To prevent issues, callback functions are still declared
as returning`int`. To at least make things easier to understand for
humans, I marked those with `int /*eContextResult*/`.
This is a followup of D9090, and is intended to unify how context
callbacks return values. This will make it easier to extend the approach
in D9090 to those functions.
No functional changes.
Differential Revision: https://developer.blender.org/D9095
											
										 
											2020-10-02 18:56:25 +02:00
										 |  |  |       if (done == CTX_RESULT_OK) { | 
					
						
							| 
									
										
										
										
											2011-12-18 08:50:06 +00:00
										 |  |  |         switch (newtype) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           case CTX_DATA_TYPE_POINTER: | 
					
						
							|  |  |  |             if (newptr.data == NULL) { | 
					
						
							|  |  |  |               ret = Py_None; | 
					
						
							|  |  |  |               Py_INCREF(ret); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               ret = pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case CTX_DATA_TYPE_COLLECTION: { | 
					
						
							| 
									
										
										
										
											2010-04-24 19:26:05 +00:00
										 |  |  |             CollectionPointerLink *link; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |             ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |             for (link = newlb.first; link; link = link->next) { | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |               PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr)); | 
					
						
							| 
									
										
										
										
											2010-04-24 19:26:05 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-07-03 10:32:10 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2010-01-27 10:54:11 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           default: | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Should never happen. */ | 
					
						
							| 
									
										
										
										
											2021-07-15 18:23:28 +10:00
										 |  |  |             BLI_assert_msg(0, "Invalid context type"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |             PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                          "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context", | 
					
						
							|  |  |  |                          newtype, | 
					
						
							|  |  |  |                          name); | 
					
						
							|  |  |  |             ret = NULL; | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2009-11-10 15:09:53 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
											
												Cleanup: Use enum for return values in context callbacks
Define enum `eContextResult` and use its values for returns, instead of
just returning 1, 0, or -1 (and always having some comment that explains
what -1 means).
This also cleans up the mixup between returning `0` and `false`, and `1`
and `true`. An inconsistency was discovered during this cleanup, and
marked with `TODO(sybren)`. It's not fixed here, as it would consititute
a functional change.
The enum isn't used everywhere, as enums in C and C++ can have different
storage sizes. To prevent issues, callback functions are still declared
as returning`int`. To at least make things easier to understand for
humans, I marked those with `int /*eContextResult*/`.
This is a followup of D9090, and is intended to unify how context
callbacks return values. This will make it easier to extend the approach
in D9090 to those functions.
No functional changes.
Differential Revision: https://developer.blender.org/D9095
											
										 
											2020-10-02 18:56:25 +02:00
										 |  |  |       else if (done == CTX_RESULT_NO_DATA) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         ret = Py_None; | 
					
						
							| 
									
										
										
										
											2009-11-10 15:09:53 +00:00
										 |  |  |         Py_INCREF(ret); | 
					
						
							| 
									
										
										
										
											2009-03-19 19:03:38 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       else { /* Not found in the context. */ | 
					
						
							|  |  |  |         /* Lookup the subclass. raise an error if it's not found. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2010-01-27 10:54:11 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 10:54:11 +00:00
										 |  |  |       BLI_freelistN(&newlb); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-03-19 19:03:38 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Include this in case this instance is a subtype of a Python class
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |      * In these instances we may want to return a function or variable provided by the subtype | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |      * Also needed to return methods when it's not a subtype. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* The error raised here will be displayed */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-19 18:22:21 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *dict = *(_PyObject_GetDictPtr((PyObject *)self)); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |   if (UNLIKELY(dict == NULL)) { | 
					
						
							| 
									
										
										
										
											2011-04-21 15:53:30 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-19 18:22:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return PyDict_Contains(dict, pyname); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | /* --------------- setattr------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 07:26:07 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr) | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *ret = PyType_Type.tp_getattro(cls, attr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  |   /* Allows:
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |    * >>> bpy.types.Scene.foo = BoolProperty() | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  |    * >>> bpy.types.Scene.foo | 
					
						
							| 
									
										
										
										
											2011-12-01 22:08:42 +00:00
										 |  |  |    * <bpy_struct, BoolProperty("foo")> | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |    * ...rather than returning the deferred class register tuple | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |    * as checked by BPy_PropDeferred_CheckTypeExact() | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  |    * | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |    * Disable for now, | 
					
						
							|  |  |  |    * this is faking internal behavior in a way that's too tricky to maintain well. */ | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | #  if 0
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   if ((ret == NULL)  /* || BPy_PropDeferred_CheckTypeExact(ret) */ ) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     StructRNA *srna = srna_from_self(cls, "StructRNA.__getattr__"); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (srna) { | 
					
						
							| 
									
										
										
										
											2021-08-12 16:44:39 +10:00
										 |  |  |       PropertyRNA *prop = RNA_struct_type_find_property_no_base(srna, PyUnicode_AsUTF8(attr)); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (prop) { | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  |         PointerRNA tptr; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         PyErr_Clear(); /* Clear error from tp_getattro. */ | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  |         RNA_pointer_create(NULL, &RNA_Property, prop, &tptr); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         ret = pyrna_struct_CreatePyObject(&tptr); | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-02-14 07:26:07 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   StructRNA *srna = srna_from_self(cls, "StructRNA.__setattr__"); | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   const bool is_deferred_prop = (value && BPy_PropDeferred_CheckTypeExact(value)); | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *attr_str = PyUnicode_AsUTF8(attr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |   if (srna && !pyrna_write_check() && | 
					
						
							| 
									
										
										
										
											2021-08-12 16:44:39 +10:00
										 |  |  |       (is_deferred_prop || RNA_struct_type_find_property_no_base(srna, attr_str))) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "pyrna_struct_meta_idprop_setattro() " | 
					
						
							|  |  |  |                  "can't set in readonly state '%.200s.%S'", | 
					
						
							|  |  |  |                  ((PyTypeObject *)cls)->tp_name, | 
					
						
							|  |  |  |                  attr); | 
					
						
							| 
									
										
										
										
											2011-03-14 23:02:47 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (srna == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Allow setting on unregistered classes which can be registered later on. */ | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (value && is_deferred_prop) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'", | 
					
						
							|  |  |  |                    ((PyTypeObject *)cls)->tp_name); | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* srna_from_self may set an error. */ | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  |     PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  |     return PyType_Type.tp_setattro(cls, attr, value); | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (value) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Check if the value is a property. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (is_deferred_prop) { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |       const int ret = deferred_register_prop(srna, attr, value); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (ret == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Error set. */ | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  |         return ret; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  |       /* pass through and assign to the classes __dict__ as well
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |        * so when the value isn't assigned it still creates the RNA property, | 
					
						
							|  |  |  |        * but gets confusing from script writers POV if the assigned value can't be read back. */ | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Remove existing property if it's set or we also end up with confusion. */ | 
					
						
							|  |  |  |       RNA_def_property_free_identifier(srna, attr_str); /* Ignore on failure. */ | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  |   else { /* __delattr__ */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* First find if this is a registered property. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     const int ret = RNA_def_property_free_identifier(srna, attr_str); | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  |     if (ret == -1) { | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |       PyErr_Format( | 
					
						
							|  |  |  |           PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str); | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-22 08:16:37 +10:00
										 |  |  |   /* Fallback to standard Python's `delattr/setattr`. */ | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  |   return PyType_Type.tp_setattro(cls, attr, value); | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject *value) | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *name = PyUnicode_AsUTF8(pyname); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PropertyRNA *prop = NULL; | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) { | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (name == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-09 13:58:38 +00:00
										 |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) { | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |     if (!RNA_property_editable_flag(&self->ptr, prop)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", | 
					
						
							|  |  |  |                    RNA_property_identifier(prop), | 
					
						
							|  |  |  |                    RNA_struct_identifier(self->ptr.type)); | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |   else if (self->ptr.type == &RNA_Context) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Code just raises correct error, context prop's can't be set,
 | 
					
						
							|  |  |  |      * unless it's a part of the py class. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     bContext *C = self->ptr.data; | 
					
						
							|  |  |  |     if (C == NULL) { | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", | 
					
						
							|  |  |  |                    name); | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     PointerRNA newptr; | 
					
						
							|  |  |  |     ListBase newlb; | 
					
						
							|  |  |  |     short newtype; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Cleanup: Use enum for return values in context callbacks
Define enum `eContextResult` and use its values for returns, instead of
just returning 1, 0, or -1 (and always having some comment that explains
what -1 means).
This also cleans up the mixup between returning `0` and `false`, and `1`
and `true`. An inconsistency was discovered during this cleanup, and
marked with `TODO(sybren)`. It's not fixed here, as it would consititute
a functional change.
The enum isn't used everywhere, as enums in C and C++ can have different
storage sizes. To prevent issues, callback functions are still declared
as returning`int`. To at least make things easier to understand for
humans, I marked those with `int /*eContextResult*/`.
This is a followup of D9090, and is intended to unify how context
callbacks return values. This will make it easier to extend the approach
in D9090 to those functions.
No functional changes.
Differential Revision: https://developer.blender.org/D9095
											
										 
											2020-10-02 18:56:25 +02:00
										 |  |  |     const eContextResult done = CTX_data_get(C, name, &newptr, &newlb, &newtype); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Cleanup: Use enum for return values in context callbacks
Define enum `eContextResult` and use its values for returns, instead of
just returning 1, 0, or -1 (and always having some comment that explains
what -1 means).
This also cleans up the mixup between returning `0` and `false`, and `1`
and `true`. An inconsistency was discovered during this cleanup, and
marked with `TODO(sybren)`. It's not fixed here, as it would consititute
a functional change.
The enum isn't used everywhere, as enums in C and C++ can have different
storage sizes. To prevent issues, callback functions are still declared
as returning`int`. To at least make things easier to understand for
humans, I marked those with `int /*eContextResult*/`.
This is a followup of D9090, and is intended to unify how context
callbacks return values. This will make it easier to extend the approach
in D9090 to those functions.
No functional changes.
Differential Revision: https://developer.blender.org/D9095
											
										 
											2020-10-02 18:56:25 +02:00
										 |  |  |     if (done == CTX_RESULT_OK) { | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       PyErr_Format( | 
					
						
							|  |  |  |           PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name); | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |       BLI_freelistN(&newlb); | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     BLI_freelistN(&newlb); | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 03:52:07 +00:00
										 |  |  |   /* pyrna_py_to_prop sets its own exceptions */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (prop) { | 
					
						
							|  |  |  |     if (value == NULL) { | 
					
						
							| 
									
										
										
										
											2010-08-24 23:52:20 +00:00
										 |  |  |       PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported"); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:"); | 
					
						
							| 
									
										
										
										
											2010-08-24 23:52:20 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return PyObject_GenericSetAttr((PyObject *)self, pyname, value); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   PointerRNA r_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Include this in case this instance is a subtype of a Python class
 | 
					
						
							|  |  |  |    * In these instances we may want to return a function or variable provided by the subtype. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-30 13:18:04 +00:00
										 |  |  |   if (!BPy_PropertyRNA_CheckExact(self)) { | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |     pyrna_dir_members_py(ret, (PyObject *)self); | 
					
						
							| 
									
										
										
										
											2011-07-30 13:18:04 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_type(self->prop) == PROP_COLLECTION) { | 
					
						
							|  |  |  |     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							| 
									
										
										
										
											2011-07-30 13:18:04 +00:00
										 |  |  |       pyrna_dir_members_rna(ret, &r_ptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | static PyObject *pyrna_prop_array_getattro(BPy_PropertyRNA *self, PyObject *pyname) | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   return PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject *pyname) | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *name = PyUnicode_AsUTF8(pyname); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (name == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-09 13:58:38 +00:00
										 |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (name[0] != '_') { | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     PyObject *ret; | 
					
						
							|  |  |  |     PropertyRNA *prop; | 
					
						
							|  |  |  |     FunctionRNA *func; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       if ((prop = RNA_struct_find_property(&r_ptr, name))) { | 
					
						
							|  |  |  |         ret = pyrna_prop_to_py(&r_ptr, prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |         return ret; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       if ((func = RNA_struct_find_function(r_ptr.type, name))) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr); | 
					
						
							|  |  |  |         ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |         Py_DECREF(self_collection); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2009-11-13 16:37:44 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-11-13 16:08:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2009-11-13 16:08:03 +00:00
										 |  |  |   return PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /* Could just do this except for 1 awkward case.
 | 
					
						
							| 
									
										
										
										
											2021-03-06 13:03:30 +11:00
										 |  |  |      * `PyObject_GenericGetAttr((PyObject *)self, pyname);` | 
					
						
							|  |  |  |      * so as to support `bpy.data.library.load()` */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-06 13:03:30 +11:00
										 |  |  |     if (ret == NULL && name[0] != '_') { /* Avoid inheriting `__call__` and similar. */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Since this is least common case, handle it last. */ | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  |       PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							| 
									
										
										
										
											2011-03-14 05:39:07 +00:00
										 |  |  |         PyObject *cls; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-14 05:39:07 +00:00
										 |  |  |         PyObject *error_type, *error_value, *error_traceback; | 
					
						
							|  |  |  |         PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  |         cls = pyrna_struct_Subtype(&r_ptr); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         ret = PyObject_GenericGetAttr(cls, pyname); | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  |         Py_DECREF(cls); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Restore the original error. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |         if (ret == NULL) { | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  |           PyErr_Restore(error_type, error_value, error_traceback); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-03-04 23:09:11 +11:00
										 |  |  |         else { | 
					
						
							|  |  |  |           if (Py_TYPE(ret) == &PyMethodDescr_Type) { | 
					
						
							|  |  |  |             PyMethodDef *m = ((PyMethodDescrObject *)ret)->d_method; | 
					
						
							|  |  |  |             /* TODO: #METH_CLASS */ | 
					
						
							|  |  |  |             if (m->ml_flags & METH_STATIC) { | 
					
						
							|  |  |  |               /* Keep 'ret' as-is. */ | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               Py_DECREF(ret); | 
					
						
							|  |  |  |               ret = PyCMethod_New(m, (PyObject *)self, NULL, NULL); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  |     return ret; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | /* --------------- setattr------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pyname, PyObject *value) | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *name = PyUnicode_AsUTF8(pyname); | 
					
						
							| 
									
										
										
										
											2009-11-13 16:08:03 +00:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |   PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) { | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (name == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-09 13:58:38 +00:00
										 |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (value == NULL) { | 
					
						
							| 
									
										
										
										
											2010-08-24 02:12:09 +00:00
										 |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if ((prop = RNA_struct_find_property(&r_ptr, name))) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* pyrna_py_to_prop sets its own exceptions. */ | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  |       return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):"); | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |   PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name); | 
					
						
							| 
									
										
										
										
											2009-11-13 16:08:03 +00:00
										 |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Odd case, we need to be able return a Python method from a #PyTypeObject.tp_getset. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  |   PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  |   RNA_property_collection_add(&self->ptr, self->prop, &r_ptr); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (!r_ptr.data) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_collection.add(): not supported for this collection"); | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return pyrna_struct_CreatePyObject(&r_ptr); | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value) | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const int key = PyLong_AsLong(value); | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (key == -1 && PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument"); | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (!RNA_property_collection_remove(&self->ptr, self->prop, key)) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_collection.remove() not supported for this collection"); | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 17:36:54 +00:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-02 11:28:26 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_idprop_clear(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-02 11:28:26 +00:00
										 |  |  |   RNA_property_collection_clear(&self->ptr, self->prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   int key = 0, pos = 0; | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  |   if (!PyArg_ParseTuple(args, "ii", &key, &pos)) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments"); | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (!RNA_property_collection_move(&self->ptr, self->prop, key, pos)) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_collection.move() not supported for this collection"); | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 17:36:54 +00:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_get_id_data_doc, | 
					
						
							|  |  |  |              "The :class:`bpy.types.ID` object this datablock is from or None, (not available for " | 
					
						
							|  |  |  |              "all data types)"); | 
					
						
							| 
									
										
										
										
											2010-08-23 22:10:13 +00:00
										 |  |  | static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self) | 
					
						
							| 
									
										
										
										
											2009-12-13 10:46:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Used for struct and pointer since both have a ptr. */ | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   if (self->ptr.owner_id) { | 
					
						
							| 
									
										
										
										
											2009-12-13 10:46:34 +00:00
										 |  |  |     PointerRNA id_ptr; | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |     RNA_id_pointer_create((ID *)self->ptr.owner_id, &id_ptr); | 
					
						
							| 
									
										
										
										
											2009-12-13 10:46:34 +00:00
										 |  |  |     return pyrna_struct_CreatePyObject(&id_ptr); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_get_data_doc, | 
					
						
							|  |  |  |              "The data this property is using, *type* :class:`bpy.types.bpy_struct`"); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | static PyObject *pyrna_struct_get_data(BPy_DummyPointerRNA *self) | 
					
						
							| 
									
										
										
										
											2011-10-13 00:52:09 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   return pyrna_struct_CreatePyObject(&self->ptr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_get_rna_type_doc, "The property type for introspection"); | 
					
						
							| 
									
										
										
										
											2011-10-09 02:11:43 +00:00
										 |  |  | static PyObject *pyrna_struct_get_rna_type(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PointerRNA tptr; | 
					
						
							|  |  |  |   RNA_pointer_create(NULL, &RNA_Property, self->prop, &tptr); | 
					
						
							|  |  |  |   return pyrna_struct_Subtype(&tptr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Python attributes get/set structure:                                      */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2010-08-23 22:10:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyGetSetDef pyrna_prop_getseters[] = { | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |     {"id_data", | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |      (getter)pyrna_struct_get_id_data, | 
					
						
							|  |  |  |      (setter)NULL, | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |      pyrna_struct_get_id_data_doc, | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |      NULL}, | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |     {"data", (getter)pyrna_struct_get_data, (setter)NULL, pyrna_struct_get_data_doc, NULL}, | 
					
						
							|  |  |  |     {"rna_type", | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |      (getter)pyrna_struct_get_rna_type, | 
					
						
							|  |  |  |      (setter)NULL, | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |      pyrna_struct_get_rna_type_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |      NULL}, | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2010-08-23 22:10:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyGetSetDef pyrna_struct_getseters[] = { | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |     {"id_data", | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |      (getter)pyrna_struct_get_id_data, | 
					
						
							|  |  |  |      (setter)NULL, | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |      pyrna_struct_get_id_data_doc, | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |      NULL}, | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ | 
					
						
							| 
									
										
										
										
											2009-12-13 10:46:34 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *closure); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyGetSetDef pyrna_func_getseters[] = { | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |     {"__doc__", (getter)pyrna_func_doc_get, (setter)NULL, NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  |     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_keys_doc, | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              ".. method:: keys()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   Return the identifiers of collection members\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matching Python's dict.keys() functionality).\n" | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: the identifiers for each member of this collection.\n" | 
					
						
							| 
									
										
										
										
											2012-03-16 05:03:13 +00:00
										 |  |  |              "   :rtype: list of strings\n"); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |   char name[256], *nameptr; | 
					
						
							| 
									
										
										
										
											2011-10-22 10:49:35 +00:00
										 |  |  |   int namelen; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							| 
									
										
										
										
											2009-06-24 14:03:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (nameptr) { | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |       PyList_APPEND(ret, PyUnicode_FromStringAndSize(nameptr, namelen)); | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (name != nameptr) { | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |         MEM_freeN(nameptr); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_items_doc, | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              ".. method:: items()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   Return the identifiers of collection members\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matching Python's dict.items() functionality).\n" | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: (key, value) pairs for each member of this collection.\n" | 
					
						
							|  |  |  |              "   :rtype: list of tuples\n"); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |   PyObject *item; | 
					
						
							|  |  |  |   char name[256], *nameptr; | 
					
						
							| 
									
										
										
										
											2011-10-22 10:49:35 +00:00
										 |  |  |   int namelen; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   int i = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (itemptr.data) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Add to Python list. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       item = PyTuple_New(2); | 
					
						
							|  |  |  |       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (nameptr) { | 
					
						
							| 
									
										
										
										
											2011-10-22 10:49:35 +00:00
										 |  |  |         PyTuple_SET_ITEM(item, 0, PyUnicode_FromStringAndSize(nameptr, namelen)); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         if (name != nameptr) { | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |           MEM_freeN(nameptr); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* A bit strange, but better than returning an empty list. */ | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |         PyTuple_SET_ITEM(item, 0, PyLong_FromLong(i)); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |       PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |       PyList_APPEND(ret, item); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |       i++; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_values_doc, | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              ".. method:: values()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   Return the values of collection\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matching Python's dict.values() functionality).\n" | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: the members of this collection.\n" | 
					
						
							|  |  |  |              "   :rtype: list\n"); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Re-use slice. */ | 
					
						
							| 
									
										
										
										
											2011-01-07 05:33:30 +00:00
										 |  |  |   return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_get_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: get(key, default=None)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   Returns the value of the custom property assigned to key or default\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   when not found (matches Python's dictionary function of the same name).\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-10-17 06:39:13 +00:00
										 |  |  |              "   :arg key: The key associated with the custom property.\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "   :type key: string\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   :arg default: Optional argument for the value to return if\n" | 
					
						
							|  |  |  |              "      *key* is not found.\n" | 
					
						
							| 
									
										
										
										
											2011-02-22 05:23:20 +00:00
										 |  |  |              "   :type default: Undefined\n" | 
					
						
							| 
									
										
										
										
											2011-10-09 02:24:51 +00:00
										 |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   IDProperty *group, *idprop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *key; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |   PyObject *def = Py_None; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) { | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Mostly copied from BPy_IDGroup_Map_GetItem. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (group) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     idprop = IDP_GetPropertyFromGroup(group, key); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (idprop) { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |       return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  |   return Py_INCREF_RET(def); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_pop_doc, | 
					
						
							|  |  |  |              ".. method:: pop(key, default=None)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Remove and return the value of the custom property assigned to key or default\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   when not found (matches Python's dictionary function of the same name).\n" | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg key: The key associated with the custom property.\n" | 
					
						
							|  |  |  |              "   :type key: string\n" | 
					
						
							|  |  |  |              "   :arg default: Optional argument for the value to return if\n" | 
					
						
							|  |  |  |              "      *key* is not found.\n" | 
					
						
							|  |  |  |              "   :type default: Undefined\n" | 
					
						
							|  |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							|  |  |  | static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   IDProperty *group, *idprop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const char *key; | 
					
						
							|  |  |  |   PyObject *def = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) { | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Mostly copied from BPy_IDGroup_Map_GetItem. */ | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							|  |  |  |   if (group) { | 
					
						
							|  |  |  |     idprop = IDP_GetPropertyFromGroup(group, key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (idprop) { | 
					
						
							| 
									
										
										
										
											2021-05-14 19:18:50 +10:00
										 |  |  |       /* Don't use #BPy_IDGroup_WrapData as the id-property is being removed from the ID. */ | 
					
						
							|  |  |  |       PyObject *ret = BPy_IDGroup_MapDataToPy(idprop); | 
					
						
							|  |  |  |       /* Internal error. */ | 
					
						
							|  |  |  |       if (UNLIKELY(ret == NULL)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       IDP_FreeFromGroup(group, idprop); | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  |       return ret; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (def == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_KeyError, "key not found"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Py_INCREF_RET(def); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_as_pointer_doc, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              ".. method:: as_pointer()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   Returns the memory address which holds a pointer to Blender's internal data\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2010-09-08 10:43:36 +00:00
										 |  |  |              "   :return: int (memory address).\n" | 
					
						
							| 
									
										
										
										
											2010-09-01 15:25:22 +00:00
										 |  |  |              "   :rtype: int\n" | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   .. note:: This is intended only for advanced script writers who need to\n" | 
					
						
							|  |  |  |              "      pass blender data to their own C/Python modules.\n"); | 
					
						
							| 
									
										
										
										
											2010-03-06 12:37:29 +00:00
										 |  |  | static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-01 15:25:22 +00:00
										 |  |  |   return PyLong_FromVoidPtr(self->ptr.data); | 
					
						
							| 
									
										
										
										
											2010-03-06 12:37:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_get_doc, | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              ".. method:: get(key, default=None)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   Returns the value of the item assigned to key or default when not found\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matches Python's dictionary function of the same name).\n" | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg key: The identifier for the collection member.\n" | 
					
						
							|  |  |  |              "   :type key: string\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   :arg default: Optional argument for the value to return if\n" | 
					
						
							|  |  |  |              "      *key* is not found.\n" | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |              "   :type default: Undefined\n"); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2009-07-09 08:06:26 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PointerRNA newptr; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   PyObject *key_ob; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |   PyObject *def = Py_None; | 
					
						
							| 
									
										
										
										
											2009-07-09 08:06:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "O|O:get", &key_ob, &def)) { | 
					
						
							| 
									
										
										
										
											2009-07-09 08:06:26 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   if (PyUnicode_Check(key_ob)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |     const char *key = PyUnicode_AsUTF8(key_ob); | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (RNA_property_collection_lookup_string(&self->ptr, self->prop, key, &newptr)) { | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |       return pyrna_struct_CreatePyObject(&newptr); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else if (PyTuple_Check(key_ob)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair( | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |         self, key_ob, "bpy_prop_collection.get((id, lib))", false); | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  |     if (ret) { | 
					
						
							|  |  |  |       return ret; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                  "bpy_prop_collection.get(key, ...): key must be a string or tuple, not %.200s", | 
					
						
							|  |  |  |                  Py_TYPE(key_ob)->tp_name); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-09-09 17:36:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  |   return Py_INCREF_RET(def); | 
					
						
							| 
									
										
										
										
											2009-07-09 08:06:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_find_doc, | 
					
						
							|  |  |  |              ".. method:: find(key)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Returns the index of a key in a collection or -1 when not found\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matches Python's string find function of the same name).\n" | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg key: The identifier for the collection member.\n" | 
					
						
							|  |  |  |              "   :type key: string\n" | 
					
						
							|  |  |  |              "   :return: index of the key.\n" | 
					
						
							|  |  |  |              "   :rtype: int\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Py_ssize_t key_len_ssize_t; | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *key = PyUnicode_AsUTF8AndSize(key_ob, &key_len_ssize_t); | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |   const int key_len = (int)key_len_ssize_t; /* Compare with same type. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |   char name[256], *nameptr; | 
					
						
							|  |  |  |   int namelen; | 
					
						
							|  |  |  |   int i = 0; | 
					
						
							|  |  |  |   int index = -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |     nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |     if (nameptr) { | 
					
						
							|  |  |  |       if ((key_len == namelen) && memcmp(nameptr, key, key_len) == 0) { | 
					
						
							|  |  |  |         index = i; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |       if (name != nameptr) { | 
					
						
							|  |  |  |         MEM_freeN(nameptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |     i++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |   return PyLong_FromLong(index); | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static bool foreach_attr_type(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                               const char *attr, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                               /* Values to assign. */ | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |                               RawPropertyType *r_raw_type, | 
					
						
							|  |  |  |                               int *r_attr_tot, | 
					
						
							|  |  |  |                               bool *r_attr_signed) | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |   bool attr_ok = true; | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   *r_raw_type = PROP_RAW_UNSET; | 
					
						
							|  |  |  |   *r_attr_tot = 0; | 
					
						
							|  |  |  |   *r_attr_signed = false; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |   /* NOTE: this is fail with zero length lists, so don't let this get called in that case. */ | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     prop = RNA_struct_find_property(&itemptr, attr); | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |     if (prop) { | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |       *r_raw_type = RNA_property_raw_type(prop); | 
					
						
							|  |  |  |       *r_attr_tot = RNA_property_array_length(&itemptr, prop); | 
					
						
							|  |  |  |       *r_attr_signed = (RNA_property_subtype(prop) != PROP_UNSIGNED); | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       attr_ok = false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |   return attr_ok; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* pyrna_prop_collection_foreach_get/set both use this. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static int foreach_parse_args(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                               PyObject *args, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                               /* Values to assign. */ | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |                               const char **r_attr, | 
					
						
							|  |  |  |                               PyObject **r_seq, | 
					
						
							|  |  |  |                               int *r_tot, | 
					
						
							|  |  |  |                               int *r_size, | 
					
						
							|  |  |  |                               RawPropertyType *r_raw_type, | 
					
						
							|  |  |  |                               int *r_attr_tot, | 
					
						
							|  |  |  |                               bool *r_attr_signed) | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   int array_tot; | 
					
						
							|  |  |  |   int target_tot; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   *r_size = *r_attr_tot = 0; | 
					
						
							|  |  |  |   *r_attr_signed = false; | 
					
						
							|  |  |  |   *r_raw_type = PROP_RAW_UNSET; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "sO:foreach_get/set", r_attr, r_seq)) { | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   if (!PySequence_Check(*r_seq) && PyObject_CheckBuffer(*r_seq)) { | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_TypeError, | 
					
						
							|  |  |  |         "foreach_get/set expected second argument to be a sequence or buffer, not a %.200s", | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |         Py_TYPE(*r_seq)->tp_name); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* TODO: buffer may not be a sequence! array.array() is though. */ | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   *r_tot = PySequence_Size(*r_seq); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   if (*r_tot > 0) { | 
					
						
							|  |  |  |     if (!foreach_attr_type(self, *r_attr, r_raw_type, r_attr_tot, r_attr_signed)) { | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "foreach_get/set '%.200s.%200s[...]' elements have no attribute '%.200s'", | 
					
						
							|  |  |  |                    RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                    RNA_property_identifier(self->prop), | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |                    *r_attr); | 
					
						
							| 
									
										
										
										
											2013-02-26 00:31:36 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |     *r_size = RNA_raw_type_sizeof(*r_raw_type); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #if 0 /* Works fine, but not strictly needed. \
 | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |        * we could allow RNA_property_collection_raw_* to do the checks */ | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |     if ((*r_attr_tot) < 1) { | 
					
						
							|  |  |  |       *r_attr_tot = 1; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (RNA_property_type(self->prop) == PROP_COLLECTION) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       array_tot = RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       array_tot = RNA_property_array_length(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |     target_tot = array_tot * (*r_attr_tot); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* rna_access.c - rna_raw_access(...) uses this same method. */ | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |     if (target_tot != (*r_tot)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "foreach_get(attr, sequence) sequence length mismatch given %d, needed %d", | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |                    *r_tot, | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |                    target_tot); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   /* Check 'r_attr_tot' otherwise we don't know if any values were set.
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |    * This isn't ideal because it means running on an empty list may | 
					
						
							|  |  |  |    * fail silently when it's not compatible. */ | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   if (*r_size == 0 && *r_attr_tot != 0) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_AttributeError, "attribute does not support foreach method"); | 
					
						
							| 
									
										
										
										
											2010-01-04 22:30:09 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const char f = format ? *format : 'B'; /* B is assumed when not set */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-18 08:50:06 +00:00
										 |  |  |   switch (raw_type) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case PROP_RAW_CHAR: | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (attr_signed) { | 
					
						
							|  |  |  |         return (f == 'b') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return (f == 'B') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case PROP_RAW_SHORT: | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (attr_signed) { | 
					
						
							|  |  |  |         return (f == 'h') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return (f == 'H') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case PROP_RAW_INT: | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (attr_signed) { | 
					
						
							|  |  |  |         return (f == 'i') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return (f == 'I') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-07-01 15:47:09 +02:00
										 |  |  |     case PROP_RAW_BOOLEAN: | 
					
						
							|  |  |  |       return (f == '?') ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case PROP_RAW_FLOAT: | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       return (f == 'f') ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case PROP_RAW_DOUBLE: | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       return (f == 'd') ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     case PROP_RAW_UNSET: | 
					
						
							|  |  |  |       return 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *item = NULL; | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   int i = 0, ok = 0; | 
					
						
							|  |  |  |   bool buffer_is_compat; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   void *array = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Get/set both take the same args currently. */ | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |   const char *attr; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   PyObject *seq; | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   int tot, size, attr_tot; | 
					
						
							|  |  |  |   bool attr_signed; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   RawPropertyType raw_type; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (foreach_parse_args( | 
					
						
							|  |  |  |           self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1) { | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (tot == 0) { | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   if (set) { /* Get the array from python. */ | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |     buffer_is_compat = false; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (PyObject_CheckBuffer(seq)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |       Py_buffer buf; | 
					
						
							|  |  |  |       PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Check if the buffer matches. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (buffer_is_compat) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         ok = RNA_property_collection_raw_set( | 
					
						
							|  |  |  |             NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |       PyBuffer_Release(&buf); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Could not use the buffer, fallback to sequence. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (!buffer_is_compat) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       array = PyMem_Malloc(size * tot); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       for (; i < tot; i++) { | 
					
						
							|  |  |  |         item = PySequence_GetItem(seq, i); | 
					
						
							| 
									
										
										
										
											2011-12-18 08:50:06 +00:00
										 |  |  |         switch (raw_type) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |           case PROP_RAW_CHAR: | 
					
						
							|  |  |  |             ((char *)array)[i] = (char)PyLong_AsLong(item); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_SHORT: | 
					
						
							|  |  |  |             ((short *)array)[i] = (short)PyLong_AsLong(item); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_INT: | 
					
						
							|  |  |  |             ((int *)array)[i] = (int)PyLong_AsLong(item); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2018-07-01 15:47:09 +02:00
										 |  |  |           case PROP_RAW_BOOLEAN: | 
					
						
							|  |  |  |             ((bool *)array)[i] = (int)PyLong_AsLong(item) != 0; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |           case PROP_RAW_FLOAT: | 
					
						
							|  |  |  |             ((float *)array)[i] = (float)PyFloat_AsDouble(item); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_DOUBLE: | 
					
						
							|  |  |  |             ((double *)array)[i] = (double)PyFloat_AsDouble(item); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_UNSET: | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Should never happen. */ | 
					
						
							| 
									
										
										
										
											2021-07-15 18:23:28 +10:00
										 |  |  |             BLI_assert_msg(0, "Invalid array type - set"); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ok = RNA_property_collection_raw_set( | 
					
						
							|  |  |  |           NULL, &self->ptr, self->prop, attr, array, raw_type, tot); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |     buffer_is_compat = false; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (PyObject_CheckBuffer(seq)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |       Py_buffer buf; | 
					
						
							|  |  |  |       PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |       /* Check if the buffer matches, TODO: signed/unsigned types. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (buffer_is_compat) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         ok = RNA_property_collection_raw_get( | 
					
						
							|  |  |  |             NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |       PyBuffer_Release(&buf); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Could not use the buffer, fallback to sequence. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (!buffer_is_compat) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       array = PyMem_Malloc(size * tot); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ok = RNA_property_collection_raw_get( | 
					
						
							|  |  |  |           NULL, &self->ptr, self->prop, attr, array, raw_type, tot); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (!ok) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Skip the loop. */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         i = tot; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       for (; i < tot; i++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-18 08:50:06 +00:00
										 |  |  |         switch (raw_type) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |           case PROP_RAW_CHAR: | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |             item = PyLong_FromLong((long)((char *)array)[i]); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_SHORT: | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |             item = PyLong_FromLong((long)((short *)array)[i]); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_INT: | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |             item = PyLong_FromLong((long)((int *)array)[i]); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_FLOAT: | 
					
						
							|  |  |  |             item = PyFloat_FromDouble((double)((float *)array)[i]); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_DOUBLE: | 
					
						
							|  |  |  |             item = PyFloat_FromDouble((double)((double *)array)[i]); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2018-07-16 09:48:52 +02:00
										 |  |  |           case PROP_RAW_BOOLEAN: | 
					
						
							|  |  |  |             item = PyBool_FromLong((long)((bool *)array)[i]); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |           default: /* PROP_RAW_UNSET */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Should never happen. */ | 
					
						
							| 
									
										
										
										
											2021-07-15 18:23:28 +10:00
										 |  |  |             BLI_assert_msg(0, "Invalid array type - get"); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |             item = Py_None; | 
					
						
							|  |  |  |             Py_INCREF(item); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |         PySequence_SetItem(seq, i, item); | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (array) { | 
					
						
							| 
									
										
										
										
											2009-12-08 09:40:30 +00:00
										 |  |  |     PyMem_Free(array); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Maybe we could make our own error. */ | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     PyErr_Print(); | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |     PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence"); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!ok) { | 
					
						
							| 
									
										
										
										
											2011-02-18 06:04:05 +00:00
										 |  |  |     PyErr_SetString(PyExc_RuntimeError, "internal error setting the array"); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_foreach_get_doc, | 
					
						
							| 
									
										
										
										
											2011-01-18 11:27:52 +00:00
										 |  |  |              ".. method:: foreach_get(attr, seq)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |              "   This is a function to give fast access to attributes within a collection.\n"); | 
					
						
							| 
									
										
										
										
											2011-01-06 04:01:06 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_foreach_get(BPy_PropertyRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   return foreach_getset(self, args, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_foreach_set_doc, | 
					
						
							| 
									
										
										
										
											2011-01-18 11:27:52 +00:00
										 |  |  |              ".. method:: foreach_set(attr, seq)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |              "   This is a function to give fast access to attributes within a collection.\n"); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |   return foreach_getset(self, args, 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Python: add foreach_get and foreach_set methods to pyrna_prop_array
This allows fast access to various arrays in the Python API.
Most notably, `image.pixels` can be accessed much more efficiently now.
**Benchmark**
Below are the results of a benchmark that compares different ways to
set/get all pixel values. I do the tests on 2048x2048 rgba images.
The benchmark tests the following dimensions:
- Byte vs. float per color channel
- Python list vs. numpy array containing floats
- `foreach_set` (new) vs. `image.pixels = ...` (old)
```
Pixel amount: 2048 * 2048 = 4.194.304
Byte buffer size:  16.8 mb
Float buffer size: 67.1 mb
Set pixel colors:
    byte  - new - list:    271 ms
    byte  - new - buffer:   29 ms
    byte  - old - list:    350 ms
    byte  - old - buffer: 2900 ms
    float - new - list:    249 ms
    float - new - buffer:    8 ms
    float - old - list:    330 ms
    float - old - buffer: 2880 ms
Get pixel colors:
    byte - list:   128 ms
    byte - buffer:   9 ms
    float - list:  125 ms
    float - buffer:  8 ms
```
**Observations**
The best set and get speed can be achieved with buffers and a float image,
at the cost of higher memory consumption. Furthermore, using buffers when
using `pixels = ...` is incredibly slow, because it is not optimized.
Optimizing this is possible, but might not be trivial (there were multiple
attempts afaik).
Float images are faster due to overhead introduced by the api for byte images.
If I profiled it correctly, a lot of time is spend in the `[0, 1] -> {0, ..., 255}`
conversion. The functions doing that conversion is `unit_float_to_uchar_clamp`.
While I have an idea on how it can be optimized, I do not know if it can be done
without changing its functionality slightly. Performance wise the best solution
would be to not do this conversion at all and accept byte input from the api
user directly, but that seems to be a more involved task as well.
Differential Revision: https://developer.blender.org/D7053
Reviewers: JacquesLucke, mont29
											
										 
											2020-03-13 12:57:12 +01:00
										 |  |  | static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                              PyObject *args, | 
					
						
							|  |  |  |                                              const bool do_set) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *item = NULL; | 
					
						
							|  |  |  |   Py_ssize_t i, seq_size, size; | 
					
						
							|  |  |  |   void *array = NULL; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PropertyType prop_type = RNA_property_type(self->prop); | 
					
						
							| 
									
										
											  
											
												Python: add foreach_get and foreach_set methods to pyrna_prop_array
This allows fast access to various arrays in the Python API.
Most notably, `image.pixels` can be accessed much more efficiently now.
**Benchmark**
Below are the results of a benchmark that compares different ways to
set/get all pixel values. I do the tests on 2048x2048 rgba images.
The benchmark tests the following dimensions:
- Byte vs. float per color channel
- Python list vs. numpy array containing floats
- `foreach_set` (new) vs. `image.pixels = ...` (old)
```
Pixel amount: 2048 * 2048 = 4.194.304
Byte buffer size:  16.8 mb
Float buffer size: 67.1 mb
Set pixel colors:
    byte  - new - list:    271 ms
    byte  - new - buffer:   29 ms
    byte  - old - list:    350 ms
    byte  - old - buffer: 2900 ms
    float - new - list:    249 ms
    float - new - buffer:    8 ms
    float - old - list:    330 ms
    float - old - buffer: 2880 ms
Get pixel colors:
    byte - list:   128 ms
    byte - buffer:   9 ms
    float - list:  125 ms
    float - buffer:  8 ms
```
**Observations**
The best set and get speed can be achieved with buffers and a float image,
at the cost of higher memory consumption. Furthermore, using buffers when
using `pixels = ...` is incredibly slow, because it is not optimized.
Optimizing this is possible, but might not be trivial (there were multiple
attempts afaik).
Float images are faster due to overhead introduced by the api for byte images.
If I profiled it correctly, a lot of time is spend in the `[0, 1] -> {0, ..., 255}`
conversion. The functions doing that conversion is `unit_float_to_uchar_clamp`.
While I have an idea on how it can be optimized, I do not know if it can be done
without changing its functionality slightly. Performance wise the best solution
would be to not do this conversion at all and accept byte input from the api
user directly, but that seems to be a more involved task as well.
Differential Revision: https://developer.blender.org/D7053
Reviewers: JacquesLucke, mont29
											
										 
											2020-03-13 12:57:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* Get/set both take the same args currently. */ | 
					
						
							|  |  |  |   PyObject *seq; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 12:30:59 +11:00
										 |  |  |   if (!ELEM(prop_type, PROP_INT, PROP_FLOAT)) { | 
					
						
							| 
									
										
											  
											
												Python: add foreach_get and foreach_set methods to pyrna_prop_array
This allows fast access to various arrays in the Python API.
Most notably, `image.pixels` can be accessed much more efficiently now.
**Benchmark**
Below are the results of a benchmark that compares different ways to
set/get all pixel values. I do the tests on 2048x2048 rgba images.
The benchmark tests the following dimensions:
- Byte vs. float per color channel
- Python list vs. numpy array containing floats
- `foreach_set` (new) vs. `image.pixels = ...` (old)
```
Pixel amount: 2048 * 2048 = 4.194.304
Byte buffer size:  16.8 mb
Float buffer size: 67.1 mb
Set pixel colors:
    byte  - new - list:    271 ms
    byte  - new - buffer:   29 ms
    byte  - old - list:    350 ms
    byte  - old - buffer: 2900 ms
    float - new - list:    249 ms
    float - new - buffer:    8 ms
    float - old - list:    330 ms
    float - old - buffer: 2880 ms
Get pixel colors:
    byte - list:   128 ms
    byte - buffer:   9 ms
    float - list:  125 ms
    float - buffer:  8 ms
```
**Observations**
The best set and get speed can be achieved with buffers and a float image,
at the cost of higher memory consumption. Furthermore, using buffers when
using `pixels = ...` is incredibly slow, because it is not optimized.
Optimizing this is possible, but might not be trivial (there were multiple
attempts afaik).
Float images are faster due to overhead introduced by the api for byte images.
If I profiled it correctly, a lot of time is spend in the `[0, 1] -> {0, ..., 255}`
conversion. The functions doing that conversion is `unit_float_to_uchar_clamp`.
While I have an idea on how it can be optimized, I do not know if it can be done
without changing its functionality slightly. Performance wise the best solution
would be to not do this conversion at all and accept byte input from the api
user directly, but that seems to be a more involved task as well.
Differential Revision: https://developer.blender.org/D7053
Reviewers: JacquesLucke, mont29
											
										 
											2020-03-13 12:57:12 +01:00
										 |  |  |     PyErr_Format(PyExc_TypeError, "foreach_get/set available only for int and float"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "O:foreach_get/set", &seq)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PySequence_Check(seq) && PyObject_CheckBuffer(seq)) { | 
					
						
							|  |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_TypeError, | 
					
						
							|  |  |  |         "foreach_get/set expected second argument to be a sequence or buffer, not a %.200s", | 
					
						
							|  |  |  |         Py_TYPE(seq)->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   size = pyrna_prop_array_length(self); | 
					
						
							|  |  |  |   seq_size = PySequence_Size(seq); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (size != seq_size) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, "expected sequence size %d, got %d", size, seq_size); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_buffer buf; | 
					
						
							|  |  |  |   if (PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT) == -1) { | 
					
						
							|  |  |  |     PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (prop_type) { | 
					
						
							|  |  |  |       case PROP_INT: | 
					
						
							|  |  |  |         array = PyMem_Malloc(sizeof(int) * size); | 
					
						
							|  |  |  |         if (do_set) { | 
					
						
							|  |  |  |           for (i = 0; i < size; i++) { | 
					
						
							|  |  |  |             item = PySequence_GetItem(seq, i); | 
					
						
							|  |  |  |             ((int *)array)[i] = (int)PyLong_AsLong(item); | 
					
						
							|  |  |  |             Py_DECREF(item); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           RNA_property_int_set_array(&self->ptr, self->prop, array); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_int_get_array(&self->ptr, self->prop, array); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           for (i = 0; i < size; i++) { | 
					
						
							|  |  |  |             item = PyLong_FromLong((long)((int *)array)[i]); | 
					
						
							|  |  |  |             PySequence_SetItem(seq, i, item); | 
					
						
							|  |  |  |             Py_DECREF(item); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_FLOAT: | 
					
						
							|  |  |  |         array = PyMem_Malloc(sizeof(float) * size); | 
					
						
							|  |  |  |         if (do_set) { | 
					
						
							|  |  |  |           for (i = 0; i < size; i++) { | 
					
						
							|  |  |  |             item = PySequence_GetItem(seq, i); | 
					
						
							|  |  |  |             ((float *)array)[i] = (float)PyFloat_AsDouble(item); | 
					
						
							|  |  |  |             Py_DECREF(item); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           RNA_property_float_set_array(&self->ptr, self->prop, array); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_float_get_array(&self->ptr, self->prop, array); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           for (i = 0; i < size; i++) { | 
					
						
							|  |  |  |             item = PyFloat_FromDouble((double)((float *)array)[i]); | 
					
						
							|  |  |  |             PySequence_SetItem(seq, i, item); | 
					
						
							|  |  |  |             Py_DECREF(item); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_BOOLEAN: | 
					
						
							|  |  |  |       case PROP_STRING: | 
					
						
							|  |  |  |       case PROP_ENUM: | 
					
						
							|  |  |  |       case PROP_POINTER: | 
					
						
							|  |  |  |       case PROP_COLLECTION: | 
					
						
							|  |  |  |         /* Should never happen. */ | 
					
						
							| 
									
										
										
										
											2021-03-24 12:38:08 +11:00
										 |  |  |         BLI_assert_unreachable(); | 
					
						
							| 
									
										
											  
											
												Python: add foreach_get and foreach_set methods to pyrna_prop_array
This allows fast access to various arrays in the Python API.
Most notably, `image.pixels` can be accessed much more efficiently now.
**Benchmark**
Below are the results of a benchmark that compares different ways to
set/get all pixel values. I do the tests on 2048x2048 rgba images.
The benchmark tests the following dimensions:
- Byte vs. float per color channel
- Python list vs. numpy array containing floats
- `foreach_set` (new) vs. `image.pixels = ...` (old)
```
Pixel amount: 2048 * 2048 = 4.194.304
Byte buffer size:  16.8 mb
Float buffer size: 67.1 mb
Set pixel colors:
    byte  - new - list:    271 ms
    byte  - new - buffer:   29 ms
    byte  - old - list:    350 ms
    byte  - old - buffer: 2900 ms
    float - new - list:    249 ms
    float - new - buffer:    8 ms
    float - old - list:    330 ms
    float - old - buffer: 2880 ms
Get pixel colors:
    byte - list:   128 ms
    byte - buffer:   9 ms
    float - list:  125 ms
    float - buffer:  8 ms
```
**Observations**
The best set and get speed can be achieved with buffers and a float image,
at the cost of higher memory consumption. Furthermore, using buffers when
using `pixels = ...` is incredibly slow, because it is not optimized.
Optimizing this is possible, but might not be trivial (there were multiple
attempts afaik).
Float images are faster due to overhead introduced by the api for byte images.
If I profiled it correctly, a lot of time is spend in the `[0, 1] -> {0, ..., 255}`
conversion. The functions doing that conversion is `unit_float_to_uchar_clamp`.
While I have an idea on how it can be optimized, I do not know if it can be done
without changing its functionality slightly. Performance wise the best solution
would be to not do this conversion at all and accept byte input from the api
user directly, but that seems to be a more involved task as well.
Differential Revision: https://developer.blender.org/D7053
Reviewers: JacquesLucke, mont29
											
										 
											2020-03-13 12:57:12 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_Free(array); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyErr_Occurred()) { | 
					
						
							|  |  |  |       /* Maybe we could make our own error. */ | 
					
						
							|  |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const char f = buf.format ? buf.format[0] : 0; | 
					
						
							| 
									
										
										
										
											2022-10-07 22:52:53 +11:00
										 |  |  |     if ((prop_type == PROP_INT && (buf.itemsize != sizeof(int) || !ELEM(f, 'l', 'i'))) || | 
					
						
							| 
									
										
											  
											
												Python: add foreach_get and foreach_set methods to pyrna_prop_array
This allows fast access to various arrays in the Python API.
Most notably, `image.pixels` can be accessed much more efficiently now.
**Benchmark**
Below are the results of a benchmark that compares different ways to
set/get all pixel values. I do the tests on 2048x2048 rgba images.
The benchmark tests the following dimensions:
- Byte vs. float per color channel
- Python list vs. numpy array containing floats
- `foreach_set` (new) vs. `image.pixels = ...` (old)
```
Pixel amount: 2048 * 2048 = 4.194.304
Byte buffer size:  16.8 mb
Float buffer size: 67.1 mb
Set pixel colors:
    byte  - new - list:    271 ms
    byte  - new - buffer:   29 ms
    byte  - old - list:    350 ms
    byte  - old - buffer: 2900 ms
    float - new - list:    249 ms
    float - new - buffer:    8 ms
    float - old - list:    330 ms
    float - old - buffer: 2880 ms
Get pixel colors:
    byte - list:   128 ms
    byte - buffer:   9 ms
    float - list:  125 ms
    float - buffer:  8 ms
```
**Observations**
The best set and get speed can be achieved with buffers and a float image,
at the cost of higher memory consumption. Furthermore, using buffers when
using `pixels = ...` is incredibly slow, because it is not optimized.
Optimizing this is possible, but might not be trivial (there were multiple
attempts afaik).
Float images are faster due to overhead introduced by the api for byte images.
If I profiled it correctly, a lot of time is spend in the `[0, 1] -> {0, ..., 255}`
conversion. The functions doing that conversion is `unit_float_to_uchar_clamp`.
While I have an idea on how it can be optimized, I do not know if it can be done
without changing its functionality slightly. Performance wise the best solution
would be to not do this conversion at all and accept byte input from the api
user directly, but that seems to be a more involved task as well.
Differential Revision: https://developer.blender.org/D7053
Reviewers: JacquesLucke, mont29
											
										 
											2020-03-13 12:57:12 +01:00
										 |  |  |         (prop_type == PROP_FLOAT && (buf.itemsize != sizeof(float) || f != 'f'))) { | 
					
						
							|  |  |  |       PyBuffer_Release(&buf); | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, "incorrect sequence item type: %s", buf.format); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (prop_type) { | 
					
						
							|  |  |  |       case PROP_INT: | 
					
						
							|  |  |  |         if (do_set) { | 
					
						
							|  |  |  |           RNA_property_int_set_array(&self->ptr, self->prop, buf.buf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_int_get_array(&self->ptr, self->prop, buf.buf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_FLOAT: | 
					
						
							|  |  |  |         if (do_set) { | 
					
						
							|  |  |  |           RNA_property_float_set_array(&self->ptr, self->prop, buf.buf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_float_get_array(&self->ptr, self->prop, buf.buf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_BOOLEAN: | 
					
						
							|  |  |  |       case PROP_STRING: | 
					
						
							|  |  |  |       case PROP_ENUM: | 
					
						
							|  |  |  |       case PROP_POINTER: | 
					
						
							|  |  |  |       case PROP_COLLECTION: | 
					
						
							|  |  |  |         /* Should never happen. */ | 
					
						
							| 
									
										
										
										
											2021-03-24 12:38:08 +11:00
										 |  |  |         BLI_assert_unreachable(); | 
					
						
							| 
									
										
											  
											
												Python: add foreach_get and foreach_set methods to pyrna_prop_array
This allows fast access to various arrays in the Python API.
Most notably, `image.pixels` can be accessed much more efficiently now.
**Benchmark**
Below are the results of a benchmark that compares different ways to
set/get all pixel values. I do the tests on 2048x2048 rgba images.
The benchmark tests the following dimensions:
- Byte vs. float per color channel
- Python list vs. numpy array containing floats
- `foreach_set` (new) vs. `image.pixels = ...` (old)
```
Pixel amount: 2048 * 2048 = 4.194.304
Byte buffer size:  16.8 mb
Float buffer size: 67.1 mb
Set pixel colors:
    byte  - new - list:    271 ms
    byte  - new - buffer:   29 ms
    byte  - old - list:    350 ms
    byte  - old - buffer: 2900 ms
    float - new - list:    249 ms
    float - new - buffer:    8 ms
    float - old - list:    330 ms
    float - old - buffer: 2880 ms
Get pixel colors:
    byte - list:   128 ms
    byte - buffer:   9 ms
    float - list:  125 ms
    float - buffer:  8 ms
```
**Observations**
The best set and get speed can be achieved with buffers and a float image,
at the cost of higher memory consumption. Furthermore, using buffers when
using `pixels = ...` is incredibly slow, because it is not optimized.
Optimizing this is possible, but might not be trivial (there were multiple
attempts afaik).
Float images are faster due to overhead introduced by the api for byte images.
If I profiled it correctly, a lot of time is spend in the `[0, 1] -> {0, ..., 255}`
conversion. The functions doing that conversion is `unit_float_to_uchar_clamp`.
While I have an idea on how it can be optimized, I do not know if it can be done
without changing its functionality slightly. Performance wise the best solution
would be to not do this conversion at all and accept byte input from the api
user directly, but that seems to be a more involved task as well.
Differential Revision: https://developer.blender.org/D7053
Reviewers: JacquesLucke, mont29
											
										 
											2020-03-13 12:57:12 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyBuffer_Release(&buf); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pyrna_prop_array_foreach_get_doc, | 
					
						
							|  |  |  |              ".. method:: foreach_get(seq)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   This is a function to give fast access to array data.\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_prop_array_foreach_get(BPy_PropertyArrayRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return pyprop_array_foreach_getset(self, args, false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pyrna_prop_array_foreach_set_doc, | 
					
						
							|  |  |  |              ".. method:: foreach_set(seq)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   This is a function to give fast access to array data.\n"); | 
					
						
							|  |  |  | static PyObject *pyrna_prop_array_foreach_set(BPy_PropertyArrayRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return pyprop_array_foreach_getset(self, args, true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 15:27:10 +00:00
										 |  |  | /* A bit of a kludge, make a list out of a collection or array,
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * then return the list's iter function, not especially fast, but convenient for now. */ | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self) | 
					
						
							| 
									
										
										
										
											2008-12-02 15:27:10 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Try get values from a collection. */ | 
					
						
							| 
									
										
										
										
											2009-09-15 10:01:20 +00:00
										 |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *iter = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  |   int len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 07:10:53 +00:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   len = pyrna_prop_array_length(self); | 
					
						
							|  |  |  |   ret = pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |   /* we know this is a list so no need to PyIter_Check
 | 
					
						
							|  |  |  |    * otherwise it could be NULL (unlikely) if conversion failed */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (ret) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     iter = PyObject_GetIter(ret); | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     Py_DECREF(ret); | 
					
						
							| 
									
										
										
										
											2008-12-02 15:27:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return iter; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef USE_PYRNA_ITER
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Try get values from a collection. */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *iter = NULL; | 
					
						
							|  |  |  |   ret = pyrna_prop_collection_values(self); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-09 19:22:57 +00:00
										 |  |  |   /* we know this is a list so no need to PyIter_Check
 | 
					
						
							|  |  |  |    * otherwise it could be NULL (unlikely) if conversion failed */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (ret) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     iter = PyObject_GetIter(ret); | 
					
						
							| 
									
										
										
										
											2010-02-09 19:22:57 +00:00
										 |  |  |     Py_DECREF(ret); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-15 10:01:20 +00:00
										 |  |  |   return iter; | 
					
						
							| 
									
										
										
										
											2008-12-02 15:27:10 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #endif /* # !USE_PYRNA_ITER */
 | 
					
						
							| 
									
										
										
										
											2008-12-02 15:27:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct PyMethodDef pyrna_struct_methods[] = { | 
					
						
							| 
									
										
										
										
											2009-07-08 09:23:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Only for PointerRNA's with ID'props. */ | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |     {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc}, | 
					
						
							|  |  |  |     {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, pyrna_struct_values_doc}, | 
					
						
							|  |  |  |     {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, pyrna_struct_items_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |     {"get", (PyCFunction)pyrna_struct_get, METH_VARARGS, pyrna_struct_get_doc}, | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  |     {"pop", (PyCFunction)pyrna_struct_pop, METH_VARARGS, pyrna_struct_pop_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |     {"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, pyrna_struct_as_pointer_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  |     /* bpy_rna_anim.c */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |     {"keyframe_insert", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_keyframe_insert, | 
					
						
							|  |  |  |      METH_VARARGS | METH_KEYWORDS, | 
					
						
							|  |  |  |      pyrna_struct_keyframe_insert_doc}, | 
					
						
							|  |  |  |     {"keyframe_delete", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_keyframe_delete, | 
					
						
							|  |  |  |      METH_VARARGS | METH_KEYWORDS, | 
					
						
							|  |  |  |      pyrna_struct_keyframe_delete_doc}, | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  |     {"driver_add", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_driver_add, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_driver_add_doc}, | 
					
						
							| 
									
										
										
										
											2010-04-11 09:13:37 +00:00
										 |  |  |     {"driver_remove", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_driver_remove, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_driver_remove_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |     {"is_property_set", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_is_property_set, | 
					
						
							| 
									
										
										
										
											2020-11-04 18:06:34 +11:00
										 |  |  |      METH_VARARGS | METH_KEYWORDS, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |      pyrna_struct_is_property_set_doc}, | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  |     {"property_unset", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_property_unset, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_property_unset_doc}, | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  |     {"is_property_hidden", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_is_property_hidden, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_is_property_hidden_doc}, | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  |     {"is_property_readonly", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_is_property_readonly, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_is_property_readonly_doc}, | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |     {"is_property_overridable_library", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_is_property_overridable_library, | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |      METH_VARARGS, | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |      pyrna_struct_is_property_overridable_library_doc}, | 
					
						
							|  |  |  |     {"property_overridable_library_set", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_property_overridable_library_set, | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  |      METH_VARARGS, | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |      pyrna_struct_property_overridable_library_set_doc}, | 
					
						
							| 
									
										
										
										
											2010-08-23 05:36:21 +00:00
										 |  |  |     {"path_resolve", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_path_resolve, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_path_resolve_doc}, | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  |     {"path_from_id", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_path_from_id, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_path_from_id_doc}, | 
					
						
							| 
									
										
										
										
											2010-08-25 01:51:38 +00:00
										 |  |  |     {"type_recast", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_type_recast, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_struct_type_recast_doc}, | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  |     {"bl_rna_get_subclass_py", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_bl_rna_get_subclass_py, | 
					
						
							|  |  |  |      METH_VARARGS | METH_CLASS, | 
					
						
							|  |  |  |      pyrna_struct_bl_rna_get_subclass_py_doc}, | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  |     {"bl_rna_get_subclass", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_bl_rna_get_subclass, | 
					
						
							|  |  |  |      METH_VARARGS | METH_CLASS, | 
					
						
							|  |  |  |      pyrna_struct_bl_rna_get_subclass_doc}, | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  |     {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL}, | 
					
						
							| 
									
										
										
										
											2021-07-14 10:51:28 -04:00
										 |  |  |     {"id_properties_ensure", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_id_properties_ensure, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_struct_id_properties_ensure_doc}, | 
					
						
							|  |  |  |     {"id_properties_clear", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_id_properties_clear, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_struct_id_properties_clear_doc}, | 
					
						
							| 
									
										
											  
											
												Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
 - `as_dict`: Returns a dictionary of the property's UI data.
 - `clear`: Removes the property's UI data.
 - `update_from`: Copy UI data between properties,
   even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
											
										 
											2021-08-27 08:27:24 -05:00
										 |  |  |     {"id_properties_ui", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_id_properties_ui, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_id_properties_ui_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-13 06:22:43 +00:00
										 |  |  | /* experimental */ | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | /* unused for now */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     {"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL}, | 
					
						
							|  |  |  |     {"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL}, | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     {"callback_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_CLASS, NULL}, | 
					
						
							|  |  |  |     {"callback_remove", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_callback_classmethod_remove, | 
					
						
							|  |  |  |      METH_VARARGS | METH_CLASS, | 
					
						
							|  |  |  |      NULL}, | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-02-03 14:01:45 +11:00
										 |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct PyMethodDef pyrna_prop_methods[] = { | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  |     {"path_from_id", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_path_from_id, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_prop_path_from_id_doc}, | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  |     {"as_bytes", (PyCFunction)pyrna_prop_as_bytes, METH_NOARGS, pyrna_prop_as_bytes_doc}, | 
					
						
							| 
									
										
										
										
											2015-09-11 04:24:36 +10:00
										 |  |  |     {"update", (PyCFunction)pyrna_prop_update, METH_NOARGS, pyrna_prop_update_doc}, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL}, | 
					
						
							| 
									
										
										
										
											2019-02-03 14:01:45 +11:00
										 |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct PyMethodDef pyrna_prop_array_methods[] = { | 
					
						
							| 
									
										
											  
											
												Python: add foreach_get and foreach_set methods to pyrna_prop_array
This allows fast access to various arrays in the Python API.
Most notably, `image.pixels` can be accessed much more efficiently now.
**Benchmark**
Below are the results of a benchmark that compares different ways to
set/get all pixel values. I do the tests on 2048x2048 rgba images.
The benchmark tests the following dimensions:
- Byte vs. float per color channel
- Python list vs. numpy array containing floats
- `foreach_set` (new) vs. `image.pixels = ...` (old)
```
Pixel amount: 2048 * 2048 = 4.194.304
Byte buffer size:  16.8 mb
Float buffer size: 67.1 mb
Set pixel colors:
    byte  - new - list:    271 ms
    byte  - new - buffer:   29 ms
    byte  - old - list:    350 ms
    byte  - old - buffer: 2900 ms
    float - new - list:    249 ms
    float - new - buffer:    8 ms
    float - old - list:    330 ms
    float - old - buffer: 2880 ms
Get pixel colors:
    byte - list:   128 ms
    byte - buffer:   9 ms
    float - list:  125 ms
    float - buffer:  8 ms
```
**Observations**
The best set and get speed can be achieved with buffers and a float image,
at the cost of higher memory consumption. Furthermore, using buffers when
using `pixels = ...` is incredibly slow, because it is not optimized.
Optimizing this is possible, but might not be trivial (there were multiple
attempts afaik).
Float images are faster due to overhead introduced by the api for byte images.
If I profiled it correctly, a lot of time is spend in the `[0, 1] -> {0, ..., 255}`
conversion. The functions doing that conversion is `unit_float_to_uchar_clamp`.
While I have an idea on how it can be optimized, I do not know if it can be done
without changing its functionality slightly. Performance wise the best solution
would be to not do this conversion at all and accept byte input from the api
user directly, but that seems to be a more involved task as well.
Differential Revision: https://developer.blender.org/D7053
Reviewers: JacquesLucke, mont29
											
										 
											2020-03-13 12:57:12 +01:00
										 |  |  |     {"foreach_get", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_array_foreach_get, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_prop_array_foreach_get_doc}, | 
					
						
							|  |  |  |     {"foreach_set", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_array_foreach_set, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_prop_array_foreach_set_doc}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-19 13:21:18 +11:00
										 |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct PyMethodDef pyrna_prop_collection_methods[] = { | 
					
						
							| 
									
										
										
										
											2011-01-18 11:27:52 +00:00
										 |  |  |     {"foreach_get", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_collection_foreach_get, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_prop_collection_foreach_get_doc}, | 
					
						
							|  |  |  |     {"foreach_set", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_collection_foreach_set, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_prop_collection_foreach_set_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |     {"keys", (PyCFunction)pyrna_prop_collection_keys, METH_NOARGS, pyrna_prop_collection_keys_doc}, | 
					
						
							|  |  |  |     {"items", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_collection_items, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_prop_collection_items_doc}, | 
					
						
							|  |  |  |     {"values", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_collection_values, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_prop_collection_values_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 04:28:51 +00:00
										 |  |  |     {"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc}, | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  |     {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc}, | 
					
						
							| 
									
										
										
										
											2019-02-03 14:01:45 +11:00
										 |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct PyMethodDef pyrna_prop_collection_idprop_methods[] = { | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |     {"add", (PyCFunction)pyrna_prop_collection_idprop_add, METH_NOARGS, NULL}, | 
					
						
							|  |  |  |     {"remove", (PyCFunction)pyrna_prop_collection_idprop_remove, METH_O, NULL}, | 
					
						
							| 
									
										
										
										
											2012-10-21 07:58:38 +00:00
										 |  |  |     {"clear", (PyCFunction)pyrna_prop_collection_idprop_clear, METH_NOARGS, NULL}, | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |     {"move", (PyCFunction)pyrna_prop_collection_idprop_move, METH_VARARGS, NULL}, | 
					
						
							| 
									
										
										
										
											2019-02-03 14:01:45 +11:00
										 |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * only needed for sub-typing, so a new class gets a valid #BPy_StructRNA | 
					
						
							|  |  |  |  * TODO: also accept useful args. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (PyTuple_GET_SIZE(args) == 1) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     BPy_StructRNA *base = (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0); | 
					
						
							| 
									
										
										
										
											2011-03-27 06:56:37 +00:00
										 |  |  |     if (Py_TYPE(base) == type) { | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  |       Py_INCREF(base); | 
					
						
							|  |  |  |       return (PyObject *)base; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |     if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) { | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  |       /* this almost never runs, only when using user defined subclasses of built-in object.
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |        * this isn't common since it's NOT related to registerable subclasses. eg: | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |        * | 
					
						
							|  |  |  |        *  >>> class MyObSubclass(bpy.types.Object): | 
					
						
							|  |  |  |        *  ...     def test_func(self): | 
					
						
							|  |  |  |        *  ...         print(100) | 
					
						
							|  |  |  |        *  ... | 
					
						
							|  |  |  |        *  >>> myob = MyObSubclass(bpy.context.object) | 
					
						
							|  |  |  |        *  >>> myob.test_func() | 
					
						
							|  |  |  |        *  100 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |        * | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  |        * Keep this since it could be useful. | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       BPy_StructRNA *ret; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) { | 
					
						
							|  |  |  |         ret->ptr = base->ptr; | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							|  |  |  |         /* #PyType_GenericAlloc will have set tracking.
 | 
					
						
							|  |  |  |          * We only want tracking when `StructRNA.reference` has been set. */ | 
					
						
							|  |  |  |         PyObject_GC_UnTrack(ret); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Pass on exception & NULL if tp_alloc fails. */ | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  |       return (PyObject *)ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Error, invalid type given. */ | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", | 
					
						
							|  |  |  |                  type->tp_name); | 
					
						
							| 
									
										
										
										
											2008-12-01 16:59:18 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument"); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2008-12-01 16:59:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Only needed for sub-typing, so a new class gets a valid #BPy_StructRNA | 
					
						
							|  |  |  |  * TODO: also accept useful args. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-09-28 05:53:40 +00:00
										 |  |  | static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-28 12:11:40 +00:00
										 |  |  |   BPy_PropertyRNA *base; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!PyArg_ParseTuple(args, "O!:bpy_prop.__new__", &pyrna_prop_Type, &base)) { | 
					
						
							| 
									
										
										
										
											2008-12-01 16:59:18 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 12:11:40 +00:00
										 |  |  |   if (type == Py_TYPE(base)) { | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  |     return Py_INCREF_RET((PyObject *)base); | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PyType_IsSubtype(type, &pyrna_prop_Type)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     BPy_PropertyRNA *ret = (BPy_PropertyRNA *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  |     ret->ptr = base->ptr; | 
					
						
							|  |  |  |     ret->prop = base->prop; | 
					
						
							| 
									
										
										
										
											2008-12-01 16:59:18 +00:00
										 |  |  |     return (PyObject *)ret; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop", | 
					
						
							|  |  |  |                type->tp_name); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2008-12-01 16:59:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const int type = RNA_property_type(prop); | 
					
						
							|  |  |  |   const int flag = RNA_property_flag(prop); | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |   const int flag_parameter = RNA_parameter_flag(prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_property_array_check(prop)) { | 
					
						
							| 
									
										
										
										
											2010-10-05 21:22:33 +00:00
										 |  |  |     int a, len; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-24 10:51:59 +00:00
										 |  |  |     if (flag & PROP_DYNAMIC) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ParameterDynAlloc *data_alloc = data; | 
					
						
							|  |  |  |       len = data_alloc->array_tot; | 
					
						
							|  |  |  |       data = data_alloc->array; | 
					
						
							| 
									
										
										
										
											2010-01-24 10:51:59 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       len = RNA_property_array_length(ptr, prop); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 14:47:27 +10:00
										 |  |  |     /* Resolve the array from a new Python type. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-19 14:32:41 +10:00
										 |  |  |     /* TODO(Kazanbas): make multi-dimensional sequences here. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     switch (type) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_BOOLEAN: | 
					
						
							|  |  |  |         ret = PyTuple_New(len); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         for (a = 0; a < len; a++) { | 
					
						
							| 
									
										
										
										
											2018-07-01 15:47:09 +02:00
										 |  |  |           PyTuple_SET_ITEM(ret, a, PyBool_FromLong(((bool *)data)[a])); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case PROP_INT: | 
					
						
							|  |  |  |         ret = PyTuple_New(len); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         for (a = 0; a < len; a++) { | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |           PyTuple_SET_ITEM(ret, a, PyLong_FromLong(((int *)data)[a])); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case PROP_FLOAT: | 
					
						
							|  |  |  |         switch (RNA_property_subtype(prop)) { | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           case PROP_ALL_VECTOR_SUBTYPES: | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |             ret = Vector_CreatePyObject(data, len, NULL); | 
					
						
							| 
									
										
										
										
											2010-01-04 13:29:55 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           case PROP_MATRIX: | 
					
						
							|  |  |  |             if (len == 16) { | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |               ret = Matrix_CreatePyObject(data, 4, 4, NULL); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |               break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (len == 9) { | 
					
						
							| 
									
										
										
										
											2015-01-04 17:03:54 +11:00
										 |  |  |               ret = Matrix_CreatePyObject(data, 3, 3, NULL); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |               break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-05-20 14:01:03 +10:00
										 |  |  |             ATTR_FALLTHROUGH; | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           default: | 
					
						
							|  |  |  |             ret = PyTuple_New(len); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             for (a = 0; a < len; a++) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |               PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble(((float *)data)[a])); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         PyErr_Format( | 
					
						
							|  |  |  |             PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type); | 
					
						
							|  |  |  |         ret = NULL; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* See if we can coerce into a python type - PropertyType. */ | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     switch (type) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_BOOLEAN: | 
					
						
							| 
									
										
										
										
											2018-07-01 15:47:09 +02:00
										 |  |  |         ret = PyBool_FromLong(*(bool *)data); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case PROP_INT: | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  |         ret = PyLong_FromLong(*(int *)data); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case PROP_FLOAT: | 
					
						
							|  |  |  |         ret = PyFloat_FromDouble(*(float *)data); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_STRING: { | 
					
						
							| 
									
										
										
										
											2014-04-27 00:21:23 +10:00
										 |  |  |         const char *data_ch; | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         const int subtype = RNA_property_subtype(prop); | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |         size_t data_ch_len; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |         if (flag & PROP_DYNAMIC) { | 
					
						
							|  |  |  |           ParameterDynAlloc *data_alloc = data; | 
					
						
							|  |  |  |           data_ch = data_alloc->array; | 
					
						
							|  |  |  |           data_ch_len = data_alloc->array_tot; | 
					
						
							|  |  |  |           BLI_assert((data_ch == NULL) || strlen(data_ch) == data_ch_len); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |           data_ch = (flag & PROP_THICK_WRAP) ? (char *)data : *(char **)data; | 
					
						
							| 
									
										
										
										
											2022-03-11 22:34:59 +11:00
										 |  |  |           data_ch_len = data_ch ? strlen(data_ch) : 0; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |         if (UNLIKELY(data_ch == NULL)) { | 
					
						
							|  |  |  |           BLI_assert((flag & PROP_NEVER_NULL) == 0); | 
					
						
							|  |  |  |           ret = Py_None; | 
					
						
							|  |  |  |           Py_INCREF(ret); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |         else if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  |           ret = PyBytes_FromStringAndSize(data_ch, data_ch_len); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-07-20 01:30:29 +10:00
										 |  |  |         else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |           ret = PyC_UnicodeFromByteAndSize(data_ch, data_ch_len); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |           ret = PyUnicode_FromStringAndSize(data_ch, data_ch_len); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-03-11 14:42:39 +11:00
										 |  |  |         else if (subtype == PROP_BYTESTRING) { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           ret = PyBytes_FromString(buf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           ret = PyUnicode_FromString(data_ch); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_ENUM: { | 
					
						
							|  |  |  |         ret = pyrna_enum_to_py(ptr, prop, *(int *)data); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_POINTER: { | 
					
						
							|  |  |  |         PointerRNA newptr; | 
					
						
							|  |  |  |         StructRNA *ptype = RNA_property_pointer_type(ptr, prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |         if (flag_parameter & PARM_RNAPTR) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* In this case we get the full ptr. */ | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           newptr = *(PointerRNA *)data; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           if (RNA_struct_is_ID(ptype)) { | 
					
						
							|  |  |  |             RNA_id_pointer_create(*(void **)data, &newptr); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |             /* NOTE: this is taken from the function's ID pointer
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |              * and will break if a function returns a pointer from | 
					
						
							|  |  |  |              * another ID block, watch this! - it should at least be | 
					
						
							|  |  |  |              * easy to debug since they are all ID's */ | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |             RNA_pointer_create(ptr->owner_id, ptype, *(void **)data, &newptr); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2009-07-28 01:06:56 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         if (newptr.data) { | 
					
						
							|  |  |  |           ret = pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           ret = Py_None; | 
					
						
							|  |  |  |           Py_INCREF(ret); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |       case PROP_COLLECTION: { | 
					
						
							| 
									
										
										
										
											2016-06-22 18:04:04 +02:00
										 |  |  |         CollectionListBase *lb = (CollectionListBase *)data; | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         CollectionPointerLink *link; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         for (link = lb->first; link; link = link->next) { | 
					
						
							| 
									
										
										
										
											2015-01-06 17:39:47 +11:00
										 |  |  |           PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr)); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); | 
					
						
							|  |  |  |         ret = NULL; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Use to replace PyDict_GetItemString() when the overhead of converting a | 
					
						
							|  |  |  |  * string into a Python unicode is higher than a non hash lookup. | 
					
						
							|  |  |  |  * works on small dict's such as keyword args. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  | static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *key = NULL; | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  |   Py_ssize_t pos = 0; | 
					
						
							|  |  |  |   PyObject *value = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (PyDict_Next(dict, &pos, &key, &value)) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (PyUnicode_Check(key)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |       if (STREQ(key_lookup, PyUnicode_AsUTF8(key))) { | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  |         return value; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 12:51:31 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \param parm_index: The argument index or -1 for keyword arguments. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void pyrna_func_error_prefix(BPy_FunctionRNA *self, | 
					
						
							|  |  |  |                                     PropertyRNA *parm, | 
					
						
							|  |  |  |                                     const int parm_index, | 
					
						
							|  |  |  |                                     char *error, | 
					
						
							|  |  |  |                                     const size_t error_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PointerRNA *self_ptr = &self->ptr; | 
					
						
							|  |  |  |   FunctionRNA *self_func = self->func; | 
					
						
							|  |  |  |   if (parm_index == -1) { | 
					
						
							|  |  |  |     BLI_snprintf(error, | 
					
						
							|  |  |  |                  error_size, | 
					
						
							|  |  |  |                  "%.200s.%.200s(): error with keyword argument \"%.200s\" - ", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |                  RNA_function_identifier(self_func), | 
					
						
							|  |  |  |                  RNA_property_identifier(parm)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     BLI_snprintf(error, | 
					
						
							|  |  |  |                  error_size, | 
					
						
							|  |  |  |                  "%.200s.%.200s(): error with argument %d, \"%.200s\" - ", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |                  RNA_function_identifier(self_func), | 
					
						
							|  |  |  |                  parm_index + 1, | 
					
						
							|  |  |  |                  RNA_property_identifier(parm)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) | 
					
						
							| 
									
										
										
										
											2009-04-09 13:20:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* NOTE: both BPy_StructRNA and BPy_PropertyRNA can be used here. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PointerRNA *self_ptr = &self->ptr; | 
					
						
							|  |  |  |   FunctionRNA *self_func = self->func; | 
					
						
							| 
									
										
										
										
											2009-04-09 13:20:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |   PointerRNA funcptr; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |   ParameterList parms; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |   ParameterIterator iter; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |   PropertyRNA *parm; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |   PyObject *ret, *item; | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |   int i, pyargs_len, pykw_len, parms_len, ret_len, flag_parameter, err = 0, kw_tot = 0; | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   bool kw_arg; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PropertyRNA *pret_single = NULL; | 
					
						
							|  |  |  |   void *retdata_single = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  |   /* enable this so all strings are copied and freed after calling.
 | 
					
						
							|  |  |  |    * this exposes bugs where the pointer to the string is held and re-used */ | 
					
						
							|  |  |  |   /* #define DEBUG_STRING_FREE */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_STRING_FREE
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *string_free_ls = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Should never happen, but it does in rare cases. */ | 
					
						
							| 
									
										
										
										
											2011-01-09 15:12:08 +00:00
										 |  |  |   BLI_assert(self_ptr != NULL); | 
					
						
							| 
									
										
										
										
											2010-12-15 10:22:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (self_ptr == NULL) { | 
					
						
							| 
									
										
										
										
											2009-07-17 12:26:40 +00:00
										 |  |  |     PyErr_SetString(PyExc_RuntimeError, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                     "RNA functions internal RNA pointer is NULL, this is a bug. aborting"); | 
					
						
							| 
									
										
										
										
											2009-07-17 12:26:40 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (self_func == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_RuntimeError, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         "%.200s.<unknown>(): RNA function internal function is NULL, this is a bug. aborting", | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         RNA_struct_identifier(self_ptr->type)); | 
					
						
							| 
									
										
										
										
											2009-07-17 12:26:40 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* For testing. */ | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  |   { | 
					
						
							|  |  |  |     const char *fn; | 
					
						
							|  |  |  |     int lineno; | 
					
						
							|  |  |  |     PyC_FileAndNum(&fn, &lineno); | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |     printf("pyrna_func_call > %.200s.%.200s : %.200s:%d\n", | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |            RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |            RNA_function_identifier(self_func), | 
					
						
							|  |  |  |            fn, | 
					
						
							|  |  |  |            lineno); | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-16 09:20:21 +00:00
										 |  |  |   /* include the ID pointer for pyrna_param_to_py() so we can include the
 | 
					
						
							|  |  |  |    * ID pointer on return values, this only works when returned values have | 
					
						
							|  |  |  |    * the same ID as the functions. */ | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   RNA_pointer_create(self_ptr->owner_id, &RNA_Function, self_func, &funcptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   pyargs_len = PyTuple_GET_SIZE(args); | 
					
						
							|  |  |  |   pykw_len = kw ? PyDict_Size(kw) : 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |   RNA_parameter_list_create(&parms, self_ptr, self_func); | 
					
						
							|  |  |  |   RNA_parameter_list_begin(&parms, &iter); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   parms_len = RNA_parameter_list_arg_count(&parms); | 
					
						
							|  |  |  |   ret_len = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (pyargs_len + pykw_len > parms_len) { | 
					
						
							| 
									
										
										
										
											2010-01-02 19:01:19 +00:00
										 |  |  |     RNA_parameter_list_end(&iter); | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.%.200s(): takes at most %d arguments, got %d", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |                  RNA_function_identifier(self_func), | 
					
						
							|  |  |  |                  parms_len, | 
					
						
							|  |  |  |                  pyargs_len + pykw_len); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     err = -1; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Parse function parameters. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |     parm = iter.parm; | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |     flag_parameter = RNA_parameter_flag(parm); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Only useful for single argument returns, we'll need another list loop for multiple. */ | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |     if (flag_parameter & PARM_OUTPUT) { | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |       ret_len++; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       if (pret_single == NULL) { | 
					
						
							|  |  |  |         pret_single = parm; | 
					
						
							|  |  |  |         retdata_single = iter.data; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     item = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-23 15:25:33 +00:00
										 |  |  |     if (i < pyargs_len) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* New in 2.8x, optional arguments must be keywords. */ | 
					
						
							| 
									
										
										
										
											2018-08-28 13:50:24 +10:00
										 |  |  |       if (UNLIKELY((flag_parameter & PARM_REQUIRED) == 0)) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%.200s.%.200s(): required parameter \"%.200s\" to be a keyword argument!", | 
					
						
							|  |  |  |                      RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |                      RNA_function_identifier(self_func), | 
					
						
							|  |  |  |                      RNA_property_identifier(parm)); | 
					
						
							|  |  |  |         err = -1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       item = PyTuple_GET_ITEM(args, i); | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |       kw_arg = false; | 
					
						
							| 
									
										
										
										
											2009-04-11 01:45:05 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     else if (kw != NULL) { | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* Borrow reference. */ | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* Borrow reference. */ | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (item) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         kw_tot++; /* Make sure invalid keywords are not given. */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |       kw_arg = true; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if (item == NULL) { | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |       if (flag_parameter & PARM_REQUIRED) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%.200s.%.200s(): required parameter \"%.200s\" not specified", | 
					
						
							| 
									
										
										
										
											2011-08-19 10:35:47 +00:00
										 |  |  |                      RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |                      RNA_function_identifier(self_func), | 
					
						
							|  |  |  |                      RNA_property_identifier(parm)); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         err = -1; | 
					
						
							| 
									
										
										
										
											2009-04-11 01:45:05 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-22 10:42:32 -07:00
										 |  |  |       /* PyDict_GetItemString won't raise an error. */ | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-15 12:51:31 +11:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | #ifdef DEBUG_STRING_FREE
 | 
					
						
							| 
									
										
										
										
											2022-02-15 12:51:31 +11:00
										 |  |  |       if (item) { | 
					
						
							|  |  |  |         if (PyUnicode_Check(item)) { | 
					
						
							|  |  |  |           PyList_APPEND(string_free_ls, PyUnicode_FromString(PyUnicode_AsUTF8(item))); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |       /* the error generated isn't that useful, so generate it again with a useful prefix
 | 
					
						
							| 
									
										
										
										
											2009-07-23 13:48:15 +00:00
										 |  |  |        * could also write a function to prepend to error messages */ | 
					
						
							|  |  |  |       char error_prefix[512]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 12:51:31 +11:00
										 |  |  |       err = pyrna_py_to_prop(&funcptr, parm, iter.data, item, ""); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 12:51:31 +11:00
										 |  |  |       if (err != 0) { | 
					
						
							|  |  |  |         PyErr_Clear(); /* Re-raise. */ | 
					
						
							|  |  |  |         pyrna_func_error_prefix(self, parm, kw_arg ? -1 : i, error_prefix, sizeof(error_prefix)); | 
					
						
							|  |  |  |         pyrna_py_to_prop(&funcptr, parm, iter.data, item, error_prefix); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 12:51:31 +11:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-15 12:51:31 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |     i++; /* Current argument. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 19:01:19 +00:00
										 |  |  |   RNA_parameter_list_end(&iter); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |   /* Check if we gave args that don't exist in the function
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |    * Printing the error is slow, but it should only happen when developing. | 
					
						
							|  |  |  |    * The "if" below is quick check to make sure less keyword args were passed than we gave. | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |    * (Don't overwrite the error if we have one, | 
					
						
							|  |  |  |    * otherwise can skip important messages and confuse with args). | 
					
						
							| 
									
										
										
										
											2009-09-17 00:14:47 +00:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (err == 0 && kw && (pykw_len > kw_tot)) { | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     PyObject *key, *value; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     Py_ssize_t pos = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     DynStr *bad_args = BLI_dynstr_new(); | 
					
						
							|  |  |  |     DynStr *good_args = BLI_dynstr_new(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |     const char *arg_name, *bad_args_str, *good_args_str; | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |     bool found = false, first = true; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     while (PyDict_Next(kw, &pos, &key, &value)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |       arg_name = PyUnicode_AsUTF8(key); | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |       found = false; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 11:32:48 +11:00
										 |  |  |       if (arg_name == NULL) { /* Unlikely the `arg_name` is not a string, but ignore if it is. */ | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Search for arg_name. */ | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |         RNA_parameter_list_begin(&parms, &iter); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |         for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           parm = iter.parm; | 
					
						
							| 
									
										
										
										
											2013-03-10 06:18:03 +00:00
										 |  |  |           if (STREQ(arg_name, RNA_property_identifier(parm))) { | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |             found = true; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |         RNA_parameter_list_end(&iter); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |         if (found == false) { | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |           BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name); | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |           first = false; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* List good args. */ | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |     first = true; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     RNA_parameter_list_begin(&parms, &iter); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       parm = iter.parm; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							| 
									
										
										
										
											2009-12-10 11:20:43 +00:00
										 |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |       BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |       first = false; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     RNA_parameter_list_end(&iter); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     bad_args_str = BLI_dynstr_get_cstring(bad_args); | 
					
						
							|  |  |  |     good_args_str = BLI_dynstr_get_cstring(good_args); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2015-06-10 17:28:43 +10:00
										 |  |  |         "%.200s.%.200s(): was called with invalid keyword argument(s) (%s), expected (%s)", | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |         RNA_function_identifier(self_func), | 
					
						
							|  |  |  |         bad_args_str, | 
					
						
							|  |  |  |         good_args_str); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     BLI_dynstr_free(bad_args); | 
					
						
							|  |  |  |     BLI_dynstr_free(good_args); | 
					
						
							| 
									
										
										
										
											2011-02-01 23:53:54 +00:00
										 |  |  |     MEM_freeN((void *)bad_args_str); | 
					
						
							|  |  |  |     MEM_freeN((void *)good_args_str); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     err = -1; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   ret = NULL; | 
					
						
							|  |  |  |   if (err == 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Call function. */ | 
					
						
							| 
									
										
										
										
											2009-06-18 19:48:55 +00:00
										 |  |  |     ReportList reports; | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     bContext *C = BPY_context_get(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-18 19:48:55 +00:00
										 |  |  |     BKE_reports_init(&reports, RPT_STORE); | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |     RNA_function_call(C, &reports, self_ptr, self_func, &parms); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-07 22:52:53 +11:00
										 |  |  |     err = BPy_reports_to_error(&reports, PyExc_RuntimeError, true); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Return value. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (err != -1) { | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |       if (ret_len > 0) { | 
					
						
							|  |  |  |         if (ret_len > 1) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           ret = PyTuple_New(ret_len); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           i = 0; /* Arg index. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |           RNA_parameter_list_begin(&parms, &iter); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |           for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |             parm = iter.parm; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |             if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  |               PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |           RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Possible there is an error in conversion. */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         if (ret == NULL) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           err = -1; | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_STRING_FREE
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #  if 0
 | 
					
						
							| 
									
										
										
										
											2012-02-05 02:04:26 +00:00
										 |  |  |   if (PyList_GET_SIZE(string_free_ls)) { | 
					
						
							|  |  |  |     printf("%.200s.%.200s():  has %d strings\n", | 
					
						
							|  |  |  |            RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |            RNA_function_identifier(self_func), | 
					
						
							|  |  |  |            (int)PyList_GET_SIZE(string_free_ls)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  |   Py_DECREF(string_free_ls); | 
					
						
							|  |  |  | #  undef DEBUG_STRING_FREE
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Cleanup. */ | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |   RNA_parameter_list_end(&iter); | 
					
						
							| 
									
										
										
										
											2009-07-17 02:31:28 +00:00
										 |  |  |   RNA_parameter_list_free(&parms); | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (ret) { | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (err == -1) { | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   char *args; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-18 01:22:28 +00:00
										 |  |  |   args = RNA_function_as_string_keywords(NULL, self->func, true, true, INT_MAX); | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s", | 
					
						
							|  |  |  |                              RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                              RNA_function_identifier(self->func), | 
					
						
							|  |  |  |                              args, | 
					
						
							|  |  |  |                              RNA_function_ui_description(self->func)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MEM_freeN(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Sub-classes of #pyrna_struct_Type which support idprop definitions use this as a meta-class. | 
					
						
							|  |  |  |  * \note tp_base member is set to `&PyType_Type` on initialization. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_struct_meta_idprop_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_struct_meta_idprop", | 
					
						
							|  |  |  |     /* NOTE: would be `sizeof(PyTypeObject)`,
 | 
					
						
							|  |  |  |      * but sub-types of Type must be #PyHeapTypeObject's. */ | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(PyHeapTypeObject), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset*/ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_async*/ NULL, | 
					
						
							|  |  |  |     /*tp_repr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_number*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ NULL, | 
					
						
							|  |  |  |     /*tp_hash*/ NULL, | 
					
						
							|  |  |  |     /*tp_call*/ NULL, | 
					
						
							|  |  |  |     /*tp_str*/ NULL, | 
					
						
							|  |  |  |     /*tp_getattro*/ NULL, /* Sub-classed: #pyrna_struct_meta_idprop_getattro. */ | 
					
						
							|  |  |  |     /*tp_setattro*/ (setattrofunc)pyrna_struct_meta_idprop_setattro, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							|  |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							|  |  |  |     /*tp_richcompare*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklistoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_iter*/ NULL, | 
					
						
							|  |  |  |     /*tp_iternext*/ NULL, | 
					
						
							|  |  |  |     /*tp_methods*/ NULL, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ NULL, | 
					
						
							| 
									
										
										
										
											2017-05-27 15:34:55 -04:00
										 |  |  | #if defined(_MSC_VER)
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_base*/ NULL, /* Defer assignment. */ | 
					
						
							| 
									
										
										
										
											2011-10-01 15:02:55 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_base*/ &PyType_Type, | 
					
						
							| 
									
										
										
										
											2011-10-01 15:02:55 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ NULL, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | /*-----------------------BPy_StructRNA method def------------------------------*/ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_struct_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_struct", | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(BPy_StructRNA), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ (destructor)pyrna_struct_dealloc, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset */ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_async*/ NULL, | 
					
						
							|  |  |  |     /*tp_repr*/ (reprfunc)pyrna_struct_repr, | 
					
						
							|  |  |  |     /*tp_as_number*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ &pyrna_struct_as_sequence, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ &pyrna_struct_as_mapping, | 
					
						
							|  |  |  |     /*tp_hash*/ (hashfunc)pyrna_struct_hash, | 
					
						
							|  |  |  |     /*tp_call*/ NULL, | 
					
						
							|  |  |  |     /*tp_str*/ (reprfunc)pyrna_struct_str, | 
					
						
							|  |  |  |     /*tp_getattro*/ (getattrofunc)pyrna_struct_getattro, | 
					
						
							|  |  |  |     /*tp_setattro*/ (setattrofunc)pyrna_struct_setattro, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							|  |  |  |         | Py_TPFLAGS_HAVE_GC | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     , | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_traverse*/ (traverseproc)pyrna_struct_traverse, | 
					
						
							|  |  |  |     /*tp_clear*/ (inquiry)pyrna_struct_clear, | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_richcompare*/ (richcmpfunc)pyrna_struct_richcmp, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ offsetof(BPy_StructRNA, in_weakreflist), | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_iter*/ NULL, | 
					
						
							|  |  |  |     /*tp_iternext*/ NULL, | 
					
						
							|  |  |  |     /*tp_methods*/ pyrna_struct_methods, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ pyrna_struct_getseters, | 
					
						
							|  |  |  |     /*tp_base*/ NULL, | 
					
						
							|  |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ pyrna_struct_new, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*-----------------------BPy_PropertyRNA method def------------------------------*/ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_prop_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_prop", | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(BPy_PropertyRNA), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ (destructor)pyrna_prop_dealloc, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset*/ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_async*/ NULL, | 
					
						
							|  |  |  |     /*tp_repr*/ (reprfunc)pyrna_prop_repr, | 
					
						
							|  |  |  |     /*tp_as_number*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ NULL, | 
					
						
							|  |  |  |     /*tp_hash*/ (hashfunc)pyrna_prop_hash, | 
					
						
							|  |  |  |     /*tp_call*/ NULL, | 
					
						
							|  |  |  |     /*tp_str*/ (reprfunc)pyrna_prop_str, | 
					
						
							|  |  |  |     /*tp_getattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							|  |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							|  |  |  |     /*tp_richcompare*/ (richcmpfunc)pyrna_prop_richcmp, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist), | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ 0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_iter*/ NULL, | 
					
						
							|  |  |  |     /*tp_iternext*/ NULL, | 
					
						
							|  |  |  |     /*tp_methods*/ pyrna_prop_methods, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ pyrna_prop_getseters, | 
					
						
							|  |  |  |     /*tp_base*/ NULL, | 
					
						
							|  |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ pyrna_prop_new, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_prop_array_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_prop_array", | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(BPy_PropertyArrayRNA), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ (destructor)pyrna_prop_array_dealloc, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset*/ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_async*/ NULL, | 
					
						
							|  |  |  |     /*tp_repr*/ (reprfunc)pyrna_prop_array_repr, | 
					
						
							|  |  |  |     /*tp_as_number*/ &pyrna_prop_array_as_number, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ &pyrna_prop_array_as_sequence, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ &pyrna_prop_array_as_mapping, | 
					
						
							|  |  |  |     /*tp_hash*/ NULL, | 
					
						
							|  |  |  |     /*tp_call*/ NULL, | 
					
						
							|  |  |  |     /*tp_str*/ NULL, | 
					
						
							|  |  |  |     /*tp_getattro*/ (getattrofunc)pyrna_prop_array_getattro, | 
					
						
							|  |  |  |     /*tp_setattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							|  |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							|  |  |  |     /*tp_richcompare*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ offsetof(BPy_PropertyArrayRNA, in_weakreflist), | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ 0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_iter*/ (getiterfunc)pyrna_prop_array_iter, | 
					
						
							|  |  |  |     /*tp_iternext*/ NULL, | 
					
						
							|  |  |  |     /*tp_methods*/ pyrna_prop_array_methods, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ NULL /* Sub-classed: #pyrna_prop_getseters. */, | 
					
						
							|  |  |  |     /*tp_base*/ &pyrna_prop_Type, | 
					
						
							|  |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ NULL, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_prop_collection_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_prop_collection", | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(BPy_PropertyRNA), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ (destructor)pyrna_prop_dealloc, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset*/ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_async*/ NULL, | 
					
						
							|  |  |  |     /*tp_repr*/ NULL, /* Sub-classed, no need to define. */ | 
					
						
							|  |  |  |     /*tp_as_number*/ &pyrna_prop_collection_as_number, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ &pyrna_prop_collection_as_sequence, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ &pyrna_prop_collection_as_mapping, | 
					
						
							|  |  |  |     /*tp_hash*/ NULL, | 
					
						
							|  |  |  |     /*tp_call*/ NULL, | 
					
						
							|  |  |  |     /*tp_str*/ NULL, | 
					
						
							|  |  |  |     /*tp_getattro*/ (getattrofunc)pyrna_prop_collection_getattro, | 
					
						
							|  |  |  |     /*tp_setattro*/ (setattrofunc)pyrna_prop_collection_setattro, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							|  |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							|  |  |  |     /*tp_richcompare*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist), | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ 0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_iter*/ (getiterfunc)pyrna_prop_collection_iter, | 
					
						
							|  |  |  |     /*tp_iternext*/ NULL, | 
					
						
							|  |  |  |     /*tp_methods*/ pyrna_prop_collection_methods, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ NULL /*Sub-classed: see #pyrna_prop_getseters. */, | 
					
						
							|  |  |  |     /*tp_base*/ &pyrna_prop_Type, | 
					
						
							|  |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ NULL, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | /* only for add/remove/move methods */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyTypeObject pyrna_prop_collection_idprop_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_prop_collection_idprop", | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(BPy_PropertyRNA), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ (destructor)pyrna_prop_dealloc, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset*/ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_compare*/ NULL, /* DEPRECATED. */ | 
					
						
							|  |  |  |     /*tp_repr*/ NULL,    /* Sub-classed, no need to define. */ | 
					
						
							|  |  |  |     /*tp_as_number*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ NULL, | 
					
						
							|  |  |  |     /*tp_hash*/ NULL, | 
					
						
							|  |  |  |     /*tp_call*/ NULL, | 
					
						
							|  |  |  |     /*tp_str*/ NULL, | 
					
						
							|  |  |  |     /*tp_getattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							|  |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							|  |  |  |     /*tp_richcompare*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist), | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ 0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_iter*/ NULL, | 
					
						
							|  |  |  |     /*tp_iternext*/ NULL, | 
					
						
							|  |  |  |     /*tp_methods*/ pyrna_prop_collection_idprop_methods, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ NULL /* Sub-classed: #pyrna_prop_getseters. */, | 
					
						
							|  |  |  |     /*tp_base*/ &pyrna_prop_collection_Type, | 
					
						
							|  |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ NULL, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | /*-----------------------BPy_PropertyRNA method def------------------------------*/ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_func_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_func", | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(BPy_FunctionRNA), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset*/ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_async*/ NULL, | 
					
						
							|  |  |  |     /*tp_repr*/ (reprfunc)pyrna_func_repr, | 
					
						
							|  |  |  |     /*tp_as_number*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ NULL, | 
					
						
							|  |  |  |     /*tp_hash*/ NULL, | 
					
						
							|  |  |  |     /*tp_call*/ (ternaryfunc)pyrna_func_call, | 
					
						
							|  |  |  |     /*tp_str*/ NULL, | 
					
						
							|  |  |  |     /*tp_getattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT, | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							|  |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							|  |  |  |     /*tp_richcompare*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist), | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ 0, | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_iter*/ NULL, | 
					
						
							|  |  |  |     /*tp_iternext*/ NULL, | 
					
						
							|  |  |  |     /*tp_methods*/ NULL, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ pyrna_func_getseters, | 
					
						
							|  |  |  |     /*tp_base*/ NULL, | 
					
						
							|  |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ NULL, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #ifdef USE_PYRNA_ITER
 | 
					
						
							|  |  |  | /* --- collection iterator: start --- */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* wrap RNA collection iterator functions */ | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * RNA_property_collection_begin(...) | 
					
						
							|  |  |  |  * RNA_property_collection_next(...) | 
					
						
							|  |  |  |  * RNA_property_collection_end(...) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self); | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 03:44:05 +00:00
										 |  |  | static PyTypeObject pyrna_prop_collection_iter_Type = { | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     /*tp_name*/ "bpy_prop_collection_iter", | 
					
						
							|  |  |  |     /*tp_basicsize*/ sizeof(BPy_PropertyCollectionIterRNA), | 
					
						
							|  |  |  |     /*tp_itemsize*/ 0, | 
					
						
							|  |  |  |     /*tp_dealloc*/ (destructor)pyrna_prop_collection_iter_dealloc, | 
					
						
							|  |  |  |     /*tp_vectorcall_offset*/ 0, | 
					
						
							|  |  |  |     /*tp_getattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_setattr*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_async*/ NULL, | 
					
						
							|  |  |  |     /*tp_repr*/ NULL, /* No need to define, sub-classed. */ | 
					
						
							|  |  |  |     /*tp_as_number*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_sequence*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_mapping*/ NULL, | 
					
						
							|  |  |  |     /*tp_hash*/ NULL, | 
					
						
							|  |  |  |     /*tp_call*/ NULL, | 
					
						
							|  |  |  |     /*tp_str*/ NULL, | 
					
						
							|  |  |  |     /*tp_getattro*/ PyObject_GenericGetAttr, | 
					
						
							|  |  |  |     /*tp_setattro*/ NULL, | 
					
						
							|  |  |  |     /*tp_as_buffer*/ NULL, | 
					
						
							|  |  |  |     /*tp_flags*/ Py_TPFLAGS_DEFAULT, | 
					
						
							|  |  |  |     /*tp_doc*/ NULL, | 
					
						
							|  |  |  |     /*tp_traverse*/ NULL, | 
					
						
							|  |  |  |     /*tp_clear*/ NULL, | 
					
						
							|  |  |  |     /*tp_richcompare*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #  ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist), | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #  else
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_weaklistoffset*/ 0, | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2022-11-07 22:34:35 +11:00
										 |  |  |     /*tp_iter*/ PyObject_SelfIter, | 
					
						
							|  |  |  |     /*tp_iternext*/ (iternextfunc)pyrna_prop_collection_iter_next, | 
					
						
							|  |  |  |     /*tp_methods*/ NULL, | 
					
						
							|  |  |  |     /*tp_members*/ NULL, | 
					
						
							|  |  |  |     /*tp_getset*/ NULL, | 
					
						
							|  |  |  |     /*tp_base*/ NULL, | 
					
						
							|  |  |  |     /*tp_dict*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_get*/ NULL, | 
					
						
							|  |  |  |     /*tp_descr_set*/ NULL, | 
					
						
							|  |  |  |     /*tp_dictoffset*/ 0, | 
					
						
							|  |  |  |     /*tp_init*/ NULL, | 
					
						
							|  |  |  |     /*tp_alloc*/ NULL, | 
					
						
							|  |  |  |     /*tp_new*/ NULL, | 
					
						
							|  |  |  |     /*tp_free*/ NULL, | 
					
						
							|  |  |  |     /*tp_is_gc*/ NULL, | 
					
						
							|  |  |  |     /*tp_bases*/ NULL, | 
					
						
							|  |  |  |     /*tp_mro*/ NULL, | 
					
						
							|  |  |  |     /*tp_cache*/ NULL, | 
					
						
							|  |  |  |     /*tp_subclasses*/ NULL, | 
					
						
							|  |  |  |     /*tp_weaklist*/ NULL, | 
					
						
							|  |  |  |     /*tp_del*/ NULL, | 
					
						
							|  |  |  |     /*tp_version_tag*/ 0, | 
					
						
							|  |  |  |     /*tp_finalize*/ NULL, | 
					
						
							|  |  |  |     /*tp_vectorcall*/ NULL, | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 01:52:28 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop) | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_PropertyCollectionIterRNA *self = PyObject_New(BPy_PropertyCollectionIterRNA, | 
					
						
							|  |  |  |                                                      &pyrna_prop_collection_iter_Type); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 02:43:30 +00:00
										 |  |  | #  ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   self->in_weakreflist = NULL; | 
					
						
							| 
									
										
										
										
											2011-03-11 02:43:30 +00:00
										 |  |  | #  endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  |   RNA_property_collection_begin(ptr, prop, &self->iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (PyObject *)self; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return pyrna_prop_collection_iter_CreatePyObject(&self->ptr, self->prop); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   if (self->iter.valid == false) { | 
					
						
							| 
									
										
										
										
											2013-11-17 15:09:57 +11:00
										 |  |  |     PyErr_SetNone(PyExc_StopIteration); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #  ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (pyrna) { /* Unlikely, but may fail. */ | 
					
						
							|  |  |  |     if ((PyObject *)pyrna != Py_None) { | 
					
						
							|  |  |  |       /* hold a reference to the iterator since it may have
 | 
					
						
							| 
									
										
										
										
											2021-06-24 15:56:58 +10:00
										 |  |  |        * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's. */ | 
					
						
							|  |  |  |       /* TODO: we could have an api call to know if this is
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |        * needed since most collections don't */ | 
					
						
							|  |  |  |       pyrna_struct_reference_set(pyrna, (PyObject *)self); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #  endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   RNA_property_collection_next(&self->iter); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   return (PyObject *)pyrna; | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #  ifdef USE_WEAKREFS
 | 
					
						
							|  |  |  |   if (self->in_weakreflist != NULL) { | 
					
						
							|  |  |  |     PyObject_ClearWeakRefs((PyObject *)self); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_property_collection_end(&self->iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyObject_DEL(self); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- collection iterator: end --- */ | 
					
						
							|  |  |  | #endif /* !USE_PYRNA_ITER */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-08-16 12:29:46 +00:00
										 |  |  |   PointerRNA ptr; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   PyObject *item; | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 06:29:15 +00:00
										 |  |  |   Py_INCREF(newclass); | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (RNA_struct_py_type_get(srna)) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  |     PyC_ObSpit("RNA WAS SET - ", RNA_struct_py_type_get(srna)); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-26 14:23:52 +10:00
										 |  |  |   Py_XDECREF((PyObject *)RNA_struct_py_type_get(srna)); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Not 100% needed, but useful,
 | 
					
						
							|  |  |  |    * having an instance within a type looks wrong, but this instance _is_ an RNA type. */ | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Python deals with the circular reference. */ | 
					
						
							| 
									
										
										
										
											2009-08-16 12:29:46 +00:00
										 |  |  |   RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   item = pyrna_struct_CreatePyObject(&ptr); | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* NOTE: must set the class not the __dict__ else the internal slots are not updated correctly.
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2011-06-18 08:45:45 +00:00
										 |  |  |   PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Add staticmethods and classmethods. */ | 
					
						
							| 
									
										
										
										
											2012-12-17 06:58:19 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |     const PointerRNA func_ptr = {NULL, srna, NULL}; | 
					
						
							| 
									
										
										
										
											2012-12-17 06:58:19 +00:00
										 |  |  |     const ListBase *lb; | 
					
						
							|  |  |  |     Link *link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lb = RNA_struct_type_functions(srna); | 
					
						
							|  |  |  |     for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |       FunctionRNA *func = (FunctionRNA *)link; | 
					
						
							|  |  |  |       const int flag = RNA_function_flag(func); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       if ((flag & FUNC_NO_SELF) &&         /* Is staticmethod or classmethod. */ | 
					
						
							|  |  |  |           (flag & FUNC_REGISTER) == false) /* Is not for registration. */ | 
					
						
							| 
									
										
										
										
											2012-12-17 09:17:21 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* We may want to set the type of this later. */ | 
					
						
							| 
									
										
										
										
											2012-12-17 06:58:19 +00:00
										 |  |  |         PyObject *func_py = pyrna_func_to_py(&func_ptr, func); | 
					
						
							|  |  |  |         PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py); | 
					
						
							|  |  |  |         Py_DECREF(func_py); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Done with RNA instance. */ | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | static PyObject *pyrna_srna_Subtype(StructRNA *srna); | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Return a borrowed reference. */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | static PyObject *pyrna_srna_PyBase(StructRNA *srna)  //, PyObject *bpy_types_dict)
 | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Assume RNA_struct_py_type_get(srna) was already checked. */ | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  |   StructRNA *base; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *py_base = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Get the base type. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   base = RNA_struct_base(srna); | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (base && base != srna) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     // printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna);
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     py_base = pyrna_srna_Subtype(base);  //, bpy_types_dict);
 | 
					
						
							| 
									
										
										
										
											2022-09-16 18:13:19 +10:00
										 |  |  |     Py_DECREF(py_base);                  /* `srna` owns, this is only to pass as an argument. */ | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (py_base == NULL) { | 
					
						
							|  |  |  |     py_base = (PyObject *)&pyrna_struct_Type; | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return py_base; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Check if we have a native Python subclass, use it when it exists
 | 
					
						
							|  |  |  |  * return a borrowed reference. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyObject *bpy_types_dict = NULL; | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | static PyObject *pyrna_srna_ExternalType(StructRNA *srna) | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const char *idname = RNA_struct_identifier(srna); | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |   PyObject *newclass; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (bpy_types_dict == NULL) { | 
					
						
							| 
									
										
										
										
											2013-03-17 18:30:31 +00:00
										 |  |  |     PyObject *bpy_types = PyImport_ImportModuleLevel("bpy_types", NULL, NULL, NULL, 0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if (bpy_types == NULL) { | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2018-04-02 15:39:43 +02:00
										 |  |  |       CLOG_ERROR(BPY_LOG_RNA, "failed to find 'bpy_types' module"); | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     bpy_types_dict = PyModule_GetDict(bpy_types); /* Borrow. */ | 
					
						
							|  |  |  |     Py_DECREF(bpy_types);                         /* Fairly safe to assume the dict is kept. */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   newclass = PyDict_GetItemString(bpy_types_dict, idname); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Sanity check, could skip this unless in debug mode. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (newclass) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *base_compare = pyrna_srna_PyBase(srna); | 
					
						
							| 
									
										
										
										
											2021-10-06 14:44:27 +11:00
										 |  |  |     /* Can't do this because it gets super-classes values! */ | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |     // PyObject *slots = PyObject_GetAttrString(newclass, "__slots__");
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Can do this, but faster not to. */ | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |     // PyObject *bases = PyObject_GetAttrString(newclass, "__bases__");
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *tp_bases = ((PyTypeObject *)newclass)->tp_bases; | 
					
						
							|  |  |  |     PyObject *tp_slots = PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, | 
					
						
							|  |  |  |                                         bpy_intern_str___slots__); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if (tp_slots == NULL) { | 
					
						
							| 
									
										
										
										
											2018-04-02 15:39:43 +02:00
										 |  |  |       CLOG_ERROR( | 
					
						
							|  |  |  |           BPY_LOG_RNA, "expected class '%s' to have __slots__ defined, see bpy_types.py", idname); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       newclass = NULL; | 
					
						
							| 
									
										
										
										
											2009-12-05 23:41:45 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     else if (PyTuple_GET_SIZE(tp_bases)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       PyObject *base = PyTuple_GET_ITEM(tp_bases, 0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (base_compare != base) { | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  |         char pyob_info[256]; | 
					
						
							|  |  |  |         PyC_ObSpitStr(pyob_info, sizeof(pyob_info), base_compare); | 
					
						
							|  |  |  |         CLOG_ERROR(BPY_LOG_RNA, | 
					
						
							| 
									
										
										
										
											2018-04-02 15:39:43 +02:00
										 |  |  |                    "incorrect subclassing of SRNA '%s', expected '%s', see bpy_types.py", | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  |                    idname, | 
					
						
							|  |  |  |                    pyob_info); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         newclass = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2018-04-02 15:39:43 +02:00
										 |  |  |         CLOG_INFO(BPY_LOG_RNA, 2, "SRNA sub-classed: '%s'", idname); | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |   return newclass; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | static PyObject *pyrna_srna_Subtype(StructRNA *srna) | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *newclass = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Stupid/simple case. */ | 
					
						
							| 
									
										
										
										
											2009-07-10 04:25:49 +00:00
										 |  |  |   if (srna == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     newclass = NULL; /* Nothing to do. */ | 
					
						
							|  |  |  |   }                  /* The class may have already been declared & allocated. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   else if ((newclass = RNA_struct_py_type_get(srna))) { | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |     Py_INCREF(newclass); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   } /* Check if bpy_types.py module has the class defined in it. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   else if ((newclass = pyrna_srna_ExternalType(srna))) { | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |     pyrna_subtype_set_rna(newclass, srna); | 
					
						
							|  |  |  |     Py_INCREF(newclass); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |   } /* create a new class instance with the C api
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |      * mainly for the purposing of matching the C/RNA type hierarchy */ | 
					
						
							| 
									
										
										
										
											2010-08-24 02:12:09 +00:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |     /* subclass equivalents
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |      * - class myClass(myBase): | 
					
						
							|  |  |  |      *     some = 'value' # or ... | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |      * - myClass = type( | 
					
						
							|  |  |  |      *       name='myClass', | 
					
						
							|  |  |  |      *       bases=(myBase,), dict={'__module__': 'bpy.types', '__slots__': ()} | 
					
						
							|  |  |  |      *   ) | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Assume RNA_struct_py_type_get(srna) was already checked. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *py_base = pyrna_srna_PyBase(srna); | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  |     PyObject *metaclass; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     const char *idname = RNA_struct_identifier(srna); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-20 15:01:03 +10:00
										 |  |  |     /* Remove `__doc__` for now because we don't need it to generate docs. */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  |     const char *descr = RNA_struct_ui_description(srna); | 
					
						
							|  |  |  |     if (!descr) { | 
					
						
							|  |  |  |       descr = "(no docs)"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |     if (RNA_struct_idprops_check(srna) && | 
					
						
							|  |  |  |         !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       metaclass = (PyObject *)&pyrna_struct_meta_idprop_Type; | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       metaclass = (PyObject *)&PyType_Type; | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Always use O not N when calling, N causes refcount errors. */ | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     newclass = PyObject_CallFunction( | 
					
						
							|  |  |  |         metaclass, "s(O) {sss()}", idname, py_base, "__module__", "bpy.types", "__slots__"); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Longhand of the call above. */ | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  |       PyObject *args, *item, *value; | 
					
						
							|  |  |  |       int ok; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       args = PyTuple_New(3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* arg[0] (name=...) */ | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(idname)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* arg[1] (bases=...) */ | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args, 1, item = PyTuple_New(1)); | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  |       PyTuple_SET_ITEM(item, 0, Py_INCREF_RET(py_base)); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* arg[2] (dict=...) */ | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args, 2, item = PyDict_New()); | 
					
						
							| 
									
										
										
										
											2015-01-06 16:42:22 +11:00
										 |  |  |       ok = PyDict_SetItem(item, bpy_intern_str___module__, bpy_intern_str_bpy_types); | 
					
						
							|  |  |  |       BLI_assert(ok != -1); | 
					
						
							|  |  |  |       ok = PyDict_SetItem(item, bpy_intern_str___slots__, value = PyTuple_New(0)); | 
					
						
							|  |  |  |       Py_DECREF(value); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  |       BLI_assert(ok != -1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       newclass = PyObject_CallObject(metaclass, args); | 
					
						
							|  |  |  |       Py_DECREF(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       (void)ok; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |     /* Newclass will now have 2 ref's, ???,
 | 
					
						
							| 
									
										
										
										
											2019-09-30 17:06:28 +10:00
										 |  |  |      * probably 1 is internal since #Py_DECREF here segfaults. */ | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 14:34:41 +10:00
										 |  |  |     // PyC_ObSpit("new class ref", newclass);
 | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-10 04:25:49 +00:00
										 |  |  |     if (newclass) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* srna owns one, and the other is owned by the caller. */ | 
					
						
							| 
									
										
										
										
											2009-07-10 04:25:49 +00:00
										 |  |  |       pyrna_subtype_set_rna(newclass, srna); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* XXX, adding this back segfaults Blender on load. */ | 
					
						
							| 
									
										
										
										
											2010-08-24 02:12:09 +00:00
										 |  |  |       // Py_DECREF(newclass); /* let srna own */
 | 
					
						
							| 
									
										
										
										
											2009-07-10 04:25:49 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* This should not happen. */ | 
					
						
							| 
									
										
										
										
											2018-04-02 15:39:43 +02:00
										 |  |  |       CLOG_ERROR(BPY_LOG_RNA, "failed to register '%s'", idname); | 
					
						
							| 
									
										
										
										
											2009-07-10 04:25:49 +00:00
										 |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  |   return newclass; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Use for sub-typing so we know which SRNA is used for a #PointerRNA. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | static StructRNA *srna_from_ptr(PointerRNA *ptr) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (ptr->type == &RNA_Struct) { | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  |     return ptr->data; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return ptr->type; | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Always returns a new ref, be sure to decref when done. */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | static PyObject *pyrna_struct_Subtype(PointerRNA *ptr) | 
					
						
							| 
									
										
										
										
											2009-07-10 18:09:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  |   return pyrna_srna_Subtype(srna_from_ptr(ptr)); | 
					
						
							| 
									
										
										
										
											2009-07-10 18:09:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | /*-----------------------CreatePyObject---------------------------------*/ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_StructRNA *pyrna = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* NOTE: don't rely on this to return None since NULL data with a valid type can often crash. */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data. */ | 
					
						
							| 
									
										
										
										
											2009-03-05 16:24:30 +00:00
										 |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 23:05:00 +10:00
										 |  |  |   /* New in 2.8x, since not many types support instancing
 | 
					
						
							|  |  |  |    * we may want to use a flag to avoid looping over all classes. - campbell */ | 
					
						
							| 
									
										
										
										
											2017-07-27 03:19:12 +10:00
										 |  |  |   void **instance = ptr->data ? RNA_struct_instance(ptr) : NULL; | 
					
						
							| 
									
										
										
										
											2017-07-26 23:05:00 +10:00
										 |  |  |   if (instance && *instance) { | 
					
						
							|  |  |  |     pyrna = *instance; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 17:11:09 +10:00
										 |  |  |     /* Refine may have changed types after the first instance was created. */ | 
					
						
							|  |  |  |     if (ptr->type == pyrna->ptr.type) { | 
					
						
							|  |  |  |       Py_INCREF(pyrna); | 
					
						
							|  |  |  |       return (PyObject *)pyrna; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Existing users will need to use 'type_recast' method. */ | 
					
						
							|  |  |  |     Py_DECREF(pyrna); | 
					
						
							|  |  |  |     *instance = NULL; | 
					
						
							|  |  |  |     /* Continue as if no instance was made. */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #if 0 /* No need to assign, will be written to next... */
 | 
					
						
							| 
									
										
										
										
											2017-08-01 17:15:50 +10:00
										 |  |  |       pyrna = NULL; | 
					
						
							| 
									
										
										
										
											2017-08-01 17:11:09 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-26 23:05:00 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 23:05:00 +10:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |     if (tp) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0); | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							|  |  |  |       /* #PyType_GenericAlloc will have set tracking.
 | 
					
						
							|  |  |  |        * We only want tracking when `StructRNA.reference` has been set. */ | 
					
						
							|  |  |  |       if (pyrna != NULL) { | 
					
						
							|  |  |  |         PyObject_GC_UnTrack(pyrna); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       Py_DECREF(tp); /* srna owns, can't hold a reference. */ | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  |       CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type)); | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       pyrna = (BPy_StructRNA *)PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type); | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  | #else
 | 
					
						
							|  |  |  |       pyrna = (BPy_StructRNA *)PyObject_New(BPy_StructRNA, &pyrna_struct_Type); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2021-03-04 15:06:14 +11:00
										 |  |  |       if (pyrna != NULL) { | 
					
						
							|  |  |  |         pyrna->in_weakreflist = NULL; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-10 04:25:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (pyrna == NULL) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_MemoryError, "couldn't create bpy_struct object"); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 23:05:00 +10:00
										 |  |  |   /* Blender's instance owns a reference (to avoid Python freeing it). */ | 
					
						
							|  |  |  |   if (instance) { | 
					
						
							|  |  |  |     *instance = pyrna; | 
					
						
							|  |  |  |     Py_INCREF(pyrna); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   pyrna->ptr = *ptr; | 
					
						
							| 
									
										
										
										
											2011-08-05 16:29:38 +00:00
										 |  |  | #ifdef PYRNA_FREE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   pyrna->freeptr = false; | 
					
						
							| 
									
										
										
										
											2011-08-05 16:29:38 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   pyrna->reference = NULL; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  |   // PyC_ObSpit("NewStructRNA: ", (PyObject *)pyrna);
 | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   if (ptr->owner_id) { | 
					
						
							|  |  |  |     id_weakref_pool_add(ptr->owner_id, (BPy_DummyPointerRNA *)pyrna); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |   return (PyObject *)pyrna; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   BPy_PropertyRNA *pyrna; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-14 10:28:18 +00:00
										 |  |  |   if (RNA_property_array_check(prop) == 0) { | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |     PyTypeObject *type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (RNA_property_type(prop) != PROP_COLLECTION) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       type = &pyrna_prop_Type; | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if ((RNA_property_flag(prop) & PROP_IDPROPERTY) == 0) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         type = &pyrna_prop_collection_Type; | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         type = &pyrna_prop_collection_idprop_Type; | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyRNA, type); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     pyrna->in_weakreflist = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type); | 
					
						
							|  |  |  |     ((BPy_PropertyArrayRNA *)pyrna)->arraydim = 0; | 
					
						
							|  |  |  |     ((BPy_PropertyArrayRNA *)pyrna)->arrayoffset = 0; | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (pyrna == NULL) { | 
					
						
							| 
									
										
										
										
											2010-11-23 16:45:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_MemoryError, "couldn't create BPy_rna object"); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   pyrna->ptr = *ptr; | 
					
						
							|  |  |  |   pyrna->prop = prop; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   if (ptr->owner_id) { | 
					
						
							|  |  |  |     id_weakref_pool_add(ptr->owner_id, (BPy_DummyPointerRNA *)pyrna); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |   return (PyObject *)pyrna; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-01 06:50:43 +00:00
										 |  |  | PyObject *pyrna_id_CreatePyObject(ID *id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (id) { | 
					
						
							|  |  |  |     PointerRNA ptr; | 
					
						
							|  |  |  |     RNA_id_pointer_create(id, &ptr); | 
					
						
							|  |  |  |     return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2012-05-01 06:50:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | bool pyrna_id_FromPyObject(PyObject *obj, ID **id) | 
					
						
							| 
									
										
										
										
											2012-05-01 06:50:43 +00:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
											
										 
											2017-04-13 12:30:03 +03:00
										 |  |  |   if (pyrna_id_CheckPyObject(obj)) { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |     *id = ((BPy_StructRNA *)obj)->ptr.owner_id; | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2012-05-01 06:50:43 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   *id = NULL; | 
					
						
							|  |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2012-05-01 06:50:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
											
										 
											2017-04-13 12:30:03 +03:00
										 |  |  | bool pyrna_id_CheckPyObject(PyObject *obj) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-10-07 22:52:53 +11:00
										 |  |  |   return BPy_StructRNA_Check(obj) && RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type); | 
					
						
							| 
									
										
											  
											
												Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
											
										 
											2017-04-13 12:30:03 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | void BPY_rna_init(void) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #ifdef USE_MATHUTILS /* Register mathutils callbacks, ok to run more than once. */
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   mathutils_rna_array_cb_index = Mathutils_RegisterCallback(&mathutils_rna_array_cb); | 
					
						
							|  |  |  |   mathutils_rna_matrix_cb_index = Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* For some reason MSVC complains of these. */ | 
					
						
							| 
									
										
										
										
											2017-05-27 15:34:55 -04:00
										 |  |  | #if defined(_MSC_VER)
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type; | 
					
						
							| 
									
										
										
										
											2011-10-01 15:02:55 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* metaclass */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_struct_meta_idprop_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_struct_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_array_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_collection_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_func_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #ifdef USE_PYRNA_ITER
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_collection_iter_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-08-11 17:29:26 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							|  |  |  |   BLI_assert(id_weakref_pool == NULL); | 
					
						
							|  |  |  |   id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BPY_rna_exit(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							|  |  |  |   /* This can help track down which kinds of data were not released.
 | 
					
						
							|  |  |  |    * If they were in fact freed by Blender, printing their names | 
					
						
							|  |  |  |    * will crash giving a useful error with address sanitizer. The likely cause | 
					
						
							|  |  |  |    * for this list not being empty is a missing call to: #BKE_libblock_free_data_py. */ | 
					
						
							|  |  |  |   const int id_weakref_pool_len = BLI_ghash_len(id_weakref_pool); | 
					
						
							| 
									
										
										
										
											2021-08-24 14:36:25 +10:00
										 |  |  |   if (id_weakref_pool_len != 0) { | 
					
						
							| 
									
										
										
										
											2021-08-11 17:29:26 +10:00
										 |  |  |     printf("Found %d unreleased ID's\n", id_weakref_pool_len); | 
					
						
							|  |  |  |     GHashIterator gh_iter; | 
					
						
							|  |  |  |     GHASH_ITER (gh_iter, id_weakref_pool) { | 
					
						
							|  |  |  |       ID *id = BLI_ghashIterator_getKey(&gh_iter); | 
					
						
							|  |  |  |       printf("ID: %s\n", id->name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-10-12 17:52:36 +11:00
										 |  |  |   BLI_ghash_free(id_weakref_pool, NULL, id_weakref_pool_free_value_fn); | 
					
						
							| 
									
										
										
										
											2021-08-11 17:29:26 +10:00
										 |  |  |   id_weakref_pool = NULL; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* 'bpy.data' from Python. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PointerRNA *rna_module_ptr = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | PyObject *BPY_rna_module(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BPy_StructRNA *pyrna; | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* For now, return the base RNA type rather than a real module. */ | 
					
						
							| 
									
										
										
										
											2018-06-22 11:37:47 +02:00
										 |  |  |   RNA_main_pointer_create(G_MAIN, &ptr); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   rna_module_ptr = &pyrna->ptr; | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  |   return (PyObject *)pyrna; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BPY_update_rna_module(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-22 22:03:41 +00:00
										 |  |  |   if (rna_module_ptr) { | 
					
						
							| 
									
										
										
										
											2011-10-05 07:28:59 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2018-06-22 11:37:47 +02:00
										 |  |  |     RNA_main_pointer_create(G_MAIN, rna_module_ptr); | 
					
						
							| 
									
										
										
										
											2011-10-05 07:28:59 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     rna_module_ptr->data = G_MAIN; /* Just set data is enough. */ | 
					
						
							| 
									
										
										
										
											2011-10-05 07:28:59 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-05-08 22:07:06 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2020-07-19 17:12:48 +10:00
										 |  |  | /* This is a way we can access doc-strings for RNA types
 | 
					
						
							|  |  |  |  * without having the data-types in Blender. */ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | PyObject *BPY_rna_doc(void) | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* For now, return the base RNA type rather than a real module. */ | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  |   RNA_blender_rna_pointer_create(&ptr); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  |   return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name RNA Types Module `bpy.types`
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * This could be a static variable as we only have one `bpy.types` module, | 
					
						
							| 
									
										
										
										
											2021-11-07 23:20:29 -06:00
										 |  |  |  * it just keeps the data isolated to store in the module itself. | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-02-20 15:38:14 +11:00
										 |  |  |  * This data doesn't change one initialized. | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |  */ | 
					
						
							|  |  |  | struct BPy_TypesModule_State { | 
					
						
							|  |  |  |   /** `RNA_BlenderRNA`. */ | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   /** `RNA_BlenderRNA.structs`, exposed as `bpy.types` */ | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *bpy_types_module_getattro(PyObject *self, PyObject *pyname) | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |   struct BPy_TypesModule_State *state = PyModule_GetState(self); | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |   PointerRNA newptr; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |   const char *name = PyUnicode_AsUTF8(pyname); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (name == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-09 13:58:38 +00:00
										 |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = NULL; | 
					
						
							| 
									
										
										
										
											2010-09-09 13:58:38 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |   else if (RNA_property_collection_lookup_string(&state->ptr, state->prop, name, &newptr)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = pyrna_struct_Subtype(&newptr); | 
					
						
							|  |  |  |     if (ret == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                    "bpy.types.%.200s subtype could not be generated, this is a bug!", | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |                    PyUnicode_AsUTF8(pyname)); | 
					
						
							| 
									
										
										
										
											2009-04-11 15:05:42 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  |   else { | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy.types.%.200s RNA_Struct does not exist", | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |                  PyUnicode_AsUTF8(pyname)); | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* The error raised here will be displayed. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  | static PyObject *bpy_types_module_dir(PyObject *self) | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |   struct BPy_TypesModule_State *state = PyModule_GetState(self); | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  |   PyObject *ret = PyList_New(0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |   RNA_PROP_BEGIN (&state->ptr, itemptr, state->prop) { | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  |     StructRNA *srna = itemptr.data; | 
					
						
							| 
									
										
										
										
											2017-08-31 23:32:21 +10:00
										 |  |  |     PyList_APPEND(ret, PyUnicode_FromString(RNA_struct_identifier(srna))); | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2021-02-19 19:10:48 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* Include the modules `__dict__` for Python only types. */ | 
					
						
							|  |  |  |   PyObject *submodule_dict = PyModule_GetDict(self); | 
					
						
							|  |  |  |   PyObject *key, *value; | 
					
						
							|  |  |  |   Py_ssize_t pos = 0; | 
					
						
							|  |  |  |   while (PyDict_Next(submodule_dict, &pos, &key, &value)) { | 
					
						
							| 
									
										
										
										
											2021-02-22 22:26:20 +11:00
										 |  |  |     PyList_Append(ret, key); | 
					
						
							| 
									
										
										
										
											2021-02-19 19:10:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  | static struct PyMethodDef bpy_types_module_methods[] = { | 
					
						
							|  |  |  |     {"__getattr__", (PyCFunction)bpy_types_module_getattro, METH_O, NULL}, | 
					
						
							|  |  |  |     {"__dir__", (PyCFunction)bpy_types_module_dir, METH_NOARGS, NULL}, | 
					
						
							|  |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  | PyDoc_STRVAR(bpy_types_module_doc, "Access to internal Blender types"); | 
					
						
							|  |  |  | static struct PyModuleDef bpy_types_module_def = { | 
					
						
							|  |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     "bpy.types",                          /* m_name */ | 
					
						
							|  |  |  |     bpy_types_module_doc,                 /* m_doc */ | 
					
						
							|  |  |  |     sizeof(struct BPy_TypesModule_State), /* m_size */ | 
					
						
							|  |  |  |     bpy_types_module_methods,             /* m_methods */ | 
					
						
							| 
									
										
										
										
											2022-09-08 15:32:33 +10:00
										 |  |  |     NULL,                                 /* m_slots */ | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |     NULL,                                 /* m_traverse */ | 
					
						
							|  |  |  |     NULL,                                 /* m_clear */ | 
					
						
							|  |  |  |     NULL,                                 /* m_free */ | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPY_rna_types(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |   PyObject *submodule = PyModule_Create(&bpy_types_module_def); | 
					
						
							|  |  |  |   struct BPy_TypesModule_State *state = PyModule_GetState(submodule); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |   RNA_blender_rna_pointer_create(&state->ptr); | 
					
						
							|  |  |  |   state->prop = RNA_struct_find_property(&state->ptr, "structs"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Internal base types we have no other accessors for. */ | 
					
						
							| 
									
										
										
										
											2015-11-30 11:02:09 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |     static PyTypeObject *pyrna_types[] = { | 
					
						
							| 
									
										
										
										
											2015-11-30 11:02:09 +11:00
										 |  |  |         &pyrna_struct_meta_idprop_Type, | 
					
						
							|  |  |  |         &pyrna_struct_Type, | 
					
						
							|  |  |  |         &pyrna_prop_Type, | 
					
						
							|  |  |  |         &pyrna_prop_array_Type, | 
					
						
							|  |  |  |         &pyrna_prop_collection_Type, | 
					
						
							|  |  |  |         &pyrna_func_Type, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |     PyObject *submodule_dict = PyModule_GetDict(submodule); | 
					
						
							| 
									
										
										
										
											2015-11-30 11:02:09 +11:00
										 |  |  |     for (int i = 0; i < ARRAY_SIZE(pyrna_types); i += 1) { | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |       PyDict_SetItemString(submodule_dict, pyrna_types[i]->tp_name, (PyObject *)pyrna_types[i]); | 
					
						
							| 
									
										
										
										
											2015-11-30 11:02:09 +11:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  |   return submodule; | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-16 15:54:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 19:08:28 +11:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   BPy_StructRNA *py_srna = NULL; | 
					
						
							| 
									
										
										
										
											2009-08-16 12:29:46 +00:00
										 |  |  |   StructRNA *srna; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-22 10:42:32 -07:00
										 |  |  |   /* Unfortunately PyObject_GetAttrString won't look up this types tp_dict first :/ */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (PyType_Check(self)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict, | 
					
						
							|  |  |  |                                               bpy_intern_str_bl_rna); | 
					
						
							| 
									
										
										
										
											2009-08-22 17:06:10 +00:00
										 |  |  |     Py_XINCREF(py_srna); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (parent) { | 
					
						
							| 
									
										
										
										
											2010-03-16 17:20:15 +00:00
										 |  |  |     /* be very careful with this since it will return a parent classes srna.
 | 
					
						
							|  |  |  |      * modifying this will do confusing stuff! */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (py_srna == NULL) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       py_srna = (BPy_StructRNA *)PyObject_GetAttr(self, bpy_intern_str_bl_rna); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-03-16 17:20:15 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (py_srna == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                  "%.200s, missing bl_rna attribute from '%.200s' instance (may not be registered)", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(self)->tp_name); | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (!BPy_StructRNA_Check(py_srna)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s, bl_rna attribute wrong type '%.200s' on '%.200s'' instance", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(py_srna)->tp_name, | 
					
						
							|  |  |  |                  Py_TYPE(self)->tp_name); | 
					
						
							| 
									
										
										
										
											2011-04-21 15:53:30 +00:00
										 |  |  |     Py_DECREF(py_srna); | 
					
						
							| 
									
										
										
										
											2009-08-16 12:29:46 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (py_srna->ptr.type != &RNA_Struct) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s, bl_rna attribute not a RNA_Struct, on '%.200s'' instance", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(self)->tp_name); | 
					
						
							| 
									
										
										
										
											2011-04-21 15:53:30 +00:00
										 |  |  |     Py_DECREF(py_srna); | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   srna = py_srna->ptr.data; | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  |   Py_DECREF(py_srna); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-16 12:29:46 +00:00
										 |  |  |   return srna; | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-20 12:06:03 +10:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Orphan functions, not sure where they should go. */ | 
					
						
							| 
									
										
										
										
											2010-03-16 17:20:15 +00:00
										 |  |  | StructRNA *srna_from_self(PyObject *self, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2009-08-09 10:05:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-19 00:59:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (self == NULL) { | 
					
						
							| 
									
										
										
										
											2009-08-09 10:05:33 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PyCapsule_CheckExact(self)) { | 
					
						
							| 
									
										
										
										
											2010-02-12 21:14:01 +00:00
										 |  |  |     return PyCapsule_GetPointer(self, NULL); | 
					
						
							| 
									
										
										
										
											2009-08-09 10:05:33 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (PyType_Check(self) == 0) { | 
					
						
							| 
									
										
										
										
											2009-08-11 02:27:25 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   /* These cases above not errors, they just mean the type was not compatible
 | 
					
						
							|  |  |  |    * After this any errors will be raised in the script */ | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   PyObject *error_type, *error_value, *error_traceback; | 
					
						
							|  |  |  |   StructRNA *srna; | 
					
						
							| 
									
										
										
										
											2009-08-09 10:05:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
					
						
							|  |  |  |   srna = pyrna_struct_as_srna(self, false, error_prefix); | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |   if (!PyErr_Occurred()) { | 
					
						
							|  |  |  |     PyErr_Restore(error_type, error_value, error_traceback); | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return srna; | 
					
						
							| 
									
										
										
										
											2009-08-09 10:05:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  | static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item) | 
					
						
							| 
									
										
										
										
											2009-08-22 17:30:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   if (!BPy_PropDeferred_CheckTypeExact(item)) { | 
					
						
							|  |  |  |     /* No error, ignoring. */ | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-20 20:58:46 +00:00
										 |  |  |   /* We only care about results from C which
 | 
					
						
							|  |  |  |    * are for sure types, save some time with error */ | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   PyObject *py_func = ((BPy_PropDeferred *)item)->fn; | 
					
						
							|  |  |  |   PyObject *py_kw = ((BPy_PropDeferred *)item)->kw; | 
					
						
							|  |  |  |   PyObject *py_srna_cobject, *py_ret; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |   /* Show the function name in errors to help give context. */ | 
					
						
							|  |  |  |   BLI_assert(PyCFunction_CheckExact(py_func)); | 
					
						
							|  |  |  |   PyMethodDef *py_func_method_def = ((PyCFunctionObject *)py_func)->m_ml; | 
					
						
							|  |  |  |   const char *func_name = py_func_method_def->ml_name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   PyObject *args_fake; | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |   const char *key_str = PyUnicode_AsUTF8(key); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |   if (*key_str == '_') { | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "bpy_struct \"%.200s\" registration error: " | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |                  "'%.200s' %.200s could not register because it starts with an '_'", | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |                  RNA_struct_identifier(srna), | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |                  key_str, | 
					
						
							|  |  |  |                  func_name); | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   py_srna_cobject = PyCapsule_New(srna, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   /* Not 100% nice :/, modifies the dict passed, should be ok. */ | 
					
						
							|  |  |  |   PyDict_SetItem(py_kw, bpy_intern_str_attr, key); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   args_fake = PyTuple_New(1); | 
					
						
							|  |  |  |   PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   PyObject *type = PyDict_GetItemString(py_kw, "type"); | 
					
						
							|  |  |  |   StructRNA *type_srna = srna_from_self(type, ""); | 
					
						
							|  |  |  |   if (type_srna) { | 
					
						
							|  |  |  |     if (!RNA_struct_idprops_datablock_allowed(srna) && | 
					
						
							|  |  |  |         (*(PyCFunctionWithKeywords)PyCFunction_GET_FUNCTION(py_func) == BPy_PointerProperty || | 
					
						
							|  |  |  |          *(PyCFunctionWithKeywords)PyCFunction_GET_FUNCTION(py_func) == BPy_CollectionProperty) && | 
					
						
							|  |  |  |         RNA_struct_idprops_contains_datablock(type_srna)) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |                    "bpy_struct \"%.200s\" registration error: " | 
					
						
							|  |  |  |                    "'%.200s' %.200s could not register because " | 
					
						
							|  |  |  |                    "this type doesn't support data-block properties", | 
					
						
							|  |  |  |                    RNA_struct_identifier(srna), | 
					
						
							|  |  |  |                    key_str, | 
					
						
							|  |  |  |                    func_name); | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   py_ret = PyObject_Call(py_func, args_fake, py_kw); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |   if (py_ret) { | 
					
						
							|  |  |  |     Py_DECREF(py_ret); | 
					
						
							|  |  |  |     Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* _must_ print before decreffing args_fake. */ | 
					
						
							|  |  |  |     PyErr_Print(); | 
					
						
							|  |  |  |     PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |     Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "bpy_struct \"%.200s\" registration error: " | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |                  "'%.200s' %.200s could not register (see previous error)", | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |                  RNA_struct_identifier(srna), | 
					
						
							| 
									
										
										
										
											2021-07-30 16:04:00 +10:00
										 |  |  |                  key_str, | 
					
						
							|  |  |  |                  func_name); | 
					
						
							| 
									
										
										
										
											2021-02-20 16:16:43 +11:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2009-11-20 20:58:46 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 21:21:18 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Extract `__annotations__` using `typing.get_type_hints` which handles the delayed evaluation. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int pyrna_deferred_register_class_from_type_hints(StructRNA *srna, PyTypeObject *py_class) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *annotations_dict = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* `typing.get_type_hints(py_class)` */ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     PyObject *typing_mod = PyImport_ImportModuleLevel("typing", NULL, NULL, NULL, 0); | 
					
						
							|  |  |  |     if (typing_mod != NULL) { | 
					
						
							|  |  |  |       PyObject *get_type_hints_fn = PyObject_GetAttrString(typing_mod, "get_type_hints"); | 
					
						
							|  |  |  |       if (get_type_hints_fn != NULL) { | 
					
						
							|  |  |  |         PyObject *args = PyTuple_New(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         PyTuple_SET_ITEM(args, 0, (PyObject *)py_class); | 
					
						
							|  |  |  |         Py_INCREF(py_class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         annotations_dict = PyObject_CallObject(get_type_hints_fn, args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Py_DECREF(args); | 
					
						
							|  |  |  |         Py_DECREF(get_type_hints_fn); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       Py_DECREF(typing_mod); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int ret = 0; | 
					
						
							|  |  |  |   if (annotations_dict != NULL) { | 
					
						
							|  |  |  |     if (PyDict_CheckExact(annotations_dict)) { | 
					
						
							|  |  |  |       PyObject *item, *key; | 
					
						
							|  |  |  |       Py_ssize_t pos = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       while (PyDict_Next(annotations_dict, &pos, &key, &item)) { | 
					
						
							|  |  |  |         ret = deferred_register_prop(srna, key, item); | 
					
						
							|  |  |  |         if (ret != 0) { | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2021-06-22 10:42:32 -07:00
										 |  |  |       /* Should never happen, an error won't have been raised, so raise one. */ | 
					
						
							| 
									
										
										
										
											2021-02-21 21:21:18 +11:00
										 |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "typing.get_type_hints returned: %.200s, expected dict\n", | 
					
						
							|  |  |  |                    Py_TYPE(annotations_dict)->tp_name); | 
					
						
							|  |  |  |       ret = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(annotations_dict); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     BLI_assert(PyErr_Occurred()); | 
					
						
							|  |  |  |     fprintf(stderr, "typing.get_type_hints failed with: %.200s\n", py_class->tp_name); | 
					
						
							|  |  |  |     ret = -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  | static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) | 
					
						
							| 
									
										
										
										
											2009-11-20 20:58:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-20 14:56:36 +10:00
										 |  |  |   PyObject *annotations_dict; | 
					
						
							| 
									
										
										
										
											2009-11-20 20:58:46 +00:00
										 |  |  |   PyObject *item, *key; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   Py_ssize_t pos = 0; | 
					
						
							|  |  |  |   int ret = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-27 02:52:12 +00:00
										 |  |  |   /* in both cases PyDict_CheckExact(class_dict) will be true even
 | 
					
						
							|  |  |  |    * though Operators have a metaclass dict namespace */ | 
					
						
							| 
									
										
										
										
											2018-09-20 14:56:36 +10:00
										 |  |  |   if ((annotations_dict = PyDict_GetItem(class_dict, bpy_intern_str___annotations__)) && | 
					
						
							|  |  |  |       PyDict_CheckExact(annotations_dict)) { | 
					
						
							|  |  |  |     while (PyDict_Next(annotations_dict, &pos, &key, &item)) { | 
					
						
							| 
									
										
										
										
											2018-07-11 22:18:09 +02:00
										 |  |  |       ret = deferred_register_prop(srna, key, item); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 22:18:09 +02:00
										 |  |  |       if (ret != 0) { | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-11-26 02:33:57 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-20 20:58:46 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-13 07:54:35 +00:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-08-22 17:30:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  | static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject *py_class) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const int len = PyTuple_GET_SIZE(py_class->tp_bases); | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |   int i, ret; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* First scan base classes for registerable properties. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |     PyTypeObject *py_superclass = (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |     /* the rules for using these base classes are not clear,
 | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |      * 'object' is of course not worth looking into and | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |      * existing subclasses of RNA would cause a lot more dictionary | 
					
						
							|  |  |  |      * looping then is needed (SomeOperator would scan Operator.__dict__) | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |      * which is harmless, but not at all useful. | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |      * | 
					
						
							|  |  |  |      * So only scan base classes which are not subclasses if blender types. | 
					
						
							|  |  |  |      * This best fits having 'mix-in' classes for operators and render engines. | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (py_superclass != &PyBaseObject_Type && | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |         !PyObject_IsSubclass((PyObject *)py_superclass, (PyObject *)&pyrna_struct_Type)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = pyrna_deferred_register_class_recursive(srna, py_superclass); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (ret != 0) { | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Not register out own properties. */ | 
					
						
							|  |  |  |   /* getattr(..., "__dict__") returns a proxy. */ | 
					
						
							|  |  |  |   return pyrna_deferred_register_props(srna, py_class->tp_dict); | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-22 15:47:02 +00:00
										 |  |  | int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class) | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  |   /* Panels and Menus don't need this
 | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |    * save some time and skip the checks here */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!RNA_struct_idprops_register_check(srna)) { | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 21:21:18 +11:00
										 |  |  | #ifdef USE_POSTPONED_ANNOTATIONS
 | 
					
						
							|  |  |  |   const bool use_postponed_annotations = true; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   const bool use_postponed_annotations = false; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (use_postponed_annotations) { | 
					
						
							|  |  |  |     return pyrna_deferred_register_class_from_type_hints(srna, py_class); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-03-22 15:47:02 +00:00
										 |  |  |   return pyrna_deferred_register_class_recursive(srna, py_class); | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | /*-------------------- Type Registration ------------------------*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  | static int rna_function_arg_count(FunctionRNA *func, int *min_count) | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const ListBase *lb = RNA_function_defined_parameters(func); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   PropertyRNA *parm; | 
					
						
							|  |  |  |   Link *link; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const int flag = RNA_function_flag(func); | 
					
						
							| 
									
										
										
										
											2014-01-28 03:52:21 +11:00
										 |  |  |   const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); | 
					
						
							| 
									
										
										
										
											2012-12-20 09:33:12 +00:00
										 |  |  |   int count = is_staticmethod ? 0 : 1; | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |   bool done_min_count = false; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |     parm = (PropertyRNA *)link; | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |     if (!(RNA_parameter_flag(parm) & PARM_OUTPUT)) { | 
					
						
							|  |  |  |       if (!done_min_count && (RNA_parameter_flag(parm) & PARM_PYFUNC_OPTIONAL)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* From now on, the following parameters are optional in a Python function. */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         if (min_count) { | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |           *min_count = count; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |         done_min_count = true; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       count++; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (!done_min_count && min_count) { | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |     *min_count = count; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   return count; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-24 12:00:02 +00:00
										 |  |  | static int bpy_class_validate_recursive(PointerRNA *dummyptr, | 
					
						
							|  |  |  |                                         StructRNA *srna, | 
					
						
							|  |  |  |                                         void *py_data, | 
					
						
							|  |  |  |                                         int *have_function) | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   const ListBase *lb; | 
					
						
							|  |  |  |   Link *link; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const char *class_type = RNA_struct_identifier(srna); | 
					
						
							| 
									
										
										
										
											2012-07-24 12:00:02 +00:00
										 |  |  |   StructRNA *srna_base = RNA_struct_base(srna); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *py_class = (PyObject *)py_data; | 
					
						
							|  |  |  |   PyObject *base_class = RNA_struct_py_type_get(srna); | 
					
						
							| 
									
										
										
										
											2010-08-08 23:46:49 +00:00
										 |  |  |   PyObject *item; | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:36 +10:00
										 |  |  |   int i, arg_count, func_arg_count, func_arg_min_count = 0; | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  |   const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-24 12:00:02 +00:00
										 |  |  |   if (srna_base) { | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (bpy_class_validate_recursive(dummyptr, srna_base, py_data, have_function) != 0) { | 
					
						
							| 
									
										
										
										
											2012-07-24 12:00:02 +00:00
										 |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   if (base_class) { | 
					
						
							|  |  |  |     if (!PyObject_IsSubclass(py_class, base_class)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "expected %.200s subclass of class \"%.200s\"", | 
					
						
							|  |  |  |                    class_type, | 
					
						
							|  |  |  |                    py_class_name); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Verify callback functions. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   lb = RNA_struct_type_functions(srna); | 
					
						
							|  |  |  |   i = 0; | 
					
						
							|  |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:36 +10:00
										 |  |  |     FunctionRNA *func = (FunctionRNA *)link; | 
					
						
							|  |  |  |     const int flag = RNA_function_flag(func); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (!(flag & FUNC_REGISTER)) { | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     item = PyObject_GetAttrString(py_class, RNA_function_identifier(func)); | 
					
						
							|  |  |  |     have_function[i] = (item != NULL); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     i++; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if (item == NULL) { | 
					
						
							| 
									
										
										
										
											2013-01-28 12:17:49 +00:00
										 |  |  |       if ((flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER)) == 0) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                      "expected %.200s, %.200s class to have an \"%.200s\" attribute", | 
					
						
							|  |  |  |                      class_type, | 
					
						
							|  |  |  |                      py_class_name, | 
					
						
							|  |  |  |                      RNA_function_identifier(func)); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 14:18:18 +10:00
										 |  |  |     /* TODO(@campbellbarton): this is used for classmethod's too,
 | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |      * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg. | 
					
						
							|  |  |  |      * Keep this as-is since it's working, but we should be using | 
					
						
							|  |  |  |      * 'FUNC_USE_SELF_TYPE' for many functions. */ | 
					
						
							|  |  |  |     const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Store original so we can decrement its reference before returning. */ | 
					
						
							|  |  |  |     PyObject *item_orig = item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (is_staticmethod) { | 
					
						
							|  |  |  |       if (PyMethod_Check(item) == 0) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "expected %.200s, %.200s class \"%.200s\" " | 
					
						
							|  |  |  |                      "attribute to be a static/class method, not a %.200s", | 
					
						
							|  |  |  |                      class_type, | 
					
						
							|  |  |  |                      py_class_name, | 
					
						
							|  |  |  |                      RNA_function_identifier(func), | 
					
						
							|  |  |  |                      Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |         Py_DECREF(item_orig); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2010-08-09 01:37:09 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |       item = ((PyMethodObject *)item)->im_func; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       if (PyFunction_Check(item) == 0) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "expected %.200s, %.200s class \"%.200s\" " | 
					
						
							|  |  |  |                      "attribute to be a function, not a %.200s", | 
					
						
							|  |  |  |                      class_type, | 
					
						
							|  |  |  |                      py_class_name, | 
					
						
							|  |  |  |                      RNA_function_identifier(func), | 
					
						
							|  |  |  |                      Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |         Py_DECREF(item_orig); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |     func_arg_count = rna_function_arg_count(func, &func_arg_min_count); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |     if (func_arg_count >= 0) { /* -1 if we don't care. */ | 
					
						
							|  |  |  |       arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-26 21:35:18 +10:00
										 |  |  |       /* NOTE: the number of args we check for and the number of args we give to
 | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |        * '@staticmethods' are different (quirk of Python), | 
					
						
							| 
									
										
										
										
											2021-06-26 21:35:18 +10:00
										 |  |  |        * this is why rna_function_arg_count() doesn't return the value -1. */ | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |       if (is_staticmethod) { | 
					
						
							|  |  |  |         func_arg_count++; | 
					
						
							|  |  |  |         func_arg_min_count++; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |       if (arg_count < func_arg_min_count || arg_count > func_arg_count) { | 
					
						
							|  |  |  |         if (func_arg_min_count != func_arg_count) { | 
					
						
							|  |  |  |           PyErr_Format( | 
					
						
							|  |  |  |               PyExc_ValueError, | 
					
						
							|  |  |  |               "expected %.200s, %.200s class \"%.200s\" function to have between %d and %d " | 
					
						
							|  |  |  |               "args, found %d", | 
					
						
							|  |  |  |               class_type, | 
					
						
							|  |  |  |               py_class_name, | 
					
						
							|  |  |  |               RNA_function_identifier(func), | 
					
						
							|  |  |  |               func_arg_count, | 
					
						
							|  |  |  |               func_arg_min_count, | 
					
						
							|  |  |  |               arg_count); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           PyErr_Format( | 
					
						
							|  |  |  |               PyExc_ValueError, | 
					
						
							|  |  |  |               "expected %.200s, %.200s class \"%.200s\" function to have %d args, found %d", | 
					
						
							|  |  |  |               class_type, | 
					
						
							|  |  |  |               py_class_name, | 
					
						
							|  |  |  |               RNA_function_identifier(func), | 
					
						
							|  |  |  |               func_arg_count, | 
					
						
							|  |  |  |               arg_count); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |         Py_DECREF(item_orig); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-14 16:21:13 +11:00
										 |  |  |     Py_DECREF(item_orig); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Verify properties. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   lb = RNA_struct_type_properties(srna); | 
					
						
							|  |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							| 
									
										
										
										
											2009-12-24 16:10:26 +00:00
										 |  |  |     const char *identifier; | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:36 +10:00
										 |  |  |     PropertyRNA *prop = (PropertyRNA *)link; | 
					
						
							|  |  |  |     const int flag = RNA_property_flag(prop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (!(flag & PROP_REGISTER)) { | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 14:18:18 +10:00
										 |  |  |     /* TODO(@campbellbarton): Use Python3.7x _PyObject_LookupAttr(), also in the macro below. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     identifier = RNA_property_identifier(prop); | 
					
						
							|  |  |  |     item = PyObject_GetAttrString(py_class, identifier); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if (item == NULL) { | 
					
						
							| 
									
										
										
										
											2018-07-12 08:28:06 +02:00
										 |  |  |       PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Sneaky workaround to use the class name as the bl_idname. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-05 05:44:52 +00:00
										 |  |  | #define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
 | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |   else if (STREQ(identifier, rna_attr)) \ | 
					
						
							|  |  |  |   { \ | 
					
						
							|  |  |  |     if ((item = PyObject_GetAttr(py_class, py_attr))) { \ | 
					
						
							|  |  |  |       if (item != Py_None) { \ | 
					
						
							|  |  |  |         if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) { \ | 
					
						
							|  |  |  |           Py_DECREF(item); \ | 
					
						
							|  |  |  |           return -1; \ | 
					
						
							|  |  |  |         } \ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } \ | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |       Py_DECREF(item); \ | 
					
						
							|  |  |  |     } \ | 
					
						
							| 
									
										
										
										
											2018-07-12 08:28:06 +02:00
										 |  |  |     else { \ | 
					
						
							|  |  |  |       PyErr_Clear(); \ | 
					
						
							|  |  |  |     } \ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   } /* Intentionally allow else here. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |       if (false) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       } /* Needed for macro. */ | 
					
						
							| 
									
										
										
										
											2013-07-21 08:16:37 +00:00
										 |  |  |       BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__) | 
					
						
							|  |  |  |       BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__) | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  | #undef BPY_REPLACEMENT_STRING
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-26 14:23:52 +10:00
										 |  |  |       if (item == NULL && ((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                      "expected %.200s, %.200s class to have an \"%.200s\" attribute", | 
					
						
							|  |  |  |                      class_type, | 
					
						
							|  |  |  |                      py_class_name, | 
					
						
							|  |  |  |                      identifier); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2012-11-22 08:45:32 +00:00
										 |  |  |       if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) { | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2012-11-22 08:45:32 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-24 12:00:02 +00:00
										 |  |  | static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_function) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return bpy_class_validate_recursive(dummyptr, dummyptr->type, py_data, have_function); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  | /* TODO: multiple return values like with RNA functions. */ | 
					
						
							| 
									
										
										
										
											2010-12-07 04:12:15 +00:00
										 |  |  | static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   PyObject *args; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *ret = NULL, *py_srna = NULL, *py_class_instance = NULL, *parmitem; | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  |   PyTypeObject *py_class; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |   PropertyRNA *parm; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   ParameterIterator iter; | 
					
						
							|  |  |  |   PointerRNA funcptr; | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |   int err = 0, i, ret_len = 0, arg_count; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const int flag = RNA_function_flag(func); | 
					
						
							| 
									
										
										
										
											2016-04-12 11:26:06 +10:00
										 |  |  |   const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); | 
					
						
							|  |  |  |   const bool is_classmethod = (flag & FUNC_NO_SELF) && (flag & FUNC_USE_SELF_TYPE); | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PropertyRNA *pret_single = NULL; | 
					
						
							|  |  |  |   void *retdata_single = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  |   PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |   const bool is_readonly_init = !(RNA_struct_is_a(ptr->type, &RNA_Operator) || | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  |                                   RNA_struct_is_a(ptr->type, &RNA_Gizmo)); | 
					
						
							| 
									
										
										
										
											2012-11-03 15:35:03 +00:00
										 |  |  |   // const char *func_id = RNA_function_identifier(func);  /* UNUSED */
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Testing, for correctness, not operator and not draw function. */ | 
					
						
							| 
									
										
										
										
											2014-01-28 03:52:21 +11:00
										 |  |  |   const bool is_readonly = !(RNA_function_flag(func) & FUNC_ALLOW_WRITE); | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   py_class = RNA_struct_py_type_get(ptr->type); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Rare case. can happen when registering subclasses. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (py_class == NULL) { | 
					
						
							| 
									
										
										
										
											2018-04-02 15:39:43 +02:00
										 |  |  |     CLOG_WARN(BPY_LOG_RNA, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |               "unable to get Python class for RNA struct '%.200s'", | 
					
						
							| 
									
										
										
										
											2018-04-02 15:39:43 +02:00
										 |  |  |               RNA_struct_identifier(ptr->type)); | 
					
						
							| 
									
										
										
										
											2010-08-02 04:20:41 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 03:25:31 +00:00
										 |  |  |   /* XXX, this is needed because render engine calls without a context
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |    * this should be supported at some point, but at the moment it's not! */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (C == NULL) { | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |     C = BPY_context_get(); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Annoying! We need to check if the screen gets set to NULL which is a
 | 
					
						
							| 
									
										
										
										
											2016-04-12 11:26:06 +10:00
										 |  |  |    * hint that the file was actually re-loaded. */ | 
					
						
							|  |  |  |   const bool is_valid_wm = (CTX_wm_manager(C) != NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 04:20:41 +00:00
										 |  |  |   bpy_context_set(C, &gilstate); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-20 09:33:12 +00:00
										 |  |  |   if (!(is_staticmethod || is_classmethod)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Some datatypes (operator, render engine) can store PyObjects for re-use. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (ptr->data) { | 
					
						
							| 
									
										
										
										
											2011-05-18 11:21:10 +00:00
										 |  |  |       void **instance = RNA_struct_instance(ptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (instance) { | 
					
						
							|  |  |  |         if (*instance) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           py_class_instance = *instance; | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |           Py_INCREF(py_class_instance); | 
					
						
							| 
									
										
										
										
											2010-02-27 14:44:46 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* End exception. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     if (py_class_instance == NULL) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       py_srna = pyrna_struct_CreatePyObject(ptr); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (py_class_instance) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Special case, instance is cached. */ | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     else if (py_srna == NULL) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       py_class_instance = NULL; | 
					
						
							| 
									
										
										
										
											2010-07-28 12:11:40 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-22 10:42:32 -07:00
										 |  |  |     else if (py_srna == Py_None) { /* Probably won't ever happen, but possible. */ | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       Py_DECREF(py_srna); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       py_class_instance = NULL; | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  | #if 1
 | 
					
						
							|  |  |  |       /* Skip the code below and call init directly on the allocated 'py_srna'
 | 
					
						
							|  |  |  |        * otherwise __init__() always needs to take a second self argument, see pyrna_struct_new(). | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |        * Although this is annoying to have to implement a part of Python's | 
					
						
							|  |  |  |        * typeobject.c:type_call(). | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  |        */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (py_class->tp_init) { | 
					
						
							| 
									
										
										
										
											2011-06-21 08:09:42 +00:00
										 |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         const int prev_write = rna_disallow_writes; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |         rna_disallow_writes = is_readonly_init ? false : | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                                                  true; /* Only operators can write on __init__. */ | 
					
						
							| 
									
										
										
										
											2011-06-21 08:09:42 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* True in most cases even when the class itself doesn't define an __init__ function. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         args = PyTuple_New(0); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |         if (py_class->tp_init(py_srna, args, NULL) < 0) { | 
					
						
							|  |  |  |           Py_DECREF(py_srna); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           py_srna = NULL; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Err set below. */ | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         Py_DECREF(args); | 
					
						
							| 
									
										
										
										
											2011-06-21 08:09:42 +00:00
										 |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         rna_disallow_writes = prev_write; | 
					
						
							| 
									
										
										
										
											2011-06-21 08:09:42 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       py_class_instance = py_srna; | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       const int prev_write = rna_disallow_writes; | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |       rna_disallow_writes = true; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |       /* 'almost' all the time calling the class isn't needed.
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |        * We could just do... */ | 
					
						
							|  |  |  | #  if 0
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       py_class_instance = py_srna; | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  |       Py_INCREF(py_class_instance); | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #  endif
 | 
					
						
							|  |  |  |       /*
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |        * This would work fine, but means __init__ functions wouldn't run. | 
					
						
							|  |  |  |        * None of Blender's default scripts use __init__ but it's nice to call it | 
					
						
							| 
									
										
										
										
											2011-02-14 11:30:35 +00:00
										 |  |  |        * for general correctness. just to note why this is here when it could be safely removed. | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       args = PyTuple_New(1); | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       PyTuple_SET_ITEM(args, 0, py_srna); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       py_class_instance = PyObject_Call(py_class, args, NULL); | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       Py_DECREF(args); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       rna_disallow_writes = prev_write; | 
					
						
							| 
									
										
										
										
											2011-06-21 08:09:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-06-21 08:09:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (py_class_instance == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         err = -1; /* So the error is not overridden below. */ | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-02-27 14:44:46 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-20 05:35:53 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Initializing the class worked, now run its invoke function. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |   if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (item) { | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |       if (is_staticmethod) { | 
					
						
							|  |  |  |         arg_count = | 
					
						
							|  |  |  |             ((PyCodeObject *)PyFunction_GET_CODE(((PyMethodObject *)item)->im_func))->co_argcount - | 
					
						
							|  |  |  |             1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  |       /* First arg is included in 'item'. */ | 
					
						
							|  |  |  |       args = PyTuple_New(rna_function_arg_count(func)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       args = PyTuple_New(arg_count); /* First arg is included in 'item'. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-20 09:33:12 +00:00
										 |  |  |       if (is_staticmethod) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         i = 0; | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-12-20 09:33:12 +00:00
										 |  |  |       else if (is_classmethod) { | 
					
						
							|  |  |  |         PyTuple_SET_ITEM(args, 0, (PyObject *)py_class); | 
					
						
							|  |  |  |         i = 1; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       else { | 
					
						
							|  |  |  |         PyTuple_SET_ITEM(args, 0, py_class_instance); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         i = 1; | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       RNA_parameter_list_begin(parms, &iter); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Parse function parameters. */ | 
					
						
							| 
									
										
										
										
											2010-08-05 16:05:30 +00:00
										 |  |  |       for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         parm = iter.parm; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Only useful for single argument returns, we'll need another list loop for multiple. */ | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |         if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |           ret_len++; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |           if (pret_single == NULL) { | 
					
						
							|  |  |  |             pret_single = parm; | 
					
						
							|  |  |  |             retdata_single = iter.data; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |           continue; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-26 21:11:52 +00:00
										 |  |  |         if (i < arg_count) { | 
					
						
							|  |  |  |           parmitem = pyrna_param_to_py(&funcptr, parm, iter.data); | 
					
						
							|  |  |  |           PyTuple_SET_ITEM(args, i, parmitem); | 
					
						
							|  |  |  |           i++; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2021-08-10 19:50:58 +10:00
										 |  |  |       /* Handle nested draw calls, see: T89253. */ | 
					
						
							|  |  |  |       const bool rna_disallow_writes_prev = rna_disallow_writes; | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |       rna_disallow_writes = is_readonly ? true : false; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |       /* *** Main Caller *** */ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       ret = PyObject_Call(item, args, NULL); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  |       /* *** Done Calling *** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2021-08-10 19:50:58 +10:00
										 |  |  |       rna_disallow_writes = rna_disallow_writes_prev; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 19:01:19 +00:00
										 |  |  |       RNA_parameter_list_end(&iter); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |       Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											2009-05-20 05:35:53 +00:00
										 |  |  |       Py_DECREF(args); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "could not find function %.200s in %.200s to execute callback", | 
					
						
							|  |  |  |                    RNA_function_identifier(func), | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type)); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       err = -1; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* The error may be already set if the class instance couldn't be created. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (err != -1) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                    "could not create instance of %.200s to call callback function %.200s", | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                    RNA_function_identifier(func)); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       err = -1; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   if (ret == NULL) { /* Covers py_class_instance failing too. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     err = -1; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     if (ret_len == 0 && ret != Py_None) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                    "expected class %.200s, function %.200s to return None, not %.200s", | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                    RNA_function_identifier(func), | 
					
						
							|  |  |  |                    Py_TYPE(ret)->tp_name); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       err = -1; | 
					
						
							| 
									
										
										
										
											2010-09-17 05:58:06 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     else if (ret_len == 1) { | 
					
						
							|  |  |  |       err = pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, ""); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 14:47:27 +10:00
										 |  |  |       /* When calling operator functions only gives `Function.result` with  no line number
 | 
					
						
							|  |  |  |        * since the function has finished calling on error, re-raise the exception with more | 
					
						
							|  |  |  |        * information since it would be slow to create prefix on every call | 
					
						
							|  |  |  |        * (when there are no errors). */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (err == -1) { | 
					
						
							| 
									
										
										
										
											2011-09-15 10:43:55 +00:00
										 |  |  |         PyC_Err_Format_Prefix(PyExc_RuntimeError, | 
					
						
							|  |  |  |                               "class %.200s, function %.200s: incompatible return value ", | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |                               RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                               RNA_function_identifier(func)); | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |     else if (ret_len > 1) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       if (PyTuple_Check(ret) == 0) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         PyErr_Format( | 
					
						
							|  |  |  |             PyExc_RuntimeError, | 
					
						
							|  |  |  |             "expected class %.200s, function %.200s to return a tuple of size %d, not %.200s", | 
					
						
							|  |  |  |             RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |             RNA_function_identifier(func), | 
					
						
							|  |  |  |             ret_len, | 
					
						
							|  |  |  |             Py_TYPE(ret)->tp_name); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         err = -1; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       else if (PyTuple_GET_SIZE(ret) != ret_len) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |         PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                      "class %.200s, function %.200s to returned %d items, expected %d", | 
					
						
							|  |  |  |                      RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                      RNA_function_identifier(func), | 
					
						
							|  |  |  |                      PyTuple_GET_SIZE(ret), | 
					
						
							|  |  |  |                      ret_len); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         err = -1; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |         RNA_parameter_list_begin(parms, &iter); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Parse function parameters. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |         for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |           parm = iter.parm; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Only useful for single argument returns, we'll need another list loop for multiple. */ | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |           if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |             err = pyrna_py_to_prop( | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  |                 &funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |             if (err) { | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |               break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 19:01:19 +00:00
										 |  |  |         RNA_parameter_list_end(&iter); | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     Py_DECREF(ret); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (err != 0) { | 
					
						
							| 
									
										
										
										
											2010-11-20 16:39:15 +00:00
										 |  |  |     ReportList *reports; | 
					
						
							| 
									
										
										
										
											2021-06-22 10:42:32 -07:00
										 |  |  |     /* Alert the user, else they won't know unless they see the console. */ | 
					
						
							| 
									
										
										
										
											2012-12-20 09:33:12 +00:00
										 |  |  |     if ((!is_staticmethod) && (!is_classmethod) && (ptr->data) && | 
					
						
							| 
									
										
										
										
											2022-10-07 22:52:53 +11:00
										 |  |  |         RNA_struct_is_a(ptr->type, &RNA_Operator) && | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  |         (is_valid_wm == (CTX_wm_manager(C) != NULL))) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       wmOperator *op = ptr->data; | 
					
						
							|  |  |  |       reports = op->reports; | 
					
						
							| 
									
										
										
										
											2010-11-20 16:39:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2021-06-22 10:42:32 -07:00
										 |  |  |       /* Won't alert users, but they can view in 'info' space. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       reports = CTX_wm_reports(C); | 
					
						
							| 
									
										
										
										
											2010-11-20 16:39:15 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-20 16:39:15 +00:00
										 |  |  |     BPy_errors_to_report(reports); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Also print in the console for Python. */ | 
					
						
							| 
									
										
										
										
											2009-07-23 13:48:15 +00:00
										 |  |  |     PyErr_Print(); | 
					
						
							|  |  |  |     PyErr_Clear(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  |   bpy_context_clear(C, &gilstate); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   return err; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bpy_class_free(void *pyob_ptr) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   PyObject *self = (PyObject *)pyob_ptr; | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  |   PyGILState_STATE gilstate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Breaks re-registering classes. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   // PyDict_Clear(((PyTypeObject *)self)->tp_dict);
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Remove the RNA attribute instead. */ | 
					
						
							| 
									
										
										
										
											2011-06-18 08:45:45 +00:00
										 |  |  |   PyDict_DelItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2010-02-15 11:24:43 +00:00
										 |  |  |     PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #if 0 /* Needs further investigation, too annoying so quiet for now. */
 | 
					
						
							| 
									
										
										
										
											2012-03-31 00:59:17 +00:00
										 |  |  |   if (G.debug & G_DEBUG_PYTHON) { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (self->ob_refcnt > 1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       PyC_ObSpit("zombie class - reference should be 1", self); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-28 02:03:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-09 11:54:12 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   Py_DECREF((PyObject *)pyob_ptr); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 19:41:59 +10:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2022-09-16 18:13:19 +10:00
										 |  |  |  * \note This isn't essential to run on startup, since sub-types will lazy initialize. | 
					
						
							| 
									
										
										
										
											2015-07-22 19:41:59 +10:00
										 |  |  |  * But keep running in debug mode so we get immediate notification of bad class hierarchy | 
					
						
							|  |  |  |  * or any errors in "bpy_types.py" at load time, so errors don't go unnoticed. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | void pyrna_alloc_types(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-07-22 19:41:59 +10:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  |   PyGILState_STATE gilstate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Avoid doing this lookup for every getattr. */ | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  |   RNA_blender_rna_pointer_create(&ptr); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   prop = RNA_struct_find_property(&ptr, "structs"); | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |   RNA_PROP_BEGIN (&ptr, itemptr, prop) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     PyObject *item = pyrna_struct_Subtype(&itemptr); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (item == NULL) { | 
					
						
							|  |  |  |       if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2010-08-02 04:20:41 +00:00
										 |  |  |         PyErr_Print(); | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2015-07-22 19:41:59 +10:00
										 |  |  | #endif /* DEBUG */
 | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | void pyrna_free_types(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Avoid doing this lookup for every getattr. */ | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  |   RNA_blender_rna_pointer_create(&ptr); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   prop = RNA_struct_find_property(&ptr, "structs"); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |   RNA_PROP_BEGIN (&ptr, itemptr, prop) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     StructRNA *srna = srna_from_ptr(&itemptr); | 
					
						
							|  |  |  |     void *py_ptr = RNA_struct_py_type_get(srna); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (py_ptr) { | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  | #if 0 /* XXX: should be able to do this, but makes Python crash on exit. */
 | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  |       bpy_class_free(py_ptr); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       RNA_struct_py_type_set(srna, NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 15:15:38 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \warning memory leak! | 
					
						
							| 
									
										
										
										
											2009-08-16 04:59:11 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * There is currently a bug where moving the registration of a Python class does | 
					
						
							| 
									
										
										
										
											2021-01-20 15:15:38 +11:00
										 |  |  |  * not properly manage reference-counts from the Python class. As the `srna` owns | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * the Python class this should not be so tricky, but changing the references as | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  |  * you'd expect when changing ownership crashes blender on exit so I had to comment out | 
					
						
							| 
									
										
										
										
											2021-01-20 15:15:38 +11:00
										 |  |  |  * the #Py_DECREF. This is not so bad because the leak only happens when re-registering | 
					
						
							|  |  |  |  * (continuously running `SCRIPT_OT_reload`). | 
					
						
							| 
									
										
										
										
											2009-08-16 04:59:11 +00:00
										 |  |  |  * - Should still be fixed - Campbell | 
					
						
							| 
									
										
										
										
											2021-01-20 15:15:38 +11:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_register_class_doc, | 
					
						
							| 
									
										
										
										
											2021-10-22 18:27:03 -04:00
										 |  |  |              ".. function:: register_class(cls)\n" | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2020-09-29 16:45:29 -04:00
										 |  |  |              "   Register a subclass of a Blender type class.\n" | 
					
						
							| 
									
										
										
										
											2011-03-22 01:38:26 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2020-09-29 16:45:29 -04:00
										 |  |  |              "   :arg cls: Blender type class in:\n" | 
					
						
							|  |  |  |              "      :class:`bpy.types.Panel`, :class:`bpy.types.UIList`,\n" | 
					
						
							|  |  |  |              "      :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n" | 
					
						
							|  |  |  |              "      :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n" | 
					
						
							|  |  |  |              "      :class:`bpy.types.RenderEngine`\n" | 
					
						
							|  |  |  |              "   :type cls: class\n" | 
					
						
							| 
									
										
										
										
											2020-09-29 15:05:45 -04:00
										 |  |  |              "   :raises ValueError:\n" | 
					
						
							| 
									
										
										
										
											2020-09-29 16:45:29 -04:00
										 |  |  |              "      if the class is not a subclass of a registerable blender class.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   .. note::\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "      If the class has a *register* class method it will be called\n" | 
					
						
							|  |  |  |              "      before registration.\n"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyMethodDef meth_bpy_register_class = { | 
					
						
							|  |  |  |     "register_class", pyrna_register_class, METH_O, pyrna_register_class_doc}; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class) | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   bContext *C = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   ReportList reports; | 
					
						
							|  |  |  |   StructRegisterFunc reg; | 
					
						
							|  |  |  |   StructRNA *srna; | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  |   StructRNA *srna_new; | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |   const char *identifier; | 
					
						
							| 
									
										
										
										
											2011-03-22 01:38:26 +00:00
										 |  |  |   PyObject *py_cls_meth; | 
					
						
							| 
									
										
										
										
											2019-03-27 14:03:16 +11:00
										 |  |  |   const char *error_prefix = "register_class(...):"; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-18 19:50:44 +00:00
										 |  |  |   if (!PyType_Check(py_class)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "register_class(...): " | 
					
						
							|  |  |  |                  "expected a class argument, not '%.200s'", | 
					
						
							|  |  |  |                  Py_TYPE(py_class)->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna)) { | 
					
						
							| 
									
										
										
										
											2019-08-17 04:51:50 +10:00
										 |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "register_class(...): " | 
					
						
							|  |  |  |                  "already registered as a subclass '%.200s'", | 
					
						
							|  |  |  |                  ((PyTypeObject *)py_class)->tp_name); | 
					
						
							| 
									
										
										
										
											2012-01-18 19:50:44 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-18 19:50:44 +00:00
										 |  |  |   if (!pyrna_write_check()) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                  "register_class(...): " | 
					
						
							|  |  |  |                  "can't run in readonly state '%.200s'", | 
					
						
							|  |  |  |                  ((PyTypeObject *)py_class)->tp_name); | 
					
						
							| 
									
										
										
										
											2010-02-14 11:21:21 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 09:24:28 +10:00
										 |  |  |   /* WARNING: gets parent classes srna, only for the register function. */ | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   srna = pyrna_struct_as_srna(py_class, true, "register_class(...):"); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (srna == NULL) { | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Fails in some cases, so can't use this check, but would like to :| */ | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_struct_py_type_get(srna)) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |                  "register_class(...): %.200s's parent class %.200s is already registered, this " | 
					
						
							|  |  |  |                  "is not allowed", | 
					
						
							|  |  |  |                  ((PyTypeObject *)py_class)->tp_name, | 
					
						
							|  |  |  |                  RNA_struct_identifier(srna)); | 
					
						
							| 
									
										
										
										
											2010-08-02 04:20:41 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-08-02 04:20:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Check that we have a register callback for this type. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   reg = RNA_struct_register(srna); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (!reg) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "register_class(...): expected a subclass of a registerable " | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                  "RNA type (%.200s does not support registration)", | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |                  RNA_struct_identifier(srna)); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Get the context, so register callback can do necessary refreshes. */ | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |   C = BPY_context_get(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Call the register callback with reports & identifier. */ | 
					
						
							| 
									
										
										
										
											2009-06-18 19:48:55 +00:00
										 |  |  |   BKE_reports_init(&reports, RPT_STORE); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   identifier = ((PyTypeObject *)py_class)->tp_name; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   srna_new = reg(CTX_data_main(C), | 
					
						
							|  |  |  |                  &reports, | 
					
						
							|  |  |  |                  py_class, | 
					
						
							|  |  |  |                  identifier, | 
					
						
							|  |  |  |                  bpy_class_validate, | 
					
						
							|  |  |  |                  bpy_class_call, | 
					
						
							|  |  |  |                  bpy_class_free); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 14:03:16 +11:00
										 |  |  |   if (!BLI_listbase_is_empty(&reports.list)) { | 
					
						
							|  |  |  |     const bool has_error = BPy_reports_to_error(&reports, PyExc_RuntimeError, false); | 
					
						
							|  |  |  |     if (!has_error) { | 
					
						
							|  |  |  |       BPy_reports_write_stdout(&reports, error_prefix); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     BKE_reports_clear(&reports); | 
					
						
							|  |  |  |     if (has_error) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Python errors validating are not converted into reports so the check above will fail.
 | 
					
						
							| 
									
										
										
										
											2011-01-03 18:15:15 +00:00
										 |  |  |    * the cause for returning NULL will be printed as an error */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (srna_new == NULL) { | 
					
						
							| 
									
										
										
										
											2011-01-03 18:15:15 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Takes a reference to 'py_class'. */ | 
					
						
							|  |  |  |   pyrna_subtype_set_rna(py_class, srna_new); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Old srna still references us, keep the check in case registering somehow can free it. */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (RNA_struct_py_type_get(srna)) { | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  |     RNA_struct_py_type_set(srna, NULL); | 
					
						
							| 
									
										
										
										
											2020-10-10 18:19:55 +11:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Should be able to do this XXX since the old RNA adds a new ref. */ | 
					
						
							|  |  |  |     Py_DECREF(py_class); | 
					
						
							| 
									
										
										
										
											2020-10-10 18:19:55 +11:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												define operator properties in the class, similar to django fields
# Before
[
	bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
	bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
	bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
	bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
	bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
]
# After
path = StringProperty(attr="", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
use_modifiers = BoolProperty(attr="", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
use_normals = BoolProperty(attr="", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True)
use_uvs = BoolProperty(attr="", name="Export UVs", description="Exort the active UV layer", default= True)
use_colors = BoolProperty(attr="", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
											
										 
											2009-10-31 16:40:14 +00:00
										 |  |  |   /* Can't use this because it returns a dict proxy
 | 
					
						
							|  |  |  |    * | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |    * item = PyObject_GetAttrString(py_class, "__dict__"); | 
					
						
							| 
									
										
											  
											
												define operator properties in the class, similar to django fields
# Before
[
	bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
	bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
	bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
	bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
	bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
]
# After
path = StringProperty(attr="", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
use_modifiers = BoolProperty(attr="", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
use_normals = BoolProperty(attr="", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True)
use_uvs = BoolProperty(attr="", name="Export UVs", description="Exort the active UV layer", default= True)
use_colors = BoolProperty(attr="", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
											
										 
											2009-10-31 16:40:14 +00:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (pyrna_deferred_register_class(srna_new, (PyTypeObject *)py_class) != 0) { | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:10:33 +11:00
										 |  |  |   /* Call classed register method.
 | 
					
						
							|  |  |  |    * Note that zero falls through, no attribute, no error. */ | 
					
						
							| 
									
										
										
										
											2019-02-04 23:35:23 +11:00
										 |  |  |   switch (_PyObject_LookupAttr(py_class, bpy_intern_str_register, &py_cls_meth)) { | 
					
						
							|  |  |  |     case 1: { | 
					
						
							|  |  |  |       PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); | 
					
						
							| 
									
										
										
										
											2019-11-20 17:53:22 +11:00
										 |  |  |       Py_DECREF(py_cls_meth); | 
					
						
							| 
									
										
										
										
											2019-02-04 23:35:23 +11:00
										 |  |  |       if (ret) { | 
					
						
							|  |  |  |         Py_DECREF(ret); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2011-04-02 14:58:58 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-02-04 23:35:23 +11:00
										 |  |  |     case -1: { | 
					
						
							| 
									
										
										
										
											2011-04-02 14:58:58 +00:00
										 |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, | 
					
						
							|  |  |  |                                                  StructRNA *srna, | 
					
						
							|  |  |  |                                                  const char **r_prop_identifier) | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-01-25 07:31:11 +00:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   LinkData *link; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Verify properties. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   const ListBase *lb = RNA_struct_type_properties(srna); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |     prop = (PropertyRNA *)link; | 
					
						
							| 
									
										
										
											
												Refactor RNA property: split flags in property flags, parameter flags, and internal flags.
This gives us 9 flags available again for properties (we had none anymore),
and also makes things slightly cleaner.
To simplify (and make more clear the differences between mere properties
and function parameters), also added RNA_def_parameter_flags function (and
its clear counterpart), to be used instead of RNA_def_property_flag for
function parameters.
This patch is also a big cleanup (some RNA function definitions were
still using 'prop' PropertyRNA pointer, etc.).
And yes, am aware this will be annoying for all branches, but we really need
to get new flags available for properties (will need at least one for override, etc.).
Reviewers: sergey, Severin
Subscribers: dfelinto, brecht
Differential Revision: https://developer.blender.org/D2400
											
										 
											2016-12-12 15:23:55 +01:00
										 |  |  |     if (RNA_property_type(prop) == PROP_POINTER && !RNA_property_builtin(prop)) { | 
					
						
							| 
									
										
										
										
											2011-01-25 07:31:11 +00:00
										 |  |  |       PointerRNA tptr; | 
					
						
							|  |  |  |       RNA_pointer_create(NULL, &RNA_Struct, srna_props, &tptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (RNA_property_pointer_type(&tptr, prop) == srna) { | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |         *r_prop_identifier = RNA_property_identifier(prop); | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |         return 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_unregister_class_doc, | 
					
						
							| 
									
										
										
										
											2021-10-22 18:27:03 -04:00
										 |  |  |              ".. function:: unregister_class(cls)\n" | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   Unload the Python class from blender.\n" | 
					
						
							| 
									
										
										
										
											2011-03-22 01:38:26 +00:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2011-05-26 19:13:01 +00:00
										 |  |  |              "   If the class has an *unregister* class method it will be called\n" | 
					
						
							|  |  |  |              "   before unregistering.\n"); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyMethodDef meth_bpy_unregister_class = { | 
					
						
							| 
									
										
										
										
											2019-01-19 13:21:18 +11:00
										 |  |  |     "unregister_class", | 
					
						
							|  |  |  |     pyrna_unregister_class, | 
					
						
							|  |  |  |     METH_O, | 
					
						
							|  |  |  |     pyrna_unregister_class_doc, | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_class) | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   bContext *C = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   StructUnregisterFunc unreg; | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  |   StructRNA *srna; | 
					
						
							| 
									
										
										
										
											2011-03-22 01:38:26 +00:00
										 |  |  |   PyObject *py_cls_meth; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-18 19:50:44 +00:00
										 |  |  |   if (!PyType_Check(py_class)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "register_class(...): " | 
					
						
							|  |  |  |                  "expected a class argument, not '%.200s'", | 
					
						
							|  |  |  |                  Py_TYPE(py_class)->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  |   if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna) == NULL) { | 
					
						
							| 
									
										
										
										
											2021-03-05 10:36:57 +01:00
										 |  |  |     PWM_cursor_wait(false); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  |     PyErr_SetString(PyExc_ValueError, "unregister_class(): not a registered as a subclass"); | 
					
						
							| 
									
										
										
										
											2010-02-15 11:24:43 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-02-15 11:24:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-18 19:50:44 +00:00
										 |  |  |   if (!pyrna_write_check()) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                  "unregister_class(...): " | 
					
						
							|  |  |  |                  "can't run in readonly state '%.200s'", | 
					
						
							|  |  |  |                  ((PyTypeObject *)py_class)->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |   srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):"); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (srna == NULL) { | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Check that we have a unregister callback for this type. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |   unreg = RNA_struct_unregister(srna); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |   if (!unreg) { | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |     PyErr_SetString( | 
					
						
							|  |  |  |         PyExc_ValueError, | 
					
						
							|  |  |  |         "unregister_class(...): " | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         "expected a Type subclassed from a registerable RNA type (no unregister supported)"); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:10:33 +11:00
										 |  |  |   /* Call classed unregister method.
 | 
					
						
							|  |  |  |    * Note that zero falls through, no attribute, no error. */ | 
					
						
							| 
									
										
										
										
											2019-02-04 23:35:23 +11:00
										 |  |  |   switch (_PyObject_LookupAttr(py_class, bpy_intern_str_unregister, &py_cls_meth)) { | 
					
						
							|  |  |  |     case 1: { | 
					
						
							|  |  |  |       PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); | 
					
						
							| 
									
										
										
										
											2019-11-20 17:53:22 +11:00
										 |  |  |       Py_DECREF(py_cls_meth); | 
					
						
							| 
									
										
										
										
											2019-02-04 23:35:23 +11:00
										 |  |  |       if (ret) { | 
					
						
							|  |  |  |         Py_DECREF(ret); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2011-03-22 01:38:26 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-02-04 23:35:23 +11:00
										 |  |  |     case -1: { | 
					
						
							| 
									
										
										
										
											2011-03-22 01:38:26 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-22 01:38:26 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Should happen all the time, however it's very slow. */ | 
					
						
							| 
									
										
										
										
											2012-03-31 00:59:17 +00:00
										 |  |  |   if (G.debug & G_DEBUG_PYTHON) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Remove all properties using this class. */ | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |     StructRNA *srna_iter; | 
					
						
							|  |  |  |     PointerRNA ptr_rna; | 
					
						
							|  |  |  |     PropertyRNA *prop_rna; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     const char *prop_identifier = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |     RNA_blender_rna_pointer_create(&ptr_rna); | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |     prop_rna = RNA_struct_find_property(&ptr_rna, "structs"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Loop over all structs. */ | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  |     RNA_PROP_BEGIN (&ptr_rna, itemptr, prop_rna) { | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  |       srna_iter = itemptr.data; | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |       if (pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) { | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  |     if (prop_identifier) { | 
					
						
							| 
									
										
										
										
											2011-04-30 13:58:31 +00:00
										 |  |  |       PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                    "unregister_class(...): can't unregister %s because %s.%s pointer property is " | 
					
						
							|  |  |  |                    "using this", | 
					
						
							|  |  |  |                    RNA_struct_identifier(srna), | 
					
						
							|  |  |  |                    RNA_struct_identifier(srna_iter), | 
					
						
							|  |  |  |                    prop_identifier); | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Get the context, so register callback can do necessary refreshes. */ | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |   C = BPY_context_get(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Call unregister. */ | 
					
						
							|  |  |  |   unreg(CTX_data_main(C), srna); /* Calls bpy_class_free, this decref's py_class. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-18 08:45:45 +00:00
										 |  |  |   PyDict_DelItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna); | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2019-05-01 11:09:22 +10:00
										 |  |  |     PyErr_Clear();  // return NULL;
 | 
					
						
							| 
									
										
										
										
											2019-03-30 06:12:48 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-13 15:57:29 +10:00
										 |  |  | void pyrna_struct_type_extend_capi(struct StructRNA *srna, | 
					
						
							|  |  |  |                                    struct PyMethodDef *method, | 
					
						
							|  |  |  |                                    struct PyGetSetDef *getset) | 
					
						
							| 
									
										
										
										
											2020-05-13 15:05:09 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-05-29 14:14:43 +10:00
										 |  |  |   /* See 'add_methods' in Python's 'typeobject.c'. */ | 
					
						
							|  |  |  |   PyTypeObject *type = (PyTypeObject *)pyrna_srna_Subtype(srna); | 
					
						
							|  |  |  |   PyObject *dict = type->tp_dict; | 
					
						
							| 
									
										
										
										
											2020-05-13 15:05:09 +10:00
										 |  |  |   if (method != NULL) { | 
					
						
							|  |  |  |     for (; method->ml_name != NULL; method++) { | 
					
						
							| 
									
										
										
										
											2020-05-29 14:14:43 +10:00
										 |  |  |       PyObject *py_method; | 
					
						
							| 
									
										
										
										
											2020-05-13 15:05:09 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-29 14:14:43 +10:00
										 |  |  |       if (method->ml_flags & METH_CLASS) { | 
					
						
							|  |  |  |         PyObject *cfunc = PyCFunction_New(method, (PyObject *)type); | 
					
						
							|  |  |  |         py_method = PyClassMethod_New(cfunc); | 
					
						
							|  |  |  |         Py_DECREF(cfunc); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-09-01 15:23:55 +10:00
										 |  |  |       else if (method->ml_flags & METH_STATIC) { | 
					
						
							| 
									
										
										
										
											2020-05-29 14:14:43 +10:00
										 |  |  |         py_method = PyCFunction_New(method, NULL); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-09-01 15:23:55 +10:00
										 |  |  |       else { | 
					
						
							|  |  |  |         py_method = PyDescr_NewMethod(type, method); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-05-13 15:05:09 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |       const int err = PyDict_SetItemString(dict, method->ml_name, py_method); | 
					
						
							| 
									
										
										
										
											2020-05-29 14:14:43 +10:00
										 |  |  |       Py_DECREF(py_method); | 
					
						
							|  |  |  |       BLI_assert(!(err < 0)); | 
					
						
							|  |  |  |       UNUSED_VARS_NDEBUG(err); | 
					
						
							| 
									
										
										
										
											2020-05-13 15:05:09 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-05-13 15:57:29 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (getset != NULL) { | 
					
						
							|  |  |  |     for (; getset->name != NULL; getset++) { | 
					
						
							| 
									
										
										
										
											2020-05-29 14:14:43 +10:00
										 |  |  |       PyObject *descr = PyDescr_NewGetSet(type, getset); | 
					
						
							| 
									
										
										
										
											2020-05-14 13:52:56 +10:00
										 |  |  |       /* Ensure we're not overwriting anything that already exists. */ | 
					
						
							| 
									
										
										
										
											2020-05-13 15:57:29 +10:00
										 |  |  |       BLI_assert(PyDict_GetItem(dict, PyDescr_NAME(descr)) == NULL); | 
					
						
							|  |  |  |       PyDict_SetItem(dict, PyDescr_NAME(descr), descr); | 
					
						
							|  |  |  |       Py_DECREF(descr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-05-29 14:14:43 +10:00
										 |  |  |   Py_DECREF(type); | 
					
						
							| 
									
										
										
										
											2020-05-13 15:05:09 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-01 01:26:02 +11:00
										 |  |  | /* Access to 'owner_id' internal global. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_bl_owner_id_get(PyObject *UNUSED(self)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const char *name = RNA_struct_state_owner_get(); | 
					
						
							|  |  |  |   if (name) { | 
					
						
							|  |  |  |     return PyUnicode_FromString(name); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_bl_owner_id_set(PyObject *UNUSED(self), PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const char *name; | 
					
						
							|  |  |  |   if (value == Py_None) { | 
					
						
							|  |  |  |     name = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyUnicode_Check(value)) { | 
					
						
							| 
									
										
										
										
											2021-02-13 22:57:01 +11:00
										 |  |  |     name = PyUnicode_AsUTF8(value); | 
					
						
							| 
									
										
										
										
											2018-03-01 01:26:02 +11:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "owner_set(...): " | 
					
						
							|  |  |  |                  "expected None or a string, not '%.200s'", | 
					
						
							|  |  |  |                  Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_struct_state_owner_set(name); | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMethodDef meth_bpy_owner_id_get = { | 
					
						
							|  |  |  |     "_bl_owner_id_get", | 
					
						
							|  |  |  |     (PyCFunction)pyrna_bl_owner_id_get, | 
					
						
							|  |  |  |     METH_NOARGS, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | PyMethodDef meth_bpy_owner_id_set = { | 
					
						
							|  |  |  |     "_bl_owner_id_set", | 
					
						
							|  |  |  |     (PyCFunction)pyrna_bl_owner_id_set, | 
					
						
							|  |  |  |     METH_O, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  | }; |