| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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"
 | 
					
						
							| 
									
										
										
										
											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.* */
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BKE_idcode.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "BKE_idprop.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. */
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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" \ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   "      :class:`bpy.types.PoseBone` classes support custom properties.\n" | 
					
						
							| 
									
										
										
										
											2011-10-09 02:24:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | int pyrna_struct_validity_check(BPy_StructRNA *pysrna) | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (pysrna->ptr.type) { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   PyErr_Format( | 
					
						
							|  |  |  |       PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name); | 
					
						
							|  |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | int pyrna_prop_validity_check(BPy_PropertyRNA *self) | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->ptr.type) { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   PyErr_Format(PyExc_ReferenceError, | 
					
						
							|  |  |  |                "PropertyRNA of type %.200s.%.200s has been removed", | 
					
						
							|  |  |  |                Py_TYPE(self)->tp_name, | 
					
						
							|  |  |  |                RNA_property_identifier(self->prop)); | 
					
						
							|  |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-26 10:33:57 +00:00
										 |  |  | void pyrna_invalidate(BPy_DummyPointerRNA *self) | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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 { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGC_Head head; | 
					
						
							|  |  |  |   int threshold; | 
					
						
							|  |  |  |   int count; | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | } gc_generation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void id_release_gc(struct ID *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  |   uint j; | 
					
						
							|  |  |  |   // uint i = 0;
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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); | 
					
						
							|  |  |  |       if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || | 
					
						
							|  |  |  |           PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) { | 
					
						
							|  |  |  |         BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob; | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |         if (ob_ptr->ptr.owner_id == id) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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);
 | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GHash *weakinfo_hash = NULL; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (id_weakref_pool) { | 
					
						
							|  |  |  |     weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* First time, allocate pool. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool"); | 
					
						
							|  |  |  |     weakinfo_hash = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (weakinfo_hash == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* We use a ghash as a set, we could use libHX's HXMAP_SINGULAR, but would be an extra dep. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     weakinfo_hash = BLI_ghash_ptr_new("rna_id"); | 
					
						
							|  |  |  |     BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *weakref; | 
					
						
							|  |  |  |   PyObject *weakref_capsule; | 
					
						
							|  |  |  |   PyObject *weakref_cb_py; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL); | 
					
						
							|  |  |  |   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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* weakinfo_hash owns the weakref */ | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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); | 
					
						
							|  |  |  | static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref) | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Important to search backwards. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (BLI_ghash_len(weakinfo_hash) > 1) { | 
					
						
							|  |  |  |     BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   else { /* Get the last id and free it. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set); | 
					
						
							|  |  |  |     id_release_weakref_list(_id_tmp_ptr, weakinfo_hash); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_DECREF(weakref); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GHashIterator weakinfo_hash_iter; | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef DEBUG_RNA_WEAKREF
 | 
					
						
							|  |  |  |   fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_len(weakinfo_hash)); | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) { | 
					
						
							|  |  |  |     PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter); | 
					
						
							|  |  |  |     PyObject *item = PyWeakref_GET_OBJECT(weakref); | 
					
						
							|  |  |  |     if (item != Py_None) { | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef DEBUG_RNA_WEAKREF
 | 
					
						
							|  |  |  |       PyC_ObSpit("id_release_weakref item ", item); | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       pyrna_invalidate((BPy_DummyPointerRNA *)item); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     Py_DECREF(weakref); | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     BLI_ghashIterator_step(&weakinfo_hash_iter); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL); | 
					
						
							|  |  |  |   BLI_ghash_free(weakinfo_hash, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (BLI_ghash_len(id_weakref_pool) == 0) { | 
					
						
							|  |  |  |     BLI_ghash_free(id_weakref_pool, NULL, NULL); | 
					
						
							|  |  |  |     id_weakref_pool = NULL; | 
					
						
							|  |  |  | #  ifdef DEBUG_RNA_WEAKREF
 | 
					
						
							|  |  |  |     printf("id_release_weakref freeing pool\n"); | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-02 18:59:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void id_release_weakref(struct ID *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); | 
					
						
							|  |  |  |   if (weakinfo_hash) { | 
					
						
							|  |  |  |     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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   id_release_gc(id); | 
					
						
							| 
									
										
										
										
											2011-03-01 09:02:54 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PYRNA_INVALIDATE_WEAKREF
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (id_weakref_pool) { | 
					
						
							|  |  |  |     PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     id_release_weakref(id); | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   (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; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (id) { | 
					
						
							|  |  |  |     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)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       const char *idtype = BKE_idcode_to_name(idcode); | 
					
						
							|  |  |  |       const char *pyname; | 
					
						
							|  |  |  |       if (key && PyUnicode_Check(key)) { | 
					
						
							|  |  |  |         pyname = _PyUnicode_AsString(key); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         pyname = "<UNKNOWN>"; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Make a nice string error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       BLI_assert(idtype != NULL); | 
					
						
							|  |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "Writing to ID classes in this context is not allowed: " | 
					
						
							|  |  |  |                    "%.200s, %.200s datablock, error setting %.200s.%.200s", | 
					
						
							|  |  |  |                    id->name + 2, | 
					
						
							|  |  |  |                    idtype, | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                    pyname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return !rna_disallow_writes; | 
					
						
							| 
									
										
										
										
											2011-02-01 00:32:50 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int pyrna_py_to_prop( | 
					
						
							|  |  |  |     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix); | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | 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
										 |  |  | 
 | 
					
						
							|  |  |  | 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* bpyrna vector/euler/quat 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Subtype not used much yet. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  define MATHUTILS_CB_SUBTYPE_EUL 0
 | 
					
						
							|  |  |  | #  define MATHUTILS_CB_SUBTYPE_VEC 1
 | 
					
						
							|  |  |  | #  define MATHUTILS_CB_SUBTYPE_QUAT 2
 | 
					
						
							|  |  |  | #  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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { | 
					
						
							|  |  |  |     EulerObject *eul = (EulerObject *)bmo; | 
					
						
							|  |  |  |     PropertyRNA *prop_eul_order = NULL; | 
					
						
							|  |  |  |     eul->order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							|  |  |  |   float min, max; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (self->prop == NULL) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy_prop \"%.200s.%.200s\" is read-only", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop)); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_property_float_range(&self->ptr, self->prop, &min, &max); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (min != -FLT_MAX || max != FLT_MAX) { | 
					
						
							|  |  |  |     int i, len = RNA_property_array_length(&self->ptr, self->prop); | 
					
						
							|  |  |  |     for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |       CLAMP(bmo->data[i], min, max); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data); | 
					
						
							|  |  |  |   if (RNA_property_update_check(self->prop)) { | 
					
						
							|  |  |  |     RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Euler order exception. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { | 
					
						
							|  |  |  |     EulerObject *eul = (EulerObject *)bmo; | 
					
						
							|  |  |  |     PropertyRNA *prop_eul_order = NULL; | 
					
						
							|  |  |  |     short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order); | 
					
						
							|  |  |  |     if (order != eul->order) { | 
					
						
							|  |  |  |       RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order); | 
					
						
							|  |  |  |       if (RNA_property_update_check(prop_eul_order)) { | 
					
						
							|  |  |  |         RNA_property_update(BPy_GetContext(), &self->ptr, prop_eul_order); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index); | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy_prop \"%.200s.%.200s\" is read-only", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop)); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-22 04:26:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_update_check(self->prop)) { | 
					
						
							|  |  |  |     RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (BaseMathCheckFunc)mathutils_rna_generic_check, | 
					
						
							|  |  |  |     (BaseMathGetFunc)mathutils_rna_vector_get, | 
					
						
							|  |  |  |     (BaseMathSetFunc)mathutils_rna_vector_set, | 
					
						
							|  |  |  |     (BaseMathGetIndexFunc)mathutils_rna_vector_get_index, | 
					
						
							|  |  |  |     (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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2010-04-26 21:04:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_float_get_array(&self->ptr, self->prop, bmo->data); | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->prop == NULL) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy_prop \"%.200s.%.200s\" is read-only", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(self->prop)); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Can ignore clamping here. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data); | 
					
						
							| 
									
										
										
										
											2010-10-25 21:57:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_update_check(self->prop)) { | 
					
						
							|  |  |  |     RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     mathutils_rna_generic_check, | 
					
						
							|  |  |  |     mathutils_rna_matrix_get, | 
					
						
							|  |  |  |     mathutils_rna_matrix_set, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (*r_prop_eul_order) { | 
					
						
							|  |  |  |     short order = RNA_property_enum_get(ptr, *r_prop_eul_order); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Could be quat or axisangle. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) { | 
					
						
							|  |  |  |       return order; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-27 15:28:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return order_fallback; | 
					
						
							| 
									
										
										
										
											2010-02-27 15:28:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #define PROP_ALL_VECTOR_SUBTYPES \
 | 
					
						
							|  |  |  |   PROP_COORDS: \ | 
					
						
							|  |  |  |   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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret = NULL; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int subtype, totdim; | 
					
						
							|  |  |  |   int len; | 
					
						
							|  |  |  |   const int flag = RNA_property_flag(prop); | 
					
						
							|  |  |  |   const int type = RNA_property_type(prop); | 
					
						
							|  |  |  |   const bool is_thick = (flag & PROP_THICK_WRAP) != 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* disallow dynamic sized arrays to be wrapped since the size could change
 | 
					
						
							|  |  |  |    * to a size mathutils does not support */ | 
					
						
							|  |  |  |   if (flag & PROP_DYNAMIC) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   len = RNA_property_array_length(ptr, prop); | 
					
						
							|  |  |  |   if (type == PROP_FLOAT) { | 
					
						
							|  |  |  |     /* pass */ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (type == PROP_INT) { | 
					
						
							|  |  |  |     if (is_thick) { | 
					
						
							|  |  |  |       goto thick_wrap_slice; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   subtype = RNA_property_subtype(prop); | 
					
						
							|  |  |  |   totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) { | 
					
						
							|  |  |  |     if (!is_thick) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Owned by the mathutils PyObject. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       ret = pyrna_prop_CreatePyObject(ptr, prop); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (subtype) { | 
					
						
							|  |  |  |       case PROP_ALL_VECTOR_SUBTYPES: | 
					
						
							|  |  |  |         if (len >= 2 && len <= 4) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							|  |  |  |             ret = Vector_CreatePyObject(NULL, len, NULL); | 
					
						
							|  |  |  |             RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_MATRIX: | 
					
						
							|  |  |  |         if (len == 16) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							|  |  |  |             ret = Matrix_CreatePyObject(NULL, 4, 4, NULL); | 
					
						
							|  |  |  |             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (len == 9) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							|  |  |  |             ret = Matrix_CreatePyObject(NULL, 3, 3, NULL); | 
					
						
							|  |  |  |             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_EULER: | 
					
						
							|  |  |  |       case PROP_QUATERNION: | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         if (len == 3) { /* Euler. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             PropertyRNA *prop_eul_order = NULL; | 
					
						
							|  |  |  |             short order = pyrna_rotation_euler_order_get(ptr, EULER_ORDER_XYZ, &prop_eul_order); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             // TODO, get order from RNA
 | 
					
						
							|  |  |  |             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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (len == 4) { | 
					
						
							|  |  |  |           if (is_thick) { | 
					
						
							|  |  |  |             ret = Quaternion_CreatePyObject(NULL, NULL); | 
					
						
							|  |  |  |             RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_COLOR: | 
					
						
							|  |  |  |       case PROP_COLOR_GAMMA: | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         if (len == 3) { /* Color. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           if (is_thick) { | 
					
						
							|  |  |  |             ret = Color_CreatePyObject(NULL, NULL); | 
					
						
							|  |  |  |             RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (ret == NULL) { | 
					
						
							|  |  |  |     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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     thick_wrap_slice: | 
					
						
							|  |  |  |       ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       ret = pyrna_prop_CreatePyObject(ptr, prop); /* Owned by the mathutils PyObject. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #else  /* USE_MATHUTILS */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   (void)ptr; | 
					
						
							|  |  |  |   (void)prop; | 
					
						
							|  |  |  | #endif /* USE_MATHUTILS */
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Same as #RNA_enum_value_from_id, but raises an exception. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | int pyrna_enum_value_from_id(const EnumPropertyItem *item, | 
					
						
							|  |  |  |                              const char *identifier, | 
					
						
							|  |  |  |                              int *r_value, | 
					
						
							|  |  |  |                              const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2010-04-27 07:50:31 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_enum_value_from_id(item, identifier, r_value) == 0) { | 
					
						
							|  |  |  |     const char *enum_str = BPy_enum_as_string(item); | 
					
						
							|  |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_ValueError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str); | 
					
						
							|  |  |  |     MEM_freeN((void *)enum_str); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-27 07:50:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2010-04-27 07:50:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-15 12:35:40 +00:00
										 |  |  | /* note on __cmp__:
 | 
					
						
							|  |  |  |  * 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, | 
					
						
							|  |  |  |  * but _not_ 'ptr->type' but include this check for completeness. | 
					
						
							|  |  |  |  * - campbell */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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-04-17 06:17:24 +02:00
										 |  |  |   if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) { | 
					
						
							|  |  |  |     ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   switch (op) { | 
					
						
							|  |  |  |     case Py_NE: | 
					
						
							|  |  |  |       ok = !ok; | 
					
						
							|  |  |  |       ATTR_FALLTHROUGH; | 
					
						
							|  |  |  |     case Py_EQ: | 
					
						
							|  |  |  |       res = ok ? Py_False : Py_True; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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-04-17 06:17:24 +02:00
										 |  |  |   if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) { | 
					
						
							|  |  |  |     ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   switch (op) { | 
					
						
							|  |  |  |     case Py_NE: | 
					
						
							|  |  |  |       ok = !ok; | 
					
						
							|  |  |  |       ATTR_FALLTHROUGH; | 
					
						
							|  |  |  |     case Py_EQ: | 
					
						
							|  |  |  |       res = ok ? Py_False : Py_True; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							| 
									
										
										
										
											2009-03-23 13:28:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PYRNA_STRUCT_IS_VALID(self)) { | 
					
						
							|  |  |  |     return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Print name if available. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL); | 
					
						
							|  |  |  |   if (name) { | 
					
						
							|  |  |  |     ret = PyUnicode_FromFormat( | 
					
						
							|  |  |  |         "<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name); | 
					
						
							|  |  |  |     MEM_freeN((void *)name); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-03-23 13:28:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyUnicode_FromFormat( | 
					
						
							|  |  |  |       "<bpy_struct, %.200s at %p>", RNA_struct_identifier(self->ptr.type), self->ptr.data); | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *tmp_str; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (id == NULL || !PYRNA_STRUCT_IS_VALID(self)) { | 
					
						
							|  |  |  |     /* fallback */ | 
					
						
							|  |  |  |     return pyrna_struct_str(self); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tmp_str = PyUnicode_FromString(id->name + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 12:24:26 +02:00
										 |  |  |   if (DEG_get_original_id(id) != id) { | 
					
						
							|  |  |  |     ret = PyUnicode_FromFormat("Evaluated %s %R", BKE_idcode_to_name(GS(id->name)), tmp_str); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-03-11 12:47:25 +01:00
										 |  |  |   else if (RNA_struct_is_ID(self->ptr.type) && (id->flag & LIB_EMBEDDED_DATA) == 0) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     ret = PyUnicode_FromFormat( | 
					
						
							|  |  |  |         "bpy.data.%s[%R]", BKE_idcode_to_name_plural(GS(id->name)), tmp_str); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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); | 
					
						
							| 
									
										
										
										
											2019-10-04 12:24:26 +02:00
										 |  |  |         ret = PyUnicode_FromFormat( | 
					
						
							|  |  |  |             "bpy.data.%s[%R].%s", BKE_idcode_to_name_plural(GS(real_id->name)), tmp_str, path); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         /* Can't find the path, print something useful as a fallback. */ | 
					
						
							|  |  |  |         ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", | 
					
						
							|  |  |  |                                    BKE_idcode_to_name_plural(GS(id->name)), | 
					
						
							|  |  |  |                                    tmp_str, | 
					
						
							|  |  |  |                                    RNA_struct_identifier(self->ptr.type)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       MEM_freeN((void *)path); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     else { | 
					
						
							|  |  |  |       /* Can't find the path, print something useful as a fallback. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", | 
					
						
							|  |  |  |                                  BKE_idcode_to_name_plural(GS(id->name)), | 
					
						
							|  |  |  |                                  tmp_str, | 
					
						
							|  |  |  |                                  RNA_struct_identifier(self->ptr.type)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_DECREF(tmp_str); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							|  |  |  |   const char *type_id = NULL; | 
					
						
							|  |  |  |   char type_fmt[64] = ""; | 
					
						
							|  |  |  |   int type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   type = RNA_property_type(self->prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* This should never fail. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     int len = -1; | 
					
						
							|  |  |  |     char *c = type_fmt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while ((*c++ = tolower(*type_id++))) { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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-06-21 09:50:23 +10:00
										 |  |  |   /* If a pointer, try to print name of pointer target too. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (type == PROP_POINTER) { | 
					
						
							|  |  |  |     ptr = RNA_property_pointer_get(&self->ptr, self->prop); | 
					
						
							|  |  |  |     name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (name) { | 
					
						
							|  |  |  |       ret = PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", | 
					
						
							|  |  |  |                                  type_fmt, | 
					
						
							|  |  |  |                                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                                  RNA_property_identifier(self->prop), | 
					
						
							|  |  |  |                                  name); | 
					
						
							|  |  |  |       MEM_freeN((void *)name); | 
					
						
							|  |  |  |       return ret; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (type == PROP_COLLECTION) { | 
					
						
							|  |  |  |     PointerRNA r_ptr; | 
					
						
							|  |  |  |     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							|  |  |  |       return PyUnicode_FromFormat( | 
					
						
							|  |  |  |           "<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>", | 
					
						
							|  |  |  |                               type_fmt, | 
					
						
							|  |  |  |                               RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                               RNA_property_identifier(self->prop)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, const int index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   ID *id = self->ptr.owner_id; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *tmp_str; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   const char *path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (id == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Fallback. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return pyrna_prop_str(self); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tmp_str = PyUnicode_FromString(id->name + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |   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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-02 18:37:55 +02:00
										 |  |  |     const char *data_delim = (path[0] == '[') ? "" : "."; | 
					
						
							|  |  |  |     ret = PyUnicode_FromFormat("bpy.data.%s[%R]%s%s", | 
					
						
							|  |  |  |                                BKE_idcode_to_name_plural(GS(real_id->name)), | 
					
						
							|  |  |  |                                tmp_str, | 
					
						
							|  |  |  |                                data_delim, | 
					
						
							|  |  |  |                                path); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     MEM_freeN((void *)path); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   else { | 
					
						
							|  |  |  |     /* Can't find the path, print something useful as a fallback. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", | 
					
						
							|  |  |  |                                BKE_idcode_to_name_plural(GS(id->name)), | 
					
						
							|  |  |  |                                tmp_str, | 
					
						
							|  |  |  |                                RNA_property_identifier(self->prop)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_DECREF(tmp_str); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2010-08-10 15:46:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-28 22:23:39 +10:00
										 |  |  | static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return pyrna_prop_repr_ex(self, 0, -1); | 
					
						
							| 
									
										
										
										
											2016-05-28 22:23:39 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_array_repr(BPy_PropertyArrayRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return pyrna_prop_repr_ex((BPy_PropertyRNA *)self, self->arraydim, self->arrayoffset); | 
					
						
							| 
									
										
										
										
											2016-05-28 22:23:39 +10:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_func_repr(BPy_FunctionRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return _Py_HashPointer(self->ptr.data); | 
					
						
							| 
									
										
										
										
											2010-04-25 21:13:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   long x, y; | 
					
						
							|  |  |  |   if (self->ptr.data == NULL) { | 
					
						
							|  |  |  |     x = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     x = _Py_HashPointer(self->ptr.data); | 
					
						
							|  |  |  |     if (x == -1) { | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   y = _Py_HashPointer((void *)(self->prop)); | 
					
						
							|  |  |  |   if (y == -1) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   x ^= y; | 
					
						
							|  |  |  |   if (x == -1) { | 
					
						
							|  |  |  |     x = -2; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_VISIT(self->reference); | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int pyrna_struct_clear(BPy_StructRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_CLEAR(self->reference); | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											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_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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->freeptr && self->ptr.data) { | 
					
						
							|  |  |  |     IDP_FreeProperty(self->ptr.data); | 
					
						
							|  |  |  |     self->ptr.data = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->reference) { | 
					
						
							|  |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     pyrna_struct_clear(self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_TYPE(self)->tp_free(self); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							|  |  |  | static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->reference) { | 
					
						
							|  |  |  |     //      PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */
 | 
					
						
							|  |  |  |     pyrna_struct_clear(self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Reference is now NULL. */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (reference) { | 
					
						
							|  |  |  |     self->reference = reference; | 
					
						
							|  |  |  |     Py_INCREF(reference); | 
					
						
							|  |  |  |     //      PyObject_GC_Track(self);  /* INITIALIZED TRACKED ? */
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->in_weakreflist != NULL) { | 
					
						
							|  |  |  |     PyObject_ClearWeakRefs((PyObject *)self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_TYPE(self)->tp_free(self); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->in_weakreflist != NULL) { | 
					
						
							|  |  |  |     PyObject_ClearWeakRefs((PyObject *)self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const EnumPropertyItem *item; | 
					
						
							|  |  |  |   const char *result; | 
					
						
							|  |  |  |   bool free = false; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); | 
					
						
							|  |  |  |   if (item) { | 
					
						
							|  |  |  |     result = BPy_enum_as_string(item); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     result = ""; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (free) { | 
					
						
							|  |  |  |     MEM_freeN((void *)item); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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( | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *r_value, const char *error_prefix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const char *param = _PyUnicode_AsString(item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (param == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s expected a string enum, not %.200s", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, r_value)) { | 
					
						
							|  |  |  |       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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:00:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 19:34:42 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Takes a set of strings and map it to and array of booleans. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Useful when the values aren't flags. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-01-15 05:24:15 +11:00
										 |  |  |  * \param type_convert_sign: Maps signed to unsigned range, | 
					
						
							| 
									
										
										
										
											2016-01-06 19:34:42 +01:00
										 |  |  |  * needed when we want to use the full range of a signed short/char. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | BLI_bitmap *pyrna_set_to_enum_bitmap(const EnumPropertyItem *items, | 
					
						
							|  |  |  |                                      PyObject *value, | 
					
						
							|  |  |  |                                      int type_size, | 
					
						
							|  |  |  |                                      bool type_convert_sign, | 
					
						
							|  |  |  |                                      int bitmap_size, | 
					
						
							|  |  |  |                                      const char *error_prefix) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Set looping. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_ssize_t pos = 0; | 
					
						
							|  |  |  |   Py_ssize_t hash = 0; | 
					
						
							|  |  |  |   PyObject *key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BLI_bitmap *bitmap = BLI_BITMAP_NEW(bitmap_size, __func__); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (_PySet_NextEntry(value, &pos, &key, &hash)) { | 
					
						
							|  |  |  |     const char *param = _PyUnicode_AsString(key); | 
					
						
							|  |  |  |     if (param == NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%.200s expected a string, not %.200s", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    Py_TYPE(key)->tp_name); | 
					
						
							|  |  |  |       goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int ret; | 
					
						
							|  |  |  |     if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { | 
					
						
							|  |  |  |       goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int index = ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (type_convert_sign) { | 
					
						
							|  |  |  |       if (type_size == 2) { | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |           signed short as_signed; | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  |           ushort as_unsigned; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         } ret_convert; | 
					
						
							|  |  |  |         ret_convert.as_signed = (signed short)ret; | 
					
						
							|  |  |  |         index = (int)ret_convert.as_unsigned; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (type_size == 1) { | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |           signed char as_signed; | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  |           uchar as_unsigned; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         } ret_convert; | 
					
						
							|  |  |  |         ret_convert.as_signed = (signed char)ret; | 
					
						
							|  |  |  |         index = (int)ret_convert.as_unsigned; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         BLI_assert(0); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     BLI_assert(index < bitmap_size); | 
					
						
							|  |  |  |     BLI_BITMAP_ENABLE(bitmap, index); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return bitmap; | 
					
						
							| 
									
										
										
										
											2016-01-06 19:34:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | error: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   MEM_freeN(bitmap); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2016-01-06 19:34:42 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* 'value' _must_ be a set type, error check before calling. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | int pyrna_set_to_enum_bitfield(const EnumPropertyItem *items, | 
					
						
							|  |  |  |                                PyObject *value, | 
					
						
							|  |  |  |                                int *r_value, | 
					
						
							|  |  |  |                                const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Set of enum items, concatenate all values with OR. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int ret, flag = 0; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Set looping. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_ssize_t pos = 0; | 
					
						
							|  |  |  |   Py_ssize_t hash = 0; | 
					
						
							|  |  |  |   PyObject *key; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   *r_value = 0; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   while (_PySet_NextEntry(value, &pos, &key, &hash)) { | 
					
						
							|  |  |  |     const char *param = _PyUnicode_AsString(key); | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (param == NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%.200s expected a string, not %.200s", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    Py_TYPE(key)->tp_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-25 17:01:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     flag |= ret; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   *r_value = flag; | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | static int pyrna_prop_to_enum_bitfield( | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const EnumPropertyItem *item; | 
					
						
							|  |  |  |   int ret; | 
					
						
							|  |  |  |   bool free = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r_value = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (item) { | 
					
						
							|  |  |  |     ret = pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     if (PySet_GET_SIZE(value)) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%.200s: empty enum \"%.200s\" could not have any values assigned", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    RNA_property_identifier(prop)); | 
					
						
							|  |  |  |       ret = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       ret = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (free) { | 
					
						
							|  |  |  |     MEM_freeN((void *)item); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2010-02-01 22:04:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 15:07:26 +11:00
										 |  |  | PyObject *pyrna_enum_bitfield_to_py(const EnumPropertyItem *items, int value) | 
					
						
							| 
									
										
										
										
											2010-01-23 01:02:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret = PySet_New(NULL); | 
					
						
							|  |  |  |   const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1]; | 
					
						
							| 
									
										
										
										
											2010-01-23 01:02:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_enum_bitflag_identifiers(items, value, identifier)) { | 
					
						
							|  |  |  |     PyObject *item; | 
					
						
							|  |  |  |     int index; | 
					
						
							|  |  |  |     for (index = 0; identifier[index]; index++) { | 
					
						
							|  |  |  |       item = PyUnicode_FromString(identifier[index]); | 
					
						
							|  |  |  |       PySet_Add(ret, item); | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-01-23 01:02:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2010-01-23 01:02:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *item, *ret = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { | 
					
						
							|  |  |  |     const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ret = PySet_New(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (RNA_property_enum_bitflag_identifiers(BPy_GetContext(), ptr, prop, val, identifier)) { | 
					
						
							|  |  |  |       int index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (index = 0; identifier[index]; index++) { | 
					
						
							|  |  |  |         item = PyUnicode_FromString(identifier[index]); | 
					
						
							|  |  |  |         PySet_Add(ret, item); | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     const char *identifier; | 
					
						
							|  |  |  |     if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) { | 
					
						
							|  |  |  |       ret = PyUnicode_FromString(identifier); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       /* 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-29 19:59:13 +10:00
										 |  |  |       /* Do not print warning in case of DummyRNA_NULL_items,
 | 
					
						
							|  |  |  |        * this one will never match any value... */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (enum_item != DummyRNA_NULL_items) { | 
					
						
							|  |  |  |         const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Prefer not to fail silently in case of API errors, maybe disable it later. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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-06-21 09:50:23 +10:00
										 |  |  | #if 0 /* Gives Python decoding errors while generating docs :( */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         char error_str[256]; | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |         BLI_snprintf(error_str, | 
					
						
							|  |  |  |                      sizeof(error_str), | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							|  |  |  |         PyErr_Warn(PyExc_RuntimeWarning, error_str); | 
					
						
							| 
									
										
										
										
											2009-11-12 15:46:45 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (ptr_name) { | 
					
						
							|  |  |  |           MEM_freeN((void *)ptr_name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-01-02 17:03:45 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       ret = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-12-07 00:16:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   const int type = RNA_property_type(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_property_array_check(prop)) { | 
					
						
							|  |  |  |     return pyrna_py_from_array(ptr, prop); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* See if we can coerce into a Python type - 'PropertyType'. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   switch (type) { | 
					
						
							|  |  |  |     case PROP_BOOLEAN: | 
					
						
							|  |  |  |       ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PROP_INT: | 
					
						
							|  |  |  |       ret = PyLong_FromLong(RNA_property_int_get(ptr, prop)); | 
					
						
							|  |  |  |       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]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Only file paths get special treatment, they may contain non utf-8 chars. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  |         ret = PyBytes_FromStringAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { | 
					
						
							|  |  |  |         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 */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  |         ret = PyBytes_FromStringAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         ret = PyUnicode_FromStringAndSize(buf, buf_len); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif /* USE_STRING_COERCE */
 | 
					
						
							|  |  |  |       if (buf_fixed != buf) { | 
					
						
							|  |  |  |         MEM_freeN((void *)buf); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_ENUM: { | 
					
						
							|  |  |  |       ret = pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * This function is used by operators and converting dicts into collections. | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * It takes keyword args and fills them with property values. | 
					
						
							| 
									
										
										
										
											2016-07-23 04:03:36 +10:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | int pyrna_pydict_to_props(PointerRNA *ptr, | 
					
						
							|  |  |  |                           PyObject *kw, | 
					
						
							|  |  |  |                           const bool all_args, | 
					
						
							|  |  |  |                           const char *error_prefix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int error_val = 0; | 
					
						
							|  |  |  |   int totkw; | 
					
						
							|  |  |  |   const char *arg_name = NULL; | 
					
						
							|  |  |  |   PyObject *item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   totkw = kw ? PyDict_Size(kw) : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_STRUCT_BEGIN (ptr, prop) { | 
					
						
							|  |  |  |     arg_name = RNA_property_identifier(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (STREQ(arg_name, "rna_type")) { | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (kw == NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%.200s: no keywords, expected \"%.200s\"", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    arg_name ? arg_name : "<UNKNOWN>"); | 
					
						
							|  |  |  |       error_val = -1; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     item = PyDict_GetItemString(kw, arg_name); /* Wont set an error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (item == NULL) { | 
					
						
							|  |  |  |       if (all_args) { | 
					
						
							|  |  |  |         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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) { | 
					
						
							|  |  |  |         error_val = -1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       totkw--; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_STRUCT_END; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   if (error_val == 0 && totkw > 0) { /* Some keywords were given that were not used :/. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *key, *value; | 
					
						
							|  |  |  |     Py_ssize_t pos = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (PyDict_Next(kw, &pos, &key, &value)) { | 
					
						
							|  |  |  |       arg_name = _PyUnicode_AsString(key); | 
					
						
							|  |  |  |       if (RNA_struct_find_property(ptr, arg_name) == NULL) { | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       arg_name = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s: keyword \"%.200s\" unrecognized", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  arg_name ? arg_name : "<UNKNOWN>"); | 
					
						
							|  |  |  |     error_val = -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return error_val; | 
					
						
							| 
									
										
										
											
												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-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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *)PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); | 
					
						
							|  |  |  |   pyfunc->ptr = *ptr; | 
					
						
							|  |  |  |   pyfunc->func = func; | 
					
						
							|  |  |  |   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( | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* XXX hard limits should be checked here. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const int type = RNA_property_type(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_property_array_check(prop)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Done getting the length. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) { | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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'. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     switch (type) { | 
					
						
							|  |  |  |       case PROP_BOOLEAN: { | 
					
						
							|  |  |  |         int param; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Prefer not to have an exception here
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (RNA_parameter_flag(prop) & PARM_OUTPUT) { | 
					
						
							|  |  |  |           param = PyObject_IsTrue(value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           param = PyC_Long_AsI32(value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (param == -1) { | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           if (data) { | 
					
						
							|  |  |  |             *((bool *)data) = param; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             RNA_property_boolean_set(ptr, prop, param); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_INT: { | 
					
						
							|  |  |  |         int overflow; | 
					
						
							|  |  |  |         long param = PyLong_AsLongAndOverflow(value, &overflow); | 
					
						
							|  |  |  |         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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (param == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           int param_i = (int)param; | 
					
						
							|  |  |  |           if (data) { | 
					
						
							|  |  |  |             RNA_property_int_clamp(ptr, prop, ¶m_i); | 
					
						
							|  |  |  |             *((int *)data) = param_i; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             RNA_property_int_set(ptr, prop, param_i); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_FLOAT: { | 
					
						
							|  |  |  |         float param = PyFloat_AsDouble(value); | 
					
						
							|  |  |  |         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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           if (data) { | 
					
						
							|  |  |  |             RNA_property_float_clamp(ptr, prop, (float *)¶m); | 
					
						
							|  |  |  |             *((float *)data) = param; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             RNA_property_float_set(ptr, prop, param); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_STRING: { | 
					
						
							|  |  |  |         const int subtype = RNA_property_subtype(prop); | 
					
						
							|  |  |  |         const char *param; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               RNA_property_string_set(ptr, prop, NULL); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Byte String. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           param = PyBytes_AsString(value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           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); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             if (data) { | 
					
						
							| 
									
										
										
										
											2019-09-06 16:26:10 +03:00
										 |  |  |               if (RNA_property_flag(prop) & PROP_THICK_WRAP) { | 
					
						
							|  |  |  |                 BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else { | 
					
						
							|  |  |  |                 *((char **)data) = (char *)param; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Unicode String. */ | 
					
						
							| 
									
										
										
										
											2011-11-15 07:09:41 +00:00
										 |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           PyObject *value_coerce = NULL; | 
					
						
							|  |  |  |           if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* TODO, get size. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             param = PyC_UnicodeAsByte(value, &value_coerce); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             param = _PyUnicode_AsString(value); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | #else  /* USE_STRING_COERCE */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           param = _PyUnicode_AsString(value); | 
					
						
							|  |  |  | #endif /* USE_STRING_COERCE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           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); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Same as bytes. */ | 
					
						
							|  |  |  |             /* XXX, this is suspect, but needed for function calls,
 | 
					
						
							| 
									
										
										
										
											2019-08-01 13:53:25 +10:00
										 |  |  |              * need to see if there's a better way. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             if (data) { | 
					
						
							| 
									
										
										
										
											2019-09-06 16:26:10 +03:00
										 |  |  |               if (RNA_property_flag(prop) & PROP_THICK_WRAP) { | 
					
						
							|  |  |  |                 BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else { | 
					
						
							|  |  |  |                 *((char **)data) = (char *)param; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               RNA_property_string_set(ptr, prop, param); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           Py_XDECREF(value_coerce); | 
					
						
							|  |  |  | #endif /* USE_STRING_COERCE */
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_ENUM: { | 
					
						
							|  |  |  |         int val = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Type checking is done by each function. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) { | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Simple enum string. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) { | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (data) { | 
					
						
							|  |  |  |           *((int *)data) = val; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_enum_set(ptr, prop, val); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_POINTER: { | 
					
						
							|  |  |  |         PyObject *value_new = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop); | 
					
						
							|  |  |  |         int flag = RNA_property_flag(prop); | 
					
						
							|  |  |  |         int flag_parameter = RNA_parameter_flag(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* This is really nasty! Done so we can fake the operator having direct properties, eg:
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |          * layout.prop(self, "filepath") | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |          * ... which in fact should be: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |          */ | 
					
						
							|  |  |  |         if ((ptr_type == &RNA_AnyType) && (BPy_StructRNA_Check(value))) { | 
					
						
							|  |  |  |           const StructRNA *base_type = RNA_struct_base_child_of( | 
					
						
							|  |  |  |               ((const BPy_StructRNA *)value)->ptr.type, NULL); | 
					
						
							|  |  |  |           if (ELEM(base_type, &RNA_Operator, &RNA_Gizmo)) { | 
					
						
							|  |  |  |             value = PyObject_GetAttr(value, bpy_intern_str_properties); | 
					
						
							|  |  |  |             value_new = value; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* if property is an OperatorProperties/GizmoProperties pointer and value is a map,
 | 
					
						
							|  |  |  |          * forward back to pyrna_pydict_to_props */ | 
					
						
							|  |  |  |         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); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else if (base_type == &RNA_GizmoProperties) { | 
					
						
							|  |  |  |             PointerRNA opptr = RNA_property_pointer_get(ptr, prop); | 
					
						
							|  |  |  |             return pyrna_pydict_to_props(&opptr, value, false, error_prefix); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Another exception, allow to pass a collection as an RNA property. */ | 
					
						
							|  |  |  |         if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                          error_prefix, | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                          RNA_property_identifier(prop), | 
					
						
							|  |  |  |                          RNA_struct_identifier(ptr_type)); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!BPy_StructRNA_Check(value) && value != Py_None) { | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if ((flag & PROP_NEVER_NULL) && value == Py_None) { | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) && | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |                                         ptr->owner_id == ((BPy_StructRNA *)value)->ptr.owner_id)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           PyErr_Format(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                        "%.200s %.200s.%.200s ID type does not support assignment to itself", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                        error_prefix, | 
					
						
							|  |  |  |                        RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                        RNA_property_identifier(prop)); | 
					
						
							|  |  |  |           Py_XDECREF(value_new); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           BPy_StructRNA *param = (BPy_StructRNA *)value; | 
					
						
							|  |  |  |           bool raise_error = false; | 
					
						
							|  |  |  |           if (data) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (flag_parameter & PARM_RNAPTR) { | 
					
						
							|  |  |  |               if (flag & PROP_THICK_WRAP) { | 
					
						
							|  |  |  |                 if (value == Py_None) { | 
					
						
							|  |  |  |                   memset(data, 0, sizeof(PointerRNA)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							|  |  |  |                   *((PointerRNA *)data) = param->ptr; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                   raise_error = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else { | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |                 /* For function calls, we sometimes want to pass the 'ptr' directly,
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                  * but watch out that it remains valid! | 
					
						
							|  |  |  |                  * We could possibly support this later if needed. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                 BLI_assert(value_new == NULL); | 
					
						
							|  |  |  |                 if (value == Py_None) { | 
					
						
							|  |  |  |                   *((void **)data) = NULL; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							|  |  |  |                   *((PointerRNA **)data) = ¶m->ptr; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                   raise_error = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (value == Py_None) { | 
					
						
							|  |  |  |               *((void **)data) = NULL; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							|  |  |  |               *((void **)data) = param->ptr.data; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               raise_error = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Data == NULL, assign to RNA. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) { | 
					
						
							| 
									
										
										
										
											2019-05-17 13:59:59 +02:00
										 |  |  |               ReportList reports; | 
					
						
							|  |  |  |               BKE_reports_init(&reports, RPT_STORE); | 
					
						
							|  |  |  |               RNA_property_pointer_set( | 
					
						
							| 
									
										
										
										
											2019-05-20 18:06:09 +10:00
										 |  |  |                   ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports); | 
					
						
							| 
									
										
										
										
											2019-05-17 13:59:59 +02:00
										 |  |  |               int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); | 
					
						
							|  |  |  |               if (err == -1) { | 
					
						
							|  |  |  |                 Py_XDECREF(value_new); | 
					
						
							|  |  |  |                 return -1; | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               raise_error = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (raise_error) { | 
					
						
							|  |  |  |             if (pyrna_struct_validity_check(param) == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |               /* Error set. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Py_XDECREF(value_new); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_COLLECTION: { | 
					
						
							|  |  |  |         Py_ssize_t seq_len, i; | 
					
						
							|  |  |  |         PyObject *item; | 
					
						
							|  |  |  |         PointerRNA itemptr; | 
					
						
							|  |  |  |         ListBase *lb; | 
					
						
							|  |  |  |         CollectionPointerLink *link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         lb = (data) ? (ListBase *)data : NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Convert a sequence of dict's into a collection. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (!PySequence_Check(value)) { | 
					
						
							|  |  |  |           PyErr_Format( | 
					
						
							|  |  |  |               PyExc_TypeError, | 
					
						
							|  |  |  |               "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s", | 
					
						
							|  |  |  |               error_prefix, | 
					
						
							|  |  |  |               RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |               RNA_property_identifier(prop), | 
					
						
							|  |  |  |               Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         seq_len = PySequence_Size(value); | 
					
						
							|  |  |  |         for (i = 0; i < seq_len; i++) { | 
					
						
							|  |  |  |           item = PySequence_GetItem(value, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (lb) { | 
					
						
							|  |  |  |             link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink"); | 
					
						
							|  |  |  |             link->ptr = itemptr; | 
					
						
							|  |  |  |             BLI_addtail(lb, link); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             RNA_property_collection_add(ptr, prop, &itemptr); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           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) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             PyObject *msg = PyC_ExceptionBuffer(); | 
					
						
							|  |  |  |             const char *msg_char = _PyUnicode_AsString(msg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Py_DECREF(item); | 
					
						
							|  |  |  |             Py_DECREF(msg); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           Py_DECREF(item); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Run RNA property functions. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_update_check(prop)) { | 
					
						
							|  |  |  |     RNA_property_update(BPy_GetContext(), ptr, prop); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int ret = 0; | 
					
						
							|  |  |  |   PointerRNA *ptr = &self->ptr; | 
					
						
							|  |  |  |   PropertyRNA *prop = self->prop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const int totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     // char error_str[512];
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       ret = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* See if we can coerce into a Python type - 'PropertyType'. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     switch (RNA_property_type(prop)) { | 
					
						
							|  |  |  |       case PROP_BOOLEAN: { | 
					
						
							|  |  |  |         int param = PyC_Long_AsBool(value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (param == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Error is set. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           ret = -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_boolean_set_index(ptr, prop, index, param); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_INT: { | 
					
						
							|  |  |  |         int param = PyC_Long_AsI32(value); | 
					
						
							|  |  |  |         if (param == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |           PyErr_SetString(PyExc_TypeError, "expected an int type"); | 
					
						
							|  |  |  |           ret = -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_int_clamp(ptr, prop, ¶m); | 
					
						
							|  |  |  |           RNA_property_int_set_index(ptr, prop, index, param); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_FLOAT: { | 
					
						
							|  |  |  |         float param = PyFloat_AsDouble(value); | 
					
						
							|  |  |  |         if (PyErr_Occurred()) { | 
					
						
							|  |  |  |           PyErr_SetString(PyExc_TypeError, "expected a float type"); | 
					
						
							|  |  |  |           ret = -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           RNA_property_float_clamp(ptr, prop, ¶m); | 
					
						
							|  |  |  |           RNA_property_float_set_index(ptr, prop, index, param); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_AttributeError, "not an array type"); | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Run RNA property functions. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_update_check(prop)) { | 
					
						
							|  |  |  |     RNA_property_update(BPy_GetContext(), ptr, prop); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1) { | 
					
						
							|  |  |  |     return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* No callback defined, just iterate and find the nth item. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   CollectionPropertyIterator iter; | 
					
						
							|  |  |  |   int test; | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_collection_begin(&self->ptr, self->prop, &iter); | 
					
						
							|  |  |  |   test = iter.valid; | 
					
						
							|  |  |  |   RNA_property_collection_end(&iter); | 
					
						
							|  |  |  |   return test; | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
 | 
					
						
							|  |  |  |   if (keynum < 0) { \ | 
					
						
							|  |  |  |     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; \ | 
					
						
							|  |  |  |     } \ | 
					
						
							|  |  |  |   } \ | 
					
						
							|  |  |  |   (void)0 | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA newptr; | 
					
						
							|  |  |  |   Py_ssize_t keynum_abs = keynum; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_COLLECTION_ABS_INDEX(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) { | 
					
						
							|  |  |  |     return pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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, " | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                    "valid index %d given in %d sized collection, but value not found", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                    keynum_abs, | 
					
						
							|  |  |  |                    len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                    Py_ssize_t keynum, | 
					
						
							|  |  |  |                                                    PyObject *value) | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_COLLECTION_ABS_INDEX(-1); | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) { | 
					
						
							|  |  |  |     const int len = RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							|  |  |  |     if (keynum_abs >= len) { | 
					
						
							|  |  |  |       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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PyErr_Format(PyExc_IndexError, | 
					
						
							|  |  |  |                    "bpy_prop_collection[index] = value: " | 
					
						
							|  |  |  |                    "failed assignment (unknown reason)", | 
					
						
							|  |  |  |                    keynum); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int len; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   len = pyrna_prop_array_length(self); | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (keynum < 0) { | 
					
						
							|  |  |  |     keynum += len; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (keynum >= 0 && keynum < len) { | 
					
						
							|  |  |  |     return pyrna_prop_array_to_py_index(self, keynum); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA newptr; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { | 
					
						
							|  |  |  |     return pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 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) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const char *keyname; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* First validate the args, all we know is that they are a tuple. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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)); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (self->ptr.type != &RNA_BlendData) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                  "%s: is only valid for bpy.data collections, not %.200s", | 
					
						
							|  |  |  |                  err_prefix, | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type)); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                  "%s: id must be a string, not %.200s", | 
					
						
							|  |  |  |                  err_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |       const char *keylib_str = _PyUnicode_AsString(keylib); | 
					
						
							|  |  |  |       lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, name)); | 
					
						
							|  |  |  |       if (lib == NULL) { | 
					
						
							|  |  |  |         if (err_not_found) { | 
					
						
							|  |  |  |           PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                        "%s: lib name '%.240s' " | 
					
						
							|  |  |  |                        "does not reference a valid library", | 
					
						
							|  |  |  |                        err_prefix, | 
					
						
							|  |  |  |                        keylib_str); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_KeyError, | 
					
						
							|  |  |  |                    "%s: lib must be a string or None, not %.200s", | 
					
						
							|  |  |  |                    err_prefix, | 
					
						
							|  |  |  |                    Py_TYPE(keylib)->tp_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* lib is either a valid pointer or NULL,
 | 
					
						
							|  |  |  |      * either way can do direct comparison with id.lib */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       ID *id = itemptr.data; /* Always an ID. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) { | 
					
						
							|  |  |  |         found = true; | 
					
						
							|  |  |  |         if (r_ptr) { | 
					
						
							|  |  |  |           *r_ptr = itemptr; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     RNA_PROP_END; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* We may want to fail silently as with collection.get(). */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if ((found == false) && err_not_found) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Only runs for getitem access so use fixed string. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       return found; /* 1 / 0, no exception. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                               PyObject *key, | 
					
						
							|  |  |  |                                                               const char *err_prefix, | 
					
						
							|  |  |  |                                                               const bool err_not_found) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr( | 
					
						
							|  |  |  |       self, key, err_prefix, err_not_found, &ptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (contains == 1) { | 
					
						
							|  |  |  |     return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                        Py_ssize_t start, | 
					
						
							|  |  |  |                                                        Py_ssize_t stop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   CollectionPropertyIterator rna_macro_iter; | 
					
						
							|  |  |  |   int count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyObject *list; | 
					
						
							|  |  |  |   PyObject *item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   list = PyList_New(0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Skip to start. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); | 
					
						
							|  |  |  |   RNA_property_collection_skip(&rna_macro_iter, start); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Add items until stop. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (count = start; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { | 
					
						
							|  |  |  |     item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr); | 
					
						
							|  |  |  |     PyList_APPEND(list, item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     count++; | 
					
						
							|  |  |  |     if (count == stop) { | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_property_collection_end(&rna_macro_iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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
										 |  |  | /**
 | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int count, totdim; | 
					
						
							|  |  |  |   PyObject *tuple; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Isn't needed, internal use only. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tuple = PyTuple_New(stop - start); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							|  |  |  |     for (count = start; count < stop; count++) { | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     switch (RNA_property_type(prop)) { | 
					
						
							|  |  |  |       case PROP_FLOAT: { | 
					
						
							|  |  |  |         float values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |         float *values; | 
					
						
							|  |  |  |         if (length > PYRNA_STACK_ARRAY) { | 
					
						
							|  |  |  |           values = PyMem_MALLOC(sizeof(float) * length); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           values = values_stack; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         RNA_property_float_get_array(ptr, prop, values); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (count = start; count < stop; count++) { | 
					
						
							|  |  |  |           PyTuple_SET_ITEM(tuple, count - start, PyFloat_FromDouble(values[count])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (values != values_stack) { | 
					
						
							|  |  |  |           PyMem_FREE(values); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_BOOLEAN: { | 
					
						
							|  |  |  |         bool values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |         bool *values; | 
					
						
							|  |  |  |         if (length > PYRNA_STACK_ARRAY) { | 
					
						
							|  |  |  |           values = PyMem_MALLOC(sizeof(bool) * length); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           values = values_stack; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_property_boolean_get_array(ptr, prop, values); | 
					
						
							|  |  |  |         for (count = start; count < stop; count++) { | 
					
						
							|  |  |  |           PyTuple_SET_ITEM(tuple, count - start, PyBool_FromLong(values[count])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (values != values_stack) { | 
					
						
							|  |  |  |           PyMem_FREE(values); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_INT: { | 
					
						
							|  |  |  |         int values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |         int *values; | 
					
						
							|  |  |  |         if (length > PYRNA_STACK_ARRAY) { | 
					
						
							|  |  |  |           values = PyMem_MALLOC(sizeof(int) * length); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           values = values_stack; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_property_int_get_array(ptr, prop, values); | 
					
						
							|  |  |  |         for (count = start; count < stop; count++) { | 
					
						
							|  |  |  |           PyTuple_SET_ITEM(tuple, count - start, PyLong_FromLong(values[count])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (values != values_stack) { | 
					
						
							|  |  |  |           PyMem_FREE(values); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         BLI_assert(!"Invalid array type"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "not an array type"); | 
					
						
							|  |  |  |         Py_DECREF(tuple); | 
					
						
							|  |  |  |         tuple = NULL; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (PyUnicode_Check(key)) { | 
					
						
							|  |  |  |     return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyIndex_Check(key)) { | 
					
						
							|  |  |  |     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							|  |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pyrna_prop_collection_subscript_int(self, i); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PySlice_Check(key)) { | 
					
						
							|  |  |  |     PySliceObject *key_slice = (PySliceObject *)key; | 
					
						
							|  |  |  |     Py_ssize_t step = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (step != 1) { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (key_slice->start == Py_None && key_slice->stop == Py_None) { | 
					
						
							|  |  |  |       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (start < 0 || stop < 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Only get the length for negative values. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							|  |  |  |         if (start < 0) { | 
					
						
							|  |  |  |           start += len; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (stop < 0) { | 
					
						
							|  |  |  |           stop += len; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (stop - start <= 0) { | 
					
						
							|  |  |  |         return PyList_New(0); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return pyrna_prop_collection_subscript_slice(self, start, stop); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyTuple_Check(key)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Special case, for ID datablocks we. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return pyrna_prop_collection_subscript_str_lib_pair( | 
					
						
							|  |  |  |         self, key, "bpy_prop_collection[id, lib]", true); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   StructRNA *prop_srna; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (value == Py_None) { | 
					
						
							|  |  |  |     if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "bpy_prop_collection[key] = value: invalid, " | 
					
						
							|  |  |  |                    "this collection doesn't support None assignment"); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       return 0; /* None is OK. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (BPy_StructRNA_Check(value) == 0) { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) { | 
					
						
							|  |  |  |     StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type; | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       return 0; /* OK, this is the correct type! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                "bpy_prop_collection[key] = value: internal error, " | 
					
						
							|  |  |  |                "failed to get the collection type"); | 
					
						
							|  |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00: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 */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                                                PyObject *key, | 
					
						
							|  |  |  |                                                PyObject *value) | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Validate the assigned value. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (value == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (pyrna_prop_collection_type_check(self, value) == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     return -1; /* Exception is set. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyUnicode_Check(key)) { | 
					
						
							|  |  |  |     return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyIndex_Check(key)) { | 
					
						
							|  |  |  |     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							|  |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pyrna_prop_collection_ass_subscript_int(self, i, value); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #if 0 /* TODO, fake slice assignment. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   else if (PySlice_Check(key)) { | 
					
						
							|  |  |  |     PySliceObject *key_slice = (PySliceObject *)key; | 
					
						
							|  |  |  |     Py_ssize_t step = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (step != 1) { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (key_slice->start == Py_None && key_slice->stop == Py_None) { | 
					
						
							|  |  |  |       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |       if (start < 0 || stop < 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Only get the length for negative values. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (stop < 0) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |           stop += len; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (stop - start <= 0) { | 
					
						
							|  |  |  |         return PyList_New(0); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return pyrna_prop_collection_subscript_slice(self, start, stop); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-10-01 17:54:33 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   else { | 
					
						
							|  |  |  |     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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyUnicode_Check(key)) { | 
					
						
							|  |  |  |     return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyIndex_Check(key)) { | 
					
						
							|  |  |  |     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							|  |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return pyrna_prop_array_subscript_int(self, i); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PySlice_Check(key)) { | 
					
						
							|  |  |  |     Py_ssize_t step = 1; | 
					
						
							|  |  |  |     PySliceObject *key_slice = (PySliceObject *)key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (step != 1) { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (key_slice->start == Py_None && key_slice->stop == Py_None) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Note: no significant advantage with optimizing [:] slice as with collections,
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |        * but include here for consistency with collection slice func */ | 
					
						
							|  |  |  |       Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self); | 
					
						
							|  |  |  |       return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       int len = pyrna_prop_array_length(self); | 
					
						
							|  |  |  |       Py_ssize_t start, stop, slicelength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (slicelength <= 0) { | 
					
						
							|  |  |  |         return PyTuple_New(0); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *value_fast; | 
					
						
							|  |  |  |   if (!(value_fast = PySequence_Fast(value, | 
					
						
							|  |  |  |                                      "bpy_prop_array[slice] = value: " | 
					
						
							|  |  |  |                                      "element in assignment is not a sequence type"))) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PySequence_Fast_GET_SIZE(value_fast) != length) { | 
					
						
							|  |  |  |     Py_DECREF(value_fast); | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  |                     "bpy_prop_array[slice] = value: " | 
					
						
							|  |  |  |                     "re-sizing bpy_struct element in arrays isn't supported"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     return value_fast; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int prop_subscript_ass_array_slice__float_recursive( | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       index += prop_subscript_ass_array_slice__float_recursive( | 
					
						
							|  |  |  |           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Py_DECREF(subvalue); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return index; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return i; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-03-08 19:13:37 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int prop_subscript_ass_array_slice__int_recursive( | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       index += prop_subscript_ass_array_slice__int_recursive( | 
					
						
							|  |  |  |           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Py_DECREF(subvalue); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return index; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return i; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items, | 
					
						
							|  |  |  |                                                           bool *value, | 
					
						
							|  |  |  |                                                           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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       index += prop_subscript_ass_array_slice__bool_recursive( | 
					
						
							|  |  |  |           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Py_DECREF(subvalue); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return index; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     BLI_assert(totdim == 1); | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     for (i = 0; i != length; i++) { | 
					
						
							|  |  |  |       int v = PyLong_AsLong(value_items[i]); | 
					
						
							|  |  |  |       value[i] = v; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int prop_subscript_ass_array_slice(PointerRNA *ptr, | 
					
						
							|  |  |  |                                           PropertyRNA *prop, | 
					
						
							|  |  |  |                                           int arraydim, | 
					
						
							|  |  |  |                                           int arrayoffset, | 
					
						
							|  |  |  |                                           int start, | 
					
						
							|  |  |  |                                           int stop, | 
					
						
							|  |  |  |                                           int length, | 
					
						
							|  |  |  |                                           PyObject *value_orig) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const int length_flat = RNA_property_array_length(ptr, prop); | 
					
						
							|  |  |  |   PyObject *value; | 
					
						
							|  |  |  |   PyObject **value_items; | 
					
						
							|  |  |  |   void *values_alloc = NULL; | 
					
						
							|  |  |  |   int ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (value_orig == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString( | 
					
						
							|  |  |  |         PyExc_TypeError, | 
					
						
							|  |  |  |         "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!(value = PySequence_Fast( | 
					
						
							|  |  |  |             value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (PySequence_Fast_GET_SIZE(value) != stop - start) { | 
					
						
							|  |  |  |     Py_DECREF(value); | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_array[slice] = value: re-sizing bpy_struct arrays isn't supported"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int dimsize[3]; | 
					
						
							|  |  |  |   int totdim = RNA_property_array_dimension(ptr, prop, dimsize); | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							|  |  |  |     BLI_assert(dimsize[arraydim] == length); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int span = 1; | 
					
						
							|  |  |  |   if (totdim > 1) { | 
					
						
							|  |  |  |     for (int i = arraydim + 1; i < totdim; i++) { | 
					
						
							|  |  |  |       span *= dimsize[i]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   value_items = PySequence_Fast_ITEMS(value); | 
					
						
							|  |  |  |   switch (RNA_property_type(prop)) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       float values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |       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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         RNA_property_float_get_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       float range[2]; | 
					
						
							|  |  |  |       RNA_property_float_range(ptr, prop, &range[0], &range[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dimsize[arraydim] = stop - start; | 
					
						
							|  |  |  |       prop_subscript_ass_array_slice__float_recursive(value_items, | 
					
						
							|  |  |  |                                                       &values[arrayoffset + (start * span)], | 
					
						
							|  |  |  |                                                       totdim - arraydim, | 
					
						
							|  |  |  |                                                       &dimsize[arraydim], | 
					
						
							|  |  |  |                                                       range); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         RNA_property_float_set_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_INT: { | 
					
						
							|  |  |  |       int values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |       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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         RNA_property_int_get_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       int range[2]; | 
					
						
							|  |  |  |       RNA_property_int_range(ptr, prop, &range[0], &range[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dimsize[arraydim] = stop - start; | 
					
						
							|  |  |  |       prop_subscript_ass_array_slice__int_recursive(value_items, | 
					
						
							|  |  |  |                                                     &values[arrayoffset + (start * span)], | 
					
						
							|  |  |  |                                                     totdim - arraydim, | 
					
						
							|  |  |  |                                                     &dimsize[arraydim], | 
					
						
							|  |  |  |                                                     range); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         RNA_property_int_set_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_BOOLEAN: { | 
					
						
							|  |  |  |       bool values_stack[PYRNA_STACK_ARRAY]; | 
					
						
							|  |  |  |       bool *values = (length_flat > PYRNA_STACK_ARRAY) ? | 
					
						
							|  |  |  |                          (values_alloc = PyMem_MALLOC(sizeof(bool) * length_flat)) : | 
					
						
							|  |  |  |                          values_stack; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (start != 0 || stop != length) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Partial assignment? - need to get the array. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         RNA_property_boolean_get_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dimsize[arraydim] = stop - start; | 
					
						
							|  |  |  |       prop_subscript_ass_array_slice__bool_recursive(value_items, | 
					
						
							|  |  |  |                                                      &values[arrayoffset + (start * span)], | 
					
						
							|  |  |  |                                                      totdim - arraydim, | 
					
						
							|  |  |  |                                                      &dimsize[arraydim]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         ret = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         RNA_property_boolean_set_array(ptr, prop, values); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "not an array type"); | 
					
						
							|  |  |  |       ret = -1; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_DECREF(value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (values_alloc) { | 
					
						
							|  |  |  |     PyMem_FREE(values_alloc); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                         Py_ssize_t keynum, | 
					
						
							|  |  |  |                                         PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   len = pyrna_prop_array_length(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (keynum < 0) { | 
					
						
							|  |  |  |     keynum += len; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (keynum >= 0 && keynum < len) { | 
					
						
							|  |  |  |     return pyrna_py_to_prop_array_index(self, keynum, value); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range"); | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                           PyObject *key, | 
					
						
							|  |  |  |                                           PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   // char *keyname = NULL; /* Not supported yet. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int ret = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!RNA_property_editable_flag(&self->ptr, self->prop)) { | 
					
						
							|  |  |  |     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)); | 
					
						
							|  |  |  |     ret = -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   else if (PyIndex_Check(key)) { | 
					
						
							|  |  |  |     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); | 
					
						
							|  |  |  |     if (i == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |       ret = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       ret = prop_subscript_ass_array_int(self, i, value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PySlice_Check(key)) { | 
					
						
							|  |  |  |     Py_ssize_t len = pyrna_prop_array_length(self); | 
					
						
							|  |  |  |     Py_ssize_t start, stop, step, slicelength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) { | 
					
						
							|  |  |  |       ret = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (slicelength <= 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       ret = 0; /* Do nothing. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (step == 1) { | 
					
						
							|  |  |  |       ret = prop_subscript_ass_array_slice( | 
					
						
							|  |  |  |           &self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       ret = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int"); | 
					
						
							|  |  |  |     ret = -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (ret != -1) { | 
					
						
							|  |  |  |     if (RNA_property_update_check(self->prop)) { | 
					
						
							|  |  |  |       RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (lenfunc)pyrna_prop_array_length,              /* mp_length */ | 
					
						
							|  |  |  |     (binaryfunc)pyrna_prop_array_subscript,        /* mp_subscript */ | 
					
						
							|  |  |  |     (objobjargproc)pyrna_prop_array_ass_subscript, /* mp_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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (lenfunc)pyrna_prop_collection_length,              /* mp_length */ | 
					
						
							|  |  |  |     (binaryfunc)pyrna_prop_collection_subscript,        /* mp_subscript */ | 
					
						
							|  |  |  |     (objobjargproc)pyrna_prop_collection_ass_subscript, /* mp_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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                           /* 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 */ | 
					
						
							|  |  |  |     (inquiry)pyrna_prop_array_bool, /* nb_bool */ | 
					
						
							| 
									
										
										
										
											2010-08-27 01:50:50 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyNumberMethods pyrna_prop_collection_as_number = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                                /* 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 */ | 
					
						
							|  |  |  |     (inquiry)pyrna_prop_collection_bool, /* nb_bool */ | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return pyrna_array_contains_py(&self->ptr, self->prop, value); | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyTuple_Check(key)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Special case, for ID data-blocks. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return pyrna_prop_collection_subscript_str_lib_pair_ptr( | 
					
						
							|  |  |  |         self, key, "(id, lib) in bpy_prop_collection", false, NULL); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Key in dict style check. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     const char *keyname = _PyUnicode_AsString(key); | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { | 
					
						
							|  |  |  |       return 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-03 06:10:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group; | 
					
						
							|  |  |  |   const char *name = _PyUnicode_AsString(value); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!name) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!group) { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (lenfunc)pyrna_prop_array_length, | 
					
						
							|  |  |  |     NULL, /* sq_concat */ | 
					
						
							|  |  |  |     NULL, /* sq_repeat */ | 
					
						
							|  |  |  |     (ssizeargfunc)pyrna_prop_array_subscript_int, | 
					
						
							|  |  |  |     /* sq_item */ /* Only set this so PySequence_Check() returns True */ | 
					
						
							|  |  |  |     NULL,         /* sq_slice */ | 
					
						
							|  |  |  |     (ssizeobjargproc)prop_subscript_ass_array_int, /* sq_ass_item */ | 
					
						
							|  |  |  |     NULL,                                          /* *was* sq_ass_slice */ | 
					
						
							|  |  |  |     (objobjproc)pyrna_prop_array_contains,         /* sq_contains */ | 
					
						
							|  |  |  |     (binaryfunc)NULL,                              /* sq_inplace_concat */ | 
					
						
							|  |  |  |     (ssizeargfunc)NULL,                            /* sq_inplace_repeat */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PySequenceMethods pyrna_prop_collection_as_sequence = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (lenfunc)pyrna_prop_collection_length, | 
					
						
							|  |  |  |     NULL, /* sq_concat */ | 
					
						
							|  |  |  |     NULL, /* sq_repeat */ | 
					
						
							|  |  |  |     (ssizeargfunc)pyrna_prop_collection_subscript_int, | 
					
						
							|  |  |  |     /* sq_item */                         /* Only set this so PySequence_Check() returns True */ | 
					
						
							|  |  |  |     NULL,                                 /* *was* sq_slice */ | 
					
						
							|  |  |  |     (ssizeobjargproc)                     /* pyrna_prop_collection_ass_subscript_int */ | 
					
						
							|  |  |  |     NULL /* let mapping take this one */, /* sq_ass_item */ | 
					
						
							|  |  |  |     NULL,                                 /* *was* sq_ass_slice */ | 
					
						
							|  |  |  |     (objobjproc)pyrna_prop_collection_contains, /* sq_contains */ | 
					
						
							|  |  |  |     (binaryfunc)NULL,                           /* sq_inplace_concat */ | 
					
						
							|  |  |  |     (ssizeargfunc)NULL,                         /* sq_inplace_repeat */ | 
					
						
							| 
									
										
										
										
											2009-06-13 08:04:43 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PySequenceMethods pyrna_struct_as_sequence = { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     NULL, /* Can't set the len otherwise it can evaluate as false */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /* sq_concat */ | 
					
						
							|  |  |  |     NULL, /* sq_repeat */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     /* sq_item */                      /* Only set this so PySequence_Check() returns True */ | 
					
						
							|  |  |  |     NULL,                              /* *was* sq_slice */ | 
					
						
							|  |  |  |     NULL,                              /* sq_ass_item */ | 
					
						
							|  |  |  |     NULL,                              /* *was* sq_ass_slice */ | 
					
						
							|  |  |  |     (objobjproc)pyrna_struct_contains, /* sq_contains */ | 
					
						
							|  |  |  |     (binaryfunc)NULL,                  /* sq_inplace_concat */ | 
					
						
							|  |  |  |     (ssizeargfunc)NULL,                /* sq_inplace_repeat */ | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group, *idprop; | 
					
						
							|  |  |  |   const char *name = _PyUnicode_AsString(key); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-17 12:21:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (name == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_struct[key]: only strings are allowed as keys of ID properties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (group == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   idprop = IDP_GetPropertyFromGroup(group, name); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (idprop == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_INT(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (group == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_struct[key] = val: id properties not supported for this type"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (lenfunc)NULL,                             /* mp_length */ | 
					
						
							|  |  |  |     (binaryfunc)pyrna_struct_subscript,        /* mp_subscript */ | 
					
						
							|  |  |  |     (objobjargproc)pyrna_struct_ass_subscript, /* mp_ass_subscript */ | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_keys_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "   dictionary function of the same name).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: custom property keys.\n" | 
					
						
							|  |  |  |              "   :rtype: list of strings\n" | 
					
						
							|  |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group; | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (group == NULL) { | 
					
						
							|  |  |  |     return PyList_New(0); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return BPy_Wrap_GetKeys(group); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_items_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "   dictionary function of the same name).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: custom property key, value pairs.\n" | 
					
						
							|  |  |  |              "   :rtype: list of key, value tuples\n" | 
					
						
							|  |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | static PyObject *pyrna_struct_items(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group; | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (group == NULL) { | 
					
						
							|  |  |  |     return PyList_New(0); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   return BPy_Wrap_GetItems(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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "   dictionary function of the same name).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: custom property values.\n" | 
					
						
							|  |  |  |              "   :rtype: list\n" | 
					
						
							|  |  |  |              "\n" BPY_DOC_ID_PROP_TYPE_NOTE); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | static PyObject *pyrna_struct_values(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group; | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_struct.values(): this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (group == NULL) { | 
					
						
							|  |  |  |     return PyList_New(0); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-16 20:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   return BPy_Wrap_GetValues(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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: is_property_set(property)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Check if a property is set, use for testing operator properties.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: True when the property has been set.\n" | 
					
						
							|  |  |  |              "   :rtype: boolean\n"); | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:40 +00:00
										 |  |  | static PyObject *pyrna_struct_is_property_set(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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:is_property_set", &name)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.is_property_set(\"%.200s\") not found", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyBool_FromLong(RNA_property_is_set(&self->ptr, prop)); | 
					
						
							| 
									
										
											  
											
												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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: property_unset(property)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Unset a property, will use default value afterward.\n"); | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | static PyObject *pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:property_unset", &name)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_unset(&self->ptr, prop); | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: is_property_hidden(property)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Check if a property is hidden.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: True when the property is hidden.\n" | 
					
						
							|  |  |  |              "   :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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s.is_property_hidden(\"%.200s\") not found", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. 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"); | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | static PyObject *pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:is_property_readonly", &name)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyBool_FromLong(!RNA_property_editable(&self->ptr, prop)); | 
					
						
							| 
									
										
										
										
											2015-02-11 17:06:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_is_property_overridable_library_doc, | 
					
						
							|  |  |  |              ".. method:: is_property_overridable_library(property)\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-09-24 14:51:24 +02:00
										 |  |  |              "   Check if a property is overridable.\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-09-24 14:51:24 +02:00
										 |  |  |              "   :return: True when the property is overridable.\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s:is_property_overridable_library", &name)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyBool_FromLong((long)RNA_property_overridable_get(&self->ptr, prop)); | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   const char *name; | 
					
						
							|  |  |  |   int is_overridable; | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "sp:property_overridable_library_set", &name, &is_overridable)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-17 18:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: path_resolve(path, coerce=True)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   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" | 
					
						
							|  |  |  |              "   :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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *path; | 
					
						
							|  |  |  |   PyObject *coerce = Py_True; | 
					
						
							|  |  |  |   PointerRNA r_ptr; | 
					
						
							|  |  |  |   PropertyRNA *r_prop; | 
					
						
							|  |  |  |   int index = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_path_resolve_full(&self->ptr, path, &r_ptr, &r_prop, &index)) { | 
					
						
							|  |  |  |     if (r_prop) { | 
					
						
							|  |  |  |       if (index != -1) { | 
					
						
							|  |  |  |         if (index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) { | 
					
						
							|  |  |  |           PyErr_Format(PyExc_IndexError, | 
					
						
							|  |  |  |                        "%.200s.path_resolve(\"%.200s\") index out of range", | 
					
						
							|  |  |  |                        RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                        path); | 
					
						
							|  |  |  |           return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           return pyrna_array_index(&r_ptr, r_prop, index); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         if (coerce == Py_False) { | 
					
						
							|  |  |  |           return pyrna_prop_CreatePyObject(&r_ptr, r_prop); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           return pyrna_prop_to_py(&r_ptr, r_prop); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       return pyrna_struct_CreatePyObject(&r_ptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: path_from_id(property=\"\")\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Returns the data path from the ID to this object (string).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg property: Optional property name which can be used if the path is\n" | 
					
						
							|  |  |  |              "      to a property of this object.\n" | 
					
						
							|  |  |  |              "   :type property: string\n" | 
					
						
							|  |  |  |              "   :return: The path from :class:`bpy.types.bpy_struct.id_data`\n" | 
					
						
							|  |  |  |              "      to this struct and property (when given).\n" | 
					
						
							|  |  |  |              "   :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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *name = NULL; | 
					
						
							|  |  |  |   const char *path; | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "|s:path_from_id", &name)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (name) { | 
					
						
							|  |  |  |     prop = RNA_struct_find_property(&self->ptr, name); | 
					
						
							|  |  |  |     if (prop == NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "%.200s.path_from_id(\"%.200s\") not found", | 
					
						
							|  |  |  |                    RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                    name); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     path = RNA_path_from_ID_to_property(&self->ptr, prop); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     path = RNA_path_from_ID_to_struct(&self->ptr); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (path == NULL) { | 
					
						
							|  |  |  |     if (name) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                    "%.200s.path_from_id(\"%s\") found, but does not support path creation", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                    RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                    name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                    "%.200s.path_from_id() does not support path creation for this type", | 
					
						
							|  |  |  |                    RNA_struct_identifier(self->ptr.type)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ret = PyUnicode_FromString(path); | 
					
						
							|  |  |  |   MEM_freeN((void *)path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_path_from_id_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: path_from_id()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Returns the data path from the ID to this property (string).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: The path from :class:`bpy.types.bpy_struct.id_data` to this property.\n" | 
					
						
							|  |  |  |              "   :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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *path; | 
					
						
							|  |  |  |   PropertyRNA *prop = self->prop; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   path = RNA_path_from_ID_to_property(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (path == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "%.200s.%.200s.path_from_id() does not support path creation for this type", | 
					
						
							|  |  |  |                  RNA_struct_identifier(self->ptr.type), | 
					
						
							|  |  |  |                  RNA_property_identifier(prop)); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ret = PyUnicode_FromString(path); | 
					
						
							|  |  |  |   MEM_freeN((void *)path); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_as_bytes_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. 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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: The string as bytes.\n" | 
					
						
							|  |  |  |              "   :rtype: bytes\n"); | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyObject *ret; | 
					
						
							|  |  |  |     char buf_fixed[256], *buf; | 
					
						
							|  |  |  |     int buf_len; | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     ret = PyBytes_FromStringAndSize(buf, buf_len); | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (buf_fixed != buf) { | 
					
						
							|  |  |  |       MEM_freeN(buf); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2015-09-11 04:24:36 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_type_recast_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: type_recast()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Return a new instance, this is needed because types\n" | 
					
						
							|  |  |  |              "   such as textures can be changed at runtime.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: a new instance of this object with the type initialized again.\n" | 
					
						
							|  |  |  |              "   :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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_pointer_recast(&self->ptr, &r_ptr); | 
					
						
							|  |  |  |   return pyrna_struct_CreatePyObject(&r_ptr); | 
					
						
							| 
									
										
										
										
											2010-04-10 18:35:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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-07 23:53:02 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_py_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. classmethod:: bl_rna_get_subclass_py(id, default=None)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg id: The RNA type identifier.\n" | 
					
						
							|  |  |  |              "   :type id: string\n" | 
					
						
							|  |  |  |              "   :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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   char *id; | 
					
						
							|  |  |  |   PyObject *ret_default = Py_None; | 
					
						
							| 
									
										
										
										
											2017-09-07 23:53:02 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass_py", &id, &ret_default)) { | 
					
						
							|  |  |  |     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-07 23:53:02 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. 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"); | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   char *id; | 
					
						
							|  |  |  |   PyObject *ret_default = Py_None; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass", &id, &ret_default)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   if (srna_base == &RNA_Node) { | 
					
						
							|  |  |  |     bNodeType *nt = nodeTypeFind(id); | 
					
						
							|  |  |  |     if (nt) { | 
					
						
							|  |  |  |       RNA_pointer_create(NULL, &RNA_Struct, nt->ext.srna, &ptr); | 
					
						
							|  |  |  |       return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* TODO, panels, menus etc. */ | 
					
						
							|  |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_ValueError, "Class type \"%.200s\" not supported", RNA_struct_identifier(srna_base)); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return Py_INCREF_RET(ret_default); | 
					
						
							| 
									
										
										
										
											2017-09-09 22:35:33 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  | static void pyrna_dir_members_py__add_keys(PyObject *list, PyObject *dict) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *list_tmp; | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   list_tmp = PyDict_Keys(dict); | 
					
						
							|  |  |  |   PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp); | 
					
						
							|  |  |  |   Py_DECREF(list_tmp); | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | static void pyrna_dir_members_py(PyObject *list, PyObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *dict; | 
					
						
							|  |  |  |   PyObject **dict_ptr; | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   dict_ptr = _PyObject_GetDictPtr((PyObject *)self); | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (dict_ptr && (dict = *dict_ptr)) { | 
					
						
							|  |  |  |     pyrna_dir_members_py__add_keys(list, dict); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   dict = ((PyTypeObject *)Py_TYPE(self))->tp_dict; | 
					
						
							|  |  |  |   if (dict) { | 
					
						
							|  |  |  |     pyrna_dir_members_py__add_keys(list, dict); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-20 03:13:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Since this is least common case, handle it last. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (BPy_PropertyRNA_Check(self)) { | 
					
						
							|  |  |  |     BPy_PropertyRNA *self_prop = (BPy_PropertyRNA *)self; | 
					
						
							|  |  |  |     if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) { | 
					
						
							|  |  |  |       PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2012-04-11 10:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       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); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *idname; | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* For looping over attrs and funcs. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA tptr; | 
					
						
							|  |  |  |   PropertyRNA *iterprop; | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr); | 
					
						
							|  |  |  |     iterprop = RNA_struct_find_property(&tptr, "functions"); | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     RNA_PROP_BEGIN (&tptr, itemptr, iterprop) { | 
					
						
							|  |  |  |       FunctionRNA *func = itemptr.data; | 
					
						
							|  |  |  |       if (RNA_function_defined(func)) { | 
					
						
							|  |  |  |         idname = RNA_function_identifier(itemptr.data); | 
					
						
							|  |  |  |         PyList_APPEND(list, PyUnicode_FromString(idname)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     RNA_PROP_END; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Collect RNA attributes | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     char name[256], *nameptr; | 
					
						
							|  |  |  |     int namelen; | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     iterprop = RNA_struct_iterator_property(ptr->type); | 
					
						
							| 
									
										
										
										
											2009-03-05 12:09:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     RNA_PROP_BEGIN (ptr, itemptr, iterprop) { | 
					
						
							|  |  |  |       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							| 
									
										
										
										
											2009-06-24 14:03:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (nameptr) { | 
					
						
							|  |  |  |         PyList_APPEND(list, PyUnicode_FromStringAndSize(nameptr, namelen)); | 
					
						
							| 
									
										
										
										
											2009-11-13 16:08:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (name != nameptr) { | 
					
						
							|  |  |  |           MEM_freeN(nameptr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     RNA_PROP_END; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2009-11-11 17:12:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!BPy_StructRNA_CheckExact(self)) { | 
					
						
							|  |  |  |     pyrna_dir_members_py(ret, (PyObject *)self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   pyrna_dir_members_rna(ret, &self->ptr); | 
					
						
							| 
									
										
										
										
											2009-06-20 14:55:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->ptr.type == &RNA_Context) { | 
					
						
							|  |  |  |     ListBase lb = CTX_data_dir_get(self->ptr.data); | 
					
						
							|  |  |  |     LinkData *link; | 
					
						
							| 
									
										
										
										
											2009-06-20 14:55:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     for (link = lb.first; link; link = link->next) { | 
					
						
							|  |  |  |       PyList_APPEND(ret, PyUnicode_FromString(link->data)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-20 14:55:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     BLI_freelistN(&lb); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *set = PySet_New(ret); | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     Py_DECREF(ret); | 
					
						
							|  |  |  |     ret = PySequence_List(set); | 
					
						
							|  |  |  |     Py_DECREF(set); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-27 06:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *name = _PyUnicode_AsString(pyname); | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   FunctionRNA *func; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (name == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string"); | 
					
						
							|  |  |  |     ret = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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-17 06:17:24 +02:00
										 |  |  |     if (STR_ELEM(name, "__getitem__", "__setitem__") && | 
					
						
							|  |  |  |         !RNA_struct_idprops_check(self->ptr.type)) { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type"); | 
					
						
							|  |  |  |       ret = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if ((prop = RNA_struct_find_property(&self->ptr, name))) { | 
					
						
							|  |  |  |     ret = pyrna_prop_to_py(&self->ptr, prop); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* RNA function only if callback is declared (no optional functions). */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) { | 
					
						
							|  |  |  |     ret = pyrna_func_to_py(&self->ptr, func); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (self->ptr.type == &RNA_Context) { | 
					
						
							|  |  |  |     bContext *C = self->ptr.data; | 
					
						
							|  |  |  |     if (C == NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", | 
					
						
							|  |  |  |                    name); | 
					
						
							|  |  |  |       ret = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       PointerRNA newptr; | 
					
						
							|  |  |  |       ListBase newlb; | 
					
						
							|  |  |  |       short newtype; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       if (done == 1) { /* Found. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         switch (newtype) { | 
					
						
							|  |  |  |           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: { | 
					
						
							|  |  |  |             CollectionPointerLink *link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ret = PyList_New(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (link = newlb.first; link; link = link->next) { | 
					
						
							|  |  |  |               PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           default: | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Should never happen. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             BLI_assert(!"Invalid context type"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                          "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context", | 
					
						
							|  |  |  |                          newtype, | 
					
						
							|  |  |  |                          name); | 
					
						
							|  |  |  |             ret = NULL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       else if (done == -1) { /* Found, but not set. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         ret = Py_None; | 
					
						
							|  |  |  |         Py_INCREF(ret); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       BLI_freelistN(&newlb); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* The error raised here will be displayed */ | 
					
						
							|  |  |  |     ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2008-11-29 17:58:17 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *dict = *(_PyObject_GetDictPtr((PyObject *)self)); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |   if (UNLIKELY(dict == NULL)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-19 18:22:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyDict_Contains(dict, pyname); | 
					
						
							| 
									
										
										
										
											2009-11-19 18:22:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | /* --------------- setattr------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2014-01-28 03:52:21 +11:00
										 |  |  | static bool pyrna_is_deferred_prop(const PyObject *value) | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value) == 2 && | 
					
						
							|  |  |  |          PyCFunction_Check(PyTuple_GET_ITEM(value, 0)) && | 
					
						
							|  |  |  |          PyDict_CheckExact(PyTuple_GET_ITEM(value, 1)); | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret = PyType_Type.tp_getattro(cls, attr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Allows:
 | 
					
						
							|  |  |  |    * >>> bpy.types.Scene.foo = BoolProperty() | 
					
						
							|  |  |  |    * >>> bpy.types.Scene.foo | 
					
						
							|  |  |  |    * <bpy_struct, BoolProperty("foo")> | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |    * ...rather than returning the deferred class register tuple | 
					
						
							|  |  |  |    * as checked by pyrna_is_deferred_prop() | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  if 0
 | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |   if ((ret == NULL)  /* || pyrna_is_deferred_prop(ret) */ ) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     StructRNA *srna = srna_from_self(cls, "StructRNA.__getattr__"); | 
					
						
							|  |  |  |     if (srna) { | 
					
						
							|  |  |  |       PropertyRNA *prop = RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)); | 
					
						
							|  |  |  |       if (prop) { | 
					
						
							|  |  |  |         PointerRNA tptr; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         PyErr_Clear(); /* Clear error from tp_getattro. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         RNA_pointer_create(NULL, &RNA_Property, prop, &tptr); | 
					
						
							|  |  |  |         ret = pyrna_struct_CreatePyObject(&tptr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   StructRNA *srna = srna_from_self(cls, "StructRNA.__setattr__"); | 
					
						
							|  |  |  |   const bool is_deferred_prop = (value && pyrna_is_deferred_prop(value)); | 
					
						
							|  |  |  |   const char *attr_str = _PyUnicode_AsString(attr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (srna && !pyrna_write_check() && | 
					
						
							|  |  |  |       (is_deferred_prop || RNA_struct_type_find_property(srna, attr_str))) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "pyrna_struct_meta_idprop_setattro() " | 
					
						
							|  |  |  |                  "can't set in readonly state '%.200s.%S'", | 
					
						
							|  |  |  |                  ((PyTypeObject *)cls)->tp_name, | 
					
						
							|  |  |  |                  attr); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (value && is_deferred_prop) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'", | 
					
						
							|  |  |  |                    ((PyTypeObject *)cls)->tp_name); | 
					
						
							|  |  |  |       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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyErr_Clear(); | 
					
						
							|  |  |  |     return PyType_Type.tp_setattro(cls, attr, value); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (value) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Check if the value is a property. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (is_deferred_prop) { | 
					
						
							|  |  |  |       int ret = deferred_register_prop(srna, attr, value); | 
					
						
							|  |  |  |       if (ret == -1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Error set. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         return ret; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* 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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { /* __delattr__ */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* First find if this is a registered property. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     const int ret = RNA_def_property_free_identifier(srna, attr_str); | 
					
						
							|  |  |  |     if (ret == -1) { | 
					
						
							|  |  |  |       PyErr_Format( | 
					
						
							|  |  |  |           PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Fallback to standard py, delattr/setattr. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *name = _PyUnicode_AsString(pyname); | 
					
						
							|  |  |  |   PropertyRNA *prop = NULL; | 
					
						
							| 
									
										
										
										
											2010-06-14 02:05:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (name == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) { | 
					
						
							|  |  |  |     if (!RNA_property_editable_flag(&self->ptr, prop)) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", | 
					
						
							|  |  |  |                    RNA_property_identifier(prop), | 
					
						
							|  |  |  |                    RNA_struct_identifier(self->ptr.type)); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     bContext *C = self->ptr.data; | 
					
						
							|  |  |  |     if (C == NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                    "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", | 
					
						
							|  |  |  |                    name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       PointerRNA newptr; | 
					
						
							|  |  |  |       ListBase newlb; | 
					
						
							|  |  |  |       short newtype; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (done == 1) { | 
					
						
							|  |  |  |         PyErr_Format( | 
					
						
							|  |  |  |             PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name); | 
					
						
							|  |  |  |         BLI_freelistN(&newlb); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       BLI_freelistN(&newlb); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* pyrna_py_to_prop sets its own exceptions */ | 
					
						
							|  |  |  |   if (prop) { | 
					
						
							|  |  |  |     if (value == NULL) { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported"); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!BPy_PropertyRNA_CheckExact(self)) { | 
					
						
							|  |  |  |     pyrna_dir_members_py(ret, (PyObject *)self); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_type(self->prop) == PROP_COLLECTION) { | 
					
						
							|  |  |  |     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							|  |  |  |       pyrna_dir_members_rna(ret, &r_ptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-11-20 10:00:54 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *name = _PyUnicode_AsString(pyname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (name == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (name[0] != '_') { | 
					
						
							|  |  |  |     PyObject *ret; | 
					
						
							|  |  |  |     PropertyRNA *prop; | 
					
						
							|  |  |  |     FunctionRNA *func; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PointerRNA r_ptr; | 
					
						
							|  |  |  |     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							|  |  |  |       if ((prop = RNA_struct_find_property(&r_ptr, name))) { | 
					
						
							|  |  |  |         ret = pyrna_prop_to_py(&r_ptr, prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if ((func = RNA_struct_find_function(r_ptr.type, name))) { | 
					
						
							|  |  |  |         PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr); | 
					
						
							|  |  |  |         ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); | 
					
						
							|  |  |  |         Py_DECREF(self_collection); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     /* Could just do this except for 1 awkward case.
 | 
					
						
							|  |  |  |      * PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							|  |  |  |      * so as to support 'bpy.data.library.load()' | 
					
						
							|  |  |  |      * note, this _only_ supports static methods */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     if (ret == NULL && name[0] != '_') { /* Avoid inheriting __call__ and similar. */ | 
					
						
							|  |  |  |       /* Since this is least common case, handle it last. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PointerRNA r_ptr; | 
					
						
							|  |  |  |       if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							|  |  |  |         PyObject *cls; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         PyObject *error_type, *error_value, *error_traceback; | 
					
						
							|  |  |  |         PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cls = pyrna_struct_Subtype(&r_ptr); | 
					
						
							|  |  |  |         ret = PyObject_GenericGetAttr(cls, pyname); | 
					
						
							|  |  |  |         Py_DECREF(cls); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Restore the original error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (ret == NULL) { | 
					
						
							|  |  |  |           PyErr_Restore(error_type, error_value, error_traceback); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-12 14:32:30 +00:00
										 |  |  | #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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *name = _PyUnicode_AsString(pyname); | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (name == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (value == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { | 
					
						
							|  |  |  |     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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name); | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA r_ptr; | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_property_collection_add(&self->ptr, self->prop, &r_ptr); | 
					
						
							|  |  |  |   if (!r_ptr.data) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_collection.add(): not supported for this collection"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (key == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!RNA_property_collection_remove(&self->ptr, self->prop, key)) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_collection.remove() not supported for this collection"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-11 16:28:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_collection_clear(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2012-04-02 11:28:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2012-04-02 11:28:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* USE_PEDANTIC_WRITE */
 | 
					
						
							| 
									
										
										
										
											2012-10-30 03:05:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "ii", &key, &pos)) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!RNA_property_collection_move(&self->ptr, self->prop, key, pos)) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                     "bpy_prop_collection.move() not supported for this collection"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-03-10 20:54:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "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) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PointerRNA id_ptr; | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |     RNA_id_pointer_create((ID *)self->ptr.owner_id, &id_ptr); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return pyrna_struct_CreatePyObject(&id_ptr); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-12-13 10:46:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2009-12-13 10:46:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_get_data_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return pyrna_struct_CreatePyObject(&self->ptr); | 
					
						
							| 
									
										
										
										
											2011-10-13 00:52:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA tptr; | 
					
						
							|  |  |  |   RNA_pointer_create(NULL, &RNA_Property, self->prop, &tptr); | 
					
						
							|  |  |  |   return pyrna_struct_Subtype(&tptr); | 
					
						
							| 
									
										
										
										
											2011-10-09 02:11:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |      (getter)pyrna_struct_get_id_data, | 
					
						
							|  |  |  |      (setter)NULL, | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |      pyrna_struct_get_id_data_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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}, | 
					
						
							|  |  |  |     {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", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |      (getter)pyrna_struct_get_id_data, | 
					
						
							|  |  |  |      (setter)NULL, | 
					
						
							| 
									
										
										
										
											2019-12-20 10:42:57 +11:00
										 |  |  |      pyrna_struct_get_id_data_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |      NULL}, | 
					
						
							|  |  |  |     {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}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_keys_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: keys()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Return the identifiers of collection members\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matching Python's dict.keys() functionality).\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: the identifiers for each member of this collection.\n" | 
					
						
							|  |  |  |              "   :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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret = PyList_New(0); | 
					
						
							|  |  |  |   char name[256], *nameptr; | 
					
						
							|  |  |  |   int namelen; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							|  |  |  |     nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							| 
									
										
										
										
											2009-06-24 14:03:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (nameptr) { | 
					
						
							|  |  |  |       PyList_APPEND(ret, PyUnicode_FromStringAndSize(nameptr, namelen)); | 
					
						
							| 
									
										
										
										
											2010-02-23 11:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (name != nameptr) { | 
					
						
							|  |  |  |         MEM_freeN(nameptr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_items_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: items()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Return the identifiers of collection members\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matching Python's dict.items() functionality).\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret = PyList_New(0); | 
					
						
							|  |  |  |   PyObject *item; | 
					
						
							|  |  |  |   char name[256], *nameptr; | 
					
						
							|  |  |  |   int namelen; | 
					
						
							|  |  |  |   int i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							|  |  |  |     if (itemptr.data) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Add to Python list. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       item = PyTuple_New(2); | 
					
						
							|  |  |  |       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							|  |  |  |       if (nameptr) { | 
					
						
							|  |  |  |         PyTuple_SET_ITEM(item, 0, PyUnicode_FromStringAndSize(nameptr, namelen)); | 
					
						
							|  |  |  |         if (name != nameptr) { | 
					
						
							|  |  |  |           MEM_freeN(nameptr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* A bit strange, but better then returning an empty list. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         PyTuple_SET_ITEM(item, 0, PyLong_FromLong(i)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       PyList_APPEND(ret, item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       i++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_values_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: values()\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Return the values of collection\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   (matching Python's dict.values() functionality).\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: get(key, default=None)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group, *idprop; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *key; | 
					
						
							|  |  |  |   PyObject *def = Py_None; | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Mostly copied from BPy_IDGroup_Map_GetItem. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							|  |  |  |   if (group) { | 
					
						
							|  |  |  |     idprop = IDP_GetPropertyFromGroup(group, key); | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (idprop) { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |       return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-23 23:17:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. 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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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); | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   IDProperty *group, *idprop; | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *key; | 
					
						
							|  |  |  |   PyObject *def = NULL; | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_STRUCT_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Mostly copied from BPy_IDGroup_Map_GetItem. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_idprops_check(self->ptr.type) == 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   group = RNA_struct_idprops(&self->ptr, 0); | 
					
						
							|  |  |  |   if (group) { | 
					
						
							|  |  |  |     idprop = IDP_GetPropertyFromGroup(group, key); | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (idprop) { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |       PyObject *ret = BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       IDP_RemoveFromGroup(group, idprop); | 
					
						
							|  |  |  |       return ret; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (def == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_KeyError, "key not found"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Py_INCREF_RET(def); | 
					
						
							| 
									
										
										
										
											2018-05-05 09:53:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_struct_as_pointer_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :return: int (memory address).\n" | 
					
						
							|  |  |  |              "   :rtype: int\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   .. 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: get(key, default=None)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg key: The identifier for the collection member.\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"); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA newptr; | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *key_ob; | 
					
						
							|  |  |  |   PyObject *def = Py_None; | 
					
						
							| 
									
										
										
										
											2009-07-09 08:06:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!PyArg_ParseTuple(args, "O|O:get", &key_ob, &def)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyUnicode_Check(key_ob)) { | 
					
						
							|  |  |  |     const char *key = _PyUnicode_AsString(key_ob); | 
					
						
							| 
									
										
										
										
											2011-11-17 08:47:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (RNA_property_collection_lookup_string(&self->ptr, self->prop, key, &newptr)) { | 
					
						
							|  |  |  |       return pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyTuple_Check(key_ob)) { | 
					
						
							|  |  |  |     PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair( | 
					
						
							|  |  |  |         self, key_ob, "bpy_prop_collection.get((id, lib))", false); | 
					
						
							|  |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. 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" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg key: The identifier for the collection member.\n" | 
					
						
							|  |  |  |              "   :type key: string\n" | 
					
						
							|  |  |  |              "   :return: index of the key.\n" | 
					
						
							|  |  |  |              "   :rtype: int\n"); | 
					
						
							| 
									
										
										
										
											2012-01-05 06:05:45 +00:00
										 |  |  | static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_ssize_t key_len_ssize_t; | 
					
						
							|  |  |  |   const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   const int key_len = (int)key_len_ssize_t; /* Comare with same type. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   char name[256], *nameptr; | 
					
						
							|  |  |  |   int namelen; | 
					
						
							|  |  |  |   int i = 0; | 
					
						
							|  |  |  |   int index = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							|  |  |  |     nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (nameptr) { | 
					
						
							|  |  |  |       if ((key_len == namelen) && memcmp(nameptr, key, key_len) == 0) { | 
					
						
							|  |  |  |         index = i; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (name != nameptr) { | 
					
						
							|  |  |  |         MEM_freeN(nameptr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return PyLong_FromLong(index); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool foreach_attr_type(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                               const char *attr, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                               /* Values to assign. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                               RawPropertyType *raw_type, | 
					
						
							|  |  |  |                               int *attr_tot, | 
					
						
							|  |  |  |                               bool *attr_signed) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   bool attr_ok = true; | 
					
						
							|  |  |  |   *raw_type = PROP_RAW_UNSET; | 
					
						
							|  |  |  |   *attr_tot = 0; | 
					
						
							|  |  |  |   *attr_signed = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Note: this is fail with zero length lists, so don't let this get caled in that case. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							|  |  |  |     prop = RNA_struct_find_property(&itemptr, attr); | 
					
						
							|  |  |  |     if (prop) { | 
					
						
							|  |  |  |       *raw_type = RNA_property_raw_type(prop); | 
					
						
							|  |  |  |       *attr_tot = RNA_property_array_length(&itemptr, prop); | 
					
						
							|  |  |  |       *attr_signed = (RNA_property_subtype(prop) != PROP_UNSIGNED); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       attr_ok = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int foreach_parse_args(BPy_PropertyRNA *self, | 
					
						
							|  |  |  |                               PyObject *args, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                               /* Values to assign. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                               const char **attr, | 
					
						
							|  |  |  |                               PyObject **seq, | 
					
						
							|  |  |  |                               int *tot, | 
					
						
							|  |  |  |                               int *size, | 
					
						
							|  |  |  |                               RawPropertyType *raw_type, | 
					
						
							|  |  |  |                               int *attr_tot, | 
					
						
							|  |  |  |                               bool *attr_signed) | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int array_tot; | 
					
						
							|  |  |  |   int target_tot; | 
					
						
							| 
									
										
										
										
											2009-07-01 13:31:36 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   *size = *attr_tot = 0; | 
					
						
							|  |  |  |   *attr_signed = false; | 
					
						
							|  |  |  |   *raw_type = PROP_RAW_UNSET; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "sO:foreach_get/set", attr, seq)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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 -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* TODO - buffer may not be a sequence! array.array() is though. */ | 
					
						
							|  |  |  |   *tot = PySequence_Size(*seq); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (*tot > 0) { | 
					
						
							|  |  |  |     if (!foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed)) { | 
					
						
							|  |  |  |       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), | 
					
						
							|  |  |  |                    *attr); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     *size = RNA_raw_type_sizeof(*raw_type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if ((*attr_tot) < 1) { | 
					
						
							|  |  |  |       *attr_tot = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (RNA_property_type(self->prop) == PROP_COLLECTION) { | 
					
						
							|  |  |  |       array_tot = RNA_property_collection_length(&self->ptr, self->prop); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       array_tot = RNA_property_array_length(&self->ptr, self->prop); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     target_tot = array_tot * (*attr_tot); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* rna_access.c - rna_raw_access(...) uses this same method. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (target_tot != (*tot)) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "foreach_get(attr, sequence) sequence length mismatch given %d, needed %d", | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |                    *tot, | 
					
						
							|  |  |  |                    target_tot); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Check 'attr_tot' otherwise we don't know if any values were set.
 | 
					
						
							|  |  |  |    * This isn't ideal because it means running on an empty list may | 
					
						
							|  |  |  |    * fail silently when it's not compatible. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (*size == 0 && *attr_tot != 0) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "attribute does not support foreach method"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   char f = format ? *format : 'B'; /* B is assumed when not set */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (raw_type) { | 
					
						
							|  |  |  |     case PROP_RAW_CHAR: | 
					
						
							|  |  |  |       if (attr_signed) { | 
					
						
							|  |  |  |         return (f == 'b') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return (f == 'B') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case PROP_RAW_SHORT: | 
					
						
							|  |  |  |       if (attr_signed) { | 
					
						
							|  |  |  |         return (f == 'h') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return (f == 'H') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case PROP_RAW_INT: | 
					
						
							|  |  |  |       if (attr_signed) { | 
					
						
							|  |  |  |         return (f == 'i') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return (f == 'I') ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case PROP_RAW_BOOLEAN: | 
					
						
							|  |  |  |       return (f == '?') ? 1 : 0; | 
					
						
							|  |  |  |     case PROP_RAW_FLOAT: | 
					
						
							|  |  |  |       return (f == 'f') ? 1 : 0; | 
					
						
							|  |  |  |     case PROP_RAW_DOUBLE: | 
					
						
							|  |  |  |       return (f == 'd') ? 1 : 0; | 
					
						
							|  |  |  |     case PROP_RAW_UNSET: | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *item = NULL; | 
					
						
							|  |  |  |   int i = 0, ok = 0; | 
					
						
							|  |  |  |   bool buffer_is_compat; | 
					
						
							|  |  |  |   void *array = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Get/set both take the same args currently. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *attr; | 
					
						
							|  |  |  |   PyObject *seq; | 
					
						
							|  |  |  |   int tot, size, attr_tot; | 
					
						
							|  |  |  |   bool attr_signed; | 
					
						
							|  |  |  |   RawPropertyType raw_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (foreach_parse_args( | 
					
						
							|  |  |  |           self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (tot == 0) { | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   if (set) { /* Get the array from python. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     buffer_is_compat = false; | 
					
						
							|  |  |  |     if (PyObject_CheckBuffer(seq)) { | 
					
						
							|  |  |  |       Py_buffer buf; | 
					
						
							|  |  |  |       PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Check if the buffer matches. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (buffer_is_compat) { | 
					
						
							|  |  |  |         ok = RNA_property_collection_raw_set( | 
					
						
							|  |  |  |             NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       PyBuffer_Release(&buf); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Could not use the buffer, fallback to sequence. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (!buffer_is_compat) { | 
					
						
							|  |  |  |       array = PyMem_Malloc(size * tot); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (; i < tot; i++) { | 
					
						
							|  |  |  |         item = PySequence_GetItem(seq, i); | 
					
						
							|  |  |  |         switch (raw_type) { | 
					
						
							|  |  |  |           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; | 
					
						
							|  |  |  |           case PROP_RAW_BOOLEAN: | 
					
						
							|  |  |  |             ((bool *)array)[i] = (int)PyLong_AsLong(item) != 0; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             BLI_assert(!"Invalid array type - set"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ok = RNA_property_collection_raw_set( | 
					
						
							|  |  |  |           NULL, &self->ptr, self->prop, attr, array, raw_type, tot); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     buffer_is_compat = false; | 
					
						
							|  |  |  |     if (PyObject_CheckBuffer(seq)) { | 
					
						
							|  |  |  |       Py_buffer buf; | 
					
						
							|  |  |  |       PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Check if the buffer matches, TODO - signed/unsigned types. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (buffer_is_compat) { | 
					
						
							|  |  |  |         ok = RNA_property_collection_raw_get( | 
					
						
							|  |  |  |             NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       PyBuffer_Release(&buf); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Could not use the buffer, fallback to sequence. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (!buffer_is_compat) { | 
					
						
							|  |  |  |       array = PyMem_Malloc(size * tot); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ok = RNA_property_collection_raw_get( | 
					
						
							|  |  |  |           NULL, &self->ptr, self->prop, attr, array, raw_type, tot); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!ok) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Skip the loop. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         i = tot; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (; i < tot; i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (raw_type) { | 
					
						
							|  |  |  |           case PROP_RAW_CHAR: | 
					
						
							|  |  |  |             item = PyLong_FromLong((long)((char *)array)[i]); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_SHORT: | 
					
						
							|  |  |  |             item = PyLong_FromLong((long)((short *)array)[i]); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_RAW_INT: | 
					
						
							|  |  |  |             item = PyLong_FromLong((long)((int *)array)[i]); | 
					
						
							|  |  |  |             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; | 
					
						
							|  |  |  |           case PROP_RAW_BOOLEAN: | 
					
						
							|  |  |  |             item = PyBool_FromLong((long)((bool *)array)[i]); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           default: /* PROP_RAW_UNSET */ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |             /* Should never happen. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             BLI_assert(!"Invalid array type - get"); | 
					
						
							|  |  |  |             item = Py_None; | 
					
						
							|  |  |  |             Py_INCREF(item); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         PySequence_SetItem(seq, i, item); | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (array) { | 
					
						
							|  |  |  |     PyMem_Free(array); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Maybe we could make our own error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyErr_Print(); | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!ok) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_RuntimeError, "internal error setting the array"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_foreach_get_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: foreach_get(attr, seq)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return foreach_getset(self, args, 0); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_prop_collection_foreach_set_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: foreach_set(attr, seq)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ(self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return foreach_getset(self, args, 1); | 
					
						
							| 
									
										
										
										
											2009-06-30 12:52:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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; | 
					
						
							|  |  |  |   PropertyType prop_type = RNA_property_type(self->prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Get/set both take the same args currently. */ | 
					
						
							|  |  |  |   PyObject *seq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (prop_type != PROP_INT && prop_type != PROP_FLOAT) { | 
					
						
							|  |  |  |     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. */ | 
					
						
							|  |  |  |         BLI_assert(false); | 
					
						
							|  |  |  |         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 { | 
					
						
							|  |  |  |     char f = buf.format ? buf.format[0] : 0; | 
					
						
							|  |  |  |     if ((prop_type == PROP_INT && (buf.itemsize != sizeof(int) || (f != 'l' && f != 'i'))) || | 
					
						
							|  |  |  |         (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. */ | 
					
						
							|  |  |  |         BLI_assert(false); | 
					
						
							|  |  |  |         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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   PyObject *iter = NULL; | 
					
						
							|  |  |  |   int len; | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); | 
					
						
							| 
									
										
										
										
											2011-02-28 22:56:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* we know this is a list so no need to PyIter_Check
 | 
					
						
							|  |  |  |    * otherwise it could be NULL (unlikely) if conversion failed */ | 
					
						
							|  |  |  |   if (ret) { | 
					
						
							|  |  |  |     iter = PyObject_GetIter(ret); | 
					
						
							|  |  |  |     Py_DECREF(ret); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return iter; | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   PyObject *iter = NULL; | 
					
						
							|  |  |  |   ret = pyrna_prop_collection_values(self); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* we know this is a list so no need to PyIter_Check
 | 
					
						
							|  |  |  |    * otherwise it could be NULL (unlikely) if conversion failed */ | 
					
						
							|  |  |  |   if (ret) { | 
					
						
							|  |  |  |     iter = PyObject_GetIter(ret); | 
					
						
							|  |  |  |     Py_DECREF(ret); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-09 19:22:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {"get", (PyCFunction)pyrna_struct_get, METH_VARARGS, pyrna_struct_get_doc}, | 
					
						
							|  |  |  |     {"pop", (PyCFunction)pyrna_struct_pop, METH_VARARGS, pyrna_struct_pop_doc}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, pyrna_struct_as_pointer_doc}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* bpy_rna_anim.c */ | 
					
						
							|  |  |  |     {"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}, | 
					
						
							|  |  |  |     {"driver_add", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_driver_add, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_driver_add_doc}, | 
					
						
							|  |  |  |     {"driver_remove", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_driver_remove, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_driver_remove_doc}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {"is_property_set", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_is_property_set, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_is_property_set_doc}, | 
					
						
							|  |  |  |     {"property_unset", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_property_unset, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_property_unset_doc}, | 
					
						
							|  |  |  |     {"is_property_hidden", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_is_property_hidden, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_is_property_hidden_doc}, | 
					
						
							|  |  |  |     {"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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |      METH_VARARGS, | 
					
						
							| 
									
										
										
										
											2019-06-14 23:16:04 +02:00
										 |  |  |      pyrna_struct_property_overridable_library_set_doc}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"path_resolve", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_path_resolve, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_path_resolve_doc}, | 
					
						
							|  |  |  |     {"path_from_id", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_path_from_id, | 
					
						
							|  |  |  |      METH_VARARGS, | 
					
						
							|  |  |  |      pyrna_struct_path_from_id_doc}, | 
					
						
							|  |  |  |     {"type_recast", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_type_recast, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_struct_type_recast_doc}, | 
					
						
							|  |  |  |     {"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}, | 
					
						
							|  |  |  |     {"bl_rna_get_subclass", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_struct_bl_rna_get_subclass, | 
					
						
							|  |  |  |      METH_VARARGS | METH_CLASS, | 
					
						
							|  |  |  |      pyrna_struct_bl_rna_get_subclass_doc}, | 
					
						
							|  |  |  |     {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* experimental */ | 
					
						
							|  |  |  | /* unused for now */ | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | #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-04-17 06:17:24 +02: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[] = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"path_from_id", | 
					
						
							|  |  |  |      (PyCFunction)pyrna_prop_path_from_id, | 
					
						
							|  |  |  |      METH_NOARGS, | 
					
						
							|  |  |  |      pyrna_prop_path_from_id_doc}, | 
					
						
							|  |  |  |     {"as_bytes", (PyCFunction)pyrna_prop_as_bytes, METH_NOARGS, pyrna_prop_as_bytes_doc}, | 
					
						
							|  |  |  |     {"update", (PyCFunction)pyrna_prop_update, METH_NOARGS, pyrna_prop_update_doc}, | 
					
						
							|  |  |  |     {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL}, | 
					
						
							|  |  |  |     {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-04-17 06:17:24 +02: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[] = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {"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}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc}, | 
					
						
							|  |  |  |     {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc}, | 
					
						
							|  |  |  |     {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[] = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"add", (PyCFunction)pyrna_prop_collection_idprop_add, METH_NOARGS, NULL}, | 
					
						
							|  |  |  |     {"remove", (PyCFunction)pyrna_prop_collection_idprop_remove, METH_O, NULL}, | 
					
						
							|  |  |  |     {"clear", (PyCFunction)pyrna_prop_collection_idprop_clear, METH_NOARGS, NULL}, | 
					
						
							|  |  |  |     {"move", (PyCFunction)pyrna_prop_collection_idprop_move, METH_VARARGS, NULL}, | 
					
						
							|  |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 16:59:18 +00:00
										 |  |  | /* only needed for subtyping, 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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyTuple_GET_SIZE(args) == 1) { | 
					
						
							|  |  |  |     BPy_StructRNA *base = (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0); | 
					
						
							|  |  |  |     if (Py_TYPE(base) == type) { | 
					
						
							|  |  |  |       Py_INCREF(base); | 
					
						
							|  |  |  |       return (PyObject *)base; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) { | 
					
						
							|  |  |  |       /* 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: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |        * | 
					
						
							|  |  |  |        *  >>> class MyObSubclass(bpy.types.Object): | 
					
						
							|  |  |  |        *  ...     def test_func(self): | 
					
						
							|  |  |  |        *  ...         print(100) | 
					
						
							|  |  |  |        *  ... | 
					
						
							|  |  |  |        *  >>> myob = MyObSubclass(bpy.context.object) | 
					
						
							|  |  |  |        *  >>> myob.test_func() | 
					
						
							|  |  |  |        *  100 | 
					
						
							|  |  |  |        * | 
					
						
							|  |  |  |        * Keep this since it could be useful. | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       BPy_StructRNA *ret; | 
					
						
							|  |  |  |       if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) { | 
					
						
							|  |  |  |         ret->ptr = base->ptr; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Pass on exception & NULL if tp_alloc fails. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       return (PyObject *)ret; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Error, invalid type given. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", | 
					
						
							|  |  |  |                  type->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-01 16:59:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* only needed for subtyping, 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)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *base; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "O!:bpy_prop.__new__", &pyrna_prop_Type, &base)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (type == Py_TYPE(base)) { | 
					
						
							|  |  |  |     return Py_INCREF_RET((PyObject *)base); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyType_IsSubtype(type, &pyrna_prop_Type)) { | 
					
						
							|  |  |  |     BPy_PropertyRNA *ret = (BPy_PropertyRNA *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  |     ret->ptr = base->ptr; | 
					
						
							|  |  |  |     ret->prop = base->prop; | 
					
						
							|  |  |  |     return (PyObject *)ret; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   const int type = RNA_property_type(prop); | 
					
						
							|  |  |  |   const int flag = RNA_property_flag(prop); | 
					
						
							|  |  |  |   const int flag_parameter = RNA_parameter_flag(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_property_array_check(prop)) { | 
					
						
							|  |  |  |     int a, len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (flag & PROP_DYNAMIC) { | 
					
						
							|  |  |  |       ParameterDynAlloc *data_alloc = data; | 
					
						
							|  |  |  |       len = data_alloc->array_tot; | 
					
						
							|  |  |  |       data = data_alloc->array; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       len = RNA_property_array_length(ptr, prop); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Resolve the array from a new pytype. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* TODO(Kazanbas) make multi-dimensional sequences here. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (type) { | 
					
						
							|  |  |  |       case PROP_BOOLEAN: | 
					
						
							|  |  |  |         ret = PyTuple_New(len); | 
					
						
							|  |  |  |         for (a = 0; a < len; a++) { | 
					
						
							|  |  |  |           PyTuple_SET_ITEM(ret, a, PyBool_FromLong(((bool *)data)[a])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_INT: | 
					
						
							|  |  |  |         ret = PyTuple_New(len); | 
					
						
							|  |  |  |         for (a = 0; a < len; a++) { | 
					
						
							|  |  |  |           PyTuple_SET_ITEM(ret, a, PyLong_FromLong(((int *)data)[a])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_FLOAT: | 
					
						
							|  |  |  |         switch (RNA_property_subtype(prop)) { | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           case PROP_ALL_VECTOR_SUBTYPES: | 
					
						
							|  |  |  |             ret = Vector_CreatePyObject(data, len, NULL); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case PROP_MATRIX: | 
					
						
							|  |  |  |             if (len == 16) { | 
					
						
							|  |  |  |               ret = Matrix_CreatePyObject(data, 4, 4, NULL); | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (len == 9) { | 
					
						
							|  |  |  |               ret = Matrix_CreatePyObject(data, 3, 3, NULL); | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             ATTR_FALLTHROUGH; | 
					
						
							| 
									
										
										
										
											2010-12-09 06:08:19 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           default: | 
					
						
							|  |  |  |             ret = PyTuple_New(len); | 
					
						
							|  |  |  |             for (a = 0; a < len; a++) { | 
					
						
							|  |  |  |               PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble(((float *)data)[a])); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         PyErr_Format( | 
					
						
							|  |  |  |             PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type); | 
					
						
							|  |  |  |         ret = NULL; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* See if we can coerce into a python type - PropertyType. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     switch (type) { | 
					
						
							|  |  |  |       case PROP_BOOLEAN: | 
					
						
							|  |  |  |         ret = PyBool_FromLong(*(bool *)data); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_INT: | 
					
						
							|  |  |  |         ret = PyLong_FromLong(*(int *)data); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_FLOAT: | 
					
						
							|  |  |  |         ret = PyFloat_FromDouble(*(float *)data); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case PROP_STRING: { | 
					
						
							|  |  |  |         const char *data_ch; | 
					
						
							|  |  |  |         PyObject *value_coerce = NULL; | 
					
						
							|  |  |  |         const int subtype = RNA_property_subtype(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (flag & PROP_THICK_WRAP) { | 
					
						
							|  |  |  |           data_ch = (char *)data; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           data_ch = *(char **)data; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  |           ret = PyBytes_FromString(data_ch); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { | 
					
						
							|  |  |  |           ret = PyC_UnicodeFromByte(data_ch); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           ret = PyUnicode_FromString(data_ch); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (subtype == PROP_BYTESTRING) { | 
					
						
							|  |  |  |           ret = PyBytes_FromString(buf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           ret = PyUnicode_FromString(data_ch); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_STRING_COERCE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         Py_XDECREF(value_coerce); | 
					
						
							| 
									
										
										
										
											2010-08-28 12:34:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (flag_parameter & PARM_RNAPTR) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* In this case we get the full ptr. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           newptr = *(PointerRNA *)data; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           if (RNA_struct_is_ID(ptype)) { | 
					
						
							|  |  |  |             RNA_id_pointer_create(*(void **)data, &newptr); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             /* note: this is taken from the function's ID pointer
 | 
					
						
							|  |  |  |              * 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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (newptr.data) { | 
					
						
							|  |  |  |           ret = pyrna_struct_CreatePyObject(&newptr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           ret = Py_None; | 
					
						
							|  |  |  |           Py_INCREF(ret); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case PROP_COLLECTION: { | 
					
						
							|  |  |  |         CollectionListBase *lb = (CollectionListBase *)data; | 
					
						
							|  |  |  |         CollectionPointerLink *link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ret = PyList_New(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |           PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); | 
					
						
							|  |  |  |         ret = NULL; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *key = NULL; | 
					
						
							|  |  |  |   Py_ssize_t pos = 0; | 
					
						
							|  |  |  |   PyObject *value = NULL; | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   while (PyDict_Next(dict, &pos, &key, &value)) { | 
					
						
							|  |  |  |     if (PyUnicode_Check(key)) { | 
					
						
							|  |  |  |       if (STREQ(key_lookup, _PyUnicode_AsString(key))) { | 
					
						
							|  |  |  |         return value; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2011-08-19 10:38:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA *self_ptr = &self->ptr; | 
					
						
							|  |  |  |   FunctionRNA *self_func = self->func; | 
					
						
							| 
									
										
										
										
											2009-04-09 13:20:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA funcptr; | 
					
						
							|  |  |  |   ParameterList parms; | 
					
						
							|  |  |  |   ParameterIterator iter; | 
					
						
							|  |  |  |   PropertyRNA *parm; | 
					
						
							|  |  |  |   PyObject *ret, *item; | 
					
						
							|  |  |  |   int i, pyargs_len, pykw_len, parms_len, ret_len, flag_parameter, err = 0, kw_tot = 0; | 
					
						
							|  |  |  |   bool kw_arg; | 
					
						
							| 
									
										
										
										
											2010-01-02 10:42:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *pret_single = NULL; | 
					
						
							|  |  |  |   void *retdata_single = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_STRING_FREE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BLI_assert(self_ptr != NULL); | 
					
						
							| 
									
										
										
										
											2010-12-15 10:22:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self_ptr == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_RuntimeError, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                     "RNA functions internal RNA pointer is NULL, this is a bug. aborting"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self_func == NULL) { | 
					
						
							|  |  |  |     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", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         RNA_struct_identifier(self_ptr->type)); | 
					
						
							|  |  |  |     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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     const char *fn; | 
					
						
							|  |  |  |     int lineno; | 
					
						
							|  |  |  |     PyC_FileAndNum(&fn, &lineno); | 
					
						
							|  |  |  |     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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							|  |  |  |   pyargs_len = PyTuple_GET_SIZE(args); | 
					
						
							|  |  |  |   pykw_len = kw ? PyDict_Size(kw) : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_parameter_list_create(&parms, self_ptr, self_func); | 
					
						
							|  |  |  |   RNA_parameter_list_begin(&parms, &iter); | 
					
						
							|  |  |  |   parms_len = RNA_parameter_list_arg_count(&parms); | 
					
						
							|  |  |  |   ret_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pyargs_len + pykw_len > parms_len) { | 
					
						
							|  |  |  |     RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  |     err = -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Parse function parameters. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |     parm = iter.parm; | 
					
						
							|  |  |  |     flag_parameter = RNA_parameter_flag(parm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Only useful for single argument returns, we'll need another list loop for multiple. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (flag_parameter & PARM_OUTPUT) { | 
					
						
							|  |  |  |       ret_len++; | 
					
						
							|  |  |  |       if (pret_single == NULL) { | 
					
						
							|  |  |  |         pret_single = parm; | 
					
						
							|  |  |  |         retdata_single = iter.data; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (i < pyargs_len) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* New in 2.8x, optional arguments must be keywords. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       item = PyTuple_GET_ITEM(args, i); | 
					
						
							|  |  |  |       kw_arg = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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-04-17 06:17:24 +02:00
										 |  |  |       if (item) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         kw_tot++; /* Make sure invalid keywords are not given. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       kw_arg = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     i++; /* Current argument. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (item == NULL) { | 
					
						
							|  |  |  |       if (flag_parameter & PARM_REQUIRED) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%.200s.%.200s(): required parameter \"%.200s\" not specified", | 
					
						
							|  |  |  |                      RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |                      RNA_function_identifier(self_func), | 
					
						
							|  |  |  |                      RNA_property_identifier(parm)); | 
					
						
							|  |  |  |         err = -1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       else { /* PyDict_GetItemString wont raise an error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | #ifdef DEBUG_STRING_FREE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (item) { | 
					
						
							|  |  |  |       if (PyUnicode_Check(item)) { | 
					
						
							|  |  |  |         PyList_APPEND(string_free_ls, PyUnicode_FromString(_PyUnicode_AsString(item))); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     err = pyrna_py_to_prop(&funcptr, parm, iter.data, item, ""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (err != 0) { | 
					
						
							|  |  |  |       /* the error generated isn't that useful, so generate it again with a useful prefix
 | 
					
						
							|  |  |  |        * could also write a function to prepend to error messages */ | 
					
						
							|  |  |  |       char error_prefix[512]; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       PyErr_Clear(); /* Re-raise. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (kw_arg == true) { | 
					
						
							|  |  |  |         BLI_snprintf(error_prefix, | 
					
						
							|  |  |  |                      sizeof(error_prefix), | 
					
						
							|  |  |  |                      "%.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_prefix, | 
					
						
							|  |  |  |                      sizeof(error_prefix), | 
					
						
							|  |  |  |                      "%.200s.%.200s(): error with argument %d, \"%.200s\" - ", | 
					
						
							|  |  |  |                      RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |                      RNA_function_identifier(self_func), | 
					
						
							|  |  |  |                      i, | 
					
						
							|  |  |  |                      RNA_property_identifier(parm)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       pyrna_py_to_prop(&funcptr, parm, iter.data, item, error_prefix); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* 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 then 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). | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |    */ | 
					
						
							|  |  |  |   if (err == 0 && kw && (pykw_len > kw_tot)) { | 
					
						
							|  |  |  |     PyObject *key, *value; | 
					
						
							|  |  |  |     Py_ssize_t pos = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DynStr *bad_args = BLI_dynstr_new(); | 
					
						
							|  |  |  |     DynStr *good_args = BLI_dynstr_new(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char *arg_name, *bad_args_str, *good_args_str; | 
					
						
							|  |  |  |     bool found = false, first = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (PyDict_Next(kw, &pos, &key, &value)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       arg_name = _PyUnicode_AsString(key); | 
					
						
							|  |  |  |       found = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       if (arg_name == NULL) { /* Unlikely the argname is not a string, but ignore if it is. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Search for arg_name. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         RNA_parameter_list_begin(&parms, &iter); | 
					
						
							|  |  |  |         for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |           parm = iter.parm; | 
					
						
							|  |  |  |           if (STREQ(arg_name, RNA_property_identifier(parm))) { | 
					
						
							|  |  |  |             found = true; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (found == false) { | 
					
						
							|  |  |  |           BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name); | 
					
						
							|  |  |  |           first = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* List good args. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     first = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RNA_parameter_list_begin(&parms, &iter); | 
					
						
							|  |  |  |     for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |       parm = iter.parm; | 
					
						
							|  |  |  |       if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); | 
					
						
							|  |  |  |       first = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bad_args_str = BLI_dynstr_get_cstring(bad_args); | 
					
						
							|  |  |  |     good_args_str = BLI_dynstr_get_cstring(good_args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyErr_Format( | 
					
						
							|  |  |  |         PyExc_TypeError, | 
					
						
							|  |  |  |         "%.200s.%.200s(): was called with invalid keyword argument(s) (%s), expected (%s)", | 
					
						
							|  |  |  |         RNA_struct_identifier(self_ptr->type), | 
					
						
							|  |  |  |         RNA_function_identifier(self_func), | 
					
						
							|  |  |  |         bad_args_str, | 
					
						
							|  |  |  |         good_args_str); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BLI_dynstr_free(bad_args); | 
					
						
							|  |  |  |     BLI_dynstr_free(good_args); | 
					
						
							|  |  |  |     MEM_freeN((void *)bad_args_str); | 
					
						
							|  |  |  |     MEM_freeN((void *)good_args_str); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ret = NULL; | 
					
						
							|  |  |  |   if (err == 0) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Call function. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     ReportList reports; | 
					
						
							|  |  |  |     bContext *C = BPy_GetContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BKE_reports_init(&reports, RPT_STORE); | 
					
						
							|  |  |  |     RNA_function_call(C, &reports, self_ptr, self_func, &parms); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Return value. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (err != -1) { | 
					
						
							|  |  |  |       if (ret_len > 0) { | 
					
						
							|  |  |  |         if (ret_len > 1) { | 
					
						
							|  |  |  |           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
										 |  |  | 
 | 
					
						
							|  |  |  |           RNA_parameter_list_begin(&parms, &iter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |             parm = iter.parm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							|  |  |  |               PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Possible there is an error in conversion. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (ret == NULL) { | 
					
						
							|  |  |  |           err = -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_STRING_FREE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  if 0
 | 
					
						
							|  |  |  |   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)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  |   Py_DECREF(string_free_ls); | 
					
						
							|  |  |  | #  undef DEBUG_STRING_FREE
 | 
					
						
							| 
									
										
										
										
											2011-05-06 03:29:55 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Cleanup. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  |   RNA_parameter_list_free(&parms); | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (ret) { | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (err == -1) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2009-04-07 00:49:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   char *args; | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   args = RNA_function_as_string_keywords(NULL, self->func, true, true, INT_MAX); | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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)); | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   MEM_freeN(args); | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2012-03-20 07:41:47 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-09-10 14:54:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass. */ | 
					
						
							| 
									
										
										
										
											2010-09-09 05:37:22 +00:00
										 |  |  | /* note: tp_base member is set to &PyType_Type on init */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_struct_meta_idprop_Type = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct_meta_idprop", /* tp_name */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* NOTE! would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's */ | 
					
						
							|  |  |  |     sizeof(PyHeapTypeObject), /* tp_basicsize */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     0, /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     NULL,            /* tp_dealloc */ | 
					
						
							|  |  |  |     (printfunc)NULL, /* printfunc tp_print; */ | 
					
						
							|  |  |  |     NULL,            /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,            /* setattrfunc tp_setattr; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */ /* deprecated in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,            /* tp_repr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Method suites for standard classes */ | 
					
						
							|  |  |  |     NULL, /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     NULL, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     NULL, /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  |     NULL,                                                      /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     NULL,                                                      /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     NULL,                                                      /* reprfunc tp_str; */ | 
					
						
							|  |  |  |     NULL /*(getattrofunc) pyrna_struct_meta_idprop_getattro*/, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  |     (setattrofunc)pyrna_struct_meta_idprop_setattro,           /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  |     /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  |     /* call function for all accessible objects */ | 
					
						
							|  |  |  |     NULL, /* traverseproc tp_traverse; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons ***/ | 
					
						
							|  |  |  |     NULL, /* richcmpfunc tp_richcompare; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /***  weak reference enabler ***/ | 
					
						
							|  |  |  |     0, /* long tp_weaklistoffset; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  |     /*   Iterators */ | 
					
						
							|  |  |  |     NULL, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  |     NULL, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     NULL, /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL, /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     NULL, /* struct PyGetSetDef *tp_getset; */ | 
					
						
							| 
									
										
										
										
											2017-05-27 15:34:55 -04:00
										 |  |  | #if defined(_MSC_VER)
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /* defer assignment */ | 
					
						
							| 
									
										
										
										
											2011-10-01 15:02:55 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     &PyType_Type, /* struct _typeobject *tp_base; */ | 
					
						
							| 
									
										
										
										
											2011-10-01 15:02:55 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL, /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL, /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,    /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL, /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL, /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     NULL, /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct", /* tp_name */ | 
					
						
							|  |  |  |     sizeof(BPy_StructRNA),                       /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                           /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							|  |  |  |     (destructor)pyrna_struct_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     (printfunc)NULL,                  /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                             /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,                             /* setattrfunc tp_setattr; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */             /* DEPRECATED in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (reprfunc)pyrna_struct_repr, /* tp_repr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Method suites for standard classes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL,                      /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     &pyrna_struct_as_sequence, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     &pyrna_struct_as_mapping,  /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     (hashfunc)pyrna_struct_hash,         /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     NULL,                                /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     (reprfunc)pyrna_struct_str,          /* reprfunc tp_str; */ | 
					
						
							|  |  |  |     (getattrofunc)pyrna_struct_getattro, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  |     (setattrofunc)pyrna_struct_setattro, /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  | /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  | /* call function for all accessible objects */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (traverseproc)pyrna_struct_traverse, /* traverseproc tp_traverse; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     (inquiry)pyrna_struct_clear, /* inquiry tp_clear; */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,         /* traverseproc tp_traverse; */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons ***/ | 
					
						
							|  |  |  |     (richcmpfunc)pyrna_struct_richcmp, /* richcmpfunc tp_richcompare; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | /***  weak reference enabler ***/ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     offsetof(BPy_StructRNA, in_weakreflist), /* long tp_weaklistoffset; */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  |     /*   Iterators */ | 
					
						
							|  |  |  |     NULL, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  |     NULL, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     pyrna_struct_methods,   /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL,                   /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     pyrna_struct_getseters, /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  |     NULL,                   /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  |     NULL,                   /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL,                   /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL,                   /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,                      /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL,                   /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL,                   /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     pyrna_struct_new,       /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop", /* tp_name */ | 
					
						
							|  |  |  |     sizeof(BPy_PropertyRNA),                   /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                         /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							|  |  |  |     (destructor)pyrna_prop_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     (printfunc)NULL,                /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                           /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,                           /* setattrfunc tp_setattr; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */           /* DEPRECATED in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (reprfunc)pyrna_prop_repr, /* tp_repr */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* Method suites for standard classes */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     NULL, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     NULL, /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (hashfunc)pyrna_prop_hash, /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     NULL,                      /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     (reprfunc)pyrna_prop_str,  /* reprfunc tp_str; */ | 
					
						
							| 
									
										
										
										
											2009-11-03 16:07:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* will only use these if this is a subtype of a py class */ | 
					
						
							|  |  |  |     NULL, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  |     NULL, /* setattrofunc tp_setattro; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  |     /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  |     /* call function for all accessible objects */ | 
					
						
							|  |  |  |     NULL, /* traverseproc tp_traverse; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons ***/ | 
					
						
							|  |  |  |     (richcmpfunc)pyrna_prop_richcmp, /* richcmpfunc tp_richcompare; */ | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | /***  weak reference enabler ***/ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  |     /*   Iterators */ | 
					
						
							|  |  |  |     NULL, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  |     NULL, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     pyrna_prop_methods,   /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL,                 /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     pyrna_prop_getseters, /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  |     NULL,                 /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  |     NULL,                 /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL,                 /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL,                 /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,                    /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL,                 /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL,                 /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     pyrna_prop_new,       /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_prop_array_Type = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_array", /* tp_name */ | 
					
						
							|  |  |  |     sizeof(BPy_PropertyArrayRNA),                    /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                               /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							|  |  |  |     (destructor)pyrna_prop_array_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     (printfunc)NULL,                      /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                                 /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,                                 /* setattrfunc tp_setattr; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */                 /* DEPRECATED in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (reprfunc)pyrna_prop_array_repr, /* tp_repr */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* Method suites for standard classes */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     &pyrna_prop_array_as_number,   /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     &pyrna_prop_array_as_sequence, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     &pyrna_prop_array_as_mapping,  /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     NULL, /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     NULL, /* reprfunc tp_str; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* will only use these if this is a subtype of a py class */ | 
					
						
							|  |  |  |     (getattrofunc)pyrna_prop_array_getattro, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  |     NULL,                                    /* setattrofunc tp_setattro; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  |     /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  |     /* call function for all accessible objects */ | 
					
						
							|  |  |  |     NULL, /* traverseproc tp_traverse; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons (subclassed) ***/ | 
					
						
							|  |  |  |     NULL, /* richcmpfunc tp_richcompare; */ | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | /***  weak reference enabler ***/ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     offsetof(BPy_PropertyArrayRNA, in_weakreflist), /* long tp_weaklistoffset; */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  |     /*   Iterators */ | 
					
						
							|  |  |  |     (getiterfunc)pyrna_prop_array_iter, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  |     NULL,                               /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     pyrna_prop_array_methods,      /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL,                          /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  |     &pyrna_prop_Type,              /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  |     NULL,                          /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL,                          /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL,                          /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,                             /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL,                          /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL,                          /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     NULL,                          /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | PyTypeObject pyrna_prop_collection_Type = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection", /* tp_name */ | 
					
						
							|  |  |  |     sizeof(BPy_PropertyRNA),                              /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                                    /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							|  |  |  |     (destructor)pyrna_prop_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     (printfunc)NULL,                /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                           /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,                           /* setattrfunc tp_setattr; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */ /* DEPRECATED in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, | 
					
						
							|  |  |  |     /* subclassed */ /* tp_repr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Method suites for standard classes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     &pyrna_prop_collection_as_number,   /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     &pyrna_prop_collection_as_sequence, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     &pyrna_prop_collection_as_mapping,  /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     NULL, /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     NULL, /* reprfunc tp_str; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* will only use these if this is a subtype of a py class */ | 
					
						
							|  |  |  |     (getattrofunc)pyrna_prop_collection_getattro, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  |     (setattrofunc)pyrna_prop_collection_setattro, /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  |     /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  |     /* call function for all accessible objects */ | 
					
						
							|  |  |  |     NULL, /* traverseproc tp_traverse; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons (subclassed) ***/ | 
					
						
							|  |  |  |     NULL, /* richcmpfunc tp_richcompare; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***  weak reference enabler ***/ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  |     /*   Iterators */ | 
					
						
							|  |  |  |     (getiterfunc)pyrna_prop_collection_iter, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  |     NULL,                                    /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     pyrna_prop_collection_methods, /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL,                          /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  |     &pyrna_prop_Type,              /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  |     NULL,                          /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL,                          /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL,                          /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,                             /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL,                          /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL,                          /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     NULL,                          /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_idprop", /* tp_name */ | 
					
						
							|  |  |  |     sizeof(BPy_PropertyRNA),                                     /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                                           /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							|  |  |  |     (destructor)pyrna_prop_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     (printfunc)NULL,                /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                           /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,                           /* setattrfunc tp_setattr; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */ /* DEPRECATED in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, | 
					
						
							|  |  |  |     /* subclassed */ /* tp_repr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Method suites for standard classes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     NULL, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     NULL, /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     NULL, /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     NULL, /* reprfunc tp_str; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* will only use these if this is a subtype of a py class */ | 
					
						
							|  |  |  |     NULL, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  |     NULL, /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  |     /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  |     /* call function for all accessible objects */ | 
					
						
							|  |  |  |     NULL, /* traverseproc tp_traverse; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons (subclassed) ***/ | 
					
						
							|  |  |  |     NULL, /* richcmpfunc tp_richcompare; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***  weak reference enabler ***/ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */ | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     0, | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  |     /*   Iterators */ | 
					
						
							|  |  |  |     NULL, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  |     NULL, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     pyrna_prop_collection_idprop_methods, /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL,                                 /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     NULL /*pyrna_prop_getseters*/,        /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  |     &pyrna_prop_collection_Type,          /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  |     NULL,                                 /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL,                                 /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL,                                 /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,                                    /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL,                                 /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL,                                 /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     NULL,                                 /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_func", /* tp_name */ | 
					
						
							|  |  |  |     sizeof(BPy_FunctionRNA),                   /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                         /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     NULL,            /* tp_dealloc */ | 
					
						
							|  |  |  |     (printfunc)NULL, /* printfunc tp_print; */ | 
					
						
							|  |  |  |     NULL,            /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,            /* setattrfunc tp_setattr; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */           /* DEPRECATED in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     (reprfunc)pyrna_func_repr, /* tp_repr */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* Method suites for standard classes */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     NULL, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     NULL, /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                         /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     (ternaryfunc)pyrna_func_call, /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     NULL,                         /* reprfunc tp_str; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* will only use these if this is a subtype of a py class */ | 
					
						
							|  |  |  |     NULL, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  |     NULL, /* setattrofunc tp_setattro; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT, /* long tp_flags; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  |     /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  |     /* call function for all accessible objects */ | 
					
						
							|  |  |  |     NULL, /* traverseproc tp_traverse; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons ***/ | 
					
						
							|  |  |  |     NULL, /* richcmpfunc tp_richcompare; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | /***  weak reference enabler ***/ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */ | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     0, | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  |     /*   Iterators */ | 
					
						
							|  |  |  |     NULL, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  |     NULL, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     NULL,                 /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL,                 /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     pyrna_func_getseters, /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  |     NULL,                 /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  |     NULL,                 /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL,                 /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL,                 /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,                    /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL,                 /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL,                 /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     NULL,                 /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     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 = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_iter", /* tp_name */ | 
					
						
							|  |  |  |     sizeof(BPy_PropertyCollectionIterRNA),                     /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                                         /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							|  |  |  |     (destructor)pyrna_prop_collection_iter_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-10-16 14:44:36 +11:00
										 |  |  |     (printfunc)NULL,                                /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL,                                           /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  |     NULL,                                           /* setattrfunc tp_setattr; */ | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* tp_compare */ /* DEPRECATED in Python 3.0! */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     NULL, | 
					
						
							|  |  |  |     /* subclassed */ /* tp_repr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Method suites for standard classes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  |     NULL, /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  |     NULL, /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /* hashfunc tp_hash; */ | 
					
						
							|  |  |  |     NULL, /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  |     NULL, /* reprfunc tp_str; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* will only use these if this is a subtype of a py class */ | 
					
						
							|  |  |  | #  if defined(_MSC_VER)
 | 
					
						
							|  |  |  |     NULL, /* defer assignment */ | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  |     PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  |     NULL, /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  |     NULL, /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT, /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NULL, /*  char *tp_doc;  Documentation string */ | 
					
						
							|  |  |  |     /*** Assigned meaning in release 2.0 ***/ | 
					
						
							|  |  |  |     /* call function for all accessible objects */ | 
					
						
							|  |  |  |     NULL, /* traverseproc tp_traverse; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* delete references to contained objects */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_clear; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |     /*** rich comparisons (subclassed) ***/ | 
					
						
							|  |  |  |     NULL, /* richcmpfunc tp_richcompare; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***  weak reference enabler ***/ | 
					
						
							|  |  |  | #  ifdef USE_WEAKREFS
 | 
					
						
							|  |  |  |     offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist), /* long tp_weaklistoffset; */ | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  | /*   Iterators */ | 
					
						
							|  |  |  | #  if defined(_MSC_VER)
 | 
					
						
							|  |  |  |     NULL, /* defer assignment */ | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  |     PyObject_SelfIter, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  |     (iternextfunc)pyrna_prop_collection_iter_next, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  |     NULL, /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  |     NULL, /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  |     NULL, /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  |     NULL, /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_dict; */ | 
					
						
							|  |  |  |     NULL, /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  |     NULL, /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  |     0,    /* long tp_dictoffset; */ | 
					
						
							|  |  |  |     NULL, /* initproc tp_init; */ | 
					
						
							|  |  |  |     NULL, /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  |     NULL, /* newfunc tp_new; */ | 
					
						
							|  |  |  |     /*  Low-level free-memory routine */ | 
					
						
							|  |  |  |     NULL, /* freefunc tp_free;  */ | 
					
						
							|  |  |  |     /* For PyObject_IS_GC */ | 
					
						
							|  |  |  |     NULL, /* inquiry tp_is_gc;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_bases; */ | 
					
						
							|  |  |  |     /* method resolution order */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_mro;  */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_cache; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_subclasses; */ | 
					
						
							|  |  |  |     NULL, /* PyObject *tp_weaklist; */ | 
					
						
							|  |  |  |     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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyCollectionIterRNA *self = PyObject_New(BPy_PropertyCollectionIterRNA, | 
					
						
							|  |  |  |                                                      &pyrna_prop_collection_iter_Type); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef USE_WEAKREFS
 | 
					
						
							|  |  |  |   self->in_weakreflist = NULL; | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-03-11 02:43:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_collection_begin(ptr, prop, &self->iter); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (PyObject *)self; | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return pyrna_prop_collection_iter_CreatePyObject(&self->ptr, self->prop); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self->iter.valid == false) { | 
					
						
							|  |  |  |     PyErr_SetNone(PyExc_StopIteration); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef USE_PYRNA_STRUCT_REFERENCE
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     if (pyrna) { /* Unlikely, but may fail. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if ((PyObject *)pyrna != Py_None) { | 
					
						
							|  |  |  |         /* hold a reference to the iterator since it may have
 | 
					
						
							|  |  |  |          * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's  */ | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |         /* TODO, we could have an api call to know if this is
 | 
					
						
							|  |  |  |          * needed since most collections don't */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         pyrna_struct_reference_set(pyrna, (PyObject *)self); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #  endif /* !USE_PYRNA_STRUCT_REFERENCE */
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     RNA_property_collection_next(&self->iter); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return (PyObject *)pyrna; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef USE_WEAKREFS
 | 
					
						
							|  |  |  |   if (self->in_weakreflist != NULL) { | 
					
						
							|  |  |  |     PyObject_ClearWeakRefs((PyObject *)self); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_collection_end(&self->iter); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject_DEL(self); | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   PyObject *item; | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_INCREF(newclass); | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_py_type_get(srna)) { | 
					
						
							|  |  |  |     PyC_ObSpit("RNA WAS SET - ", RNA_struct_py_type_get(srna)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_XDECREF(((PyObject *)RNA_struct_py_type_get(srna))); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */ | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr); | 
					
						
							|  |  |  |   item = pyrna_struct_CreatePyObject(&ptr); | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Note, must set the class not the __dict__ else the internal slots are not updated correctly.
 | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item); | 
					
						
							|  |  |  |   Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Add staticmethods and classmethods. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |     const PointerRNA func_ptr = {NULL, srna, NULL}; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     const ListBase *lb; | 
					
						
							|  |  |  |     Link *link; | 
					
						
							| 
									
										
										
										
											2012-12-17 06:58:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* We may want to set the type of this later. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         PyObject *func_py = pyrna_func_to_py(&func_ptr, func); | 
					
						
							|  |  |  |         PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py); | 
					
						
							|  |  |  |         Py_DECREF(func_py); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-17 06:58:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   StructRNA *base; | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   base = RNA_struct_base(srna); | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (base && base != srna) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     // printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna);
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     py_base = pyrna_srna_Subtype(base);  //, bpy_types_dict);
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     Py_DECREF(py_base);                  /* Srna owns, this is only to pass as an arg. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (py_base == NULL) { | 
					
						
							|  |  |  |     py_base = (PyObject *)&pyrna_struct_Type; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return py_base; | 
					
						
							| 
									
										
										
										
											2009-11-07 22:07:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *idname = RNA_struct_identifier(srna); | 
					
						
							|  |  |  |   PyObject *newclass; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (bpy_types_dict == NULL) { | 
					
						
							|  |  |  |     PyObject *bpy_types = PyImport_ImportModuleLevel("bpy_types", NULL, NULL, NULL, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (bpy_types == NULL) { | 
					
						
							|  |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |       CLOG_ERROR(BPY_LOG_RNA, "failed to find 'bpy_types' module"); | 
					
						
							|  |  |  |       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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   newclass = PyDict_GetItemString(bpy_types_dict, idname); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Sanity check, could skip this unless in debug mode. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (newclass) { | 
					
						
							|  |  |  |     PyObject *base_compare = pyrna_srna_PyBase(srna); | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |     /* Can't do this because it gets superclasses values! */ | 
					
						
							|  |  |  |     // 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__");
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *tp_bases = ((PyTypeObject *)newclass)->tp_bases; | 
					
						
							|  |  |  |     PyObject *tp_slots = PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, | 
					
						
							|  |  |  |                                         bpy_intern_str___slots__); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tp_slots == NULL) { | 
					
						
							|  |  |  |       CLOG_ERROR( | 
					
						
							|  |  |  |           BPY_LOG_RNA, "expected class '%s' to have __slots__ defined, see bpy_types.py", idname); | 
					
						
							|  |  |  |       newclass = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (PyTuple_GET_SIZE(tp_bases)) { | 
					
						
							|  |  |  |       PyObject *base = PyTuple_GET_ITEM(tp_bases, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (base_compare != base) { | 
					
						
							|  |  |  |         char pyob_info[256]; | 
					
						
							|  |  |  |         PyC_ObSpitStr(pyob_info, sizeof(pyob_info), base_compare); | 
					
						
							|  |  |  |         CLOG_ERROR(BPY_LOG_RNA, | 
					
						
							|  |  |  |                    "incorrect subclassing of SRNA '%s', expected '%s', see bpy_types.py", | 
					
						
							|  |  |  |                    idname, | 
					
						
							|  |  |  |                    pyob_info); | 
					
						
							|  |  |  |         newclass = NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         CLOG_INFO(BPY_LOG_RNA, 2, "SRNA sub-classed: '%s'", idname); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return newclass; | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | static PyObject *pyrna_srna_Subtype(StructRNA *srna) | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *newclass = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Stupid/simple case. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   else if ((newclass = RNA_struct_py_type_get(srna))) { | 
					
						
							|  |  |  |     Py_INCREF(newclass); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   } /* Check if bpy_types.py module has the class defined in it. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   else if ((newclass = pyrna_srna_ExternalType(srna))) { | 
					
						
							|  |  |  |     pyrna_subtype_set_rna(newclass, srna); | 
					
						
							|  |  |  |     Py_INCREF(newclass); | 
					
						
							|  |  |  |   } /* 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 */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   else { | 
					
						
							|  |  |  |     /* subclass equivalents
 | 
					
						
							|  |  |  |      * - 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__': ()} | 
					
						
							|  |  |  |      *   ) | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *py_base = pyrna_srna_PyBase(srna); | 
					
						
							|  |  |  |     PyObject *metaclass; | 
					
						
							|  |  |  |     const char *idname = RNA_struct_identifier(srna); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Remove __doc__ for now. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     // const char *descr = RNA_struct_ui_description(srna);
 | 
					
						
							|  |  |  |     // if (!descr) descr = "(no docs)";
 | 
					
						
							|  |  |  |     // "__doc__", descr
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (RNA_struct_idprops_check(srna) && | 
					
						
							|  |  |  |         !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type)) { | 
					
						
							|  |  |  |       metaclass = (PyObject *)&pyrna_struct_meta_idprop_Type; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       metaclass = (PyObject *)&PyType_Type; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-04-17 06:17:24 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Longhand of the call above. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PyObject *args, *item, *value; | 
					
						
							|  |  |  |       int ok; | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       args = PyTuple_New(3); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* arg[0] (name=...) */ | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(idname)); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* arg[1] (bases=...) */ | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args, 1, item = PyTuple_New(1)); | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(item, 0, Py_INCREF_RET(py_base)); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* arg[2] (dict=...) */ | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args, 2, item = PyDict_New()); | 
					
						
							|  |  |  |       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); | 
					
						
							|  |  |  |       BLI_assert(ok != -1); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       newclass = PyObject_CallObject(metaclass, args); | 
					
						
							|  |  |  |       Py_DECREF(args); | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       (void)ok; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-01-20 18:03:23 +11:00
										 |  |  | #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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* PyC_ObSpit("new class ref", newclass); */ | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (newclass) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* srna owns one, and the other is owned by the caller. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       // Py_DECREF(newclass); /* let srna own */
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* This should not happen. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       CLOG_ERROR(BPY_LOG_RNA, "failed to register '%s'", idname); | 
					
						
							|  |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return newclass; | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Use for subtyping 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (ptr->type == &RNA_Struct) { | 
					
						
							|  |  |  |     return ptr->data; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_StructRNA *pyrna = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Note: don't rely on this to return None since NULL data with a valid type can often crash. */ | 
					
						
							|  |  |  |   if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* New in 2.8x, since not many types support instancing
 | 
					
						
							|  |  |  |    * we may want to use a flag to avoid looping over all classes. - campbell */ | 
					
						
							|  |  |  |   void **instance = ptr->data ? RNA_struct_instance(ptr) : NULL; | 
					
						
							|  |  |  |   if (instance && *instance) { | 
					
						
							|  |  |  |     pyrna = *instance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Refine may have changed types after the first instance was created. */ | 
					
						
							|  |  |  |     if (ptr->type == pyrna->ptr.type) { | 
					
						
							|  |  |  |       Py_INCREF(pyrna); | 
					
						
							|  |  |  |       return (PyObject *)pyrna; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       /* Existing users will need to use 'type_recast' method. */ | 
					
						
							|  |  |  |       Py_DECREF(pyrna); | 
					
						
							|  |  |  |       *instance = NULL; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Continue as if no instance was made. */ | 
					
						
							|  |  |  | #if 0 /* No need to assign, will be written to next... */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       pyrna = NULL; | 
					
						
							| 
									
										
										
										
											2017-08-01 17:11:09 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tp) { | 
					
						
							|  |  |  |       pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       Py_DECREF(tp); /* srna owns, can't hold a reference. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type)); | 
					
						
							|  |  |  |       pyrna = (BPy_StructRNA *)PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       pyrna->in_weakreflist = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-10 04:25:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (pyrna == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_MemoryError, "couldn't create bpy_struct object"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* Blender's instance owns a reference (to avoid Python freeing it). */ | 
					
						
							|  |  |  |   if (instance) { | 
					
						
							|  |  |  |     *instance = pyrna; | 
					
						
							|  |  |  |     Py_INCREF(pyrna); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-26 23:05:00 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   pyrna->ptr = *ptr; | 
					
						
							| 
									
										
										
										
											2011-08-05 16:29:38 +00:00
										 |  |  | #ifdef PYRNA_FREE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   pyrna->reference = NULL; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:16:06 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_PropertyRNA *pyrna; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_property_array_check(prop) == 0) { | 
					
						
							|  |  |  |     PyTypeObject *type; | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (RNA_property_type(prop) != PROP_COLLECTION) { | 
					
						
							|  |  |  |       type = &pyrna_prop_Type; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       if ((RNA_property_flag(prop) & PROP_IDPROPERTY) == 0) { | 
					
						
							|  |  |  |         type = &pyrna_prop_collection_Type; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         type = &pyrna_prop_collection_idprop_Type; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyRNA, type); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     pyrna->in_weakreflist = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     ((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (pyrna == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_MemoryError, "couldn't create BPy_rna object"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-01 14:53:26 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (PyObject *)pyrna; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Utility func to be used by external modules, sneaky! */ | 
					
						
							| 
									
										
										
										
											2012-05-01 06:50:43 +00:00
										 |  |  | PyObject *pyrna_id_CreatePyObject(ID *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (id) { | 
					
						
							|  |  |  |     PointerRNA ptr; | 
					
						
							|  |  |  |     RNA_id_pointer_create(id, &ptr); | 
					
						
							|  |  |  |     return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (pyrna_id_CheckPyObject(obj)) { | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |     *id = ((BPy_StructRNA *)obj)->ptr.owner_id; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     *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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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)
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type; | 
					
						
							| 
									
										
										
										
											2011-10-01 15:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   pyrna_prop_collection_iter_Type.tp_iter = PyObject_SelfIter; | 
					
						
							|  |  |  |   pyrna_prop_collection_iter_Type.tp_getattro = PyObject_GenericGetAttr; | 
					
						
							| 
									
										
										
										
											2011-10-01 15:02:55 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* metaclass */ | 
					
						
							|  |  |  |   if (PyType_Ready(&pyrna_struct_meta_idprop_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Ready(&pyrna_struct_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_array_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-15 23:43:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_collection_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-09-02 06:35:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Ready(&pyrna_func_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-05 16:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #ifdef USE_PYRNA_ITER
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Ready(&pyrna_prop_collection_iter_Type) < 0) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-03 07:41:09 +00:00
										 |  |  | #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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_main_pointer_create(G_MAIN, &ptr); | 
					
						
							|  |  |  |   pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   rna_module_ptr = &pyrna->ptr; | 
					
						
							|  |  |  |   return (PyObject *)pyrna; | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BPY_update_rna_module(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (rna_module_ptr) { | 
					
						
							| 
									
										
										
										
											2011-10-05 07:28:59 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
 | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  | /* This is a way we can access docstrings for RNA types
 | 
					
						
							|  |  |  |  * without having the datatypes in blender */ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | PyObject *BPY_rna_doc(void) | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_blender_rna_pointer_create(&ptr); | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return pyrna_struct_CreatePyObject(&ptr); | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-16 16:32:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-21 05:49:47 +00:00
										 |  |  | /* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a different type
 | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  |  * the self->ptr and self->prop are always set to the "structs" collection */ | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | /* ---------------getattr-------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname) | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA newptr; | 
					
						
							|  |  |  |   PyObject *ret; | 
					
						
							|  |  |  |   const char *name = _PyUnicode_AsString(pyname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (name == NULL) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string"); | 
					
						
							|  |  |  |     ret = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (RNA_property_collection_lookup_string(&self->ptr, self->prop, name, &newptr)) { | 
					
						
							|  |  |  |     ret = pyrna_struct_Subtype(&newptr); | 
					
						
							|  |  |  |     if (ret == NULL) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                    "bpy.types.%.200s subtype could not be generated, this is a bug!", | 
					
						
							|  |  |  |                    _PyUnicode_AsString(pyname)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                  "bpy.types.%.200s RNA_Struct does not exist", | 
					
						
							|  |  |  |                  _PyUnicode_AsString(pyname)); | 
					
						
							|  |  |  |     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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     ret = PyObject_GenericGetAttr((PyObject *)self, pyname); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-08 01:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self); | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class); | 
					
						
							|  |  |  | static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class); | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct PyMethodDef pyrna_basetype_methods[] = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""}, | 
					
						
							|  |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Used to call ..._keys() direct, but we need to filter out operator subclasses. */ | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *list; | 
					
						
							|  |  |  | #  if 0
 | 
					
						
							|  |  |  |   PyMethodDef *meth; | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2011-02-11 00:11:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   list = pyrna_prop_collection_keys(self); /* Like calling structs.keys(), avoids looping here. */ | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #  if 0 /* For now only contains __dir__. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (meth = pyrna_basetype_methods; meth->ml_name; meth++) { | 
					
						
							|  |  |  |     PyList_APPEND(list, PyUnicode_FromString(meth->ml_name)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  |   return list; | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret = PyList_New(0); | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { | 
					
						
							|  |  |  |     StructRNA *srna = itemptr.data; | 
					
						
							|  |  |  |     PyList_APPEND(ret, PyUnicode_FromString(RNA_struct_identifier(srna))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2012-02-02 04:43:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE; | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-01 08:24:18 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Accessed from Python as 'bpy.types' | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-03-21 06:55:30 +00:00
										 |  |  | PyObject *BPY_rna_types(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_BaseTypeRNA *self; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY) == 0) { | 
					
						
							|  |  |  |     pyrna_basetype_Type.tp_name = "RNA_Types"; | 
					
						
							|  |  |  |     pyrna_basetype_Type.tp_basicsize = sizeof(BPy_BaseTypeRNA); | 
					
						
							|  |  |  |     pyrna_basetype_Type.tp_getattro = (getattrofunc)pyrna_basetype_getattro; | 
					
						
							|  |  |  |     pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT; | 
					
						
							|  |  |  |     pyrna_basetype_Type.tp_methods = pyrna_basetype_methods; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyType_Ready(&pyrna_basetype_Type) < 0) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Static members for the base class. */ | 
					
						
							|  |  |  |   /* Add __name__ since help() expects it. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyDict_SetItem(pyrna_basetype_Type.tp_dict, bpy_intern_str___name__, bpy_intern_str_bpy_types); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Internal base types we have no other accessors for. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     PyTypeObject *pyrna_types[] = { | 
					
						
							|  |  |  |         &pyrna_struct_meta_idprop_Type, | 
					
						
							|  |  |  |         &pyrna_struct_Type, | 
					
						
							|  |  |  |         &pyrna_prop_Type, | 
					
						
							|  |  |  |         &pyrna_prop_array_Type, | 
					
						
							|  |  |  |         &pyrna_prop_collection_Type, | 
					
						
							|  |  |  |         &pyrna_func_Type, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < ARRAY_SIZE(pyrna_types); i += 1) { | 
					
						
							|  |  |  |       PyDict_SetItemString( | 
					
						
							|  |  |  |           pyrna_basetype_Type.tp_dict, pyrna_types[i]->tp_name, (PyObject *)pyrna_types[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   self = (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Avoid doing this lookup for every getattr. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_blender_rna_pointer_create(&self->ptr); | 
					
						
							|  |  |  |   self->prop = RNA_struct_find_property(&self->ptr, "structs"); | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #ifdef USE_WEAKREFS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   self->in_weakreflist = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-23 13:43:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (PyObject *)self; | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-16 15:54:43 +00: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_StructRNA *py_srna = NULL; | 
					
						
							|  |  |  |   StructRNA *srna; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Unfortunately PyObject_GetAttrString wont look up this types tp_dict first :/ */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyType_Check(self)) { | 
					
						
							|  |  |  |     py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict, | 
					
						
							|  |  |  |                                               bpy_intern_str_bl_rna); | 
					
						
							|  |  |  |     Py_XINCREF(py_srna); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (parent) { | 
					
						
							|  |  |  |     /* be very careful with this since it will return a parent classes srna.
 | 
					
						
							|  |  |  |      * modifying this will do confusing stuff! */ | 
					
						
							|  |  |  |     if (py_srna == NULL) { | 
					
						
							|  |  |  |       py_srna = (BPy_StructRNA *)PyObject_GetAttr(self, bpy_intern_str_bl_rna); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (py_srna == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                  "%.200s, missing bl_rna attribute from '%.200s' instance (may not be registered)", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(self)->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!BPy_StructRNA_Check(py_srna)) { | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  |     Py_DECREF(py_srna); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (py_srna->ptr.type != &RNA_Struct) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                  "%.200s, bl_rna attribute not a RNA_Struct, on '%.200s'' instance", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  Py_TYPE(self)->tp_name); | 
					
						
							|  |  |  |     Py_DECREF(py_srna); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   srna = py_srna->ptr.data; | 
					
						
							|  |  |  |   Py_DECREF(py_srna); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return srna; | 
					
						
							| 
									
										
										
										
											2009-08-15 05:05:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | /* Orphan functions, not sure where they should go. */ | 
					
						
							|  |  |  | /* Get the srna for methods attached to types. */ | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Caller needs to raise error.*/ | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (self == NULL) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyCapsule_CheckExact(self)) { | 
					
						
							|  |  |  |     return PyCapsule_GetPointer(self, NULL); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyType_Check(self) == 0) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *error_type, *error_value, *error_traceback; | 
					
						
							|  |  |  |     StructRNA *srna; | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
					
						
							|  |  |  |     PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2009-08-09 10:05:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     srna = pyrna_struct_as_srna(self, false, error_prefix); | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (!PyErr_Occurred()) { | 
					
						
							|  |  |  |       PyErr_Restore(error_type, error_value, error_traceback); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-25 06:54:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* We only care about results from C which
 | 
					
						
							|  |  |  |    * are for sure types, save some time with error */ | 
					
						
							|  |  |  |   if (pyrna_is_deferred_prop(item)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *py_func, *py_kw, *py_srna_cobject, *py_ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyArg_ParseTuple(item, "OO!", &py_func, &PyDict_Type, &py_kw)) { | 
					
						
							|  |  |  |       PyObject *args_fake; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (*_PyUnicode_AsString(key) == '_') { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "bpy_struct \"%.200s\" registration error: " | 
					
						
							|  |  |  |                      "%.200s could not register because the property starts with an '_'\n", | 
					
						
							|  |  |  |                      RNA_struct_identifier(srna), | 
					
						
							|  |  |  |                      _PyUnicode_AsString(key)); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       py_srna_cobject = PyCapsule_New(srna, NULL, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Not 100% nice :/, modifies the dict passed, should be ok. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PyDict_SetItem(py_kw, bpy_intern_str_attr, key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       args_fake = PyTuple_New(1); | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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, | 
					
						
							|  |  |  |                        "bpy_struct \"%.200s\" doesn't support datablock properties\n", | 
					
						
							|  |  |  |                        RNA_struct_identifier(srna)); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       py_ret = PyObject_Call(py_func, args_fake, py_kw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (py_ret) { | 
					
						
							|  |  |  |         Py_DECREF(py_ret); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* _must_ print before decreffing args_fake. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         PyErr_Print(); | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // PyC_LineSpit();
 | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "bpy_struct \"%.200s\" registration error: " | 
					
						
							|  |  |  |                      "%.200s could not register\n", | 
					
						
							|  |  |  |                      RNA_struct_identifier(srna), | 
					
						
							|  |  |  |                      _PyUnicode_AsString(key)); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Since this is a class dict, ignore args that can't be passed. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* For testing only. */ | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PyC_ObSpit("Why doesn't this work??", item); | 
					
						
							|  |  |  |       PyErr_Print(); | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-11-20 20:58:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-11-20 20:58:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *annotations_dict; | 
					
						
							|  |  |  |   PyObject *item, *key; | 
					
						
							|  |  |  |   Py_ssize_t pos = 0; | 
					
						
							|  |  |  |   int ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* in both cases PyDict_CheckExact(class_dict) will be true even
 | 
					
						
							|  |  |  |    * though Operators have a metaclass dict namespace */ | 
					
						
							|  |  |  |   if ((annotations_dict = PyDict_GetItem(class_dict, bpy_intern_str___annotations__)) && | 
					
						
							|  |  |  |       PyDict_CheckExact(annotations_dict)) { | 
					
						
							|  |  |  |     while (PyDict_Next(annotations_dict, &pos, &key, &item)) { | 
					
						
							|  |  |  |       ret = deferred_register_prop(srna, key, item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (ret != 0) { | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-28 15:50:31 +01:00
										 |  |  |   if (ret == 0) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* This block can be removed once 2.8x is released and annotations are in use. */ | 
					
						
							|  |  |  |     bool has_warning = false; | 
					
						
							|  |  |  |     while (PyDict_Next(class_dict, &pos, &key, &item)) { | 
					
						
							|  |  |  |       if (pyrna_is_deferred_prop(item)) { | 
					
						
							|  |  |  |         if (!has_warning) { | 
					
						
							|  |  |  |           printf( | 
					
						
							|  |  |  |               "Warning: class %.200s " | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |               "contains a property which should be an annotation!\n", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |               RNA_struct_identifier(srna)); | 
					
						
							|  |  |  |           PyC_LineSpit(); | 
					
						
							|  |  |  |           has_warning = true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         printf("    assign as a type annotation: %.200s.%.200s\n", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                RNA_struct_identifier(srna), | 
					
						
							|  |  |  |                _PyUnicode_AsString(key)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ret = deferred_register_prop(srna, key, item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (ret != 0) { | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const int len = PyTuple_GET_SIZE(py_class->tp_bases); | 
					
						
							|  |  |  |   int i, ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* First scan base classes for registerable properties. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |     PyTypeObject *py_superclass = (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* the rules for using these base classes are not clear,
 | 
					
						
							|  |  |  |      * 'object' is of course not worth looking into and | 
					
						
							|  |  |  |      * 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. | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if (py_superclass != &PyBaseObject_Type && | 
					
						
							|  |  |  |         !PyObject_IsSubclass((PyObject *)py_superclass, (PyObject *)&pyrna_struct_Type)) { | 
					
						
							|  |  |  |       ret = pyrna_deferred_register_class_recursive(srna, py_superclass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (ret != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* Panels and Menus don't need this
 | 
					
						
							|  |  |  |    * save some time and skip the checks here */ | 
					
						
							|  |  |  |   if (!RNA_struct_idprops_register_check(srna)) { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-08-19 10:16:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const ListBase *lb = RNA_function_defined_parameters(func); | 
					
						
							|  |  |  |   PropertyRNA *parm; | 
					
						
							|  |  |  |   Link *link; | 
					
						
							|  |  |  |   int flag = RNA_function_flag(func); | 
					
						
							|  |  |  |   const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); | 
					
						
							|  |  |  |   int count = is_staticmethod ? 0 : 1; | 
					
						
							|  |  |  |   bool done_min_count = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |     parm = (PropertyRNA *)link; | 
					
						
							|  |  |  |     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-04-17 06:17:24 +02:00
										 |  |  |         if (min_count) { | 
					
						
							|  |  |  |           *min_count = count; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         done_min_count = true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       count++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!done_min_count && min_count) { | 
					
						
							|  |  |  |     *min_count = count; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int bpy_class_validate_recursive(PointerRNA *dummyptr, | 
					
						
							|  |  |  |                                         StructRNA *srna, | 
					
						
							|  |  |  |                                         void *py_data, | 
					
						
							|  |  |  |                                         int *have_function) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const ListBase *lb; | 
					
						
							|  |  |  |   Link *link; | 
					
						
							|  |  |  |   const char *class_type = RNA_struct_identifier(srna); | 
					
						
							|  |  |  |   StructRNA *srna_base = RNA_struct_base(srna); | 
					
						
							|  |  |  |   PyObject *py_class = (PyObject *)py_data; | 
					
						
							|  |  |  |   PyObject *base_class = RNA_struct_py_type_get(srna); | 
					
						
							|  |  |  |   PyObject *item; | 
					
						
							|  |  |  |   int i, arg_count, func_arg_count, func_arg_min_count = 0; | 
					
						
							|  |  |  |   const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (srna_base) { | 
					
						
							|  |  |  |     if (bpy_class_validate_recursive(dummyptr, srna_base, py_data, have_function) != 0) { | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (base_class) { | 
					
						
							|  |  |  |     if (!PyObject_IsSubclass(py_class, base_class)) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "expected %.200s subclass of class \"%.200s\"", | 
					
						
							|  |  |  |                    class_type, | 
					
						
							|  |  |  |                    py_class_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Verify callback functions. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   lb = RNA_struct_type_functions(srna); | 
					
						
							|  |  |  |   i = 0; | 
					
						
							|  |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |     FunctionRNA *func = (FunctionRNA *)link; | 
					
						
							|  |  |  |     const int flag = RNA_function_flag(func); | 
					
						
							|  |  |  |     /* TODO(campbell): this is used for classmethod's too,
 | 
					
						
							|  |  |  |      * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg. | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |      * Keep this as-is since it's working, but we should be using | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |      * 'FUNC_USE_SELF_TYPE' for many functions. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!(flag & FUNC_REGISTER)) { | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item = PyObject_GetAttrString(py_class, RNA_function_identifier(func)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     have_function[i] = (item != NULL); | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (item == NULL) { | 
					
						
							|  |  |  |       if ((flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER)) == 0) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                      "expected %.200s, %.200s class to have an \"%.200s\" attribute", | 
					
						
							|  |  |  |                      class_type, | 
					
						
							|  |  |  |                      py_class_name, | 
					
						
							|  |  |  |                      RNA_function_identifier(func)); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* No need to keep a ref, the class owns it
 | 
					
						
							|  |  |  |        * (technically we should keep a reference, but...). */ | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       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); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         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); | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       func_arg_count = rna_function_arg_count(func, &func_arg_min_count); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       if (func_arg_count >= 0) { /* -1 if we don't care. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* note, the number of args we check for and the number of args we give to
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |          * '@staticmethods' are different (quirk of Python), | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |          * this is why rna_function_arg_count() doesn't return the value -1*/ | 
					
						
							|  |  |  |         if (is_staticmethod) { | 
					
						
							|  |  |  |           func_arg_count++; | 
					
						
							|  |  |  |           func_arg_min_count++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Verify properties. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   lb = RNA_struct_type_properties(srna); | 
					
						
							|  |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |     const char *identifier; | 
					
						
							|  |  |  |     PropertyRNA *prop = (PropertyRNA *)link; | 
					
						
							|  |  |  |     const int flag = RNA_property_flag(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!(flag & PROP_REGISTER)) { | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* TODO(campbell): Use Python3.7x _PyObject_LookupAttr(), also in the macro below. */ | 
					
						
							|  |  |  |     identifier = RNA_property_identifier(prop); | 
					
						
							|  |  |  |     item = PyObject_GetAttrString(py_class, identifier); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (item == NULL) { | 
					
						
							|  |  |  |       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
										 |  |  | 
 | 
					
						
							|  |  |  | #define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
 | 
					
						
							|  |  |  |   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; \ | 
					
						
							|  |  |  |         } \ | 
					
						
							|  |  |  |       } \ | 
					
						
							|  |  |  |       Py_DECREF(item); \ | 
					
						
							|  |  |  |     } \ | 
					
						
							|  |  |  |     else { \ | 
					
						
							|  |  |  |       PyErr_Clear(); \ | 
					
						
							|  |  |  |     } \ | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   } /* Intentionally allow else here. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (false) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       } /* Needed for macro. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__) | 
					
						
							|  |  |  |       BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef BPY_REPLACEMENT_STRING
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (item == NULL && (((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL))) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_AttributeError, | 
					
						
							|  |  |  |                      "expected %.200s, %.200s class to have an \"%.200s\" attribute", | 
					
						
							|  |  |  |                      class_type, | 
					
						
							|  |  |  |                      py_class_name, | 
					
						
							|  |  |  |                      identifier); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) { | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-24 12:00:02 +00:00
										 |  |  | static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_function) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return bpy_class_validate_recursive(dummyptr, dummyptr->type, py_data, have_function); | 
					
						
							| 
									
										
										
										
											2012-07-24 12:00:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *args; | 
					
						
							|  |  |  |   PyObject *ret = NULL, *py_srna = NULL, *py_class_instance = NULL, *parmitem; | 
					
						
							|  |  |  |   PyTypeObject *py_class; | 
					
						
							|  |  |  |   PropertyRNA *parm; | 
					
						
							|  |  |  |   ParameterIterator iter; | 
					
						
							|  |  |  |   PointerRNA funcptr; | 
					
						
							|  |  |  |   int err = 0, i, ret_len = 0, arg_count; | 
					
						
							|  |  |  |   int flag = RNA_function_flag(func); | 
					
						
							|  |  |  |   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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *pret_single = NULL; | 
					
						
							|  |  |  |   void *retdata_single = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const bool is_readonly_init = !(RNA_struct_is_a(ptr->type, &RNA_Operator) || | 
					
						
							|  |  |  |                                   RNA_struct_is_a(ptr->type, &RNA_Gizmo)); | 
					
						
							|  |  |  |   // 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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (py_class == NULL) { | 
					
						
							|  |  |  |     CLOG_WARN(BPY_LOG_RNA, | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |               "unable to get Python class for RNA struct '%.200s'", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |               RNA_struct_identifier(ptr->type)); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* 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-04-17 06:17:24 +02:00
										 |  |  |   if (C == NULL) { | 
					
						
							|  |  |  |     C = BPy_GetContext(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Annoying! We need to check if the screen gets set to NULL which is a
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |    * hint that the file was actually re-loaded. */ | 
					
						
							|  |  |  |   const bool is_valid_wm = (CTX_wm_manager(C) != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bpy_context_set(C, &gilstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!(is_staticmethod || is_classmethod)) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Some datatypes (operator, render engine) can store PyObjects for re-use. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (ptr->data) { | 
					
						
							|  |  |  |       void **instance = RNA_struct_instance(ptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (instance) { | 
					
						
							|  |  |  |         if (*instance) { | 
					
						
							|  |  |  |           py_class_instance = *instance; | 
					
						
							|  |  |  |           Py_INCREF(py_class_instance); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* End exception. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (py_class_instance == NULL) { | 
					
						
							|  |  |  |       py_srna = pyrna_struct_CreatePyObject(ptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (py_class_instance) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Special case, instance is cached. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (py_srna == NULL) { | 
					
						
							|  |  |  |       py_class_instance = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     else if (py_srna == Py_None) { /* Probably wont ever happen, but possible. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       Py_DECREF(py_srna); | 
					
						
							|  |  |  |       py_class_instance = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  | #if 1
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* 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(). | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |        */ | 
					
						
							|  |  |  |       if (py_class->tp_init) { | 
					
						
							|  |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |         const int prev_write = rna_disallow_writes; | 
					
						
							|  |  |  |         rna_disallow_writes = is_readonly_init ? false : | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |                                                  true; /* Only operators can write on __init__. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* True in most cases even when the class itself doesn't define an __init__ function. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         args = PyTuple_New(0); | 
					
						
							|  |  |  |         if (py_class->tp_init(py_srna, args, NULL) < 0) { | 
					
						
							|  |  |  |           Py_DECREF(py_srna); | 
					
						
							|  |  |  |           py_srna = NULL; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Err set below. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         Py_DECREF(args); | 
					
						
							|  |  |  | #  ifdef USE_PEDANTIC_WRITE
 | 
					
						
							|  |  |  |         rna_disallow_writes = prev_write; | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       py_class_instance = py_srna; | 
					
						
							| 
									
										
										
										
											2011-02-17 07:21:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       const int prev_write = rna_disallow_writes; | 
					
						
							|  |  |  |       rna_disallow_writes = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* 'almost' all the time calling the class isn't needed.
 | 
					
						
							|  |  |  |        * We could just do... */ | 
					
						
							|  |  |  | #  if 0
 | 
					
						
							|  |  |  |       py_class_instance = py_srna; | 
					
						
							|  |  |  |       Py_INCREF(py_class_instance); | 
					
						
							|  |  |  | #  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 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |        * for general correctness. just to note why this is here when it could be safely removed. | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       args = PyTuple_New(1); | 
					
						
							|  |  |  |       PyTuple_SET_ITEM(args, 0, py_srna); | 
					
						
							|  |  |  |       py_class_instance = PyObject_Call(py_class, args, NULL); | 
					
						
							|  |  |  |       Py_DECREF(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (py_class_instance == NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         err = -1; /* So the error is not overridden below. */ | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) { | 
					
						
							|  |  |  |     PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (item) { | 
					
						
							|  |  |  |       RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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
										 |  |  | 
 | 
					
						
							|  |  |  |       if (is_staticmethod) { | 
					
						
							|  |  |  |         i = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (is_classmethod) { | 
					
						
							|  |  |  |         PyTuple_SET_ITEM(args, 0, (PyObject *)py_class); | 
					
						
							|  |  |  |         i = 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         PyTuple_SET_ITEM(args, 0, py_class_instance); | 
					
						
							|  |  |  |         i = 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       RNA_parameter_list_begin(parms, &iter); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Parse function parameters. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       for (; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |         parm = iter.parm; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Only useful for single argument returns, we'll need another list loop for multiple. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							|  |  |  |           ret_len++; | 
					
						
							|  |  |  |           if (pret_single == NULL) { | 
					
						
							|  |  |  |             pret_single = parm; | 
					
						
							|  |  |  |             retdata_single = iter.data; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       rna_disallow_writes = is_readonly ? true : false; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* *** Main Caller *** */ | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       ret = PyObject_Call(item, args, NULL); | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* *** Done Calling *** */ | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_PEDANTIC_WRITE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       rna_disallow_writes = false; | 
					
						
							| 
									
										
										
										
											2010-12-04 06:25:36 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  |       Py_DECREF(args); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "could not find function %.200s in %.200s to execute callback", | 
					
						
							|  |  |  |                    RNA_function_identifier(func), | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type)); | 
					
						
							|  |  |  |       err = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* The error may be already set if the class instance couldn't be created. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (err != -1) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                    "could not create instance of %.200s to call callback function %.200s", | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                    RNA_function_identifier(func)); | 
					
						
							|  |  |  |       err = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   if (ret == NULL) { /* Covers py_class_instance failing too. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     err = -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     if (ret_len == 0 && ret != Py_None) { | 
					
						
							|  |  |  |       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); | 
					
						
							|  |  |  |       err = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (ret_len == 1) { | 
					
						
							|  |  |  |       err = pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, ""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* when calling operator funcs only gives Function.result with
 | 
					
						
							|  |  |  |        * no line number since the func has finished calling on error, | 
					
						
							|  |  |  |        * re-raise the exception with more info since it would be slow to | 
					
						
							|  |  |  |        * create prefix on every call (when there are no errors) */ | 
					
						
							|  |  |  |       if (err == -1) { | 
					
						
							|  |  |  |         PyC_Err_Format_Prefix(PyExc_RuntimeError, | 
					
						
							|  |  |  |                               "class %.200s, function %.200s: incompatible return value ", | 
					
						
							|  |  |  |                               RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                               RNA_function_identifier(func)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (ret_len > 1) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (PyTuple_Check(ret) == 0) { | 
					
						
							|  |  |  |         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); | 
					
						
							|  |  |  |         err = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (PyTuple_GET_SIZE(ret) != ret_len) { | 
					
						
							|  |  |  |         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); | 
					
						
							|  |  |  |         err = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_parameter_list_begin(parms, &iter); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |         /* Parse function parameters. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) { | 
					
						
							|  |  |  |           parm = iter.parm; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |           /* Only useful for single argument returns, we'll need another list loop for multiple. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | 
					
						
							|  |  |  |             err = pyrna_py_to_prop( | 
					
						
							|  |  |  |                 &funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); | 
					
						
							|  |  |  |             if (err) { | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_parameter_list_end(&iter); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_DECREF(ret); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (err != 0) { | 
					
						
							|  |  |  |     ReportList *reports; | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Alert the user, else they wont know unless they see the console. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if ((!is_staticmethod) && (!is_classmethod) && (ptr->data) && | 
					
						
							|  |  |  |         (RNA_struct_is_a(ptr->type, &RNA_Operator)) && | 
					
						
							|  |  |  |         (is_valid_wm == (CTX_wm_manager(C) != NULL))) { | 
					
						
							|  |  |  |       wmOperator *op = ptr->data; | 
					
						
							|  |  |  |       reports = op->reports; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       /* Wont alert users, but they can view in 'info' space. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       reports = CTX_wm_reports(C); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BPy_errors_to_report(reports); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Also print in the console for Python. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyErr_Print(); | 
					
						
							|  |  |  |     PyErr_Clear(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bpy_context_clear(C, &gilstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return err; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bpy_class_free(void *pyob_ptr) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *self = (PyObject *)pyob_ptr; | 
					
						
							|  |  |  |   PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Breaks re-registering classes. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyDict_DelItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); | 
					
						
							|  |  |  |   if (PyErr_Occurred()) { | 
					
						
							|  |  |  |     PyErr_Clear(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (G.debug & G_DEBUG_PYTHON) { | 
					
						
							|  |  |  |     if (self->ob_refcnt > 1) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |       PyC_ObSpit("zombie class - reference should be 1", self); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-09 11:54:12 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_DECREF((PyObject *)pyob_ptr); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-22 19:41:59 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \note This isn't essential to run on startup, since subtypes will lazy initialize. | 
					
						
							|  |  |  |  * 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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2011-03-03 05:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_blender_rna_pointer_create(&ptr); | 
					
						
							|  |  |  |   prop = RNA_struct_find_property(&ptr, "structs"); | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_PROP_BEGIN (&ptr, itemptr, prop) { | 
					
						
							|  |  |  |     PyObject *item = pyrna_struct_Subtype(&itemptr); | 
					
						
							|  |  |  |     if (item == NULL) { | 
					
						
							|  |  |  |       if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         PyErr_Print(); | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_Release(gilstate); | 
					
						
							|  |  |  | #endif /* DEBUG */
 | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | void pyrna_free_types(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PointerRNA ptr; | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Avoid doing this lookup for every getattr. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_blender_rna_pointer_create(&ptr); | 
					
						
							|  |  |  |   prop = RNA_struct_find_property(&ptr, "structs"); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_PROP_BEGIN (&ptr, itemptr, prop) { | 
					
						
							|  |  |  |     StructRNA *srna = srna_from_ptr(&itemptr); | 
					
						
							|  |  |  |     void *py_ptr = RNA_struct_py_type_get(srna); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (py_ptr) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  | #if 0 /* XXX - should be able to do this, but makes Python crash on exit. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       bpy_class_free(py_ptr); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       RNA_struct_py_type_set(srna, NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RNA_PROP_END; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-16 04:59:11 +00:00
										 |  |  | /* Note! MemLeak XXX
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |  * There is currently a bug where moving the registration of a Python class does | 
					
						
							|  |  |  |  * not properly manage reference-counts from the Python class. As the srna owns | 
					
						
							|  |  |  |  * 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 | 
					
						
							| 
									
										
										
										
											2009-08-16 04:59:11 +00:00
										 |  |  |  * the decref. This is not so bad because the leak only happens when re-registering (hold F8) | 
					
						
							|  |  |  |  * - Should still be fixed - Campbell | 
					
						
							|  |  |  |  * */ | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_register_class_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: register_class(cls)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Register a subclass of a blender type in (:class:`bpy.types.Panel`,\n" | 
					
						
							|  |  |  |              "   :class:`bpy.types.UIList`, :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n" | 
					
						
							|  |  |  |              "   :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n" | 
					
						
							|  |  |  |              "   :class:`bpy.types.RenderEngine`).\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   If the class has a *register* class method it will be called\n" | 
					
						
							|  |  |  |              "   before registration.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   .. note::\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "      :exc:`ValueError` exception is raised if the class is not a\n" | 
					
						
							|  |  |  |              "      subclass of a registerable blender class.\n" | 
					
						
							|  |  |  |              "\n"); | 
					
						
							|  |  |  | 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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   bContext *C = NULL; | 
					
						
							|  |  |  |   ReportList reports; | 
					
						
							|  |  |  |   StructRegisterFunc reg; | 
					
						
							|  |  |  |   StructRNA *srna; | 
					
						
							|  |  |  |   StructRNA *srna_new; | 
					
						
							|  |  |  |   const char *identifier; | 
					
						
							|  |  |  |   PyObject *py_cls_meth; | 
					
						
							|  |  |  |   const char *error_prefix = "register_class(...):"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!pyrna_write_check()) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_RuntimeError, | 
					
						
							|  |  |  |                  "register_class(...): " | 
					
						
							|  |  |  |                  "can't run in readonly state '%.200s'", | 
					
						
							|  |  |  |                  ((PyTypeObject *)py_class)->tp_name); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Warning: gets parent classes srna, only for the register function. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   srna = pyrna_struct_as_srna(py_class, true, "register_class(...):"); | 
					
						
							|  |  |  |   if (srna == NULL) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_py_type_get(srna)) { | 
					
						
							|  |  |  |     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)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   reg = RNA_struct_register(srna); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!reg) { | 
					
						
							|  |  |  |     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)", | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                  RNA_struct_identifier(srna)); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Get the context, so register callback can do necessary refreshes. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   C = BPy_GetContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Call the register callback with reports & identifier. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BKE_reports_init(&reports, RPT_STORE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   identifier = ((PyTypeObject *)py_class)->tp_name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   srna_new = reg(CTX_data_main(C), | 
					
						
							|  |  |  |                  &reports, | 
					
						
							|  |  |  |                  py_class, | 
					
						
							|  |  |  |                  identifier, | 
					
						
							|  |  |  |                  bpy_class_validate, | 
					
						
							|  |  |  |                  bpy_class_call, | 
					
						
							|  |  |  |                  bpy_class_free); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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-06-21 09:50:23 +10:00
										 |  |  |   /* Python errors validating are not converted into reports so the check above will fail.
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |    * the cause for returning NULL will be printed as an error */ | 
					
						
							|  |  |  |   if (srna_new == NULL) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (RNA_struct_py_type_get(srna)) { | 
					
						
							|  |  |  |     RNA_struct_py_type_set(srna, NULL); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     // Py_DECREF(py_class); /* Should be able to do this XXX since the old RNA adds a new ref. */
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Can't use this because it returns a dict proxy
 | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * item = PyObject_GetAttrString(py_class, "__dict__"); | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   if (pyrna_deferred_register_class(srna_new, (PyTypeObject *)py_class) != 0) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:10:33 +11:00
										 |  |  |   /* Call classed register method.
 | 
					
						
							|  |  |  |    * Note that zero falls through, no attribute, no error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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-04-17 06:17:24 +02:00
										 |  |  |       if (ret) { | 
					
						
							|  |  |  |         Py_DECREF(ret); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case -1: { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, | 
					
						
							|  |  |  |                                                  StructRNA *srna, | 
					
						
							|  |  |  |                                                  const char **r_prop_identifier) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   LinkData *link; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Verify properties. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const ListBase *lb = RNA_struct_type_properties(srna); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (link = lb->first; link; link = link->next) { | 
					
						
							|  |  |  |     prop = (PropertyRNA *)link; | 
					
						
							|  |  |  |     if (RNA_property_type(prop) == PROP_POINTER && !RNA_property_builtin(prop)) { | 
					
						
							|  |  |  |       PointerRNA tptr; | 
					
						
							|  |  |  |       RNA_pointer_create(NULL, &RNA_Struct, srna_props, &tptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (RNA_property_pointer_type(&tptr, prop) == srna) { | 
					
						
							|  |  |  |         *r_prop_identifier = RNA_property_identifier(prop); | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2010-07-23 01:43:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 16:05:51 +00:00
										 |  |  | PyDoc_STRVAR(pyrna_unregister_class_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: unregister_class(cls)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |              "   Unload the Python class from blender.\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              "\n" | 
					
						
							|  |  |  |              "   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-04-17 06:17:24 +02: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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   bContext *C = NULL; | 
					
						
							|  |  |  |   StructUnregisterFunc unreg; | 
					
						
							|  |  |  |   StructRNA *srna; | 
					
						
							|  |  |  |   PyObject *py_cls_meth; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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-01-18 19:50:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna) == NULL) { | 
					
						
							|  |  |  |     PWM_cursor_wait(0); | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_ValueError, "unregister_class(): not a registered as a subclass"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-02-15 11:24:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):"); | 
					
						
							|  |  |  |   if (srna == NULL) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Check that we have a unregister callback for this type. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   unreg = RNA_struct_unregister(srna); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!unreg) { | 
					
						
							|  |  |  |     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)"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:10:33 +11:00
										 |  |  |   /* Call classed unregister method.
 | 
					
						
							|  |  |  |    * Note that zero falls through, no attribute, no error. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02: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-04-17 06:17:24 +02:00
										 |  |  |       if (ret) { | 
					
						
							|  |  |  |         Py_DECREF(ret); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case -1: { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Should happen all the time, however it's very slow. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (G.debug & G_DEBUG_PYTHON) { | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Remove all properties using this class. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     StructRNA *srna_iter; | 
					
						
							|  |  |  |     PointerRNA ptr_rna; | 
					
						
							|  |  |  |     PropertyRNA *prop_rna; | 
					
						
							|  |  |  |     const char *prop_identifier = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RNA_blender_rna_pointer_create(&ptr_rna); | 
					
						
							|  |  |  |     prop_rna = RNA_struct_find_property(&ptr_rna, "structs"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     /* Loop over all structs. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     RNA_PROP_BEGIN (&ptr_rna, itemptr, prop_rna) { | 
					
						
							|  |  |  |       srna_iter = itemptr.data; | 
					
						
							|  |  |  |       if (pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) { | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     RNA_PROP_END; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (prop_identifier) { | 
					
						
							|  |  |  |       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); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |   /* Get the context, so register callback can do necessary refreshes. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   C = BPy_GetContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |   PyDict_DelItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna); | 
					
						
							|  |  |  |   if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2019-05-01 11:09:22 +10:00
										 |  |  |     PyErr_Clear();  // return NULL;
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2009-04-19 13:37:59 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00: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)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *name = RNA_struct_state_owner_get(); | 
					
						
							|  |  |  |   if (name) { | 
					
						
							|  |  |  |     return PyUnicode_FromString(name); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2018-03-01 01:26:02 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *pyrna_bl_owner_id_set(PyObject *UNUSED(self), PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *name; | 
					
						
							|  |  |  |   if (value == Py_None) { | 
					
						
							|  |  |  |     name = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PyUnicode_Check(value)) { | 
					
						
							|  |  |  |     name = _PyUnicode_AsString(value); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   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; | 
					
						
							| 
									
										
										
										
											2018-03-01 01:26:02 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMethodDef meth_bpy_owner_id_get = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     "_bl_owner_id_get", | 
					
						
							|  |  |  |     (PyCFunction)pyrna_bl_owner_id_get, | 
					
						
							|  |  |  |     METH_NOARGS, | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2018-03-01 01:26:02 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | PyMethodDef meth_bpy_owner_id_set = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     "_bl_owner_id_set", | 
					
						
							|  |  |  |     (PyCFunction)pyrna_bl_owner_id_set, | 
					
						
							|  |  |  |     METH_O, | 
					
						
							|  |  |  |     NULL, | 
					
						
							| 
									
										
										
										
											2018-03-01 01:26:02 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | /* currently this is fairly limited, we would need to make some way to split up
 | 
					
						
							| 
									
										
										
										
											2013-04-07 15:09:06 +00:00
										 |  |  |  * pyrna_callback_classmethod_... if we want more than one callback per type */ | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | typedef struct BPyRNA_CallBack { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyMethodDef py_method; | 
					
						
							|  |  |  |   StructRNA *bpy_srna; | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | } PyRNA_CallBack; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | PyDoc_STRVAR( | 
					
						
							|  |  |  |     pyrna_draw_handler_add_doc, | 
					
						
							|  |  |  |     ".. method:: draw_handler_add(callback, args, region_type, draw_type)\n" | 
					
						
							|  |  |  |     "\n" | 
					
						
							|  |  |  |     "   Add a new draw handler to this space type.\n" | 
					
						
							|  |  |  |     "   It will be called every time the specified region in the space type will be drawn.\n" | 
					
						
							|  |  |  |     "   Note: All arguments are positional only for now.\n" | 
					
						
							|  |  |  |     "\n" | 
					
						
							|  |  |  |     "   :param callback:\n" | 
					
						
							| 
									
										
										
										
											2019-04-24 04:09:56 +10:00
										 |  |  |     "      A function that will be called when the region is drawn.\n" | 
					
						
							|  |  |  |     "      It gets the specified arguments as input.\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     "   :type callback: function\n" | 
					
						
							|  |  |  |     "   :param args: Arguments that will be passed to the callback.\n" | 
					
						
							|  |  |  |     "   :type args: tuple\n" | 
					
						
							| 
									
										
										
										
											2019-04-24 04:09:56 +10:00
										 |  |  |     "   :param region_type: The region type the callback draws in; usually ``WINDOW``. " | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     "(:class:`bpy.types.Region.type`)\n" | 
					
						
							|  |  |  |     "   :type region_type: str\n" | 
					
						
							| 
									
										
										
										
											2019-04-24 04:09:56 +10:00
										 |  |  |     "   :param draw_type: Usually ``POST_PIXEL`` for 2D drawing and ``POST_VIEW`` for 3D drawing. " | 
					
						
							|  |  |  |     "In some cases ``PRE_VIEW`` can be used. ``BACKDROP`` can be used for backdrops in the node " | 
					
						
							|  |  |  |     "editor.\n" | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     "   :type draw_type: str\n" | 
					
						
							|  |  |  |     "   :return: Handler that can be removed later on.\n" | 
					
						
							|  |  |  |     "   :rtype: object"); | 
					
						
							| 
									
										
										
										
											2018-12-18 12:31:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(pyrna_draw_handler_remove_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: draw_handler_remove(handler, region_type)\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Remove a draw handler that was added previously.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :param handler: The draw handler that should be removed.\n" | 
					
						
							|  |  |  |              "   :type handler: object\n" | 
					
						
							|  |  |  |              "   :param region_type: Region type the callback was added to.\n" | 
					
						
							|  |  |  |              "   :type region_type: str\n"); | 
					
						
							| 
									
										
										
										
											2018-12-18 12:31:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | static struct BPyRNA_CallBack pyrna_cb_methods[] = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {{"draw_handler_add", | 
					
						
							|  |  |  |       (PyCFunction)pyrna_callback_classmethod_add, | 
					
						
							|  |  |  |       METH_VARARGS | METH_STATIC, | 
					
						
							|  |  |  |       pyrna_draw_handler_add_doc}, | 
					
						
							|  |  |  |      &RNA_Space}, | 
					
						
							|  |  |  |     {{"draw_handler_remove", | 
					
						
							|  |  |  |       (PyCFunction)pyrna_callback_classmethod_remove, | 
					
						
							|  |  |  |       METH_VARARGS | METH_STATIC, | 
					
						
							|  |  |  |       pyrna_draw_handler_remove_doc}, | 
					
						
							|  |  |  |      &RNA_Space}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {{"draw_cursor_add", | 
					
						
							|  |  |  |       (PyCFunction)pyrna_callback_classmethod_add, | 
					
						
							|  |  |  |       METH_VARARGS | METH_STATIC, | 
					
						
							|  |  |  |       ""}, | 
					
						
							|  |  |  |      &RNA_WindowManager}, | 
					
						
							|  |  |  |     {{"draw_cursor_remove", | 
					
						
							|  |  |  |       (PyCFunction)pyrna_callback_classmethod_remove, | 
					
						
							|  |  |  |       METH_VARARGS | METH_STATIC, | 
					
						
							|  |  |  |       ""}, | 
					
						
							|  |  |  |      &RNA_WindowManager}, | 
					
						
							|  |  |  |     {{NULL, NULL, 0, NULL}, NULL}, | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BPY_rna_register_cb(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int i; | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (i = 0; pyrna_cb_methods[i].bpy_srna; i++) { | 
					
						
							|  |  |  |     PyObject *cls; | 
					
						
							|  |  |  |     PyObject *func; | 
					
						
							|  |  |  |     PyObject *classmethod; | 
					
						
							|  |  |  |     PyObject *args = PyTuple_New(1); | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     cls = pyrna_srna_Subtype(pyrna_cb_methods[i].bpy_srna); | 
					
						
							|  |  |  |     func = PyCFunction_New(&pyrna_cb_methods[i].py_method, NULL); | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(args, 0, func); | 
					
						
							|  |  |  |     classmethod = PyObject_CallObject((PyObject *)&PyClassMethod_Type, args); | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject_SetAttrString(cls, pyrna_cb_methods[i].py_method.ml_name, classmethod); | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     Py_DECREF(classmethod); | 
					
						
							| 
									
										
										
										
											2019-06-21 09:50:23 +10:00
										 |  |  |     Py_DECREF(args); /* Clears 'func' too. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     Py_DECREF(cls); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-20 13:29:58 +00:00
										 |  |  | } |