1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup pythonintern
19  *
20  * This file is the main interface between Python and Blender's data api (RNA),
21  * exposing RNA to Python so blender data can be accessed in a Python like way.
22  *
23  * The two main types are #BPy_StructRNA and #BPy_PropertyRNA - the base
24  * classes for most of the data Python accesses in blender.
25  */
26 
27 #include <Python.h>
28 
29 #include <float.h> /* FLT_MIN/MAX */
30 #include <stddef.h>
31 
32 #include "RNA_types.h"
33 
34 #include "BLI_bitmap.h"
35 #include "BLI_dynstr.h"
36 #include "BLI_listbase.h"
37 #include "BLI_math_rotation.h"
38 #include "BLI_string.h"
39 #include "BLI_utildefines.h"
40 
41 #include "BPY_extern.h"
42 #include "BPY_extern_clog.h"
43 
44 #include "bpy_capi_utils.h"
45 #include "bpy_intern_string.h"
46 #include "bpy_props.h"
47 #include "bpy_rna.h"
48 #include "bpy_rna_anim.h"
49 #include "bpy_rna_callback.h"
50 
51 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
52 #  include "BLI_ghash.h"
53 #endif
54 
55 #include "RNA_access.h"
56 #include "RNA_define.h" /* RNA_def_property_free_identifier */
57 #include "RNA_enum_types.h"
58 
59 #include "CLG_log.h"
60 
61 #include "MEM_guardedalloc.h"
62 
63 #include "BKE_context.h"
64 #include "BKE_global.h" /* evil G.* */
65 #include "BKE_idprop.h"
66 #include "BKE_idtype.h"
67 #include "BKE_main.h"
68 #include "BKE_report.h"
69 
70 /* Only for types. */
71 #include "BKE_node.h"
72 
73 #include "DEG_depsgraph_query.h"
74 
75 #include "../generic/idprop_py_api.h" /* For IDprop lookups. */
76 #include "../generic/py_capi_utils.h"
77 #include "../generic/python_utildefines.h"
78 
79 #define USE_PEDANTIC_WRITE
80 #define USE_MATHUTILS
81 #define USE_STRING_COERCE
82 
83 /* Unfortunately Python needs to hold a global reference to the context.
84  * If we remove this is means `bpy.context` won't be usable from some parts of the code:
85  * `bpy.app.handler` callbacks for example.
86  * Even though this is arguably "correct", it's going to cause problems for existing scripts,
87  * so accept having this for the time being. */
88 BPy_StructRNA *bpy_context_module = NULL; /* for fast access */
89 
90 static PyObject *pyrna_struct_Subtype(PointerRNA *ptr);
91 static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
92 
93 #define BPY_DOC_ID_PROP_TYPE_NOTE \
94   "   .. note::\n" \
95   "\n" \
96   "      Only the :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \
97   "      :class:`bpy.types.PoseBone` classes support custom properties.\n"
98 
pyrna_struct_validity_check(BPy_StructRNA * pysrna)99 int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
100 {
101   if (pysrna->ptr.type) {
102     return 0;
103   }
104   PyErr_Format(
105       PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name);
106   return -1;
107 }
108 
pyrna_prop_validity_check(BPy_PropertyRNA * self)109 int pyrna_prop_validity_check(BPy_PropertyRNA *self)
110 {
111   if (self->ptr.type) {
112     return 0;
113   }
114   PyErr_Format(PyExc_ReferenceError,
115                "PropertyRNA of type %.200s.%.200s has been removed",
116                Py_TYPE(self)->tp_name,
117                RNA_property_identifier(self->prop));
118   return -1;
119 }
120 
pyrna_invalidate(BPy_DummyPointerRNA * self)121 void pyrna_invalidate(BPy_DummyPointerRNA *self)
122 {
123   RNA_POINTER_INVALIDATE(&self->ptr);
124 }
125 
126 #ifdef USE_PYRNA_INVALIDATE_GC
127 #  define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1))
128 
129 /* Only for sizeof(). */
130 struct gc_generation {
131   PyGC_Head head;
132   int threshold;
133   int count;
134 } gc_generation;
135 
id_release_gc(struct ID * id)136 static void id_release_gc(struct ID *id)
137 {
138   uint j;
139   // uint i = 0;
140   for (j = 0; j < 3; j++) {
141     /* Hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed. */
142     PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
143     PyGC_Head *g = gen->gc.gc_next;
144     while ((g = g->gc.gc_next) != gen) {
145       PyObject *ob = FROM_GC(g);
146       if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) ||
147           PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
148         BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob;
149         if (ob_ptr->ptr.owner_id == id) {
150           pyrna_invalidate(ob_ptr);
151           // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
152           // i++;
153         }
154       }
155     }
156   }
157   // printf("id_release_gc freed '%s': %d\n", id->name, i);
158 }
159 #endif
160 
161 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
162 //#define DEBUG_RNA_WEAKREF
163 
164 struct GHash *id_weakref_pool = NULL;
165 static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref);
166 static PyMethodDef id_free_weakref_cb_def = {
167     "id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL};
168 
169 /* Adds a reference to the list, remember to decref. */
id_weakref_pool_get(ID * id)170 static GHash *id_weakref_pool_get(ID *id)
171 {
172   GHash *weakinfo_hash = NULL;
173 
174   if (id_weakref_pool) {
175     weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
176   }
177   else {
178     /* First time, allocate pool. */
179     id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool");
180     weakinfo_hash = NULL;
181   }
182 
183   if (weakinfo_hash == NULL) {
184     /* We use a ghash as a set, we could use libHX's HXMAP_SINGULAR, but would be an extra dep. */
185     weakinfo_hash = BLI_ghash_ptr_new("rna_id");
186     BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash);
187   }
188 
189   return weakinfo_hash;
190 }
191 
192 /* Called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject(). */
id_weakref_pool_add(ID * id,BPy_DummyPointerRNA * pyrna)193 static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna)
194 {
195   PyObject *weakref;
196   PyObject *weakref_capsule;
197   PyObject *weakref_cb_py;
198 
199   /* Create a new function instance and insert the list as 'self'
200    * so we can remove ourself from it. */
201   GHash *weakinfo_hash = id_weakref_pool_get(id); /* New or existing. */
202 
203   weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL);
204   weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule);
205   Py_DECREF(weakref_capsule);
206 
207   /* Add weakref to weakinfo_hash list. */
208   weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py);
209 
210   Py_DECREF(weakref_cb_py); /* Function owned by the weakref now. */
211 
212   /* Important to add at the end of the hash, since first removal looks at the end. */
213 
214   /* Using a hash table as a set, all 'id's are the same. */
215   BLI_ghash_insert(weakinfo_hash, weakref, id);
216   /* weakinfo_hash owns the weakref */
217 }
218 
219 /* Workaround to get the last id without a lookup. */
220 static ID *_id_tmp_ptr;
value_id_set(void * id)221 static void value_id_set(void *id)
222 {
223   _id_tmp_ptr = (ID *)id;
224 }
225 
226 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash);
id_free_weakref_cb(PyObject * weakinfo_pair,PyObject * weakref)227 static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref)
228 {
229   /* Important to search backwards. */
230   GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_pair, NULL);
231 
232   if (BLI_ghash_len(weakinfo_hash) > 1) {
233     BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL);
234   }
235   else { /* Get the last id and free it. */
236     BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set);
237     id_release_weakref_list(_id_tmp_ptr, weakinfo_hash);
238   }
239 
240   Py_DECREF(weakref);
241 
242   Py_RETURN_NONE;
243 }
244 
id_release_weakref_list(struct ID * id,GHash * weakinfo_hash)245 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
246 {
247   GHashIterator weakinfo_hash_iter;
248 
249   BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
250 
251 #  ifdef DEBUG_RNA_WEAKREF
252   fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_len(weakinfo_hash));
253 #  endif
254 
255   while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) {
256     PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
257     PyObject *item = PyWeakref_GET_OBJECT(weakref);
258     if (item != Py_None) {
259 
260 #  ifdef DEBUG_RNA_WEAKREF
261       PyC_ObSpit("id_release_weakref item ", item);
262 #  endif
263 
264       pyrna_invalidate((BPy_DummyPointerRNA *)item);
265     }
266 
267     Py_DECREF(weakref);
268 
269     BLI_ghashIterator_step(&weakinfo_hash_iter);
270   }
271 
272   BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
273   BLI_ghash_free(weakinfo_hash, NULL, NULL);
274 
275   if (BLI_ghash_len(id_weakref_pool) == 0) {
276     BLI_ghash_free(id_weakref_pool, NULL, NULL);
277     id_weakref_pool = NULL;
278 #  ifdef DEBUG_RNA_WEAKREF
279     printf("id_release_weakref freeing pool\n");
280 #  endif
281   }
282 }
283 
id_release_weakref(struct ID * id)284 static void id_release_weakref(struct ID *id)
285 {
286   GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
287   if (weakinfo_hash) {
288     id_release_weakref_list(id, weakinfo_hash);
289   }
290 }
291 
292 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
293 
BPY_id_release(struct ID * id)294 void BPY_id_release(struct ID *id)
295 {
296 #ifdef USE_PYRNA_INVALIDATE_GC
297   id_release_gc(id);
298 #endif
299 
300 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
301   if (id_weakref_pool) {
302     PyGILState_STATE gilstate = PyGILState_Ensure();
303 
304     id_release_weakref(id);
305 
306     PyGILState_Release(gilstate);
307   }
308 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
309 
310   (void)id;
311 }
312 
313 #ifdef USE_PEDANTIC_WRITE
314 static bool rna_disallow_writes = false;
315 
rna_id_write_error(PointerRNA * ptr,PyObject * key)316 static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
317 {
318   ID *id = ptr->owner_id;
319   if (id) {
320     const short idcode = GS(id->name);
321     /* May need more ID types added here. */
322     if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
323       const char *idtype = BKE_idtype_idcode_to_name(idcode);
324       const char *pyname;
325       if (key && PyUnicode_Check(key)) {
326         pyname = _PyUnicode_AsString(key);
327       }
328       else {
329         pyname = "<UNKNOWN>";
330       }
331 
332       /* Make a nice string error. */
333       BLI_assert(idtype != NULL);
334       PyErr_Format(PyExc_AttributeError,
335                    "Writing to ID classes in this context is not allowed: "
336                    "%.200s, %.200s datablock, error setting %.200s.%.200s",
337                    id->name + 2,
338                    idtype,
339                    RNA_struct_identifier(ptr->type),
340                    pyname);
341 
342       return true;
343     }
344   }
345   return false;
346 }
347 #endif /* USE_PEDANTIC_WRITE */
348 
349 #ifdef USE_PEDANTIC_WRITE
pyrna_write_check(void)350 bool pyrna_write_check(void)
351 {
352   return !rna_disallow_writes;
353 }
354 
pyrna_write_set(bool val)355 void pyrna_write_set(bool val)
356 {
357   rna_disallow_writes = !val;
358 }
359 #else  /* USE_PEDANTIC_WRITE */
pyrna_write_check(void)360 bool pyrna_write_check(void)
361 {
362   return true;
363 }
pyrna_write_set(bool UNUSED (val))364 void pyrna_write_set(bool UNUSED(val))
365 {
366   /* pass */
367 }
368 #endif /* USE_PEDANTIC_WRITE */
369 
370 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
371 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
372 static int pyrna_py_to_prop(
373     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
374 static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
375 
376 #ifdef USE_MATHUTILS
377 #  include "../mathutils/mathutils.h" /* So we can have mathutils callbacks. */
378 
379 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self,
380                                                   PointerRNA *ptr,
381                                                   PropertyRNA *prop,
382                                                   Py_ssize_t start,
383                                                   Py_ssize_t stop,
384                                                   Py_ssize_t length);
385 static short pyrna_rotation_euler_order_get(PointerRNA *ptr,
386                                             const short order_fallback,
387                                             PropertyRNA **r_prop_eul_order);
388 
389 /* bpyrna vector/euler/quat callbacks. */
390 static uchar mathutils_rna_array_cb_index = -1; /* Index for our callbacks. */
391 
392 /* Subtype not used much yet. */
393 #  define MATHUTILS_CB_SUBTYPE_EUL 0
394 #  define MATHUTILS_CB_SUBTYPE_VEC 1
395 #  define MATHUTILS_CB_SUBTYPE_QUAT 2
396 #  define MATHUTILS_CB_SUBTYPE_COLOR 3
397 
mathutils_rna_generic_check(BaseMathObject * bmo)398 static int mathutils_rna_generic_check(BaseMathObject *bmo)
399 {
400   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
401 
402   PYRNA_PROP_CHECK_INT(self);
403 
404   return self->prop ? 0 : -1;
405 }
406 
mathutils_rna_vector_get(BaseMathObject * bmo,int subtype)407 static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
408 {
409   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
410 
411   PYRNA_PROP_CHECK_INT(self);
412 
413   if (self->prop == NULL) {
414     return -1;
415   }
416 
417   RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
418 
419   /* Euler order exception. */
420   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
421     EulerObject *eul = (EulerObject *)bmo;
422     PropertyRNA *prop_eul_order = NULL;
423     eul->order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
424   }
425 
426   return 0;
427 }
428 
mathutils_rna_vector_set(BaseMathObject * bmo,int subtype)429 static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
430 {
431   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
432   float min, max;
433 
434   PYRNA_PROP_CHECK_INT(self);
435 
436   if (self->prop == NULL) {
437     return -1;
438   }
439 
440 #  ifdef USE_PEDANTIC_WRITE
441   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
442     return -1;
443   }
444 #  endif /* USE_PEDANTIC_WRITE */
445 
446   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
447     PyErr_Format(PyExc_AttributeError,
448                  "bpy_prop \"%.200s.%.200s\" is read-only",
449                  RNA_struct_identifier(self->ptr.type),
450                  RNA_property_identifier(self->prop));
451     return -1;
452   }
453 
454   RNA_property_float_range(&self->ptr, self->prop, &min, &max);
455 
456   if (min != -FLT_MAX || max != FLT_MAX) {
457     int i, len = RNA_property_array_length(&self->ptr, self->prop);
458     for (i = 0; i < len; i++) {
459       CLAMP(bmo->data[i], min, max);
460     }
461   }
462 
463   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
464   if (RNA_property_update_check(self->prop)) {
465     RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
466   }
467 
468   /* Euler order exception. */
469   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
470     EulerObject *eul = (EulerObject *)bmo;
471     PropertyRNA *prop_eul_order = NULL;
472     const short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
473     if (order != eul->order) {
474       RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
475       if (RNA_property_update_check(prop_eul_order)) {
476         RNA_property_update(BPY_context_get(), &self->ptr, prop_eul_order);
477       }
478     }
479   }
480   return 0;
481 }
482 
mathutils_rna_vector_get_index(BaseMathObject * bmo,int UNUSED (subtype),int index)483 static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
484 {
485   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
486 
487   PYRNA_PROP_CHECK_INT(self);
488 
489   if (self->prop == NULL) {
490     return -1;
491   }
492 
493   bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index);
494   return 0;
495 }
496 
mathutils_rna_vector_set_index(BaseMathObject * bmo,int UNUSED (subtype),int index)497 static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
498 {
499   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
500 
501   PYRNA_PROP_CHECK_INT(self);
502 
503   if (self->prop == NULL) {
504     return -1;
505   }
506 
507 #  ifdef USE_PEDANTIC_WRITE
508   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
509     return -1;
510   }
511 #  endif /* USE_PEDANTIC_WRITE */
512 
513   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
514     PyErr_Format(PyExc_AttributeError,
515                  "bpy_prop \"%.200s.%.200s\" is read-only",
516                  RNA_struct_identifier(self->ptr.type),
517                  RNA_property_identifier(self->prop));
518     return -1;
519   }
520 
521   RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
522   RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]);
523 
524   if (RNA_property_update_check(self->prop)) {
525     RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
526   }
527 
528   return 0;
529 }
530 
531 static Mathutils_Callback mathutils_rna_array_cb = {
532     (BaseMathCheckFunc)mathutils_rna_generic_check,
533     (BaseMathGetFunc)mathutils_rna_vector_get,
534     (BaseMathSetFunc)mathutils_rna_vector_set,
535     (BaseMathGetIndexFunc)mathutils_rna_vector_get_index,
536     (BaseMathSetIndexFunc)mathutils_rna_vector_set_index,
537 };
538 
539 /* bpyrna matrix callbacks */
540 static uchar mathutils_rna_matrix_cb_index = -1; /* Index for our callbacks. */
541 
mathutils_rna_matrix_get(BaseMathObject * bmo,int UNUSED (subtype))542 static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype))
543 {
544   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
545 
546   PYRNA_PROP_CHECK_INT(self);
547 
548   if (self->prop == NULL) {
549     return -1;
550   }
551 
552   RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
553   return 0;
554 }
555 
mathutils_rna_matrix_set(BaseMathObject * bmo,int UNUSED (subtype))556 static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
557 {
558   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
559 
560   PYRNA_PROP_CHECK_INT(self);
561 
562   if (self->prop == NULL) {
563     return -1;
564   }
565 
566 #  ifdef USE_PEDANTIC_WRITE
567   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
568     return -1;
569   }
570 #  endif /* USE_PEDANTIC_WRITE */
571 
572   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
573     PyErr_Format(PyExc_AttributeError,
574                  "bpy_prop \"%.200s.%.200s\" is read-only",
575                  RNA_struct_identifier(self->ptr.type),
576                  RNA_property_identifier(self->prop));
577     return -1;
578   }
579 
580   /* Can ignore clamping here. */
581   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
582 
583   if (RNA_property_update_check(self->prop)) {
584     RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
585   }
586   return 0;
587 }
588 
589 static Mathutils_Callback mathutils_rna_matrix_cb = {
590     mathutils_rna_generic_check,
591     mathutils_rna_matrix_get,
592     mathutils_rna_matrix_set,
593     NULL,
594     NULL,
595 };
596 
pyrna_rotation_euler_order_get(PointerRNA * ptr,const short order_fallback,PropertyRNA ** r_prop_eul_order)597 static short pyrna_rotation_euler_order_get(PointerRNA *ptr,
598                                             const short order_fallback,
599                                             PropertyRNA **r_prop_eul_order)
600 {
601   /* Attempt to get order. */
602   if (*r_prop_eul_order == NULL) {
603     *r_prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode");
604   }
605 
606   if (*r_prop_eul_order) {
607     const short order = RNA_property_enum_get(ptr, *r_prop_eul_order);
608     /* Could be quat or axisangle. */
609     if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) {
610       return order;
611     }
612   }
613 
614   return order_fallback;
615 }
616 
617 #endif /* USE_MATHUTILS */
618 
619 /**
620  * Note that #PROP_NONE is included as a vector subtype. this is because it is handy to
621  * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4.
622  */
623 #define PROP_ALL_VECTOR_SUBTYPES \
624   PROP_COORDS: \
625   case PROP_TRANSLATION: \
626   case PROP_DIRECTION: \
627   case PROP_VELOCITY: \
628   case PROP_ACCELERATION: \
629   case PROP_XYZ: \
630   case PROP_XYZ_LENGTH
631 
pyrna_math_object_from_array(PointerRNA * ptr,PropertyRNA * prop)632 PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
633 {
634   PyObject *ret = NULL;
635 
636 #ifdef USE_MATHUTILS
637   int subtype, totdim;
638   int len;
639   const int flag = RNA_property_flag(prop);
640   const int type = RNA_property_type(prop);
641   const bool is_thick = (flag & PROP_THICK_WRAP) != 0;
642 
643   /* disallow dynamic sized arrays to be wrapped since the size could change
644    * to a size mathutils does not support */
645   if (flag & PROP_DYNAMIC) {
646     return NULL;
647   }
648 
649   len = RNA_property_array_length(ptr, prop);
650   if (type == PROP_FLOAT) {
651     /* pass */
652   }
653   else if (type == PROP_INT) {
654     if (is_thick) {
655       goto thick_wrap_slice;
656     }
657     else {
658       return NULL;
659     }
660   }
661   else {
662     return NULL;
663   }
664 
665   subtype = RNA_property_subtype(prop);
666   totdim = RNA_property_array_dimension(ptr, prop, NULL);
667 
668   if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
669     if (!is_thick) {
670       /* Owned by the mathutils PyObject. */
671       ret = pyrna_prop_CreatePyObject(ptr, prop);
672     }
673 
674     switch (subtype) {
675       case PROP_ALL_VECTOR_SUBTYPES:
676         if (len >= 2 && len <= 4) {
677           if (is_thick) {
678             ret = Vector_CreatePyObject(NULL, len, NULL);
679             RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
680           }
681           else {
682             PyObject *vec_cb = Vector_CreatePyObject_cb(
683                 ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC);
684             Py_DECREF(ret); /* The vector owns 'ret' now. */
685             ret = vec_cb;   /* Return the vector instead. */
686           }
687         }
688         break;
689       case PROP_MATRIX:
690         if (len == 16) {
691           if (is_thick) {
692             ret = Matrix_CreatePyObject(NULL, 4, 4, NULL);
693             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
694           }
695           else {
696             PyObject *mat_cb = Matrix_CreatePyObject_cb(
697                 ret, 4, 4, mathutils_rna_matrix_cb_index, 0);
698             Py_DECREF(ret); /* The matrix owns 'ret' now. */
699             ret = mat_cb;   /* Return the matrix instead. */
700           }
701         }
702         else if (len == 9) {
703           if (is_thick) {
704             ret = Matrix_CreatePyObject(NULL, 3, 3, NULL);
705             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
706           }
707           else {
708             PyObject *mat_cb = Matrix_CreatePyObject_cb(
709                 ret, 3, 3, mathutils_rna_matrix_cb_index, 0);
710             Py_DECREF(ret); /* The matrix owns 'ret' now. */
711             ret = mat_cb;   /* Return the matrix instead. */
712           }
713         }
714         break;
715       case PROP_EULER:
716       case PROP_QUATERNION:
717         if (len == 3) { /* Euler. */
718           if (is_thick) {
719             /* Attempt to get order,
720              * only needed for thick types since wrapped with update via callbacks. */
721             PropertyRNA *prop_eul_order = NULL;
722             const short order = pyrna_rotation_euler_order_get(
723                 ptr, EULER_ORDER_XYZ, &prop_eul_order);
724 
725             ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA. */
726             RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
727           }
728           else {
729             /* Order will be updated from callback on use. */
730             /* TODO, get order from RNA. */
731             PyObject *eul_cb = Euler_CreatePyObject_cb(
732                 ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL);
733             Py_DECREF(ret); /* The euler owns 'ret' now. */
734             ret = eul_cb;   /* Return the euler instead. */
735           }
736         }
737         else if (len == 4) {
738           if (is_thick) {
739             ret = Quaternion_CreatePyObject(NULL, NULL);
740             RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
741           }
742           else {
743             PyObject *quat_cb = Quaternion_CreatePyObject_cb(
744                 ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT);
745             Py_DECREF(ret); /* The quat owns 'ret' now. */
746             ret = quat_cb;  /* Return the quat instead. */
747           }
748         }
749         break;
750       case PROP_COLOR:
751       case PROP_COLOR_GAMMA:
752         if (len == 3) { /* Color. */
753           if (is_thick) {
754             ret = Color_CreatePyObject(NULL, NULL);
755             RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col);
756           }
757           else {
758             PyObject *col_cb = Color_CreatePyObject_cb(
759                 ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR);
760             Py_DECREF(ret); /* The color owns 'ret' now. */
761             ret = col_cb;   /* Return the color instead. */
762           }
763         }
764         break;
765       default:
766         break;
767     }
768   }
769 
770   if (ret == NULL) {
771     if (is_thick) {
772       /* This is an array we can't reference (since it is not thin wrappable)
773        * and cannot be coerced into a mathutils type, so return as a list. */
774     thick_wrap_slice:
775       ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
776     }
777     else {
778       ret = pyrna_prop_CreatePyObject(ptr, prop); /* Owned by the mathutils PyObject. */
779     }
780   }
781 #else  /* USE_MATHUTILS */
782   (void)ptr;
783   (void)prop;
784 #endif /* USE_MATHUTILS */
785 
786   return ret;
787 }
788 
789 /**
790  * Same as #RNA_enum_value_from_id, but raises an exception.
791  */
pyrna_enum_value_from_id(const EnumPropertyItem * item,const char * identifier,int * r_value,const char * error_prefix)792 int pyrna_enum_value_from_id(const EnumPropertyItem *item,
793                              const char *identifier,
794                              int *r_value,
795                              const char *error_prefix)
796 {
797   if (RNA_enum_value_from_id(item, identifier, r_value) == 0) {
798     const char *enum_str = BPy_enum_as_string(item);
799     PyErr_Format(
800         PyExc_ValueError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
801     MEM_freeN((void *)enum_str);
802     return -1;
803   }
804 
805   return 0;
806 }
807 
808 /* note on __cmp__:
809  * checking the 'ptr->data' matches works in almost all cases,
810  * however there are a few RNA properties that are fake sub-structs and
811  * share the pointer with the parent, in those cases this happens 'a.b == a'
812  * see: r43352 for example.
813  *
814  * So compare the 'ptr->type' as well to avoid this problem.
815  * It's highly unlikely this would happen that 'ptr->data' and 'ptr->prop' would match,
816  * but _not_ 'ptr->type' but include this check for completeness.
817  * - campbell */
818 
pyrna_struct_compare(BPy_StructRNA * a,BPy_StructRNA * b)819 static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
820 {
821   return (((a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ? 0 : -1);
822 }
823 
pyrna_prop_compare(BPy_PropertyRNA * a,BPy_PropertyRNA * b)824 static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
825 {
826   return (((a->prop == b->prop) && (a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ?
827               0 :
828               -1);
829 }
830 
pyrna_struct_richcmp(PyObject * a,PyObject * b,int op)831 static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
832 {
833   PyObject *res;
834   int ok = -1; /* Zero is true. */
835 
836   if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) {
837     ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
838   }
839 
840   switch (op) {
841     case Py_NE:
842       ok = !ok;
843       ATTR_FALLTHROUGH;
844     case Py_EQ:
845       res = ok ? Py_False : Py_True;
846       break;
847 
848     case Py_LT:
849     case Py_LE:
850     case Py_GT:
851     case Py_GE:
852       res = Py_NotImplemented;
853       break;
854     default:
855       PyErr_BadArgument();
856       return NULL;
857   }
858 
859   return Py_INCREF_RET(res);
860 }
861 
pyrna_prop_richcmp(PyObject * a,PyObject * b,int op)862 static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
863 {
864   PyObject *res;
865   int ok = -1; /* Zero is true. */
866 
867   if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) {
868     ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
869   }
870 
871   switch (op) {
872     case Py_NE:
873       ok = !ok;
874       ATTR_FALLTHROUGH;
875     case Py_EQ:
876       res = ok ? Py_False : Py_True;
877       break;
878 
879     case Py_LT:
880     case Py_LE:
881     case Py_GT:
882     case Py_GE:
883       res = Py_NotImplemented;
884       break;
885     default:
886       PyErr_BadArgument();
887       return NULL;
888   }
889 
890   return Py_INCREF_RET(res);
891 }
892 
893 /*----------------------repr--------------------------------------------*/
pyrna_struct_str(BPy_StructRNA * self)894 static PyObject *pyrna_struct_str(BPy_StructRNA *self)
895 {
896   PyObject *ret;
897   const char *name;
898   const char *extra_info = "";
899 
900   if (!PYRNA_STRUCT_IS_VALID(self)) {
901     return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name);
902   }
903 
904   ID *id = self->ptr.owner_id;
905   if (id && id != DEG_get_original_id(id)) {
906     extra_info = ", evaluated";
907   }
908 
909   /* Print name if available.
910    *
911    * Always include the pointer address since it can help identify unique data,
912    * or when data is re-allocated internally. */
913   name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL);
914   if (name) {
915     ret = PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\") at %p%s>",
916                                RNA_struct_identifier(self->ptr.type),
917                                name,
918                                self->ptr.data,
919                                extra_info);
920     MEM_freeN((void *)name);
921     return ret;
922   }
923 
924   return PyUnicode_FromFormat("<bpy_struct, %.200s at %p%s>",
925                               RNA_struct_identifier(self->ptr.type),
926                               self->ptr.data,
927                               extra_info);
928 }
929 
pyrna_struct_repr(BPy_StructRNA * self)930 static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
931 {
932   ID *id = self->ptr.owner_id;
933   PyObject *tmp_str;
934   PyObject *ret;
935 
936   if (id == NULL || !PYRNA_STRUCT_IS_VALID(self) || (DEG_get_original_id(id) != id)) {
937     /* fallback */
938     return pyrna_struct_str(self);
939   }
940 
941   tmp_str = PyUnicode_FromString(id->name + 2);
942 
943   if (RNA_struct_is_ID(self->ptr.type) && (id->flag & LIB_EMBEDDED_DATA) == 0) {
944     ret = PyUnicode_FromFormat(
945         "bpy.data.%s[%R]", BKE_idtype_idcode_to_name_plural(GS(id->name)), tmp_str);
946   }
947   else {
948     const char *path;
949     ID *real_id = NULL;
950     path = RNA_path_from_real_ID_to_struct(G_MAIN, &self->ptr, &real_id);
951     if (path != NULL) {
952       /* 'real_id' may be NULL in some cases, although the only valid one is evaluated data,
953        * which should have already been caught above.
954        * So assert, but handle it without crashing for release builds. */
955       BLI_assert(real_id != NULL);
956 
957       if (real_id != NULL) {
958         Py_DECREF(tmp_str);
959         tmp_str = PyUnicode_FromString(real_id->name + 2);
960         ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
961                                    BKE_idtype_idcode_to_name_plural(GS(real_id->name)),
962                                    tmp_str,
963                                    path);
964       }
965       else {
966         /* Can't find the path, print something useful as a fallback. */
967         ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
968                                    BKE_idtype_idcode_to_name_plural(GS(id->name)),
969                                    tmp_str,
970                                    RNA_struct_identifier(self->ptr.type));
971       }
972       MEM_freeN((void *)path);
973     }
974     else {
975       /* Can't find the path, print something useful as a fallback. */
976       ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
977                                  BKE_idtype_idcode_to_name_plural(GS(id->name)),
978                                  tmp_str,
979                                  RNA_struct_identifier(self->ptr.type));
980     }
981   }
982 
983   Py_DECREF(tmp_str);
984 
985   return ret;
986 }
987 
pyrna_prop_str(BPy_PropertyRNA * self)988 static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
989 {
990   PyObject *ret;
991   PointerRNA ptr;
992   const char *name;
993   const char *type_id = NULL;
994   char type_fmt[64] = "";
995   int type;
996 
997   PYRNA_PROP_CHECK_OBJ(self);
998 
999   type = RNA_property_type(self->prop);
1000 
1001   if (RNA_enum_id_from_value(rna_enum_property_type_items, type, &type_id) == 0) {
1002     /* Should never happen. */
1003     PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error");
1004     return NULL;
1005   }
1006 
1007   /* This should never fail. */
1008   int len = -1;
1009   char *c = type_fmt;
1010 
1011   while ((*c++ = tolower(*type_id++))) {
1012   }
1013 
1014   if (type == PROP_COLLECTION) {
1015     len = pyrna_prop_collection_length(self);
1016   }
1017   else if (RNA_property_array_check(self->prop)) {
1018     len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
1019   }
1020 
1021   if (len != -1) {
1022     sprintf(--c, "[%d]", len);
1023   }
1024 
1025   /* If a pointer, try to print name of pointer target too. */
1026   if (type == PROP_POINTER) {
1027     ptr = RNA_property_pointer_get(&self->ptr, self->prop);
1028     name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL);
1029 
1030     if (name) {
1031       ret = PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>",
1032                                  type_fmt,
1033                                  RNA_struct_identifier(self->ptr.type),
1034                                  RNA_property_identifier(self->prop),
1035                                  name);
1036       MEM_freeN((void *)name);
1037       return ret;
1038     }
1039   }
1040   if (type == PROP_COLLECTION) {
1041     PointerRNA r_ptr;
1042     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
1043       return PyUnicode_FromFormat(
1044           "<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type));
1045     }
1046   }
1047 
1048   return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>",
1049                               type_fmt,
1050                               RNA_struct_identifier(self->ptr.type),
1051                               RNA_property_identifier(self->prop));
1052 }
1053 
pyrna_prop_repr_ex(BPy_PropertyRNA * self,const int index_dim,const int index)1054 static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, const int index)
1055 {
1056   ID *id = self->ptr.owner_id;
1057   PyObject *tmp_str;
1058   PyObject *ret;
1059   const char *path;
1060 
1061   PYRNA_PROP_CHECK_OBJ(self);
1062 
1063   if (id == NULL) {
1064     /* Fallback. */
1065     return pyrna_prop_str(self);
1066   }
1067 
1068   tmp_str = PyUnicode_FromString(id->name + 2);
1069 
1070   /* Note that using G_MAIN is absolutely not ideal, but we have no access to actual Main DB from
1071    * here. */
1072   ID *real_id = NULL;
1073   path = RNA_path_from_real_ID_to_property_index(
1074       G_MAIN, &self->ptr, self->prop, index_dim, index, &real_id);
1075 
1076   if (path) {
1077     if (real_id != id) {
1078       Py_DECREF(tmp_str);
1079       tmp_str = PyUnicode_FromString(real_id->name + 2);
1080     }
1081     const char *data_delim = (path[0] == '[') ? "" : ".";
1082     ret = PyUnicode_FromFormat("bpy.data.%s[%R]%s%s",
1083                                BKE_idtype_idcode_to_name_plural(GS(real_id->name)),
1084                                tmp_str,
1085                                data_delim,
1086                                path);
1087 
1088     MEM_freeN((void *)path);
1089   }
1090   else {
1091     /* Can't find the path, print something useful as a fallback. */
1092     ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
1093                                BKE_idtype_idcode_to_name_plural(GS(id->name)),
1094                                tmp_str,
1095                                RNA_property_identifier(self->prop));
1096   }
1097 
1098   Py_DECREF(tmp_str);
1099 
1100   return ret;
1101 }
1102 
pyrna_prop_repr(BPy_PropertyRNA * self)1103 static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
1104 {
1105   return pyrna_prop_repr_ex(self, 0, -1);
1106 }
1107 
pyrna_prop_array_repr(BPy_PropertyArrayRNA * self)1108 static PyObject *pyrna_prop_array_repr(BPy_PropertyArrayRNA *self)
1109 {
1110   return pyrna_prop_repr_ex((BPy_PropertyRNA *)self, self->arraydim, self->arrayoffset);
1111 }
1112 
pyrna_func_repr(BPy_FunctionRNA * self)1113 static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
1114 {
1115   return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
1116                               Py_TYPE(self)->tp_name,
1117                               RNA_struct_identifier(self->ptr.type),
1118                               RNA_function_identifier(self->func));
1119 }
1120 
pyrna_struct_hash(BPy_StructRNA * self)1121 static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self)
1122 {
1123   return _Py_HashPointer(self->ptr.data);
1124 }
1125 
1126 /* From Python's meth_hash v3.1.2. */
pyrna_prop_hash(BPy_PropertyRNA * self)1127 static long pyrna_prop_hash(BPy_PropertyRNA *self)
1128 {
1129   long x, y;
1130   if (self->ptr.data == NULL) {
1131     x = 0;
1132   }
1133   else {
1134     x = _Py_HashPointer(self->ptr.data);
1135     if (x == -1) {
1136       return -1;
1137     }
1138   }
1139   y = _Py_HashPointer((void *)(self->prop));
1140   if (y == -1) {
1141     return -1;
1142   }
1143   x ^= y;
1144   if (x == -1) {
1145     x = -2;
1146   }
1147   return x;
1148 }
1149 
1150 #ifdef USE_PYRNA_STRUCT_REFERENCE
pyrna_struct_traverse(BPy_StructRNA * self,visitproc visit,void * arg)1151 static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
1152 {
1153   Py_VISIT(self->reference);
1154   return 0;
1155 }
1156 
pyrna_struct_clear(BPy_StructRNA * self)1157 static int pyrna_struct_clear(BPy_StructRNA *self)
1158 {
1159   Py_CLEAR(self->reference);
1160   return 0;
1161 }
1162 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1163 
1164 /* Use our own dealloc so we can free a property if we use one. */
pyrna_struct_dealloc(BPy_StructRNA * self)1165 static void pyrna_struct_dealloc(BPy_StructRNA *self)
1166 {
1167 #ifdef PYRNA_FREE_SUPPORT
1168   if (self->freeptr && self->ptr.data) {
1169     IDP_FreeProperty(self->ptr.data);
1170     self->ptr.data = NULL;
1171   }
1172 #endif /* PYRNA_FREE_SUPPORT */
1173 
1174 #ifdef USE_WEAKREFS
1175   if (self->in_weakreflist != NULL) {
1176     PyObject_ClearWeakRefs((PyObject *)self);
1177   }
1178 #endif
1179 
1180 #ifdef USE_PYRNA_STRUCT_REFERENCE
1181   if (self->reference) {
1182     PyObject_GC_UnTrack(self);
1183     pyrna_struct_clear(self);
1184   }
1185 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1186 
1187   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1188   Py_TYPE(self)->tp_free(self);
1189 }
1190 
1191 #ifdef USE_PYRNA_STRUCT_REFERENCE
pyrna_struct_reference_set(BPy_StructRNA * self,PyObject * reference)1192 static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
1193 {
1194   if (self->reference) {
1195     //      PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */
1196     pyrna_struct_clear(self);
1197   }
1198   /* Reference is now NULL. */
1199 
1200   if (reference) {
1201     self->reference = reference;
1202     Py_INCREF(reference);
1203     //      PyObject_GC_Track(self);  /* INITIALIZED TRACKED ? */
1204   }
1205 }
1206 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1207 
1208 /* Use our own dealloc so we can free a property if we use one. */
pyrna_prop_dealloc(BPy_PropertyRNA * self)1209 static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
1210 {
1211 #ifdef USE_WEAKREFS
1212   if (self->in_weakreflist != NULL) {
1213     PyObject_ClearWeakRefs((PyObject *)self);
1214   }
1215 #endif
1216   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1217   Py_TYPE(self)->tp_free(self);
1218 }
1219 
pyrna_prop_array_dealloc(BPy_PropertyRNA * self)1220 static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
1221 {
1222 #ifdef USE_WEAKREFS
1223   if (self->in_weakreflist != NULL) {
1224     PyObject_ClearWeakRefs((PyObject *)self);
1225   }
1226 #endif
1227   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1228   Py_TYPE(self)->tp_free(self);
1229 }
1230 
pyrna_enum_as_string(PointerRNA * ptr,PropertyRNA * prop)1231 static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
1232 {
1233   const EnumPropertyItem *item;
1234   const char *result;
1235   bool free = false;
1236 
1237   RNA_property_enum_items(BPY_context_get(), ptr, prop, &item, NULL, &free);
1238   if (item) {
1239     result = BPy_enum_as_string(item);
1240   }
1241   else {
1242     result = "";
1243   }
1244 
1245   if (free) {
1246     MEM_freeN((void *)item);
1247   }
1248 
1249   return result;
1250 }
1251 
pyrna_string_to_enum(PyObject * item,PointerRNA * ptr,PropertyRNA * prop,int * r_value,const char * error_prefix)1252 static int pyrna_string_to_enum(
1253     PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *r_value, const char *error_prefix)
1254 {
1255   const char *param = _PyUnicode_AsString(item);
1256 
1257   if (param == NULL) {
1258     PyErr_Format(PyExc_TypeError,
1259                  "%.200s expected a string enum, not %.200s",
1260                  error_prefix,
1261                  Py_TYPE(item)->tp_name);
1262     return -1;
1263   }
1264 
1265   if (!RNA_property_enum_value(BPY_context_get(), ptr, prop, param, r_value)) {
1266     const char *enum_str = pyrna_enum_as_string(ptr, prop);
1267     PyErr_Format(PyExc_TypeError,
1268                  "%.200s enum \"%.200s\" not found in (%s)",
1269                  error_prefix,
1270                  param,
1271                  enum_str);
1272     MEM_freeN((void *)enum_str);
1273     return -1;
1274   }
1275 
1276   return 0;
1277 }
1278 
1279 /**
1280  * Takes a set of strings and map it to and array of booleans.
1281  *
1282  * Useful when the values aren't flags.
1283  *
1284  * \param type_convert_sign: Maps signed to unsigned range,
1285  * needed when we want to use the full range of a signed short/char.
1286  */
pyrna_set_to_enum_bitmap(const EnumPropertyItem * items,PyObject * value,int type_size,bool type_convert_sign,int bitmap_size,const char * error_prefix)1287 BLI_bitmap *pyrna_set_to_enum_bitmap(const EnumPropertyItem *items,
1288                                      PyObject *value,
1289                                      int type_size,
1290                                      bool type_convert_sign,
1291                                      int bitmap_size,
1292                                      const char *error_prefix)
1293 {
1294   /* Set looping. */
1295   Py_ssize_t pos = 0;
1296   Py_ssize_t hash = 0;
1297   PyObject *key;
1298 
1299   BLI_bitmap *bitmap = BLI_BITMAP_NEW(bitmap_size, __func__);
1300 
1301   while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1302     const char *param = _PyUnicode_AsString(key);
1303     if (param == NULL) {
1304       PyErr_Format(PyExc_TypeError,
1305                    "%.200s expected a string, not %.200s",
1306                    error_prefix,
1307                    Py_TYPE(key)->tp_name);
1308       goto error;
1309     }
1310 
1311     int ret;
1312     if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
1313       goto error;
1314     }
1315 
1316     int index = ret;
1317 
1318     if (type_convert_sign) {
1319       if (type_size == 2) {
1320         union {
1321           signed short as_signed;
1322           ushort as_unsigned;
1323         } ret_convert;
1324         ret_convert.as_signed = (signed short)ret;
1325         index = (int)ret_convert.as_unsigned;
1326       }
1327       else if (type_size == 1) {
1328         union {
1329           signed char as_signed;
1330           uchar as_unsigned;
1331         } ret_convert;
1332         ret_convert.as_signed = (signed char)ret;
1333         index = (int)ret_convert.as_unsigned;
1334       }
1335       else {
1336         BLI_assert(0);
1337       }
1338     }
1339     BLI_assert(index < bitmap_size);
1340     BLI_BITMAP_ENABLE(bitmap, index);
1341   }
1342 
1343   return bitmap;
1344 
1345 error:
1346   MEM_freeN(bitmap);
1347   return NULL;
1348 }
1349 
1350 /* 'value' _must_ be a set type, error check before calling. */
pyrna_set_to_enum_bitfield(const EnumPropertyItem * items,PyObject * value,int * r_value,const char * error_prefix)1351 int pyrna_set_to_enum_bitfield(const EnumPropertyItem *items,
1352                                PyObject *value,
1353                                int *r_value,
1354                                const char *error_prefix)
1355 {
1356   /* Set of enum items, concatenate all values with OR. */
1357   int ret, flag = 0;
1358 
1359   /* Set looping. */
1360   Py_ssize_t pos = 0;
1361   Py_ssize_t hash = 0;
1362   PyObject *key;
1363 
1364   *r_value = 0;
1365 
1366   while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1367     const char *param = _PyUnicode_AsString(key);
1368 
1369     if (param == NULL) {
1370       PyErr_Format(PyExc_TypeError,
1371                    "%.200s expected a string, not %.200s",
1372                    error_prefix,
1373                    Py_TYPE(key)->tp_name);
1374       return -1;
1375     }
1376 
1377     if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
1378       return -1;
1379     }
1380 
1381     flag |= ret;
1382   }
1383 
1384   *r_value = flag;
1385   return 0;
1386 }
1387 
pyrna_prop_to_enum_bitfield(PointerRNA * ptr,PropertyRNA * prop,PyObject * value,int * r_value,const char * error_prefix)1388 static int pyrna_prop_to_enum_bitfield(
1389     PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
1390 {
1391   const EnumPropertyItem *item;
1392   int ret;
1393   bool free = false;
1394 
1395   *r_value = 0;
1396 
1397   if (!PyAnySet_Check(value)) {
1398     PyErr_Format(PyExc_TypeError,
1399                  "%.200s, %.200s.%.200s expected a set, not a %.200s",
1400                  error_prefix,
1401                  RNA_struct_identifier(ptr->type),
1402                  RNA_property_identifier(prop),
1403                  Py_TYPE(value)->tp_name);
1404     return -1;
1405   }
1406 
1407   RNA_property_enum_items(BPY_context_get(), ptr, prop, &item, NULL, &free);
1408 
1409   if (item) {
1410     ret = pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix);
1411   }
1412   else {
1413     if (PySet_GET_SIZE(value)) {
1414       PyErr_Format(PyExc_TypeError,
1415                    "%.200s: empty enum \"%.200s\" could not have any values assigned",
1416                    error_prefix,
1417                    RNA_property_identifier(prop));
1418       ret = -1;
1419     }
1420     else {
1421       ret = 0;
1422     }
1423   }
1424 
1425   if (free) {
1426     MEM_freeN((void *)item);
1427   }
1428 
1429   return ret;
1430 }
1431 
pyrna_enum_bitfield_to_py(const EnumPropertyItem * items,int value)1432 PyObject *pyrna_enum_bitfield_to_py(const EnumPropertyItem *items, int value)
1433 {
1434   PyObject *ret = PySet_New(NULL);
1435   const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1436 
1437   if (RNA_enum_bitflag_identifiers(items, value, identifier)) {
1438     PyObject *item;
1439     int index;
1440     for (index = 0; identifier[index]; index++) {
1441       item = PyUnicode_FromString(identifier[index]);
1442       PySet_Add(ret, item);
1443       Py_DECREF(item);
1444     }
1445   }
1446 
1447   return ret;
1448 }
1449 
pyrna_enum_to_py(PointerRNA * ptr,PropertyRNA * prop,int val)1450 static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
1451 {
1452   PyObject *item, *ret = NULL;
1453 
1454   if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1455     const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1456 
1457     ret = PySet_New(NULL);
1458 
1459     if (RNA_property_enum_bitflag_identifiers(BPY_context_get(), ptr, prop, val, identifier)) {
1460       int index;
1461 
1462       for (index = 0; identifier[index]; index++) {
1463         item = PyUnicode_FromString(identifier[index]);
1464         PySet_Add(ret, item);
1465         Py_DECREF(item);
1466       }
1467     }
1468   }
1469   else {
1470     const char *identifier;
1471     if (RNA_property_enum_identifier(BPY_context_get(), ptr, prop, val, &identifier)) {
1472       ret = PyUnicode_FromString(identifier);
1473     }
1474     else {
1475       /* Static, no need to free. */
1476       const EnumPropertyItem *enum_item;
1477       bool free_dummy;
1478       RNA_property_enum_items_ex(NULL, ptr, prop, true, &enum_item, NULL, &free_dummy);
1479       BLI_assert(!free_dummy);
1480 
1481       /* Do not print warning in case of DummyRNA_NULL_items,
1482        * this one will never match any value... */
1483       if (enum_item != DummyRNA_NULL_items) {
1484         const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
1485 
1486         /* Prefer not to fail silently in case of API errors, maybe disable it later. */
1487         CLOG_WARN(BPY_LOG_RNA,
1488                   "current value '%d' "
1489                   "matches no enum in '%s', '%s', '%s'",
1490                   val,
1491                   RNA_struct_identifier(ptr->type),
1492                   ptr_name,
1493                   RNA_property_identifier(prop));
1494 
1495 #if 0 /* Gives Python decoding errors while generating docs :( */
1496         char error_str[256];
1497         BLI_snprintf(error_str,
1498                      sizeof(error_str),
1499                      "RNA Warning: Current value \"%d\" "
1500                      "matches no enum in '%s', '%s', '%s'",
1501                      val,
1502                      RNA_struct_identifier(ptr->type),
1503                      ptr_name,
1504                      RNA_property_identifier(prop));
1505 
1506         PyErr_Warn(PyExc_RuntimeWarning, error_str);
1507 #endif
1508 
1509         if (ptr_name) {
1510           MEM_freeN((void *)ptr_name);
1511         }
1512       }
1513 
1514       ret = PyUnicode_FromString("");
1515 #if 0
1516       PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
1517       ret = NULL;
1518 #endif
1519     }
1520   }
1521 
1522   return ret;
1523 }
1524 
pyrna_prop_to_py(PointerRNA * ptr,PropertyRNA * prop)1525 PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
1526 {
1527   PyObject *ret;
1528   const int type = RNA_property_type(prop);
1529 
1530   if (RNA_property_array_check(prop)) {
1531     return pyrna_py_from_array(ptr, prop);
1532   }
1533 
1534   /* See if we can coerce into a Python type - 'PropertyType'. */
1535   switch (type) {
1536     case PROP_BOOLEAN:
1537       ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
1538       break;
1539     case PROP_INT:
1540       ret = PyLong_FromLong(RNA_property_int_get(ptr, prop));
1541       break;
1542     case PROP_FLOAT:
1543       ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
1544       break;
1545     case PROP_STRING: {
1546       const int subtype = RNA_property_subtype(prop);
1547       const char *buf;
1548       int buf_len;
1549       char buf_fixed[32];
1550 
1551       buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
1552 #ifdef USE_STRING_COERCE
1553       /* Only file paths get special treatment, they may contain non utf-8 chars. */
1554       if (subtype == PROP_BYTESTRING) {
1555         ret = PyBytes_FromStringAndSize(buf, buf_len);
1556       }
1557       else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1558         ret = PyC_UnicodeFromByteAndSize(buf, buf_len);
1559       }
1560       else {
1561         ret = PyUnicode_FromStringAndSize(buf, buf_len);
1562       }
1563 #else  /* USE_STRING_COERCE */
1564       if (subtype == PROP_BYTESTRING) {
1565         ret = PyBytes_FromStringAndSize(buf, buf_len);
1566       }
1567       else {
1568         ret = PyUnicode_FromStringAndSize(buf, buf_len);
1569       }
1570 #endif /* USE_STRING_COERCE */
1571       if (buf_fixed != buf) {
1572         MEM_freeN((void *)buf);
1573       }
1574       break;
1575     }
1576     case PROP_ENUM: {
1577       ret = pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop));
1578       break;
1579     }
1580     case PROP_POINTER: {
1581       PointerRNA newptr;
1582       newptr = RNA_property_pointer_get(ptr, prop);
1583       if (newptr.data) {
1584         ret = pyrna_struct_CreatePyObject(&newptr);
1585       }
1586       else {
1587         ret = Py_None;
1588         Py_INCREF(ret);
1589       }
1590       break;
1591     }
1592     case PROP_COLLECTION:
1593       ret = pyrna_prop_CreatePyObject(ptr, prop);
1594       break;
1595     default:
1596       PyErr_Format(PyExc_TypeError,
1597                    "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)",
1598                    type);
1599       ret = NULL;
1600       break;
1601   }
1602 
1603   return ret;
1604 }
1605 
1606 /**
1607  * This function is used by operators and converting dicts into collections.
1608  * It takes keyword args and fills them with property values.
1609  */
pyrna_pydict_to_props(PointerRNA * ptr,PyObject * kw,const bool all_args,const char * error_prefix)1610 int pyrna_pydict_to_props(PointerRNA *ptr,
1611                           PyObject *kw,
1612                           const bool all_args,
1613                           const char *error_prefix)
1614 {
1615   int error_val = 0;
1616   int totkw;
1617   const char *arg_name = NULL;
1618   PyObject *item;
1619 
1620   totkw = kw ? PyDict_Size(kw) : 0;
1621 
1622   RNA_STRUCT_BEGIN (ptr, prop) {
1623     arg_name = RNA_property_identifier(prop);
1624 
1625     if (STREQ(arg_name, "rna_type")) {
1626       continue;
1627     }
1628 
1629     if (kw == NULL) {
1630       PyErr_Format(PyExc_TypeError,
1631                    "%.200s: no keywords, expected \"%.200s\"",
1632                    error_prefix,
1633                    arg_name ? arg_name : "<UNKNOWN>");
1634       error_val = -1;
1635       break;
1636     }
1637 
1638     item = PyDict_GetItemString(kw, arg_name); /* Wont set an error. */
1639 
1640     if (item == NULL) {
1641       if (all_args) {
1642         PyErr_Format(PyExc_TypeError,
1643                      "%.200s: keyword \"%.200s\" missing",
1644                      error_prefix,
1645                      arg_name ? arg_name : "<UNKNOWN>");
1646         error_val = -1; /* pyrna_py_to_prop sets the error. */
1647         break;
1648       }
1649     }
1650     else {
1651       if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
1652         error_val = -1;
1653         break;
1654       }
1655       totkw--;
1656     }
1657   }
1658   RNA_STRUCT_END;
1659 
1660   if (error_val == 0 && totkw > 0) { /* Some keywords were given that were not used :/. */
1661     PyObject *key, *value;
1662     Py_ssize_t pos = 0;
1663 
1664     while (PyDict_Next(kw, &pos, &key, &value)) {
1665       arg_name = _PyUnicode_AsString(key);
1666       if (RNA_struct_find_property(ptr, arg_name) == NULL) {
1667         break;
1668       }
1669       arg_name = NULL;
1670     }
1671 
1672     PyErr_Format(PyExc_TypeError,
1673                  "%.200s: keyword \"%.200s\" unrecognized",
1674                  error_prefix,
1675                  arg_name ? arg_name : "<UNKNOWN>");
1676     error_val = -1;
1677   }
1678 
1679   return error_val;
1680 }
1681 
pyrna_func_to_py(const PointerRNA * ptr,FunctionRNA * func)1682 static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
1683 {
1684   BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *)PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
1685   pyfunc->ptr = *ptr;
1686   pyfunc->func = func;
1687   return (PyObject *)pyfunc;
1688 }
1689 
pyrna_py_to_prop(PointerRNA * ptr,PropertyRNA * prop,void * data,PyObject * value,const char * error_prefix)1690 static int pyrna_py_to_prop(
1691     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1692 {
1693   /* XXX hard limits should be checked here. */
1694   const int type = RNA_property_type(prop);
1695 
1696   if (RNA_property_array_check(prop)) {
1697     /* Done getting the length. */
1698     if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) {
1699       return -1;
1700     }
1701   }
1702   else {
1703     /* Normal Property (not an array). */
1704 
1705     /* See if we can coerce into a Python type - 'PropertyType'. */
1706     switch (type) {
1707       case PROP_BOOLEAN: {
1708         int param;
1709         /* Prefer not to have an exception here
1710          * however so many poll functions return None or a valid Object.
1711          * It's a hassle to convert these into a bool before returning. */
1712         if (RNA_parameter_flag(prop) & PARM_OUTPUT) {
1713           param = PyObject_IsTrue(value);
1714         }
1715         else {
1716           param = PyC_Long_AsI32(value);
1717 
1718           if (UNLIKELY(param & ~1)) { /* Only accept 0/1. */
1719             param = -1;               /* Error out below. */
1720           }
1721         }
1722 
1723         if (param == -1) {
1724           PyErr_Format(PyExc_TypeError,
1725                        "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1726                        error_prefix,
1727                        RNA_struct_identifier(ptr->type),
1728                        RNA_property_identifier(prop),
1729                        Py_TYPE(value)->tp_name);
1730           return -1;
1731         }
1732 
1733         if (data) {
1734           *((bool *)data) = param;
1735         }
1736         else {
1737           RNA_property_boolean_set(ptr, prop, param);
1738         }
1739 
1740         break;
1741       }
1742       case PROP_INT: {
1743         int overflow;
1744         const long param = PyLong_AsLongAndOverflow(value, &overflow);
1745         if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1746           PyErr_Format(PyExc_ValueError,
1747                        "%.200s %.200s.%.200s value not in 'int' range "
1748                        "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1749                        error_prefix,
1750                        RNA_struct_identifier(ptr->type),
1751                        RNA_property_identifier(prop));
1752           return -1;
1753         }
1754         if (param == -1 && PyErr_Occurred()) {
1755           PyErr_Format(PyExc_TypeError,
1756                        "%.200s %.200s.%.200s expected an int type, not %.200s",
1757                        error_prefix,
1758                        RNA_struct_identifier(ptr->type),
1759                        RNA_property_identifier(prop),
1760                        Py_TYPE(value)->tp_name);
1761           return -1;
1762         }
1763 
1764         int param_i = (int)param;
1765         if (data) {
1766           RNA_property_int_clamp(ptr, prop, &param_i);
1767           *((int *)data) = param_i;
1768         }
1769         else {
1770           RNA_property_int_set(ptr, prop, param_i);
1771         }
1772 
1773         break;
1774       }
1775       case PROP_FLOAT: {
1776         const float param = PyFloat_AsDouble(value);
1777         if (PyErr_Occurred()) {
1778           PyErr_Format(PyExc_TypeError,
1779                        "%.200s %.200s.%.200s expected a float type, not %.200s",
1780                        error_prefix,
1781                        RNA_struct_identifier(ptr->type),
1782                        RNA_property_identifier(prop),
1783                        Py_TYPE(value)->tp_name);
1784           return -1;
1785         }
1786 
1787         if (data) {
1788           RNA_property_float_clamp(ptr, prop, (float *)&param);
1789           *((float *)data) = param;
1790         }
1791         else {
1792           RNA_property_float_set(ptr, prop, param);
1793         }
1794 
1795         break;
1796       }
1797       case PROP_STRING: {
1798         const int subtype = RNA_property_subtype(prop);
1799         const char *param;
1800 
1801         if (value == Py_None) {
1802           if ((RNA_property_flag(prop) & PROP_NEVER_NULL) == 0) {
1803             if (data) {
1804               if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1805                 *(char *)data = 0;
1806               }
1807               else {
1808                 *((char **)data) = (char *)NULL;
1809               }
1810             }
1811             else {
1812               RNA_property_string_set(ptr, prop, NULL);
1813             }
1814           }
1815           else {
1816             PyC_Err_Format_Prefix(PyExc_TypeError,
1817                                   "%.200s %.200s.%.200s doesn't support None from string types",
1818                                   error_prefix,
1819                                   RNA_struct_identifier(ptr->type),
1820                                   RNA_property_identifier(prop));
1821             return -1;
1822           }
1823         }
1824         else if (subtype == PROP_BYTESTRING) {
1825 
1826           /* Byte String. */
1827 
1828           param = PyBytes_AsString(value);
1829 
1830           if (param == NULL) {
1831             if (PyBytes_Check(value)) {
1832               /* there was an error assigning a string type,
1833                * rather than setting a new error, prefix the existing one
1834                */
1835               PyC_Err_Format_Prefix(PyExc_TypeError,
1836                                     "%.200s %.200s.%.200s error assigning bytes",
1837                                     error_prefix,
1838                                     RNA_struct_identifier(ptr->type),
1839                                     RNA_property_identifier(prop));
1840             }
1841             else {
1842               PyErr_Format(PyExc_TypeError,
1843                            "%.200s %.200s.%.200s expected a bytes type, not %.200s",
1844                            error_prefix,
1845                            RNA_struct_identifier(ptr->type),
1846                            RNA_property_identifier(prop),
1847                            Py_TYPE(value)->tp_name);
1848             }
1849 
1850             return -1;
1851           }
1852 
1853           if (data) {
1854             if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1855               BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
1856             }
1857             else {
1858               *((char **)data) = (char *)param;
1859             }
1860           }
1861           else {
1862             RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value));
1863           }
1864         }
1865         else {
1866           /* Unicode String. */
1867 #ifdef USE_STRING_COERCE
1868           PyObject *value_coerce = NULL;
1869           if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1870             /* TODO, get size. */
1871             param = PyC_UnicodeAsByte(value, &value_coerce);
1872           }
1873           else {
1874             param = _PyUnicode_AsString(value);
1875           }
1876 #else  /* USE_STRING_COERCE */
1877           param = _PyUnicode_AsString(value);
1878 #endif /* USE_STRING_COERCE */
1879 
1880           if (param == NULL) {
1881             if (PyUnicode_Check(value)) {
1882               /* there was an error assigning a string type,
1883                * rather than setting a new error, prefix the existing one
1884                */
1885               PyC_Err_Format_Prefix(PyExc_TypeError,
1886                                     "%.200s %.200s.%.200s error assigning string",
1887                                     error_prefix,
1888                                     RNA_struct_identifier(ptr->type),
1889                                     RNA_property_identifier(prop));
1890             }
1891             else {
1892               PyErr_Format(PyExc_TypeError,
1893                            "%.200s %.200s.%.200s expected a string type, not %.200s",
1894                            error_prefix,
1895                            RNA_struct_identifier(ptr->type),
1896                            RNA_property_identifier(prop),
1897                            Py_TYPE(value)->tp_name);
1898             }
1899 
1900             return -1;
1901           }
1902 
1903           /* Same as bytes. */
1904           /* XXX, this is suspect, but needed for function calls,
1905            * need to see if there's a better way. */
1906           if (data) {
1907             if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1908               BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
1909             }
1910             else {
1911               *((char **)data) = (char *)param;
1912             }
1913           }
1914           else {
1915             RNA_property_string_set(ptr, prop, param);
1916           }
1917 
1918 #ifdef USE_STRING_COERCE
1919           Py_XDECREF(value_coerce);
1920 #endif /* USE_STRING_COERCE */
1921         }
1922         break;
1923       }
1924       case PROP_ENUM: {
1925         int val = 0;
1926 
1927         /* Type checking is done by each function. */
1928         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1929           /* Set of enum items, concatenate all values with OR. */
1930           if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
1931             return -1;
1932           }
1933         }
1934         else {
1935           /* Simple enum string. */
1936           if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
1937             return -1;
1938           }
1939         }
1940 
1941         if (data) {
1942           *((int *)data) = val;
1943         }
1944         else {
1945           RNA_property_enum_set(ptr, prop, val);
1946         }
1947 
1948         break;
1949       }
1950       case PROP_POINTER: {
1951         PyObject *value_new = NULL;
1952 
1953         StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop);
1954         const int flag = RNA_property_flag(prop);
1955         const int flag_parameter = RNA_parameter_flag(prop);
1956 
1957         /* This is really nasty! Done so we can fake the operator having direct properties, eg:
1958          * layout.prop(self, "filepath")
1959          * ... which in fact should be:
1960          * layout.prop(self.properties, "filepath")
1961          *
1962          * we need to do this trick.
1963          * if the prop is not an operator type and the PyObject is an operator,
1964          * use its properties in place of itself.
1965          *
1966          * This is so bad that it is almost a good reason to do away with fake
1967          * 'self.properties -> self'
1968          * class mixing. If this causes problems in the future it should be removed.
1969          */
1970         if ((ptr_type == &RNA_AnyType) && (BPy_StructRNA_Check(value))) {
1971           const StructRNA *base_type = RNA_struct_base_child_of(
1972               ((const BPy_StructRNA *)value)->ptr.type, NULL);
1973           if (ELEM(base_type, &RNA_Operator, &RNA_Gizmo)) {
1974             value = PyObject_GetAttr(value, bpy_intern_str_properties);
1975             value_new = value;
1976           }
1977         }
1978 
1979         /* if property is an OperatorProperties/GizmoProperties pointer and value is a map,
1980          * forward back to pyrna_pydict_to_props */
1981         if (PyDict_Check(value)) {
1982           const StructRNA *base_type = RNA_struct_base_child_of(ptr_type, NULL);
1983           if (base_type == &RNA_OperatorProperties) {
1984             PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1985             return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
1986           }
1987           if (base_type == &RNA_GizmoProperties) {
1988             PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1989             return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
1990           }
1991         }
1992 
1993         /* Another exception, allow to pass a collection as an RNA property. */
1994         if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */
1995           PointerRNA c_ptr;
1996           BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value;
1997           if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1998             value = pyrna_struct_CreatePyObject(&c_ptr);
1999             value_new = value;
2000           }
2001           else {
2002             PyErr_Format(PyExc_TypeError,
2003                          "%.200s %.200s.%.200s collection has no type, "
2004                          "can't be used as a %.200s type",
2005                          error_prefix,
2006                          RNA_struct_identifier(ptr->type),
2007                          RNA_property_identifier(prop),
2008                          RNA_struct_identifier(ptr_type));
2009             return -1;
2010           }
2011         }
2012 
2013         if (!BPy_StructRNA_Check(value) && value != Py_None) {
2014           PyErr_Format(PyExc_TypeError,
2015                        "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
2016                        error_prefix,
2017                        RNA_struct_identifier(ptr->type),
2018                        RNA_property_identifier(prop),
2019                        RNA_struct_identifier(ptr_type),
2020                        Py_TYPE(value)->tp_name);
2021           Py_XDECREF(value_new);
2022           return -1;
2023         }
2024         if ((flag & PROP_NEVER_NULL) && value == Py_None) {
2025           PyErr_Format(PyExc_TypeError,
2026                        "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
2027                        error_prefix,
2028                        RNA_struct_identifier(ptr->type),
2029                        RNA_property_identifier(prop),
2030                        RNA_struct_identifier(ptr_type));
2031           Py_XDECREF(value_new);
2032           return -1;
2033         }
2034         if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) &&
2035                                    ptr->owner_id == ((BPy_StructRNA *)value)->ptr.owner_id)) {
2036           PyErr_Format(PyExc_TypeError,
2037                        "%.200s %.200s.%.200s ID type does not support assignment to itself",
2038                        error_prefix,
2039                        RNA_struct_identifier(ptr->type),
2040                        RNA_property_identifier(prop));
2041           Py_XDECREF(value_new);
2042           return -1;
2043         }
2044 
2045         BPy_StructRNA *param = (BPy_StructRNA *)value;
2046         bool raise_error = false;
2047         if (data) {
2048 
2049           if (flag_parameter & PARM_RNAPTR) {
2050             if (flag & PROP_THICK_WRAP) {
2051               if (value == Py_None) {
2052                 memset(data, 0, sizeof(PointerRNA));
2053               }
2054               else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
2055                 *((PointerRNA *)data) = param->ptr;
2056               }
2057               else {
2058                 raise_error = true;
2059               }
2060             }
2061             else {
2062               /* For function calls, we sometimes want to pass the 'ptr' directly,
2063                * but watch out that it remains valid!
2064                * We could possibly support this later if needed. */
2065               BLI_assert(value_new == NULL);
2066               if (value == Py_None) {
2067                 *((void **)data) = NULL;
2068               }
2069               else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
2070                 *((PointerRNA **)data) = &param->ptr;
2071               }
2072               else {
2073                 raise_error = true;
2074               }
2075             }
2076           }
2077           else if (value == Py_None) {
2078             *((void **)data) = NULL;
2079           }
2080           else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
2081             *((void **)data) = param->ptr.data;
2082           }
2083           else {
2084             raise_error = true;
2085           }
2086         }
2087         else {
2088           /* Data == NULL, assign to RNA. */
2089           if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) {
2090             ReportList reports;
2091             BKE_reports_init(&reports, RPT_STORE);
2092             RNA_property_pointer_set(
2093                 ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports);
2094             const int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
2095             if (err == -1) {
2096               Py_XDECREF(value_new);
2097               return -1;
2098             }
2099           }
2100           else {
2101             raise_error = true;
2102           }
2103         }
2104 
2105         if (raise_error) {
2106           if (pyrna_struct_validity_check(param) == -1) {
2107             /* Error set. */
2108           }
2109           else {
2110             PointerRNA tmp;
2111             RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
2112             PyErr_Format(PyExc_TypeError,
2113                          "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
2114                          error_prefix,
2115                          RNA_struct_identifier(ptr->type),
2116                          RNA_property_identifier(prop),
2117                          RNA_struct_identifier(tmp.type),
2118                          RNA_struct_identifier(param->ptr.type));
2119           }
2120           Py_XDECREF(value_new);
2121           return -1;
2122         }
2123 
2124         Py_XDECREF(value_new);
2125 
2126         break;
2127       }
2128       case PROP_COLLECTION: {
2129         Py_ssize_t seq_len, i;
2130         PyObject *item;
2131         PointerRNA itemptr;
2132         ListBase *lb;
2133         CollectionPointerLink *link;
2134 
2135         lb = (data) ? (ListBase *)data : NULL;
2136 
2137         /* Convert a sequence of dict's into a collection. */
2138         if (!PySequence_Check(value)) {
2139           PyErr_Format(
2140               PyExc_TypeError,
2141               "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
2142               error_prefix,
2143               RNA_struct_identifier(ptr->type),
2144               RNA_property_identifier(prop),
2145               Py_TYPE(value)->tp_name);
2146           return -1;
2147         }
2148 
2149         seq_len = PySequence_Size(value);
2150         for (i = 0; i < seq_len; i++) {
2151           item = PySequence_GetItem(value, i);
2152 
2153           if (item == NULL) {
2154             PyErr_Format(
2155                 PyExc_TypeError,
2156                 "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
2157                 error_prefix,
2158                 RNA_struct_identifier(ptr->type),
2159                 RNA_property_identifier(prop),
2160                 i);
2161             Py_XDECREF(item);
2162             return -1;
2163           }
2164 
2165           if (PyDict_Check(item) == 0) {
2166             PyErr_Format(PyExc_TypeError,
2167                          "%.200s %.200s.%.200s expected a each sequence "
2168                          "member to be a dict for an RNA collection, not %.200s",
2169                          error_prefix,
2170                          RNA_struct_identifier(ptr->type),
2171                          RNA_property_identifier(prop),
2172                          Py_TYPE(item)->tp_name);
2173             Py_XDECREF(item);
2174             return -1;
2175           }
2176 
2177           if (lb) {
2178             link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
2179             link->ptr = itemptr;
2180             BLI_addtail(lb, link);
2181           }
2182           else {
2183             RNA_property_collection_add(ptr, prop, &itemptr);
2184           }
2185 
2186           if (pyrna_pydict_to_props(
2187                   &itemptr, item, true, "Converting a Python list to an RNA collection") == -1) {
2188             PyObject *msg = PyC_ExceptionBuffer();
2189             const char *msg_char = _PyUnicode_AsString(msg);
2190 
2191             PyErr_Format(PyExc_TypeError,
2192                          "%.200s %.200s.%.200s error converting a member of a collection "
2193                          "from a dicts into an RNA collection, failed with: %s",
2194                          error_prefix,
2195                          RNA_struct_identifier(ptr->type),
2196                          RNA_property_identifier(prop),
2197                          msg_char);
2198 
2199             Py_DECREF(item);
2200             Py_DECREF(msg);
2201             return -1;
2202           }
2203           Py_DECREF(item);
2204         }
2205 
2206         break;
2207       }
2208       default:
2209         PyErr_Format(PyExc_AttributeError,
2210                      "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
2211                      error_prefix,
2212                      RNA_struct_identifier(ptr->type),
2213                      RNA_property_identifier(prop));
2214         return -1;
2215     }
2216   }
2217 
2218   /* Run RNA property functions. */
2219   if (RNA_property_update_check(prop)) {
2220     RNA_property_update(BPY_context_get(), ptr, prop);
2221   }
2222 
2223   return 0;
2224 }
2225 
pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA * self,int index)2226 static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
2227 {
2228   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2229   return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
2230 }
2231 
pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA * self,int index,PyObject * value)2232 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
2233 {
2234   int ret = 0;
2235   PointerRNA *ptr = &self->ptr;
2236   PropertyRNA *prop = self->prop;
2237 
2238   const int totdim = RNA_property_array_dimension(ptr, prop, NULL);
2239 
2240   if (totdim > 1) {
2241     // char error_str[512];
2242     if (pyrna_py_to_array_index(
2243             &self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) {
2244       /* Error is set. */
2245       ret = -1;
2246     }
2247   }
2248   else {
2249     /* See if we can coerce into a Python type - 'PropertyType'. */
2250     switch (RNA_property_type(prop)) {
2251       case PROP_BOOLEAN: {
2252         const int param = PyC_Long_AsBool(value);
2253 
2254         if (param == -1) {
2255           /* Error is set. */
2256           ret = -1;
2257         }
2258         else {
2259           RNA_property_boolean_set_index(ptr, prop, index, param);
2260         }
2261         break;
2262       }
2263       case PROP_INT: {
2264         int param = PyC_Long_AsI32(value);
2265         if (param == -1 && PyErr_Occurred()) {
2266           PyErr_SetString(PyExc_TypeError, "expected an int type");
2267           ret = -1;
2268         }
2269         else {
2270           RNA_property_int_clamp(ptr, prop, &param);
2271           RNA_property_int_set_index(ptr, prop, index, param);
2272         }
2273         break;
2274       }
2275       case PROP_FLOAT: {
2276         float param = PyFloat_AsDouble(value);
2277         if (PyErr_Occurred()) {
2278           PyErr_SetString(PyExc_TypeError, "expected a float type");
2279           ret = -1;
2280         }
2281         else {
2282           RNA_property_float_clamp(ptr, prop, &param);
2283           RNA_property_float_set_index(ptr, prop, index, param);
2284         }
2285         break;
2286       }
2287       default:
2288         PyErr_SetString(PyExc_AttributeError, "not an array type");
2289         ret = -1;
2290         break;
2291     }
2292   }
2293 
2294   /* Run RNA property functions. */
2295   if (RNA_property_update_check(prop)) {
2296     RNA_property_update(BPY_context_get(), ptr, prop);
2297   }
2298 
2299   return ret;
2300 }
2301 
2302 /* ---------------sequence------------------------------------------- */
pyrna_prop_array_length(BPy_PropertyArrayRNA * self)2303 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
2304 {
2305   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2306 
2307   if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1) {
2308     return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
2309   }
2310 
2311   return RNA_property_array_length(&self->ptr, self->prop);
2312 }
2313 
pyrna_prop_collection_length(BPy_PropertyRNA * self)2314 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
2315 {
2316   PYRNA_PROP_CHECK_INT(self);
2317 
2318   return RNA_property_collection_length(&self->ptr, self->prop);
2319 }
2320 
2321 /* bool functions are for speed, so we can avoid getting the length
2322  * of 1000's of items in a linked list for eg. */
pyrna_prop_array_bool(BPy_PropertyRNA * self)2323 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
2324 {
2325   PYRNA_PROP_CHECK_INT(self);
2326 
2327   return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
2328 }
2329 
pyrna_prop_collection_bool(BPy_PropertyRNA * self)2330 static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
2331 {
2332   /* No callback defined, just iterate and find the nth item. */
2333   CollectionPropertyIterator iter;
2334   int test;
2335 
2336   PYRNA_PROP_CHECK_INT(self);
2337 
2338   RNA_property_collection_begin(&self->ptr, self->prop, &iter);
2339   test = iter.valid;
2340   RNA_property_collection_end(&iter);
2341   return test;
2342 }
2343 
2344 /* notice getting the length of the collection is avoided unless negative
2345  * index is used or to detect internal error with a valid index.
2346  * This is done for faster lookups. */
2347 #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
2348   if (keynum < 0) { \
2349     keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
2350     if (keynum_abs < 0) { \
2351       PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum); \
2352       return ret_err; \
2353     } \
2354   } \
2355   (void)0
2356 
2357 /* Internal use only. */
pyrna_prop_collection_subscript_int(BPy_PropertyRNA * self,Py_ssize_t keynum)2358 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
2359 {
2360   PointerRNA newptr;
2361   Py_ssize_t keynum_abs = keynum;
2362 
2363   PYRNA_PROP_CHECK_OBJ(self);
2364 
2365   PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
2366 
2367   if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
2368     return pyrna_struct_CreatePyObject(&newptr);
2369   }
2370 
2371   const int len = RNA_property_collection_length(&self->ptr, self->prop);
2372   if (keynum_abs >= len) {
2373     PyErr_Format(PyExc_IndexError,
2374                  "bpy_prop_collection[index]: "
2375                  "index %d out of range, size %d",
2376                  keynum,
2377                  len);
2378   }
2379   else {
2380     PyErr_Format(PyExc_RuntimeError,
2381                  "bpy_prop_collection[index]: internal error, "
2382                  "valid index %d given in %d sized collection, but value not found",
2383                  keynum_abs,
2384                  len);
2385   }
2386 
2387   return NULL;
2388 }
2389 
2390 /* Values type must have been already checked. */
pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA * self,Py_ssize_t keynum,PyObject * value)2391 static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self,
2392                                                    Py_ssize_t keynum,
2393                                                    PyObject *value)
2394 {
2395   Py_ssize_t keynum_abs = keynum;
2396   const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
2397 
2398   PYRNA_PROP_CHECK_INT(self);
2399 
2400   PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
2401 
2402   if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
2403     const int len = RNA_property_collection_length(&self->ptr, self->prop);
2404     if (keynum_abs >= len) {
2405       PyErr_Format(PyExc_IndexError,
2406                    "bpy_prop_collection[index] = value: "
2407                    "index %d out of range, size %d",
2408                    keynum,
2409                    len);
2410     }
2411     else {
2412 
2413       PyErr_Format(PyExc_IndexError,
2414                    "bpy_prop_collection[index] = value: "
2415                    "failed assignment (unknown reason)",
2416                    keynum);
2417     }
2418     return -1;
2419   }
2420 
2421   return 0;
2422 }
2423 
pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA * self,int keynum)2424 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
2425 {
2426   int len;
2427 
2428   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2429 
2430   len = pyrna_prop_array_length(self);
2431 
2432   if (keynum < 0) {
2433     keynum += len;
2434   }
2435 
2436   if (keynum >= 0 && keynum < len) {
2437     return pyrna_prop_array_to_py_index(self, keynum);
2438   }
2439 
2440   PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum);
2441   return NULL;
2442 }
2443 
pyrna_prop_collection_subscript_str(BPy_PropertyRNA * self,const char * keyname)2444 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2445 {
2446   PointerRNA newptr;
2447 
2448   PYRNA_PROP_CHECK_OBJ(self);
2449 
2450   if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
2451     return pyrna_struct_CreatePyObject(&newptr);
2452   }
2453 
2454   PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2455   return NULL;
2456 }
2457 // static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname)
2458 
2459 /**
2460  * Special case: `bpy.data.objects["some_id_name", "//some_lib_name.blend"]`
2461  * also for:     `bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)`
2462  *
2463  * \note
2464  * error codes since this is not to be called directly from Python,
2465  * this matches Python's `__contains__` values C-API.
2466  * - -1: exception set
2467  * -  0: not found
2468  * -  1: found
2469  */
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)2470 static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self,
2471                                                             PyObject *key,
2472                                                             const char *err_prefix,
2473                                                             const short err_not_found,
2474                                                             PointerRNA *r_ptr)
2475 {
2476   const char *keyname;
2477 
2478   /* First validate the args, all we know is that they are a tuple. */
2479   if (PyTuple_GET_SIZE(key) != 2) {
2480     PyErr_Format(PyExc_KeyError,
2481                  "%s: tuple key must be a pair, not size %d",
2482                  err_prefix,
2483                  PyTuple_GET_SIZE(key));
2484     return -1;
2485   }
2486   if (self->ptr.type != &RNA_BlendData) {
2487     PyErr_Format(PyExc_KeyError,
2488                  "%s: is only valid for bpy.data collections, not %.200s",
2489                  err_prefix,
2490                  RNA_struct_identifier(self->ptr.type));
2491     return -1;
2492   }
2493   if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
2494     PyErr_Format(PyExc_KeyError,
2495                  "%s: id must be a string, not %.200s",
2496                  err_prefix,
2497                  Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
2498     return -1;
2499   }
2500 
2501   PyObject *keylib = PyTuple_GET_ITEM(key, 1);
2502   Library *lib;
2503   bool found = false;
2504 
2505   if (keylib == Py_None) {
2506     lib = NULL;
2507   }
2508   else if (PyUnicode_Check(keylib)) {
2509     Main *bmain = self->ptr.data;
2510     const char *keylib_str = _PyUnicode_AsString(keylib);
2511     lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath));
2512     if (lib == NULL) {
2513       if (err_not_found) {
2514         PyErr_Format(PyExc_KeyError,
2515                      "%s: lib name '%.240s' "
2516                      "does not reference a valid library",
2517                      err_prefix,
2518                      keylib_str);
2519         return -1;
2520       }
2521 
2522       return 0;
2523     }
2524   }
2525   else {
2526     PyErr_Format(PyExc_KeyError,
2527                  "%s: lib must be a string or None, not %.200s",
2528                  err_prefix,
2529                  Py_TYPE(keylib)->tp_name);
2530     return -1;
2531   }
2532 
2533   /* lib is either a valid pointer or NULL,
2534    * either way can do direct comparison with id.lib */
2535 
2536   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
2537     ID *id = itemptr.data; /* Always an ID. */
2538     if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
2539       found = true;
2540       if (r_ptr) {
2541         *r_ptr = itemptr;
2542       }
2543       break;
2544     }
2545   }
2546   RNA_PROP_END;
2547 
2548   /* We may want to fail silently as with collection.get(). */
2549   if ((found == false) && err_not_found) {
2550     /* Only runs for getitem access so use fixed string. */
2551     PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found");
2552     return -1;
2553   }
2554 
2555   return found; /* 1 / 0, no exception. */
2556 }
2557 
pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA * self,PyObject * key,const char * err_prefix,const bool err_not_found)2558 static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self,
2559                                                               PyObject *key,
2560                                                               const char *err_prefix,
2561                                                               const bool err_not_found)
2562 {
2563   PointerRNA ptr;
2564   const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(
2565       self, key, err_prefix, err_not_found, &ptr);
2566 
2567   if (contains == 1) {
2568     return pyrna_struct_CreatePyObject(&ptr);
2569   }
2570 
2571   return NULL;
2572 }
2573 
pyrna_prop_collection_subscript_slice(BPy_PropertyRNA * self,Py_ssize_t start,Py_ssize_t stop)2574 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self,
2575                                                        Py_ssize_t start,
2576                                                        Py_ssize_t stop)
2577 {
2578   CollectionPropertyIterator rna_macro_iter;
2579   int count;
2580 
2581   PyObject *list;
2582   PyObject *item;
2583 
2584   PYRNA_PROP_CHECK_OBJ(self);
2585 
2586   list = PyList_New(0);
2587 
2588   /* Skip to start. */
2589   RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
2590   RNA_property_collection_skip(&rna_macro_iter, start);
2591 
2592   /* Add items until stop. */
2593   for (count = start; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
2594     item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2595     PyList_APPEND(list, item);
2596 
2597     count++;
2598     if (count == stop) {
2599       break;
2600     }
2601   }
2602 
2603   RNA_property_collection_end(&rna_macro_iter);
2604 
2605   return list;
2606 }
2607 
2608 /**
2609  * TODO - dimensions
2610  * \note Could also use pyrna_prop_array_to_py_index(self, count) in a loop, but it's much slower
2611  * since at the moment it reads (and even allocates) the entire array for each index.
2612  */
pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA * self,PointerRNA * ptr,PropertyRNA * prop,Py_ssize_t start,Py_ssize_t stop,Py_ssize_t length)2613 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self,
2614                                                   PointerRNA *ptr,
2615                                                   PropertyRNA *prop,
2616                                                   Py_ssize_t start,
2617                                                   Py_ssize_t stop,
2618                                                   Py_ssize_t length)
2619 {
2620   int count, totdim;
2621   PyObject *tuple;
2622 
2623   /* Isn't needed, internal use only. */
2624   // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2625 
2626   tuple = PyTuple_New(stop - start);
2627 
2628   totdim = RNA_property_array_dimension(ptr, prop, NULL);
2629 
2630   if (totdim > 1) {
2631     for (count = start; count < stop; count++) {
2632       PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2633     }
2634   }
2635   else {
2636     switch (RNA_property_type(prop)) {
2637       case PROP_FLOAT: {
2638         float values_stack[PYRNA_STACK_ARRAY];
2639         float *values;
2640         if (length > PYRNA_STACK_ARRAY) {
2641           values = PyMem_MALLOC(sizeof(float) * length);
2642         }
2643         else {
2644           values = values_stack;
2645         }
2646         RNA_property_float_get_array(ptr, prop, values);
2647 
2648         for (count = start; count < stop; count++) {
2649           PyTuple_SET_ITEM(tuple, count - start, PyFloat_FromDouble(values[count]));
2650         }
2651 
2652         if (values != values_stack) {
2653           PyMem_FREE(values);
2654         }
2655         break;
2656       }
2657       case PROP_BOOLEAN: {
2658         bool values_stack[PYRNA_STACK_ARRAY];
2659         bool *values;
2660         if (length > PYRNA_STACK_ARRAY) {
2661           values = PyMem_MALLOC(sizeof(bool) * length);
2662         }
2663         else {
2664           values = values_stack;
2665         }
2666 
2667         RNA_property_boolean_get_array(ptr, prop, values);
2668         for (count = start; count < stop; count++) {
2669           PyTuple_SET_ITEM(tuple, count - start, PyBool_FromLong(values[count]));
2670         }
2671 
2672         if (values != values_stack) {
2673           PyMem_FREE(values);
2674         }
2675         break;
2676       }
2677       case PROP_INT: {
2678         int values_stack[PYRNA_STACK_ARRAY];
2679         int *values;
2680         if (length > PYRNA_STACK_ARRAY) {
2681           values = PyMem_MALLOC(sizeof(int) * length);
2682         }
2683         else {
2684           values = values_stack;
2685         }
2686 
2687         RNA_property_int_get_array(ptr, prop, values);
2688         for (count = start; count < stop; count++) {
2689           PyTuple_SET_ITEM(tuple, count - start, PyLong_FromLong(values[count]));
2690         }
2691 
2692         if (values != values_stack) {
2693           PyMem_FREE(values);
2694         }
2695         break;
2696       }
2697       default:
2698         BLI_assert(!"Invalid array type");
2699 
2700         PyErr_SetString(PyExc_TypeError, "not an array type");
2701         Py_DECREF(tuple);
2702         tuple = NULL;
2703         break;
2704     }
2705   }
2706   return tuple;
2707 }
2708 
pyrna_prop_collection_subscript(BPy_PropertyRNA * self,PyObject * key)2709 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
2710 {
2711   PYRNA_PROP_CHECK_OBJ(self);
2712 
2713   if (PyUnicode_Check(key)) {
2714     return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2715   }
2716   if (PyIndex_Check(key)) {
2717     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2718     if (i == -1 && PyErr_Occurred()) {
2719       return NULL;
2720     }
2721 
2722     return pyrna_prop_collection_subscript_int(self, i);
2723   }
2724   if (PySlice_Check(key)) {
2725     PySliceObject *key_slice = (PySliceObject *)key;
2726     Py_ssize_t step = 1;
2727 
2728     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2729       return NULL;
2730     }
2731     if (step != 1) {
2732       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2733       return NULL;
2734     }
2735     if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2736       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2737     }
2738 
2739     Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2740 
2741     /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2742     if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
2743       return NULL;
2744     }
2745     if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
2746       return NULL;
2747     }
2748 
2749     if (start < 0 || stop < 0) {
2750       /* Only get the length for negative values. */
2751       const Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2752       if (start < 0) {
2753         start += len;
2754       }
2755       if (stop < 0) {
2756         stop += len;
2757       }
2758     }
2759 
2760     if (stop - start <= 0) {
2761       return PyList_New(0);
2762     }
2763 
2764     return pyrna_prop_collection_subscript_slice(self, start, stop);
2765   }
2766   if (PyTuple_Check(key)) {
2767     /* Special case, for ID datablocks we. */
2768     return pyrna_prop_collection_subscript_str_lib_pair(
2769         self, key, "bpy_prop_collection[id, lib]", true);
2770   }
2771 
2772   PyErr_Format(PyExc_TypeError,
2773                "bpy_prop_collection[key]: invalid key, "
2774                "must be a string or an int, not %.200s",
2775                Py_TYPE(key)->tp_name);
2776   return NULL;
2777 }
2778 
2779 /* generic check to see if a PyObject is compatible with a collection
2780  * -1 on failure, 0 on success, sets the error */
pyrna_prop_collection_type_check(BPy_PropertyRNA * self,PyObject * value)2781 static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
2782 {
2783   StructRNA *prop_srna;
2784 
2785   if (value == Py_None) {
2786     if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2787       PyErr_Format(PyExc_TypeError,
2788                    "bpy_prop_collection[key] = value: invalid, "
2789                    "this collection doesn't support None assignment");
2790       return -1;
2791     }
2792 
2793     return 0; /* None is OK. */
2794   }
2795   if (BPy_StructRNA_Check(value) == 0) {
2796     PyErr_Format(PyExc_TypeError,
2797                  "bpy_prop_collection[key] = value: invalid, "
2798                  "expected a StructRNA type or None, not a %.200s",
2799                  Py_TYPE(value)->tp_name);
2800     return -1;
2801   }
2802   if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
2803     StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
2804     if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2805       PyErr_Format(PyExc_TypeError,
2806                    "bpy_prop_collection[key] = value: invalid, "
2807                    "expected a '%.200s' type or None, not a '%.200s'",
2808                    RNA_struct_identifier(prop_srna),
2809                    RNA_struct_identifier(value_srna));
2810       return -1;
2811     }
2812 
2813     return 0; /* OK, this is the correct type! */
2814   }
2815 
2816   PyErr_Format(PyExc_TypeError,
2817                "bpy_prop_collection[key] = value: internal error, "
2818                "failed to get the collection type");
2819   return -1;
2820 }
2821 
2822 /* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
2823  * large blocks commented, we may support slice/key indices later */
pyrna_prop_collection_ass_subscript(BPy_PropertyRNA * self,PyObject * key,PyObject * value)2824 static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self,
2825                                                PyObject *key,
2826                                                PyObject *value)
2827 {
2828   PYRNA_PROP_CHECK_INT(self);
2829 
2830   /* Validate the assigned value. */
2831   if (value == NULL) {
2832     PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported");
2833     return -1;
2834   }
2835   if (pyrna_prop_collection_type_check(self, value) == -1) {
2836     return -1; /* Exception is set. */
2837   }
2838 
2839 #if 0
2840   if (PyUnicode_Check(key)) {
2841     return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2842   }
2843   else
2844 #endif
2845   if (PyIndex_Check(key)) {
2846     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2847     if (i == -1 && PyErr_Occurred()) {
2848       return -1;
2849     }
2850 
2851     return pyrna_prop_collection_ass_subscript_int(self, i, value);
2852   }
2853 #if 0 /* TODO, fake slice assignment. */
2854   else if (PySlice_Check(key)) {
2855     PySliceObject *key_slice = (PySliceObject *)key;
2856     Py_ssize_t step = 1;
2857 
2858     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2859       return NULL;
2860     }
2861     else if (step != 1) {
2862       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2863       return NULL;
2864     }
2865     else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2866       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2867     }
2868     else {
2869       Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2870 
2871       /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2872       if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
2873         return NULL;
2874       }
2875       if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
2876         return NULL;
2877       }
2878 
2879       if (start < 0 || stop < 0) {
2880         /* Only get the length for negative values. */
2881         Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2882         if (start < 0) {
2883           start += len;
2884         }
2885         if (stop < 0) {
2886           stop += len;
2887         }
2888       }
2889 
2890       if (stop - start <= 0) {
2891         return PyList_New(0);
2892       }
2893       else {
2894         return pyrna_prop_collection_subscript_slice(self, start, stop);
2895       }
2896     }
2897   }
2898 #endif
2899 
2900   PyErr_Format(PyExc_TypeError,
2901                "bpy_prop_collection[key]: invalid key, "
2902                "must be a string or an int, not %.200s",
2903                Py_TYPE(key)->tp_name);
2904   return -1;
2905 }
2906 
pyrna_prop_array_subscript(BPy_PropertyArrayRNA * self,PyObject * key)2907 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
2908 {
2909   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2910 
2911 #if 0
2912   if (PyUnicode_Check(key)) {
2913     return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
2914   }
2915   else
2916 #endif
2917   if (PyIndex_Check(key)) {
2918     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2919     if (i == -1 && PyErr_Occurred()) {
2920       return NULL;
2921     }
2922     return pyrna_prop_array_subscript_int(self, i);
2923   }
2924   if (PySlice_Check(key)) {
2925     Py_ssize_t step = 1;
2926     PySliceObject *key_slice = (PySliceObject *)key;
2927 
2928     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2929       return NULL;
2930     }
2931     if (step != 1) {
2932       PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2933       return NULL;
2934     }
2935     if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2936       /* Note: no significant advantage with optimizing [:] slice as with collections,
2937        * but include here for consistency with collection slice func */
2938       const Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
2939       return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2940     }
2941 
2942     const int len = pyrna_prop_array_length(self);
2943     Py_ssize_t start, stop, slicelength;
2944 
2945     if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
2946       return NULL;
2947     }
2948 
2949     if (slicelength <= 0) {
2950       return PyTuple_New(0);
2951     }
2952 
2953     return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2954   }
2955 
2956   PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2957   return NULL;
2958 }
2959 
2960 /**
2961  * Helpers for #prop_subscript_ass_array_slice
2962  */
2963 
prop_subscript_ass_array_slice__as_seq_fast(PyObject * value,int length)2964 static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, int length)
2965 {
2966   PyObject *value_fast;
2967   if (!(value_fast = PySequence_Fast(value,
2968                                      "bpy_prop_array[slice] = value: "
2969                                      "element in assignment is not a sequence type"))) {
2970     return NULL;
2971   }
2972   if (PySequence_Fast_GET_SIZE(value_fast) != length) {
2973     Py_DECREF(value_fast);
2974     PyErr_SetString(PyExc_ValueError,
2975                     "bpy_prop_array[slice] = value: "
2976                     "re-sizing bpy_struct element in arrays isn't supported");
2977 
2978     return NULL;
2979   }
2980 
2981   return value_fast;
2982 }
2983 
prop_subscript_ass_array_slice__float_recursive(PyObject ** value_items,float * value,int totdim,const int dimsize[],const float range[2])2984 static int prop_subscript_ass_array_slice__float_recursive(
2985     PyObject **value_items, float *value, int totdim, const int dimsize[], const float range[2])
2986 {
2987   const int length = dimsize[0];
2988   if (totdim > 1) {
2989     int index = 0;
2990     int i;
2991     for (i = 0; i != length; i++) {
2992       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
2993       if (UNLIKELY(subvalue == NULL)) {
2994         return 0;
2995       }
2996 
2997       index += prop_subscript_ass_array_slice__float_recursive(
2998           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range);
2999 
3000       Py_DECREF(subvalue);
3001     }
3002     return index;
3003   }
3004 
3005   BLI_assert(totdim == 1);
3006   const float min = range[0], max = range[1];
3007   int i;
3008   for (i = 0; i != length; i++) {
3009     float v = PyFloat_AsDouble(value_items[i]);
3010     CLAMP(v, min, max);
3011     value[i] = v;
3012   }
3013   return i;
3014 }
3015 
prop_subscript_ass_array_slice__int_recursive(PyObject ** value_items,int * value,int totdim,const int dimsize[],const int range[2])3016 static int prop_subscript_ass_array_slice__int_recursive(
3017     PyObject **value_items, int *value, int totdim, const int dimsize[], const int range[2])
3018 {
3019   const int length = dimsize[0];
3020   if (totdim > 1) {
3021     int index = 0;
3022     int i;
3023     for (i = 0; i != length; i++) {
3024       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
3025       if (UNLIKELY(subvalue == NULL)) {
3026         return 0;
3027       }
3028 
3029       index += prop_subscript_ass_array_slice__int_recursive(
3030           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range);
3031 
3032       Py_DECREF(subvalue);
3033     }
3034     return index;
3035   }
3036 
3037   BLI_assert(totdim == 1);
3038   const int min = range[0], max = range[1];
3039   int i;
3040   for (i = 0; i != length; i++) {
3041     int v = PyLong_AsLong(value_items[i]);
3042     CLAMP(v, min, max);
3043     value[i] = v;
3044   }
3045   return i;
3046 }
3047 
prop_subscript_ass_array_slice__bool_recursive(PyObject ** value_items,bool * value,int totdim,const int dimsize[])3048 static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items,
3049                                                           bool *value,
3050                                                           int totdim,
3051                                                           const int dimsize[])
3052 {
3053   const int length = dimsize[0];
3054   if (totdim > 1) {
3055     int index = 0;
3056     int i;
3057     for (i = 0; i != length; i++) {
3058       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
3059       if (UNLIKELY(subvalue == NULL)) {
3060         return 0;
3061       }
3062 
3063       index += prop_subscript_ass_array_slice__bool_recursive(
3064           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1]);
3065 
3066       Py_DECREF(subvalue);
3067     }
3068     return index;
3069   }
3070 
3071   BLI_assert(totdim == 1);
3072   int i;
3073   for (i = 0; i != length; i++) {
3074     const int v = PyLong_AsLong(value_items[i]);
3075     value[i] = v;
3076   }
3077   return i;
3078 }
3079 
3080 /* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */
prop_subscript_ass_array_slice(PointerRNA * ptr,PropertyRNA * prop,int arraydim,int arrayoffset,int start,int stop,int length,PyObject * value_orig)3081 static int prop_subscript_ass_array_slice(PointerRNA *ptr,
3082                                           PropertyRNA *prop,
3083                                           int arraydim,
3084                                           int arrayoffset,
3085                                           int start,
3086                                           int stop,
3087                                           int length,
3088                                           PyObject *value_orig)
3089 {
3090   const int length_flat = RNA_property_array_length(ptr, prop);
3091   PyObject *value;
3092   PyObject **value_items;
3093   void *values_alloc = NULL;
3094   int ret = 0;
3095 
3096   if (value_orig == NULL) {
3097     PyErr_SetString(
3098         PyExc_TypeError,
3099         "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
3100     return -1;
3101   }
3102 
3103   if (!(value = PySequence_Fast(
3104             value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
3105     return -1;
3106   }
3107 
3108   if (PySequence_Fast_GET_SIZE(value) != stop - start) {
3109     Py_DECREF(value);
3110     PyErr_SetString(PyExc_TypeError,
3111                     "bpy_prop_array[slice] = value: re-sizing bpy_struct arrays isn't supported");
3112     return -1;
3113   }
3114 
3115   int dimsize[3];
3116   const int totdim = RNA_property_array_dimension(ptr, prop, dimsize);
3117   if (totdim > 1) {
3118     BLI_assert(dimsize[arraydim] == length);
3119   }
3120 
3121   int span = 1;
3122   if (totdim > 1) {
3123     for (int i = arraydim + 1; i < totdim; i++) {
3124       span *= dimsize[i];
3125     }
3126   }
3127 
3128   value_items = PySequence_Fast_ITEMS(value);
3129   switch (RNA_property_type(prop)) {
3130     case PROP_FLOAT: {
3131       float values_stack[PYRNA_STACK_ARRAY];
3132       float *values = (length_flat > PYRNA_STACK_ARRAY) ?
3133                           (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) :
3134                           values_stack;
3135       if (start != 0 || stop != length) {
3136         /* Partial assignment? - need to get the array. */
3137         RNA_property_float_get_array(ptr, prop, values);
3138       }
3139 
3140       float range[2];
3141       RNA_property_float_range(ptr, prop, &range[0], &range[1]);
3142 
3143       dimsize[arraydim] = stop - start;
3144       prop_subscript_ass_array_slice__float_recursive(value_items,
3145                                                       &values[arrayoffset + (start * span)],
3146                                                       totdim - arraydim,
3147                                                       &dimsize[arraydim],
3148                                                       range);
3149 
3150       if (PyErr_Occurred()) {
3151         ret = -1;
3152       }
3153       else {
3154         RNA_property_float_set_array(ptr, prop, values);
3155       }
3156       break;
3157     }
3158     case PROP_INT: {
3159       int values_stack[PYRNA_STACK_ARRAY];
3160       int *values = (length_flat > PYRNA_STACK_ARRAY) ?
3161                         (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) :
3162                         values_stack;
3163       if (start != 0 || stop != length) {
3164         /* Partial assignment? - need to get the array. */
3165         RNA_property_int_get_array(ptr, prop, values);
3166       }
3167 
3168       int range[2];
3169       RNA_property_int_range(ptr, prop, &range[0], &range[1]);
3170 
3171       dimsize[arraydim] = stop - start;
3172       prop_subscript_ass_array_slice__int_recursive(value_items,
3173                                                     &values[arrayoffset + (start * span)],
3174                                                     totdim - arraydim,
3175                                                     &dimsize[arraydim],
3176                                                     range);
3177 
3178       if (PyErr_Occurred()) {
3179         ret = -1;
3180       }
3181       else {
3182         RNA_property_int_set_array(ptr, prop, values);
3183       }
3184       break;
3185     }
3186     case PROP_BOOLEAN: {
3187       bool values_stack[PYRNA_STACK_ARRAY];
3188       bool *values = (length_flat > PYRNA_STACK_ARRAY) ?
3189                          (values_alloc = PyMem_MALLOC(sizeof(bool) * length_flat)) :
3190                          values_stack;
3191 
3192       if (start != 0 || stop != length) {
3193         /* Partial assignment? - need to get the array. */
3194         RNA_property_boolean_get_array(ptr, prop, values);
3195       }
3196 
3197       dimsize[arraydim] = stop - start;
3198       prop_subscript_ass_array_slice__bool_recursive(value_items,
3199                                                      &values[arrayoffset + (start * span)],
3200                                                      totdim - arraydim,
3201                                                      &dimsize[arraydim]);
3202 
3203       if (PyErr_Occurred()) {
3204         ret = -1;
3205       }
3206       else {
3207         RNA_property_boolean_set_array(ptr, prop, values);
3208       }
3209       break;
3210     }
3211     default:
3212       PyErr_SetString(PyExc_TypeError, "not an array type");
3213       ret = -1;
3214       break;
3215   }
3216 
3217   Py_DECREF(value);
3218 
3219   if (values_alloc) {
3220     PyMem_FREE(values_alloc);
3221   }
3222 
3223   return ret;
3224 }
3225 
prop_subscript_ass_array_int(BPy_PropertyArrayRNA * self,Py_ssize_t keynum,PyObject * value)3226 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self,
3227                                         Py_ssize_t keynum,
3228                                         PyObject *value)
3229 {
3230   int len;
3231 
3232   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
3233 
3234   len = pyrna_prop_array_length(self);
3235 
3236   if (keynum < 0) {
3237     keynum += len;
3238   }
3239 
3240   if (keynum >= 0 && keynum < len) {
3241     return pyrna_py_to_prop_array_index(self, keynum, value);
3242   }
3243 
3244   PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
3245   return -1;
3246 }
3247 
pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA * self,PyObject * key,PyObject * value)3248 static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
3249                                           PyObject *key,
3250                                           PyObject *value)
3251 {
3252   // char *keyname = NULL; /* Not supported yet. */
3253   int ret = -1;
3254 
3255   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
3256 
3257   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
3258     PyErr_Format(PyExc_AttributeError,
3259                  "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
3260                  RNA_property_identifier(self->prop),
3261                  RNA_struct_identifier(self->ptr.type));
3262     ret = -1;
3263   }
3264 
3265   else if (PyIndex_Check(key)) {
3266     const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
3267     if (i == -1 && PyErr_Occurred()) {
3268       ret = -1;
3269     }
3270     else {
3271       ret = prop_subscript_ass_array_int(self, i, value);
3272     }
3273   }
3274   else if (PySlice_Check(key)) {
3275     const Py_ssize_t len = pyrna_prop_array_length(self);
3276     Py_ssize_t start, stop, step, slicelength;
3277 
3278     if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
3279       ret = -1;
3280     }
3281     else if (slicelength <= 0) {
3282       ret = 0; /* Do nothing. */
3283     }
3284     else if (step == 1) {
3285       ret = prop_subscript_ass_array_slice(
3286           &self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value);
3287     }
3288     else {
3289       PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA");
3290       ret = -1;
3291     }
3292   }
3293   else {
3294     PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
3295     ret = -1;
3296   }
3297 
3298   if (ret != -1) {
3299     if (RNA_property_update_check(self->prop)) {
3300       RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
3301     }
3302   }
3303 
3304   return ret;
3305 }
3306 
3307 /* For slice only. */
3308 static PyMappingMethods pyrna_prop_array_as_mapping = {
3309     (lenfunc)pyrna_prop_array_length,              /* mp_length */
3310     (binaryfunc)pyrna_prop_array_subscript,        /* mp_subscript */
3311     (objobjargproc)pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
3312 };
3313 
3314 static PyMappingMethods pyrna_prop_collection_as_mapping = {
3315     (lenfunc)pyrna_prop_collection_length,              /* mp_length */
3316     (binaryfunc)pyrna_prop_collection_subscript,        /* mp_subscript */
3317     (objobjargproc)pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */
3318 };
3319 
3320 /* Only for fast bool's, large structs, assign nb_bool on init. */
3321 static PyNumberMethods pyrna_prop_array_as_number = {
3322     NULL,                           /* nb_add */
3323     NULL,                           /* nb_subtract */
3324     NULL,                           /* nb_multiply */
3325     NULL,                           /* nb_remainder */
3326     NULL,                           /* nb_divmod */
3327     NULL,                           /* nb_power */
3328     NULL,                           /* nb_negative */
3329     NULL,                           /* nb_positive */
3330     NULL,                           /* nb_absolute */
3331     (inquiry)pyrna_prop_array_bool, /* nb_bool */
3332 };
3333 static PyNumberMethods pyrna_prop_collection_as_number = {
3334     NULL,                                /* nb_add */
3335     NULL,                                /* nb_subtract */
3336     NULL,                                /* nb_multiply */
3337     NULL,                                /* nb_remainder */
3338     NULL,                                /* nb_divmod */
3339     NULL,                                /* nb_power */
3340     NULL,                                /* nb_negative */
3341     NULL,                                /* nb_positive */
3342     NULL,                                /* nb_absolute */
3343     (inquiry)pyrna_prop_collection_bool, /* nb_bool */
3344 };
3345 
pyrna_prop_array_contains(BPy_PropertyRNA * self,PyObject * value)3346 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
3347 {
3348   return pyrna_array_contains_py(&self->ptr, self->prop, value);
3349 }
3350 
pyrna_prop_collection_contains(BPy_PropertyRNA * self,PyObject * key)3351 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
3352 {
3353   PointerRNA newptr; /* Not used, just so RNA_property_collection_lookup_string runs. */
3354 
3355   if (PyTuple_Check(key)) {
3356     /* Special case, for ID data-blocks. */
3357     return pyrna_prop_collection_subscript_str_lib_pair_ptr(
3358         self, key, "(id, lib) in bpy_prop_collection", false, NULL);
3359   }
3360 
3361   /* Key in dict style check. */
3362   const char *keyname = _PyUnicode_AsString(key);
3363 
3364   if (keyname == NULL) {
3365     PyErr_SetString(PyExc_TypeError,
3366                     "bpy_prop_collection.__contains__: expected a string or a tuple of strings");
3367     return -1;
3368   }
3369 
3370   if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
3371     return 1;
3372   }
3373 
3374   return 0;
3375 }
3376 
pyrna_struct_contains(BPy_StructRNA * self,PyObject * value)3377 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
3378 {
3379   IDProperty *group;
3380   const char *name = _PyUnicode_AsString(value);
3381 
3382   PYRNA_STRUCT_CHECK_INT(self);
3383 
3384   if (!name) {
3385     PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
3386     return -1;
3387   }
3388 
3389   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3390     PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
3391     return -1;
3392   }
3393 
3394   group = RNA_struct_idprops(&self->ptr, 0);
3395 
3396   if (!group) {
3397     return 0;
3398   }
3399 
3400   return IDP_GetPropertyFromGroup(group, name) ? 1 : 0;
3401 }
3402 
3403 static PySequenceMethods pyrna_prop_array_as_sequence = {
3404     (lenfunc)pyrna_prop_array_length,
3405     NULL, /* sq_concat */
3406     NULL, /* sq_repeat */
3407     (ssizeargfunc)pyrna_prop_array_subscript_int,
3408     /* sq_item */ /* Only set this so PySequence_Check() returns True */
3409     NULL,         /* sq_slice */
3410     (ssizeobjargproc)prop_subscript_ass_array_int, /* sq_ass_item */
3411     NULL,                                          /* *was* sq_ass_slice */
3412     (objobjproc)pyrna_prop_array_contains,         /* sq_contains */
3413     (binaryfunc)NULL,                              /* sq_inplace_concat */
3414     (ssizeargfunc)NULL,                            /* sq_inplace_repeat */
3415 };
3416 
3417 static PySequenceMethods pyrna_prop_collection_as_sequence = {
3418     (lenfunc)pyrna_prop_collection_length,
3419     NULL, /* sq_concat */
3420     NULL, /* sq_repeat */
3421     (ssizeargfunc)pyrna_prop_collection_subscript_int,
3422     /* sq_item */                         /* Only set this so PySequence_Check() returns True */
3423     NULL,                                 /* *was* sq_slice */
3424     (ssizeobjargproc)                     /* pyrna_prop_collection_ass_subscript_int */
3425     NULL /* let mapping take this one */, /* sq_ass_item */
3426     NULL,                                 /* *was* sq_ass_slice */
3427     (objobjproc)pyrna_prop_collection_contains, /* sq_contains */
3428     (binaryfunc)NULL,                           /* sq_inplace_concat */
3429     (ssizeargfunc)NULL,                         /* sq_inplace_repeat */
3430 };
3431 
3432 static PySequenceMethods pyrna_struct_as_sequence = {
3433     NULL, /* Can't set the len otherwise it can evaluate as false */
3434     NULL, /* sq_concat */
3435     NULL, /* sq_repeat */
3436     NULL,
3437     /* sq_item */                      /* Only set this so PySequence_Check() returns True */
3438     NULL,                              /* *was* sq_slice */
3439     NULL,                              /* sq_ass_item */
3440     NULL,                              /* *was* sq_ass_slice */
3441     (objobjproc)pyrna_struct_contains, /* sq_contains */
3442     (binaryfunc)NULL,                  /* sq_inplace_concat */
3443     (ssizeargfunc)NULL,                /* sq_inplace_repeat */
3444 };
3445 
pyrna_struct_subscript(BPy_StructRNA * self,PyObject * key)3446 static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
3447 {
3448   /* Mostly copied from BPy_IDGroup_Map_GetItem. */
3449   IDProperty *group, *idprop;
3450   const char *name = _PyUnicode_AsString(key);
3451 
3452   PYRNA_STRUCT_CHECK_OBJ(self);
3453 
3454   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3455     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
3456     return NULL;
3457   }
3458 
3459   if (name == NULL) {
3460     PyErr_SetString(PyExc_TypeError,
3461                     "bpy_struct[key]: only strings are allowed as keys of ID properties");
3462     return NULL;
3463   }
3464 
3465   group = RNA_struct_idprops(&self->ptr, 0);
3466 
3467   if (group == NULL) {
3468     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
3469     return NULL;
3470   }
3471 
3472   idprop = IDP_GetPropertyFromGroup(group, name);
3473 
3474   if (idprop == NULL) {
3475     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
3476     return NULL;
3477   }
3478 
3479   return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
3480 }
3481 
pyrna_struct_ass_subscript(BPy_StructRNA * self,PyObject * key,PyObject * value)3482 static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
3483 {
3484   IDProperty *group;
3485 
3486   PYRNA_STRUCT_CHECK_INT(self);
3487 
3488   group = RNA_struct_idprops(&self->ptr, 1);
3489 
3490 #ifdef USE_PEDANTIC_WRITE
3491   if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
3492     return -1;
3493   }
3494 #endif /* USE_PEDANTIC_WRITE */
3495 
3496   if (group == NULL) {
3497     PyErr_SetString(PyExc_TypeError,
3498                     "bpy_struct[key] = val: id properties not supported for this type");
3499     return -1;
3500   }
3501 
3502   if (value && BPy_StructRNA_Check(value)) {
3503     BPy_StructRNA *val = (BPy_StructRNA *)value;
3504     if (val && self->ptr.type && val->ptr.type) {
3505       if (!RNA_struct_idprops_datablock_allowed(self->ptr.type) &&
3506           RNA_struct_idprops_contains_datablock(val->ptr.type)) {
3507         PyErr_SetString(
3508             PyExc_TypeError,
3509             "bpy_struct[key] = val: datablock id properties not supported for this type");
3510         return -1;
3511       }
3512     }
3513   }
3514 
3515   return BPy_Wrap_SetMapItem(group, key, value);
3516 }
3517 
3518 static PyMappingMethods pyrna_struct_as_mapping = {
3519     (lenfunc)NULL,                             /* mp_length */
3520     (binaryfunc)pyrna_struct_subscript,        /* mp_subscript */
3521     (objobjargproc)pyrna_struct_ass_subscript, /* mp_ass_subscript */
3522 };
3523 
3524 PyDoc_STRVAR(pyrna_struct_keys_doc,
3525              ".. method:: keys()\n"
3526              "\n"
3527              "   Returns the keys of this objects custom properties (matches Python's\n"
3528              "   dictionary function of the same name).\n"
3529              "\n"
3530              "   :return: custom property keys.\n"
3531              "   :rtype: list of strings\n"
3532              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
pyrna_struct_keys(BPy_PropertyRNA * self)3533 static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
3534 {
3535   IDProperty *group;
3536 
3537   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3538     PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
3539     return NULL;
3540   }
3541 
3542   group = RNA_struct_idprops(&self->ptr, 0);
3543 
3544   if (group == NULL) {
3545     return PyList_New(0);
3546   }
3547 
3548   return BPy_Wrap_GetKeys(group);
3549 }
3550 
3551 PyDoc_STRVAR(pyrna_struct_items_doc,
3552              ".. method:: items()\n"
3553              "\n"
3554              "   Returns the items of this objects custom properties (matches Python's\n"
3555              "   dictionary function of the same name).\n"
3556              "\n"
3557              "   :return: custom property key, value pairs.\n"
3558              "   :rtype: list of key, value tuples\n"
3559              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
pyrna_struct_items(BPy_PropertyRNA * self)3560 static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
3561 {
3562   IDProperty *group;
3563 
3564   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3565     PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
3566     return NULL;
3567   }
3568 
3569   group = RNA_struct_idprops(&self->ptr, 0);
3570 
3571   if (group == NULL) {
3572     return PyList_New(0);
3573   }
3574 
3575   return BPy_Wrap_GetItems(self->ptr.owner_id, group);
3576 }
3577 
3578 PyDoc_STRVAR(pyrna_struct_values_doc,
3579              ".. method:: values()\n"
3580              "\n"
3581              "   Returns the values of this objects custom properties (matches Python's\n"
3582              "   dictionary function of the same name).\n"
3583              "\n"
3584              "   :return: custom property values.\n"
3585              "   :rtype: list\n"
3586              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
pyrna_struct_values(BPy_PropertyRNA * self)3587 static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
3588 {
3589   IDProperty *group;
3590 
3591   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3592     PyErr_SetString(PyExc_TypeError,
3593                     "bpy_struct.values(): this type doesn't support IDProperties");
3594     return NULL;
3595   }
3596 
3597   group = RNA_struct_idprops(&self->ptr, 0);
3598 
3599   if (group == NULL) {
3600     return PyList_New(0);
3601   }
3602 
3603   return BPy_Wrap_GetValues(self->ptr.owner_id, group);
3604 }
3605 
3606 PyDoc_STRVAR(pyrna_struct_is_property_set_doc,
3607              ".. method:: is_property_set(property, ghost=True)\n"
3608              "\n"
3609              "   Check if a property is set, use for testing operator properties.\n"
3610              "\n"
3611              "   :arg ghost: Used for operators that re-run with previous settings.\n"
3612              "      In this case the property is not marked as set,\n"
3613              "      yet the value from the previous execution is used.\n"
3614              "\n"
3615              "      In rare cases you may want to set this option to false.\n"
3616              "\n"
3617              "   :type ghost: boolean\n"
3618              "   :return: True when the property has been set.\n"
3619              "   :rtype: boolean\n");
pyrna_struct_is_property_set(BPy_StructRNA * self,PyObject * args,PyObject * kw)3620 static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args, PyObject *kw)
3621 {
3622   PropertyRNA *prop;
3623   const char *name;
3624   bool use_ghost = true;
3625 
3626   PYRNA_STRUCT_CHECK_OBJ(self);
3627 
3628   static const char *_keywords[] = {"", "ghost", NULL};
3629   static _PyArg_Parser _parser = {"s|$O&:is_property_set", _keywords, 0};
3630   if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &name, PyC_ParseBool, &use_ghost)) {
3631     return NULL;
3632   }
3633 
3634   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3635     PyErr_Format(PyExc_TypeError,
3636                  "%.200s.is_property_set(\"%.200s\") not found",
3637                  RNA_struct_identifier(self->ptr.type),
3638                  name);
3639     return NULL;
3640   }
3641 
3642   return PyBool_FromLong(RNA_property_is_set_ex(&self->ptr, prop, use_ghost));
3643 }
3644 
3645 PyDoc_STRVAR(pyrna_struct_property_unset_doc,
3646              ".. method:: property_unset(property)\n"
3647              "\n"
3648              "   Unset a property, will use default value afterward.\n");
pyrna_struct_property_unset(BPy_StructRNA * self,PyObject * args)3649 static PyObject *pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args)
3650 {
3651   PropertyRNA *prop;
3652   const char *name;
3653 
3654   PYRNA_STRUCT_CHECK_OBJ(self);
3655 
3656   if (!PyArg_ParseTuple(args, "s:property_unset", &name)) {
3657     return NULL;
3658   }
3659 
3660   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3661     PyErr_Format(PyExc_TypeError,
3662                  "%.200s.property_unset(\"%.200s\") not found",
3663                  RNA_struct_identifier(self->ptr.type),
3664                  name);
3665     return NULL;
3666   }
3667 
3668   RNA_property_unset(&self->ptr, prop);
3669 
3670   Py_RETURN_NONE;
3671 }
3672 
3673 PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc,
3674              ".. method:: is_property_hidden(property)\n"
3675              "\n"
3676              "   Check if a property is hidden.\n"
3677              "\n"
3678              "   :return: True when the property is hidden.\n"
3679              "   :rtype: boolean\n");
pyrna_struct_is_property_hidden(BPy_StructRNA * self,PyObject * args)3680 static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
3681 {
3682   PropertyRNA *prop;
3683   const char *name;
3684 
3685   PYRNA_STRUCT_CHECK_OBJ(self);
3686 
3687   if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) {
3688     return NULL;
3689   }
3690 
3691   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3692     PyErr_Format(PyExc_TypeError,
3693                  "%.200s.is_property_hidden(\"%.200s\") not found",
3694                  RNA_struct_identifier(self->ptr.type),
3695                  name);
3696     return NULL;
3697   }
3698 
3699   return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN);
3700 }
3701 
3702 PyDoc_STRVAR(pyrna_struct_is_property_readonly_doc,
3703              ".. method:: is_property_readonly(property)\n"
3704              "\n"
3705              "   Check if a property is readonly.\n"
3706              "\n"
3707              "   :return: True when the property is readonly (not writable).\n"
3708              "   :rtype: boolean\n");
pyrna_struct_is_property_readonly(BPy_StructRNA * self,PyObject * args)3709 static PyObject *pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject *args)
3710 {
3711   PropertyRNA *prop;
3712   const char *name;
3713 
3714   PYRNA_STRUCT_CHECK_OBJ(self);
3715 
3716   if (!PyArg_ParseTuple(args, "s:is_property_readonly", &name)) {
3717     return NULL;
3718   }
3719 
3720   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3721     PyErr_Format(PyExc_TypeError,
3722                  "%.200s.is_property_readonly(\"%.200s\") not found",
3723                  RNA_struct_identifier(self->ptr.type),
3724                  name);
3725     return NULL;
3726   }
3727 
3728   return PyBool_FromLong(!RNA_property_editable(&self->ptr, prop));
3729 }
3730 
3731 PyDoc_STRVAR(pyrna_struct_is_property_overridable_library_doc,
3732              ".. method:: is_property_overridable_library(property)\n"
3733              "\n"
3734              "   Check if a property is overridable.\n"
3735              "\n"
3736              "   :return: True when the property is overridable.\n"
3737              "   :rtype: boolean\n");
pyrna_struct_is_property_overridable_library(BPy_StructRNA * self,PyObject * args)3738 static PyObject *pyrna_struct_is_property_overridable_library(BPy_StructRNA *self, PyObject *args)
3739 {
3740   PropertyRNA *prop;
3741   const char *name;
3742 
3743   PYRNA_STRUCT_CHECK_OBJ(self);
3744 
3745   if (!PyArg_ParseTuple(args, "s:is_property_overridable_library", &name)) {
3746     return NULL;
3747   }
3748 
3749   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3750     PyErr_Format(PyExc_TypeError,
3751                  "%.200s.is_property_overridable_library(\"%.200s\") not found",
3752                  RNA_struct_identifier(self->ptr.type),
3753                  name);
3754     return NULL;
3755   }
3756 
3757   return PyBool_FromLong((long)RNA_property_overridable_get(&self->ptr, prop));
3758 }
3759 
3760 PyDoc_STRVAR(pyrna_struct_property_overridable_library_set_doc,
3761              ".. method:: property_overridable_library_set(property, overridable)\n"
3762              "\n"
3763              "   Define a property as overridable or not (only for custom properties!).\n"
3764              "\n"
3765              "   :return: True when the overridable status of the property was successfully set.\n"
3766              "   :rtype: boolean\n");
pyrna_struct_property_overridable_library_set(BPy_StructRNA * self,PyObject * args)3767 static PyObject *pyrna_struct_property_overridable_library_set(BPy_StructRNA *self, PyObject *args)
3768 {
3769   PropertyRNA *prop;
3770   const char *name;
3771   int is_overridable;
3772 
3773   PYRNA_STRUCT_CHECK_OBJ(self);
3774 
3775   if (!PyArg_ParseTuple(args, "sp:property_overridable_library_set", &name, &is_overridable)) {
3776     return NULL;
3777   }
3778 
3779   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3780     PyErr_Format(PyExc_TypeError,
3781                  "%.200s.property_overridable_library_set(\"%.200s\") not found",
3782                  RNA_struct_identifier(self->ptr.type),
3783                  name);
3784     return NULL;
3785   }
3786 
3787   return PyBool_FromLong(
3788       (long)RNA_property_overridable_library_set(&self->ptr, prop, (bool)is_overridable));
3789 }
3790 
3791 PyDoc_STRVAR(pyrna_struct_path_resolve_doc,
3792              ".. method:: path_resolve(path, coerce=True)\n"
3793              "\n"
3794              "   Returns the property from the path, raise an exception when not found.\n"
3795              "\n"
3796              "   :arg path: path which this property resolves.\n"
3797              "   :type path: string\n"
3798              "   :arg coerce: optional argument, when True, the property will be converted\n"
3799              "      into its Python representation.\n"
3800              "   :type coerce: boolean\n");
pyrna_struct_path_resolve(BPy_StructRNA * self,PyObject * args)3801 static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
3802 {
3803   const char *path;
3804   PyObject *coerce = Py_True;
3805   PointerRNA r_ptr;
3806   PropertyRNA *r_prop;
3807   int index = -1;
3808 
3809   PYRNA_STRUCT_CHECK_OBJ(self);
3810 
3811   if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce)) {
3812     return NULL;
3813   }
3814 
3815   if (RNA_path_resolve_full(&self->ptr, path, &r_ptr, &r_prop, &index)) {
3816     if (r_prop) {
3817       if (index != -1) {
3818         if (index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) {
3819           PyErr_Format(PyExc_IndexError,
3820                        "%.200s.path_resolve(\"%.200s\") index out of range",
3821                        RNA_struct_identifier(self->ptr.type),
3822                        path);
3823           return NULL;
3824         }
3825 
3826         return pyrna_array_index(&r_ptr, r_prop, index);
3827       }
3828 
3829       if (coerce == Py_False) {
3830         return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
3831       }
3832 
3833       return pyrna_prop_to_py(&r_ptr, r_prop);
3834     }
3835 
3836     return pyrna_struct_CreatePyObject(&r_ptr);
3837   }
3838 
3839   PyErr_Format(PyExc_ValueError,
3840                "%.200s.path_resolve(\"%.200s\") could not be resolved",
3841                RNA_struct_identifier(self->ptr.type),
3842                path);
3843   return NULL;
3844 }
3845 
3846 PyDoc_STRVAR(pyrna_struct_path_from_id_doc,
3847              ".. method:: path_from_id(property=\"\")\n"
3848              "\n"
3849              "   Returns the data path from the ID to this object (string).\n"
3850              "\n"
3851              "   :arg property: Optional property name which can be used if the path is\n"
3852              "      to a property of this object.\n"
3853              "   :type property: string\n"
3854              "   :return: The path from :class:`bpy.types.bpy_struct.id_data`\n"
3855              "      to this struct and property (when given).\n"
3856              "   :rtype: str\n");
pyrna_struct_path_from_id(BPy_StructRNA * self,PyObject * args)3857 static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
3858 {
3859   const char *name = NULL;
3860   const char *path;
3861   PropertyRNA *prop;
3862   PyObject *ret;
3863 
3864   PYRNA_STRUCT_CHECK_OBJ(self);
3865 
3866   if (!PyArg_ParseTuple(args, "|s:path_from_id", &name)) {
3867     return NULL;
3868   }
3869 
3870   if (name) {
3871     prop = RNA_struct_find_property(&self->ptr, name);
3872     if (prop == NULL) {
3873       PyErr_Format(PyExc_AttributeError,
3874                    "%.200s.path_from_id(\"%.200s\") not found",
3875                    RNA_struct_identifier(self->ptr.type),
3876                    name);
3877       return NULL;
3878     }
3879 
3880     path = RNA_path_from_ID_to_property(&self->ptr, prop);
3881   }
3882   else {
3883     path = RNA_path_from_ID_to_struct(&self->ptr);
3884   }
3885 
3886   if (path == NULL) {
3887     if (name) {
3888       PyErr_Format(PyExc_ValueError,
3889                    "%.200s.path_from_id(\"%s\") found, but does not support path creation",
3890                    RNA_struct_identifier(self->ptr.type),
3891                    name);
3892     }
3893     else {
3894       PyErr_Format(PyExc_ValueError,
3895                    "%.200s.path_from_id() does not support path creation for this type",
3896                    RNA_struct_identifier(self->ptr.type));
3897     }
3898     return NULL;
3899   }
3900 
3901   ret = PyUnicode_FromString(path);
3902   MEM_freeN((void *)path);
3903 
3904   return ret;
3905 }
3906 
3907 PyDoc_STRVAR(pyrna_prop_path_from_id_doc,
3908              ".. method:: path_from_id()\n"
3909              "\n"
3910              "   Returns the data path from the ID to this property (string).\n"
3911              "\n"
3912              "   :return: The path from :class:`bpy.types.bpy_struct.id_data` to this property.\n"
3913              "   :rtype: str\n");
pyrna_prop_path_from_id(BPy_PropertyRNA * self)3914 static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
3915 {
3916   const char *path;
3917   PropertyRNA *prop = self->prop;
3918   PyObject *ret;
3919 
3920   path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
3921 
3922   if (path == NULL) {
3923     PyErr_Format(PyExc_ValueError,
3924                  "%.200s.%.200s.path_from_id() does not support path creation for this type",
3925                  RNA_struct_identifier(self->ptr.type),
3926                  RNA_property_identifier(prop));
3927     return NULL;
3928   }
3929 
3930   ret = PyUnicode_FromString(path);
3931   MEM_freeN((void *)path);
3932 
3933   return ret;
3934 }
3935 
3936 PyDoc_STRVAR(pyrna_prop_as_bytes_doc,
3937              ".. method:: as_bytes()\n"
3938              "\n"
3939              "   Returns this string property as a byte rather than a Python string.\n"
3940              "\n"
3941              "   :return: The string as bytes.\n"
3942              "   :rtype: bytes\n");
pyrna_prop_as_bytes(BPy_PropertyRNA * self)3943 static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self)
3944 {
3945 
3946   if (RNA_property_type(self->prop) != PROP_STRING) {
3947     PyErr_Format(PyExc_TypeError,
3948                  "%.200s.%.200s.as_bytes() must be a string",
3949                  RNA_struct_identifier(self->ptr.type),
3950                  RNA_property_identifier(self->prop));
3951     return NULL;
3952   }
3953 
3954   PyObject *ret;
3955   char buf_fixed[256], *buf;
3956   int buf_len;
3957 
3958   buf = RNA_property_string_get_alloc(
3959       &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len);
3960 
3961   ret = PyBytes_FromStringAndSize(buf, buf_len);
3962 
3963   if (buf_fixed != buf) {
3964     MEM_freeN(buf);
3965   }
3966 
3967   return ret;
3968 }
3969 
3970 PyDoc_STRVAR(pyrna_prop_update_doc,
3971              ".. method:: update()\n"
3972              "\n"
3973              "   Execute the properties update callback.\n"
3974              "\n"
3975              "   .. note::\n"
3976              "      This is called when assigning a property,\n"
3977              "      however in rare cases it's useful to call explicitly.\n");
pyrna_prop_update(BPy_PropertyRNA * self)3978 static PyObject *pyrna_prop_update(BPy_PropertyRNA *self)
3979 {
3980   RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
3981   Py_RETURN_NONE;
3982 }
3983 
3984 PyDoc_STRVAR(pyrna_struct_type_recast_doc,
3985              ".. method:: type_recast()\n"
3986              "\n"
3987              "   Return a new instance, this is needed because types\n"
3988              "   such as textures can be changed at runtime.\n"
3989              "\n"
3990              "   :return: a new instance of this object with the type initialized again.\n"
3991              "   :rtype: subclass of :class:`bpy.types.bpy_struct`\n");
pyrna_struct_type_recast(BPy_StructRNA * self)3992 static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
3993 {
3994   PointerRNA r_ptr;
3995 
3996   PYRNA_STRUCT_CHECK_OBJ(self);
3997 
3998   RNA_pointer_recast(&self->ptr, &r_ptr);
3999   return pyrna_struct_CreatePyObject(&r_ptr);
4000 }
4001 
4002 /**
4003  * \note Return value is borrowed, caller must #Py_INCREF.
4004  */
pyrna_struct_bl_rna_find_subclass_recursive(PyObject * cls,const char * id)4005 static PyObject *pyrna_struct_bl_rna_find_subclass_recursive(PyObject *cls, const char *id)
4006 {
4007   PyObject *ret_test = NULL;
4008   PyObject *subclasses = ((PyTypeObject *)cls)->tp_subclasses;
4009   if (subclasses) {
4010     /* Unfortunately we can't use the dict key because Python class names
4011      * don't match the bl_idname used internally. */
4012     BLI_assert(PyDict_CheckExact(subclasses));
4013     PyObject *key = NULL;
4014     Py_ssize_t pos = 0;
4015     PyObject *value = NULL;
4016     while (PyDict_Next(subclasses, &pos, &key, &value)) {
4017       BLI_assert(PyWeakref_CheckRef(value));
4018       PyObject *subcls = PyWeakref_GET_OBJECT(value);
4019       if (subcls != Py_None) {
4020         BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)subcls)->tp_dict,
4021                                                                  bpy_intern_str_bl_rna);
4022         if (py_srna) {
4023           StructRNA *srna = py_srna->ptr.data;
4024           if (STREQ(id, RNA_struct_identifier(srna))) {
4025             ret_test = subcls;
4026             break;
4027           }
4028         }
4029         ret_test = pyrna_struct_bl_rna_find_subclass_recursive(subcls, id);
4030         if (ret_test) {
4031           break;
4032         }
4033       }
4034     }
4035   }
4036   return ret_test;
4037 }
4038 
4039 PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_py_doc,
4040              ".. classmethod:: bl_rna_get_subclass_py(id, default=None)\n"
4041              "\n"
4042              "   :arg id: The RNA type identifier.\n"
4043              "   :type id: string\n"
4044              "   :return: The class or default when not found.\n"
4045              "   :rtype: type\n");
pyrna_struct_bl_rna_get_subclass_py(PyObject * cls,PyObject * args)4046 static PyObject *pyrna_struct_bl_rna_get_subclass_py(PyObject *cls, PyObject *args)
4047 {
4048   char *id;
4049   PyObject *ret_default = Py_None;
4050 
4051   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass_py", &id, &ret_default)) {
4052     return NULL;
4053   }
4054   PyObject *ret = pyrna_struct_bl_rna_find_subclass_recursive(cls, id);
4055   if (ret == NULL) {
4056     ret = ret_default;
4057   }
4058   return Py_INCREF_RET(ret);
4059 }
4060 
4061 PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_doc,
4062              ".. classmethod:: bl_rna_get_subclass(id, default=None)\n"
4063              "\n"
4064              "   :arg id: The RNA type identifier.\n"
4065              "   :type id: string\n"
4066              "   :return: The RNA type or default when not found.\n"
4067              "   :rtype: :class:`bpy.types.Struct` subclass\n");
pyrna_struct_bl_rna_get_subclass(PyObject * cls,PyObject * args)4068 static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args)
4069 {
4070   char *id;
4071   PyObject *ret_default = Py_None;
4072 
4073   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass", &id, &ret_default)) {
4074     return NULL;
4075   }
4076 
4077   const BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)cls)->tp_dict,
4078                                                                  bpy_intern_str_bl_rna);
4079   if (py_srna == NULL) {
4080     PyErr_SetString(PyExc_ValueError, "Not a registered class");
4081     return NULL;
4082   }
4083   const StructRNA *srna_base = py_srna->ptr.data;
4084 
4085   PointerRNA ptr;
4086   if (srna_base == &RNA_Node) {
4087     bNodeType *nt = nodeTypeFind(id);
4088     if (nt) {
4089       RNA_pointer_create(NULL, &RNA_Struct, nt->rna_ext.srna, &ptr);
4090       return pyrna_struct_CreatePyObject(&ptr);
4091     }
4092   }
4093   else {
4094     /* TODO, panels, menus etc. */
4095     PyErr_Format(
4096         PyExc_ValueError, "Class type \"%.200s\" not supported", RNA_struct_identifier(srna_base));
4097     return NULL;
4098   }
4099 
4100   return Py_INCREF_RET(ret_default);
4101 }
4102 
pyrna_dir_members_py__add_keys(PyObject * list,PyObject * dict)4103 static void pyrna_dir_members_py__add_keys(PyObject *list, PyObject *dict)
4104 {
4105   PyObject *list_tmp;
4106 
4107   list_tmp = PyDict_Keys(dict);
4108   PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
4109   Py_DECREF(list_tmp);
4110 }
4111 
pyrna_dir_members_py(PyObject * list,PyObject * self)4112 static void pyrna_dir_members_py(PyObject *list, PyObject *self)
4113 {
4114   PyObject *dict;
4115   PyObject **dict_ptr;
4116 
4117   dict_ptr = _PyObject_GetDictPtr((PyObject *)self);
4118 
4119   if (dict_ptr && (dict = *dict_ptr)) {
4120     pyrna_dir_members_py__add_keys(list, dict);
4121   }
4122 
4123   dict = ((PyTypeObject *)Py_TYPE(self))->tp_dict;
4124   if (dict) {
4125     pyrna_dir_members_py__add_keys(list, dict);
4126   }
4127 
4128   /* Since this is least common case, handle it last. */
4129   if (BPy_PropertyRNA_Check(self)) {
4130     BPy_PropertyRNA *self_prop = (BPy_PropertyRNA *)self;
4131     if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) {
4132       PointerRNA r_ptr;
4133 
4134       if (RNA_property_collection_type_get(&self_prop->ptr, self_prop->prop, &r_ptr)) {
4135         PyObject *cls = pyrna_struct_Subtype(&r_ptr); /* borrows */
4136         dict = ((PyTypeObject *)cls)->tp_dict;
4137         pyrna_dir_members_py__add_keys(list, dict);
4138         Py_DECREF(cls);
4139       }
4140     }
4141   }
4142 }
4143 
pyrna_dir_members_rna(PyObject * list,PointerRNA * ptr)4144 static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
4145 {
4146   const char *idname;
4147 
4148   /* For looping over attrs and funcs. */
4149   PointerRNA tptr;
4150   PropertyRNA *iterprop;
4151 
4152   {
4153     RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
4154     iterprop = RNA_struct_find_property(&tptr, "functions");
4155 
4156     RNA_PROP_BEGIN (&tptr, itemptr, iterprop) {
4157       FunctionRNA *func = itemptr.data;
4158       if (RNA_function_defined(func)) {
4159         idname = RNA_function_identifier(itemptr.data);
4160         PyList_APPEND(list, PyUnicode_FromString(idname));
4161       }
4162     }
4163     RNA_PROP_END;
4164   }
4165 
4166   {
4167     /*
4168      * Collect RNA attributes
4169      */
4170     char name[256], *nameptr;
4171     int namelen;
4172 
4173     iterprop = RNA_struct_iterator_property(ptr->type);
4174 
4175     RNA_PROP_BEGIN (ptr, itemptr, iterprop) {
4176       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
4177 
4178       if (nameptr) {
4179         PyList_APPEND(list, PyUnicode_FromStringAndSize(nameptr, namelen));
4180 
4181         if (name != nameptr) {
4182           MEM_freeN(nameptr);
4183         }
4184       }
4185     }
4186     RNA_PROP_END;
4187   }
4188 }
4189 
pyrna_struct_dir(BPy_StructRNA * self)4190 static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
4191 {
4192   PyObject *ret;
4193 
4194   PYRNA_STRUCT_CHECK_OBJ(self);
4195 
4196   /* Include this in case this instance is a subtype of a Python class
4197    * In these instances we may want to return a function or variable provided by the subtype. */
4198   ret = PyList_New(0);
4199 
4200   if (!BPy_StructRNA_CheckExact(self)) {
4201     pyrna_dir_members_py(ret, (PyObject *)self);
4202   }
4203 
4204   pyrna_dir_members_rna(ret, &self->ptr);
4205 
4206   if (self->ptr.type == &RNA_Context) {
4207     ListBase lb = CTX_data_dir_get(self->ptr.data);
4208     LinkData *link;
4209 
4210     for (link = lb.first; link; link = link->next) {
4211       PyList_APPEND(ret, PyUnicode_FromString(link->data));
4212     }
4213 
4214     BLI_freelistN(&lb);
4215   }
4216 
4217   {
4218     /* set(), this is needed to remove-doubles because the deferred
4219      * register-props will be in both the Python __dict__ and accessed as RNA */
4220 
4221     PyObject *set = PySet_New(ret);
4222 
4223     Py_DECREF(ret);
4224     ret = PySequence_List(set);
4225     Py_DECREF(set);
4226   }
4227 
4228   return ret;
4229 }
4230 
4231 /* ---------------getattr-------------------------------------------- */
pyrna_struct_getattro(BPy_StructRNA * self,PyObject * pyname)4232 static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
4233 {
4234   const char *name = _PyUnicode_AsString(pyname);
4235   PyObject *ret;
4236   PropertyRNA *prop;
4237   FunctionRNA *func;
4238 
4239   PYRNA_STRUCT_CHECK_OBJ(self);
4240 
4241   if (name == NULL) {
4242     PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string");
4243     ret = NULL;
4244   }
4245   else if (
4246       /* RNA can't start with a "_", so for __dict__ and similar we can skip using RNA lookups. */
4247       name[0] == '_') {
4248     /* Annoying exception, maybe we need to have different types for this... */
4249     if (STR_ELEM(name, "__getitem__", "__setitem__") &&
4250         !RNA_struct_idprops_check(self->ptr.type)) {
4251       PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
4252       ret = NULL;
4253     }
4254     else {
4255       ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
4256     }
4257   }
4258   else if ((prop = RNA_struct_find_property(&self->ptr, name))) {
4259     ret = pyrna_prop_to_py(&self->ptr, prop);
4260   }
4261   /* RNA function only if callback is declared (no optional functions). */
4262   else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) {
4263     ret = pyrna_func_to_py(&self->ptr, func);
4264   }
4265   else if (self->ptr.type == &RNA_Context) {
4266     bContext *C = self->ptr.data;
4267     if (C == NULL) {
4268       PyErr_Format(PyExc_AttributeError,
4269                    "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context",
4270                    name);
4271       ret = NULL;
4272     }
4273     else {
4274       PointerRNA newptr;
4275       ListBase newlb;
4276       short newtype;
4277 
4278       const eContextResult done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
4279 
4280       if (done == CTX_RESULT_OK) {
4281         switch (newtype) {
4282           case CTX_DATA_TYPE_POINTER:
4283             if (newptr.data == NULL) {
4284               ret = Py_None;
4285               Py_INCREF(ret);
4286             }
4287             else {
4288               ret = pyrna_struct_CreatePyObject(&newptr);
4289             }
4290             break;
4291           case CTX_DATA_TYPE_COLLECTION: {
4292             CollectionPointerLink *link;
4293 
4294             ret = PyList_New(0);
4295 
4296             for (link = newlb.first; link; link = link->next) {
4297               PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr));
4298             }
4299             break;
4300           }
4301           default:
4302             /* Should never happen. */
4303             BLI_assert(!"Invalid context type");
4304 
4305             PyErr_Format(PyExc_AttributeError,
4306                          "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context",
4307                          newtype,
4308                          name);
4309             ret = NULL;
4310             break;
4311         }
4312       }
4313       else if (done == CTX_RESULT_NO_DATA) {
4314         ret = Py_None;
4315         Py_INCREF(ret);
4316       }
4317       else { /* Not found in the context. */
4318         /* Lookup the subclass. raise an error if it's not found. */
4319         ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
4320       }
4321 
4322       BLI_freelistN(&newlb);
4323     }
4324   }
4325   else {
4326 #if 0
4327     PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name);
4328     ret = NULL;
4329 #endif
4330     /* Include this in case this instance is a subtype of a Python class
4331      * In these instances we may want to return a function or variable provided by the subtype
4332      *
4333      * Also needed to return methods when it's not a subtype.
4334      */
4335 
4336     /* The error raised here will be displayed */
4337     ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
4338   }
4339 
4340   return ret;
4341 }
4342 
4343 #if 0
4344 static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname)
4345 {
4346   PyObject *dict = *(_PyObject_GetDictPtr((PyObject *)self));
4347   if (UNLIKELY(dict == NULL)) {
4348     return 0;
4349   }
4350 
4351   return PyDict_Contains(dict, pyname);
4352 }
4353 #endif
4354 
4355 /* --------------- setattr------------------------------------------- */
pyrna_is_deferred_prop(const PyObject * value)4356 static bool pyrna_is_deferred_prop(const PyObject *value)
4357 {
4358   return PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value) == 2 &&
4359          PyCFunction_Check(PyTuple_GET_ITEM(value, 0)) &&
4360          PyDict_CheckExact(PyTuple_GET_ITEM(value, 1));
4361 }
4362 
4363 #if 0
4364 static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr)
4365 {
4366   PyObject *ret = PyType_Type.tp_getattro(cls, attr);
4367 
4368   /* Allows:
4369    * >>> bpy.types.Scene.foo = BoolProperty()
4370    * >>> bpy.types.Scene.foo
4371    * <bpy_struct, BoolProperty("foo")>
4372    * ...rather than returning the deferred class register tuple
4373    * as checked by pyrna_is_deferred_prop()
4374    *
4375    * Disable for now,
4376    * this is faking internal behavior in a way that's too tricky to maintain well. */
4377 #  if 0
4378   if ((ret == NULL)  /* || pyrna_is_deferred_prop(ret) */ ) {
4379     StructRNA *srna = srna_from_self(cls, "StructRNA.__getattr__");
4380     if (srna) {
4381       PropertyRNA *prop = RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr));
4382       if (prop) {
4383         PointerRNA tptr;
4384         PyErr_Clear(); /* Clear error from tp_getattro. */
4385         RNA_pointer_create(NULL, &RNA_Property, prop, &tptr);
4386         ret = pyrna_struct_CreatePyObject(&tptr);
4387       }
4388     }
4389   }
4390 #  endif
4391 
4392   return ret;
4393 }
4394 #endif
4395 
pyrna_struct_meta_idprop_setattro(PyObject * cls,PyObject * attr,PyObject * value)4396 static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value)
4397 {
4398   StructRNA *srna = srna_from_self(cls, "StructRNA.__setattr__");
4399   const bool is_deferred_prop = (value && pyrna_is_deferred_prop(value));
4400   const char *attr_str = _PyUnicode_AsString(attr);
4401 
4402   if (srna && !pyrna_write_check() &&
4403       (is_deferred_prop || RNA_struct_type_find_property(srna, attr_str))) {
4404     PyErr_Format(PyExc_AttributeError,
4405                  "pyrna_struct_meta_idprop_setattro() "
4406                  "can't set in readonly state '%.200s.%S'",
4407                  ((PyTypeObject *)cls)->tp_name,
4408                  attr);
4409     return -1;
4410   }
4411 
4412   if (srna == NULL) {
4413     /* Allow setting on unregistered classes which can be registered later on. */
4414 #if 0
4415     if (value && is_deferred_prop) {
4416       PyErr_Format(PyExc_AttributeError,
4417                    "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'",
4418                    ((PyTypeObject *)cls)->tp_name);
4419       return -1;
4420     }
4421 #endif
4422     /* srna_from_self may set an error. */
4423     PyErr_Clear();
4424     return PyType_Type.tp_setattro(cls, attr, value);
4425   }
4426 
4427   if (value) {
4428     /* Check if the value is a property. */
4429     if (is_deferred_prop) {
4430       const int ret = deferred_register_prop(srna, attr, value);
4431       if (ret == -1) {
4432         /* Error set. */
4433         return ret;
4434       }
4435 
4436       /* pass through and assign to the classes __dict__ as well
4437        * so when the value isn't assigned it still creates the RNA property,
4438        * but gets confusing from script writers POV if the assigned value can't be read back. */
4439     }
4440     else {
4441       /* Remove existing property if it's set or we also end up with confusion. */
4442       RNA_def_property_free_identifier(srna, attr_str); /* Ignore on failure. */
4443     }
4444   }
4445   else { /* __delattr__ */
4446     /* First find if this is a registered property. */
4447     const int ret = RNA_def_property_free_identifier(srna, attr_str);
4448     if (ret == -1) {
4449       PyErr_Format(
4450           PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str);
4451       return -1;
4452     }
4453   }
4454 
4455   /* Fallback to standard py, delattr/setattr. */
4456   return PyType_Type.tp_setattro(cls, attr, value);
4457 }
4458 
pyrna_struct_setattro(BPy_StructRNA * self,PyObject * pyname,PyObject * value)4459 static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject *value)
4460 {
4461   const char *name = _PyUnicode_AsString(pyname);
4462   PropertyRNA *prop = NULL;
4463 
4464   PYRNA_STRUCT_CHECK_INT(self);
4465 
4466 #ifdef USE_PEDANTIC_WRITE
4467   if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
4468     return -1;
4469   }
4470 #endif /* USE_PEDANTIC_WRITE */
4471 
4472   if (name == NULL) {
4473     PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
4474     return -1;
4475   }
4476   if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) {
4477     if (!RNA_property_editable_flag(&self->ptr, prop)) {
4478       PyErr_Format(PyExc_AttributeError,
4479                    "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only",
4480                    RNA_property_identifier(prop),
4481                    RNA_struct_identifier(self->ptr.type));
4482       return -1;
4483     }
4484   }
4485   else if (self->ptr.type == &RNA_Context) {
4486     /* Code just raises correct error, context prop's can't be set,
4487      * unless it's a part of the py class. */
4488     bContext *C = self->ptr.data;
4489     if (C == NULL) {
4490       PyErr_Format(PyExc_AttributeError,
4491                    "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context",
4492                    name);
4493       return -1;
4494     }
4495 
4496     PointerRNA newptr;
4497     ListBase newlb;
4498     short newtype;
4499 
4500     const eContextResult done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
4501 
4502     if (done == CTX_RESULT_OK) {
4503       PyErr_Format(
4504           PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name);
4505       BLI_freelistN(&newlb);
4506       return -1;
4507     }
4508 
4509     BLI_freelistN(&newlb);
4510   }
4511 
4512   /* pyrna_py_to_prop sets its own exceptions */
4513   if (prop) {
4514     if (value == NULL) {
4515       PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported");
4516       return -1;
4517     }
4518     return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:");
4519   }
4520 
4521   return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
4522 }
4523 
pyrna_prop_dir(BPy_PropertyRNA * self)4524 static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
4525 {
4526   PyObject *ret;
4527   PointerRNA r_ptr;
4528 
4529   /* Include this in case this instance is a subtype of a Python class
4530    * In these instances we may want to return a function or variable provided by the subtype. */
4531   ret = PyList_New(0);
4532 
4533   if (!BPy_PropertyRNA_CheckExact(self)) {
4534     pyrna_dir_members_py(ret, (PyObject *)self);
4535   }
4536 
4537   if (RNA_property_type(self->prop) == PROP_COLLECTION) {
4538     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4539       pyrna_dir_members_rna(ret, &r_ptr);
4540     }
4541   }
4542 
4543   return ret;
4544 }
4545 
pyrna_prop_array_getattro(BPy_PropertyRNA * self,PyObject * pyname)4546 static PyObject *pyrna_prop_array_getattro(BPy_PropertyRNA *self, PyObject *pyname)
4547 {
4548   return PyObject_GenericGetAttr((PyObject *)self, pyname);
4549 }
4550 
pyrna_prop_collection_getattro(BPy_PropertyRNA * self,PyObject * pyname)4551 static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject *pyname)
4552 {
4553   const char *name = _PyUnicode_AsString(pyname);
4554 
4555   if (name == NULL) {
4556     PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
4557     return NULL;
4558   }
4559   if (name[0] != '_') {
4560     PyObject *ret;
4561     PropertyRNA *prop;
4562     FunctionRNA *func;
4563 
4564     PointerRNA r_ptr;
4565     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4566       if ((prop = RNA_struct_find_property(&r_ptr, name))) {
4567         ret = pyrna_prop_to_py(&r_ptr, prop);
4568 
4569         return ret;
4570       }
4571       if ((func = RNA_struct_find_function(r_ptr.type, name))) {
4572         PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr);
4573         ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func);
4574         Py_DECREF(self_collection);
4575 
4576         return ret;
4577       }
4578     }
4579   }
4580 
4581 #if 0
4582   return PyObject_GenericGetAttr((PyObject *)self, pyname);
4583 #else
4584   {
4585     /* Could just do this except for 1 awkward case.
4586      * PyObject_GenericGetAttr((PyObject *)self, pyname);
4587      * so as to support 'bpy.data.library.load()'
4588      * note, this _only_ supports static methods */
4589 
4590     PyObject *ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
4591 
4592     if (ret == NULL && name[0] != '_') { /* Avoid inheriting __call__ and similar. */
4593       /* Since this is least common case, handle it last. */
4594       PointerRNA r_ptr;
4595       if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4596         PyObject *cls;
4597 
4598         PyObject *error_type, *error_value, *error_traceback;
4599         PyErr_Fetch(&error_type, &error_value, &error_traceback);
4600         PyErr_Clear();
4601 
4602         cls = pyrna_struct_Subtype(&r_ptr);
4603         ret = PyObject_GenericGetAttr(cls, pyname);
4604         Py_DECREF(cls);
4605 
4606         /* Restore the original error. */
4607         if (ret == NULL) {
4608           PyErr_Restore(error_type, error_value, error_traceback);
4609         }
4610       }
4611     }
4612 
4613     return ret;
4614   }
4615 #endif
4616 }
4617 
4618 /* --------------- setattr------------------------------------------- */
pyrna_prop_collection_setattro(BPy_PropertyRNA * self,PyObject * pyname,PyObject * value)4619 static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pyname, PyObject *value)
4620 {
4621   const char *name = _PyUnicode_AsString(pyname);
4622   PropertyRNA *prop;
4623   PointerRNA r_ptr;
4624 
4625 #ifdef USE_PEDANTIC_WRITE
4626   if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
4627     return -1;
4628   }
4629 #endif /* USE_PEDANTIC_WRITE */
4630 
4631   if (name == NULL) {
4632     PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string");
4633     return -1;
4634   }
4635   if (value == NULL) {
4636     PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
4637     return -1;
4638   }
4639   if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
4640     if ((prop = RNA_struct_find_property(&r_ptr, name))) {
4641       /* pyrna_py_to_prop sets its own exceptions. */
4642       return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
4643     }
4644   }
4645 
4646   PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name);
4647   return -1;
4648 }
4649 
4650 /**
4651  * Odd case, we need to be able return a Python method from a #PyTypeObject.tp_getset.
4652  */
pyrna_prop_collection_idprop_add(BPy_PropertyRNA * self)4653 static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
4654 {
4655   PointerRNA r_ptr;
4656 
4657 #ifdef USE_PEDANTIC_WRITE
4658   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
4659     return NULL;
4660   }
4661 #endif /* USE_PEDANTIC_WRITE */
4662 
4663   RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
4664   if (!r_ptr.data) {
4665     PyErr_SetString(PyExc_TypeError,
4666                     "bpy_prop_collection.add(): not supported for this collection");
4667     return NULL;
4668   }
4669 
4670   return pyrna_struct_CreatePyObject(&r_ptr);
4671 }
4672 
pyrna_prop_collection_idprop_remove(BPy_PropertyRNA * self,PyObject * value)4673 static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value)
4674 {
4675   const int key = PyLong_AsLong(value);
4676 
4677 #ifdef USE_PEDANTIC_WRITE
4678   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
4679     return NULL;
4680   }
4681 #endif /* USE_PEDANTIC_WRITE */
4682 
4683   if (key == -1 && PyErr_Occurred()) {
4684     PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument");
4685     return NULL;
4686   }
4687 
4688   if (!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
4689     PyErr_SetString(PyExc_TypeError,
4690                     "bpy_prop_collection.remove() not supported for this collection");
4691     return NULL;
4692   }
4693 
4694   Py_RETURN_NONE;
4695 }
4696 
pyrna_prop_collection_idprop_clear(BPy_PropertyRNA * self)4697 static PyObject *pyrna_prop_collection_idprop_clear(BPy_PropertyRNA *self)
4698 {
4699 #ifdef USE_PEDANTIC_WRITE
4700   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
4701     return NULL;
4702   }
4703 #endif /* USE_PEDANTIC_WRITE */
4704 
4705   RNA_property_collection_clear(&self->ptr, self->prop);
4706 
4707   Py_RETURN_NONE;
4708 }
4709 
pyrna_prop_collection_idprop_move(BPy_PropertyRNA * self,PyObject * args)4710 static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObject *args)
4711 {
4712   int key = 0, pos = 0;
4713 
4714 #ifdef USE_PEDANTIC_WRITE
4715   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
4716     return NULL;
4717   }
4718 #endif /* USE_PEDANTIC_WRITE */
4719 
4720   if (!PyArg_ParseTuple(args, "ii", &key, &pos)) {
4721     PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments");
4722     return NULL;
4723   }
4724 
4725   if (!RNA_property_collection_move(&self->ptr, self->prop, key, pos)) {
4726     PyErr_SetString(PyExc_TypeError,
4727                     "bpy_prop_collection.move() not supported for this collection");
4728     return NULL;
4729   }
4730 
4731   Py_RETURN_NONE;
4732 }
4733 
4734 PyDoc_STRVAR(pyrna_struct_get_id_data_doc,
4735              "The :class:`bpy.types.ID` object this datablock is from or None, (not available for "
4736              "all data types)");
pyrna_struct_get_id_data(BPy_DummyPointerRNA * self)4737 static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
4738 {
4739   /* Used for struct and pointer since both have a ptr. */
4740   if (self->ptr.owner_id) {
4741     PointerRNA id_ptr;
4742     RNA_id_pointer_create((ID *)self->ptr.owner_id, &id_ptr);
4743     return pyrna_struct_CreatePyObject(&id_ptr);
4744   }
4745 
4746   Py_RETURN_NONE;
4747 }
4748 
4749 PyDoc_STRVAR(pyrna_struct_get_data_doc,
4750              "The data this property is using, *type* :class:`bpy.types.bpy_struct`");
pyrna_struct_get_data(BPy_DummyPointerRNA * self)4751 static PyObject *pyrna_struct_get_data(BPy_DummyPointerRNA *self)
4752 {
4753   return pyrna_struct_CreatePyObject(&self->ptr);
4754 }
4755 
4756 PyDoc_STRVAR(pyrna_struct_get_rna_type_doc, "The property type for introspection");
pyrna_struct_get_rna_type(BPy_PropertyRNA * self)4757 static PyObject *pyrna_struct_get_rna_type(BPy_PropertyRNA *self)
4758 {
4759   PointerRNA tptr;
4760   RNA_pointer_create(NULL, &RNA_Property, self->prop, &tptr);
4761   return pyrna_struct_Subtype(&tptr);
4762 }
4763 
4764 /*****************************************************************************/
4765 /* Python attributes get/set structure:                                      */
4766 /*****************************************************************************/
4767 
4768 static PyGetSetDef pyrna_prop_getseters[] = {
4769     {"id_data",
4770      (getter)pyrna_struct_get_id_data,
4771      (setter)NULL,
4772      pyrna_struct_get_id_data_doc,
4773      NULL},
4774     {"data", (getter)pyrna_struct_get_data, (setter)NULL, pyrna_struct_get_data_doc, NULL},
4775     {"rna_type",
4776      (getter)pyrna_struct_get_rna_type,
4777      (setter)NULL,
4778      pyrna_struct_get_rna_type_doc,
4779      NULL},
4780     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
4781 };
4782 
4783 static PyGetSetDef pyrna_struct_getseters[] = {
4784     {"id_data",
4785      (getter)pyrna_struct_get_id_data,
4786      (setter)NULL,
4787      pyrna_struct_get_id_data_doc,
4788      NULL},
4789     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
4790 };
4791 
4792 static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *closure);
4793 
4794 static PyGetSetDef pyrna_func_getseters[] = {
4795     {"__doc__", (getter)pyrna_func_doc_get, (setter)NULL, NULL, NULL},
4796     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
4797 };
4798 
4799 PyDoc_STRVAR(pyrna_prop_collection_keys_doc,
4800              ".. method:: keys()\n"
4801              "\n"
4802              "   Return the identifiers of collection members\n"
4803              "   (matching Python's dict.keys() functionality).\n"
4804              "\n"
4805              "   :return: the identifiers for each member of this collection.\n"
4806              "   :rtype: list of strings\n");
pyrna_prop_collection_keys(BPy_PropertyRNA * self)4807 static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
4808 {
4809   PyObject *ret = PyList_New(0);
4810   char name[256], *nameptr;
4811   int namelen;
4812 
4813   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
4814     nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
4815 
4816     if (nameptr) {
4817       PyList_APPEND(ret, PyUnicode_FromStringAndSize(nameptr, namelen));
4818 
4819       if (name != nameptr) {
4820         MEM_freeN(nameptr);
4821       }
4822     }
4823   }
4824   RNA_PROP_END;
4825 
4826   return ret;
4827 }
4828 
4829 PyDoc_STRVAR(pyrna_prop_collection_items_doc,
4830              ".. method:: items()\n"
4831              "\n"
4832              "   Return the identifiers of collection members\n"
4833              "   (matching Python's dict.items() functionality).\n"
4834              "\n"
4835              "   :return: (key, value) pairs for each member of this collection.\n"
4836              "   :rtype: list of tuples\n");
pyrna_prop_collection_items(BPy_PropertyRNA * self)4837 static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
4838 {
4839   PyObject *ret = PyList_New(0);
4840   PyObject *item;
4841   char name[256], *nameptr;
4842   int namelen;
4843   int i = 0;
4844 
4845   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
4846     if (itemptr.data) {
4847       /* Add to Python list. */
4848       item = PyTuple_New(2);
4849       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
4850       if (nameptr) {
4851         PyTuple_SET_ITEM(item, 0, PyUnicode_FromStringAndSize(nameptr, namelen));
4852         if (name != nameptr) {
4853           MEM_freeN(nameptr);
4854         }
4855       }
4856       else {
4857         /* A bit strange, but better than returning an empty list. */
4858         PyTuple_SET_ITEM(item, 0, PyLong_FromLong(i));
4859       }
4860       PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
4861 
4862       PyList_APPEND(ret, item);
4863 
4864       i++;
4865     }
4866   }
4867   RNA_PROP_END;
4868 
4869   return ret;
4870 }
4871 
4872 PyDoc_STRVAR(pyrna_prop_collection_values_doc,
4873              ".. method:: values()\n"
4874              "\n"
4875              "   Return the values of collection\n"
4876              "   (matching Python's dict.values() functionality).\n"
4877              "\n"
4878              "   :return: the members of this collection.\n"
4879              "   :rtype: list\n");
pyrna_prop_collection_values(BPy_PropertyRNA * self)4880 static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self)
4881 {
4882   /* Re-use slice. */
4883   return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
4884 }
4885 
4886 PyDoc_STRVAR(pyrna_struct_get_doc,
4887              ".. method:: get(key, default=None)\n"
4888              "\n"
4889              "   Returns the value of the custom property assigned to key or default\n"
4890              "   when not found (matches Python's dictionary function of the same name).\n"
4891              "\n"
4892              "   :arg key: The key associated with the custom property.\n"
4893              "   :type key: string\n"
4894              "   :arg default: Optional argument for the value to return if\n"
4895              "      *key* is not found.\n"
4896              "   :type default: Undefined\n"
4897              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
pyrna_struct_get(BPy_StructRNA * self,PyObject * args)4898 static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
4899 {
4900   IDProperty *group, *idprop;
4901 
4902   const char *key;
4903   PyObject *def = Py_None;
4904 
4905   PYRNA_STRUCT_CHECK_OBJ(self);
4906 
4907   if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) {
4908     return NULL;
4909   }
4910 
4911   /* Mostly copied from BPy_IDGroup_Map_GetItem. */
4912   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
4913     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
4914     return NULL;
4915   }
4916 
4917   group = RNA_struct_idprops(&self->ptr, 0);
4918   if (group) {
4919     idprop = IDP_GetPropertyFromGroup(group, key);
4920 
4921     if (idprop) {
4922       return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
4923     }
4924   }
4925 
4926   return Py_INCREF_RET(def);
4927 }
4928 
4929 PyDoc_STRVAR(pyrna_struct_pop_doc,
4930              ".. method:: pop(key, default=None)\n"
4931              "\n"
4932              "   Remove and return the value of the custom property assigned to key or default\n"
4933              "   when not found (matches Python's dictionary function of the same name).\n"
4934              "\n"
4935              "   :arg key: The key associated with the custom property.\n"
4936              "   :type key: string\n"
4937              "   :arg default: Optional argument for the value to return if\n"
4938              "      *key* is not found.\n"
4939              "   :type default: Undefined\n"
4940              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
pyrna_struct_pop(BPy_StructRNA * self,PyObject * args)4941 static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args)
4942 {
4943   IDProperty *group, *idprop;
4944 
4945   const char *key;
4946   PyObject *def = NULL;
4947 
4948   PYRNA_STRUCT_CHECK_OBJ(self);
4949 
4950   if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) {
4951     return NULL;
4952   }
4953 
4954   /* Mostly copied from BPy_IDGroup_Map_GetItem. */
4955   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
4956     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
4957     return NULL;
4958   }
4959 
4960   group = RNA_struct_idprops(&self->ptr, 0);
4961   if (group) {
4962     idprop = IDP_GetPropertyFromGroup(group, key);
4963 
4964     if (idprop) {
4965       PyObject *ret = BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
4966       IDP_RemoveFromGroup(group, idprop);
4967       return ret;
4968     }
4969   }
4970 
4971   if (def == NULL) {
4972     PyErr_SetString(PyExc_KeyError, "key not found");
4973     return NULL;
4974   }
4975   return Py_INCREF_RET(def);
4976 }
4977 
4978 PyDoc_STRVAR(pyrna_struct_as_pointer_doc,
4979              ".. method:: as_pointer()\n"
4980              "\n"
4981              "   Returns the memory address which holds a pointer to Blender's internal data\n"
4982              "\n"
4983              "   :return: int (memory address).\n"
4984              "   :rtype: int\n"
4985              "\n"
4986              "   .. note:: This is intended only for advanced script writers who need to\n"
4987              "      pass blender data to their own C/Python modules.\n");
pyrna_struct_as_pointer(BPy_StructRNA * self)4988 static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
4989 {
4990   return PyLong_FromVoidPtr(self->ptr.data);
4991 }
4992 
4993 PyDoc_STRVAR(pyrna_prop_collection_get_doc,
4994              ".. method:: get(key, default=None)\n"
4995              "\n"
4996              "   Returns the value of the item assigned to key or default when not found\n"
4997              "   (matches Python's dictionary function of the same name).\n"
4998              "\n"
4999              "   :arg key: The identifier for the collection member.\n"
5000              "   :type key: string\n"
5001              "   :arg default: Optional argument for the value to return if\n"
5002              "      *key* is not found.\n"
5003              "   :type default: Undefined\n");
pyrna_prop_collection_get(BPy_PropertyRNA * self,PyObject * args)5004 static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args)
5005 {
5006   PointerRNA newptr;
5007 
5008   PyObject *key_ob;
5009   PyObject *def = Py_None;
5010 
5011   PYRNA_PROP_CHECK_OBJ(self);
5012 
5013   if (!PyArg_ParseTuple(args, "O|O:get", &key_ob, &def)) {
5014     return NULL;
5015   }
5016 
5017   if (PyUnicode_Check(key_ob)) {
5018     const char *key = _PyUnicode_AsString(key_ob);
5019 
5020     if (RNA_property_collection_lookup_string(&self->ptr, self->prop, key, &newptr)) {
5021       return pyrna_struct_CreatePyObject(&newptr);
5022     }
5023   }
5024   else if (PyTuple_Check(key_ob)) {
5025     PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(
5026         self, key_ob, "bpy_prop_collection.get((id, lib))", false);
5027     if (ret) {
5028       return ret;
5029     }
5030   }
5031   else {
5032     PyErr_Format(PyExc_KeyError,
5033                  "bpy_prop_collection.get(key, ...): key must be a string or tuple, not %.200s",
5034                  Py_TYPE(key_ob)->tp_name);
5035   }
5036 
5037   return Py_INCREF_RET(def);
5038 }
5039 
5040 PyDoc_STRVAR(pyrna_prop_collection_find_doc,
5041              ".. method:: find(key)\n"
5042              "\n"
5043              "   Returns the index of a key in a collection or -1 when not found\n"
5044              "   (matches Python's string find function of the same name).\n"
5045              "\n"
5046              "   :arg key: The identifier for the collection member.\n"
5047              "   :type key: string\n"
5048              "   :return: index of the key.\n"
5049              "   :rtype: int\n");
pyrna_prop_collection_find(BPy_PropertyRNA * self,PyObject * key_ob)5050 static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob)
5051 {
5052   Py_ssize_t key_len_ssize_t;
5053   const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t);
5054   const int key_len = (int)key_len_ssize_t; /* Comare with same type. */
5055 
5056   char name[256], *nameptr;
5057   int namelen;
5058   int i = 0;
5059   int index = -1;
5060 
5061   PYRNA_PROP_CHECK_OBJ(self);
5062 
5063   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
5064     nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
5065 
5066     if (nameptr) {
5067       if ((key_len == namelen) && memcmp(nameptr, key, key_len) == 0) {
5068         index = i;
5069         break;
5070       }
5071 
5072       if (name != nameptr) {
5073         MEM_freeN(nameptr);
5074       }
5075     }
5076 
5077     i++;
5078   }
5079   RNA_PROP_END;
5080 
5081   return PyLong_FromLong(index);
5082 }
5083 
foreach_attr_type(BPy_PropertyRNA * self,const char * attr,RawPropertyType * r_raw_type,int * r_attr_tot,bool * r_attr_signed)5084 static bool foreach_attr_type(BPy_PropertyRNA *self,
5085                               const char *attr,
5086                               /* Values to assign. */
5087                               RawPropertyType *r_raw_type,
5088                               int *r_attr_tot,
5089                               bool *r_attr_signed)
5090 {
5091   PropertyRNA *prop;
5092   bool attr_ok = true;
5093   *r_raw_type = PROP_RAW_UNSET;
5094   *r_attr_tot = 0;
5095   *r_attr_signed = false;
5096 
5097   /* Note: this is fail with zero length lists, so don't let this get caled in that case. */
5098   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
5099     prop = RNA_struct_find_property(&itemptr, attr);
5100     if (prop) {
5101       *r_raw_type = RNA_property_raw_type(prop);
5102       *r_attr_tot = RNA_property_array_length(&itemptr, prop);
5103       *r_attr_signed = (RNA_property_subtype(prop) != PROP_UNSIGNED);
5104     }
5105     else {
5106       attr_ok = false;
5107     }
5108     break;
5109   }
5110   RNA_PROP_END;
5111 
5112   return attr_ok;
5113 }
5114 
5115 /* pyrna_prop_collection_foreach_get/set both use this. */
foreach_parse_args(BPy_PropertyRNA * self,PyObject * args,const char ** r_attr,PyObject ** r_seq,int * r_tot,int * r_size,RawPropertyType * r_raw_type,int * r_attr_tot,bool * r_attr_signed)5116 static int foreach_parse_args(BPy_PropertyRNA *self,
5117                               PyObject *args,
5118 
5119                               /* Values to assign. */
5120                               const char **r_attr,
5121                               PyObject **r_seq,
5122                               int *r_tot,
5123                               int *r_size,
5124                               RawPropertyType *r_raw_type,
5125                               int *r_attr_tot,
5126                               bool *r_attr_signed)
5127 {
5128 #if 0
5129   int array_tot;
5130   int target_tot;
5131 #endif
5132 
5133   *r_size = *r_attr_tot = 0;
5134   *r_attr_signed = false;
5135   *r_raw_type = PROP_RAW_UNSET;
5136 
5137   if (!PyArg_ParseTuple(args, "sO:foreach_get/set", r_attr, r_seq)) {
5138     return -1;
5139   }
5140 
5141   if (!PySequence_Check(*r_seq) && PyObject_CheckBuffer(*r_seq)) {
5142     PyErr_Format(
5143         PyExc_TypeError,
5144         "foreach_get/set expected second argument to be a sequence or buffer, not a %.200s",
5145         Py_TYPE(*r_seq)->tp_name);
5146     return -1;
5147   }
5148 
5149   /* TODO - buffer may not be a sequence! array.array() is though. */
5150   *r_tot = PySequence_Size(*r_seq);
5151 
5152   if (*r_tot > 0) {
5153     if (!foreach_attr_type(self, *r_attr, r_raw_type, r_attr_tot, r_attr_signed)) {
5154       PyErr_Format(PyExc_AttributeError,
5155                    "foreach_get/set '%.200s.%200s[...]' elements have no attribute '%.200s'",
5156                    RNA_struct_identifier(self->ptr.type),
5157                    RNA_property_identifier(self->prop),
5158                    *r_attr);
5159       return -1;
5160     }
5161     *r_size = RNA_raw_type_sizeof(*r_raw_type);
5162 
5163 #if 0 /* Works fine, but not strictly needed. \
5164        * we could allow RNA_property_collection_raw_* to do the checks */
5165     if ((*r_attr_tot) < 1) {
5166       *r_attr_tot = 1;
5167     }
5168 
5169     if (RNA_property_type(self->prop) == PROP_COLLECTION) {
5170       array_tot = RNA_property_collection_length(&self->ptr, self->prop);
5171     }
5172     else {
5173       array_tot = RNA_property_array_length(&self->ptr, self->prop);
5174     }
5175 
5176     target_tot = array_tot * (*r_attr_tot);
5177 
5178     /* rna_access.c - rna_raw_access(...) uses this same method. */
5179     if (target_tot != (*r_tot)) {
5180       PyErr_Format(PyExc_TypeError,
5181                    "foreach_get(attr, sequence) sequence length mismatch given %d, needed %d",
5182                    *r_tot,
5183                    target_tot);
5184       return -1;
5185     }
5186 #endif
5187   }
5188 
5189   /* Check 'r_attr_tot' otherwise we don't know if any values were set.
5190    * This isn't ideal because it means running on an empty list may
5191    * fail silently when it's not compatible. */
5192   if (*r_size == 0 && *r_attr_tot != 0) {
5193     PyErr_SetString(PyExc_AttributeError, "attribute does not support foreach method");
5194     return -1;
5195   }
5196   return 0;
5197 }
5198 
foreach_compat_buffer(RawPropertyType raw_type,int attr_signed,const char * format)5199 static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
5200 {
5201   const char f = format ? *format : 'B'; /* B is assumed when not set */
5202 
5203   switch (raw_type) {
5204     case PROP_RAW_CHAR:
5205       if (attr_signed) {
5206         return (f == 'b') ? 1 : 0;
5207       }
5208       else {
5209         return (f == 'B') ? 1 : 0;
5210       }
5211     case PROP_RAW_SHORT:
5212       if (attr_signed) {
5213         return (f == 'h') ? 1 : 0;
5214       }
5215       else {
5216         return (f == 'H') ? 1 : 0;
5217       }
5218     case PROP_RAW_INT:
5219       if (attr_signed) {
5220         return (f == 'i') ? 1 : 0;
5221       }
5222       else {
5223         return (f == 'I') ? 1 : 0;
5224       }
5225     case PROP_RAW_BOOLEAN:
5226       return (f == '?') ? 1 : 0;
5227     case PROP_RAW_FLOAT:
5228       return (f == 'f') ? 1 : 0;
5229     case PROP_RAW_DOUBLE:
5230       return (f == 'd') ? 1 : 0;
5231     case PROP_RAW_UNSET:
5232       return 0;
5233   }
5234 
5235   return 0;
5236 }
5237 
foreach_getset(BPy_PropertyRNA * self,PyObject * args,int set)5238 static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
5239 {
5240   PyObject *item = NULL;
5241   int i = 0, ok = 0;
5242   bool buffer_is_compat;
5243   void *array = NULL;
5244 
5245   /* Get/set both take the same args currently. */
5246   const char *attr;
5247   PyObject *seq;
5248   int tot, size, attr_tot;
5249   bool attr_signed;
5250   RawPropertyType raw_type;
5251 
5252   if (foreach_parse_args(
5253           self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1) {
5254     return NULL;
5255   }
5256 
5257   if (tot == 0) {
5258     Py_RETURN_NONE;
5259   }
5260 
5261   if (set) { /* Get the array from python. */
5262     buffer_is_compat = false;
5263     if (PyObject_CheckBuffer(seq)) {
5264       Py_buffer buf;
5265       PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
5266 
5267       /* Check if the buffer matches. */
5268 
5269       buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format);
5270 
5271       if (buffer_is_compat) {
5272         ok = RNA_property_collection_raw_set(
5273             NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
5274       }
5275 
5276       PyBuffer_Release(&buf);
5277     }
5278 
5279     /* Could not use the buffer, fallback to sequence. */
5280     if (!buffer_is_compat) {
5281       array = PyMem_Malloc(size * tot);
5282 
5283       for (; i < tot; i++) {
5284         item = PySequence_GetItem(seq, i);
5285         switch (raw_type) {
5286           case PROP_RAW_CHAR:
5287             ((char *)array)[i] = (char)PyLong_AsLong(item);
5288             break;
5289           case PROP_RAW_SHORT:
5290             ((short *)array)[i] = (short)PyLong_AsLong(item);
5291             break;
5292           case PROP_RAW_INT:
5293             ((int *)array)[i] = (int)PyLong_AsLong(item);
5294             break;
5295           case PROP_RAW_BOOLEAN:
5296             ((bool *)array)[i] = (int)PyLong_AsLong(item) != 0;
5297             break;
5298           case PROP_RAW_FLOAT:
5299             ((float *)array)[i] = (float)PyFloat_AsDouble(item);
5300             break;
5301           case PROP_RAW_DOUBLE:
5302             ((double *)array)[i] = (double)PyFloat_AsDouble(item);
5303             break;
5304           case PROP_RAW_UNSET:
5305             /* Should never happen. */
5306             BLI_assert(!"Invalid array type - set");
5307             break;
5308         }
5309 
5310         Py_DECREF(item);
5311       }
5312 
5313       ok = RNA_property_collection_raw_set(
5314           NULL, &self->ptr, self->prop, attr, array, raw_type, tot);
5315     }
5316   }
5317   else {
5318     buffer_is_compat = false;
5319     if (PyObject_CheckBuffer(seq)) {
5320       Py_buffer buf;
5321       PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
5322 
5323       /* Check if the buffer matches, TODO - signed/unsigned types. */
5324 
5325       buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format);
5326 
5327       if (buffer_is_compat) {
5328         ok = RNA_property_collection_raw_get(
5329             NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
5330       }
5331 
5332       PyBuffer_Release(&buf);
5333     }
5334 
5335     /* Could not use the buffer, fallback to sequence. */
5336     if (!buffer_is_compat) {
5337       array = PyMem_Malloc(size * tot);
5338 
5339       ok = RNA_property_collection_raw_get(
5340           NULL, &self->ptr, self->prop, attr, array, raw_type, tot);
5341 
5342       if (!ok) {
5343         /* Skip the loop. */
5344         i = tot;
5345       }
5346 
5347       for (; i < tot; i++) {
5348 
5349         switch (raw_type) {
5350           case PROP_RAW_CHAR:
5351             item = PyLong_FromLong((long)((char *)array)[i]);
5352             break;
5353           case PROP_RAW_SHORT:
5354             item = PyLong_FromLong((long)((short *)array)[i]);
5355             break;
5356           case PROP_RAW_INT:
5357             item = PyLong_FromLong((long)((int *)array)[i]);
5358             break;
5359           case PROP_RAW_FLOAT:
5360             item = PyFloat_FromDouble((double)((float *)array)[i]);
5361             break;
5362           case PROP_RAW_DOUBLE:
5363             item = PyFloat_FromDouble((double)((double *)array)[i]);
5364             break;
5365           case PROP_RAW_BOOLEAN:
5366             item = PyBool_FromLong((long)((bool *)array)[i]);
5367             break;
5368           default: /* PROP_RAW_UNSET */
5369             /* Should never happen. */
5370             BLI_assert(!"Invalid array type - get");
5371             item = Py_None;
5372             Py_INCREF(item);
5373             break;
5374         }
5375 
5376         PySequence_SetItem(seq, i, item);
5377         Py_DECREF(item);
5378       }
5379     }
5380   }
5381 
5382   if (array) {
5383     PyMem_Free(array);
5384   }
5385 
5386   if (PyErr_Occurred()) {
5387     /* Maybe we could make our own error. */
5388     PyErr_Print();
5389     PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence");
5390     return NULL;
5391   }
5392   if (!ok) {
5393     PyErr_SetString(PyExc_RuntimeError, "internal error setting the array");
5394     return NULL;
5395   }
5396 
5397   Py_RETURN_NONE;
5398 }
5399 
5400 PyDoc_STRVAR(pyrna_prop_collection_foreach_get_doc,
5401              ".. method:: foreach_get(attr, seq)\n"
5402              "\n"
5403              "   This is a function to give fast access to attributes within a collection.\n");
pyrna_prop_collection_foreach_get(BPy_PropertyRNA * self,PyObject * args)5404 static PyObject *pyrna_prop_collection_foreach_get(BPy_PropertyRNA *self, PyObject *args)
5405 {
5406   PYRNA_PROP_CHECK_OBJ(self);
5407 
5408   return foreach_getset(self, args, 0);
5409 }
5410 
5411 PyDoc_STRVAR(pyrna_prop_collection_foreach_set_doc,
5412              ".. method:: foreach_set(attr, seq)\n"
5413              "\n"
5414              "   This is a function to give fast access to attributes within a collection.\n");
pyrna_prop_collection_foreach_set(BPy_PropertyRNA * self,PyObject * args)5415 static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args)
5416 {
5417   PYRNA_PROP_CHECK_OBJ(self);
5418 
5419   return foreach_getset(self, args, 1);
5420 }
5421 
pyprop_array_foreach_getset(BPy_PropertyArrayRNA * self,PyObject * args,const bool do_set)5422 static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
5423                                              PyObject *args,
5424                                              const bool do_set)
5425 {
5426   PyObject *item = NULL;
5427   Py_ssize_t i, seq_size, size;
5428   void *array = NULL;
5429   const PropertyType prop_type = RNA_property_type(self->prop);
5430 
5431   /* Get/set both take the same args currently. */
5432   PyObject *seq;
5433 
5434   if (prop_type != PROP_INT && prop_type != PROP_FLOAT) {
5435     PyErr_Format(PyExc_TypeError, "foreach_get/set available only for int and float");
5436     return NULL;
5437   }
5438 
5439   if (!PyArg_ParseTuple(args, "O:foreach_get/set", &seq)) {
5440     return NULL;
5441   }
5442 
5443   if (!PySequence_Check(seq) && PyObject_CheckBuffer(seq)) {
5444     PyErr_Format(
5445         PyExc_TypeError,
5446         "foreach_get/set expected second argument to be a sequence or buffer, not a %.200s",
5447         Py_TYPE(seq)->tp_name);
5448     return NULL;
5449   }
5450 
5451   size = pyrna_prop_array_length(self);
5452   seq_size = PySequence_Size(seq);
5453 
5454   if (size != seq_size) {
5455     PyErr_Format(PyExc_TypeError, "expected sequence size %d, got %d", size, seq_size);
5456     return NULL;
5457   }
5458 
5459   Py_buffer buf;
5460   if (PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT) == -1) {
5461     PyErr_Clear();
5462 
5463     switch (prop_type) {
5464       case PROP_INT:
5465         array = PyMem_Malloc(sizeof(int) * size);
5466         if (do_set) {
5467           for (i = 0; i < size; i++) {
5468             item = PySequence_GetItem(seq, i);
5469             ((int *)array)[i] = (int)PyLong_AsLong(item);
5470             Py_DECREF(item);
5471           }
5472 
5473           RNA_property_int_set_array(&self->ptr, self->prop, array);
5474         }
5475         else {
5476           RNA_property_int_get_array(&self->ptr, self->prop, array);
5477 
5478           for (i = 0; i < size; i++) {
5479             item = PyLong_FromLong((long)((int *)array)[i]);
5480             PySequence_SetItem(seq, i, item);
5481             Py_DECREF(item);
5482           }
5483         }
5484 
5485         break;
5486       case PROP_FLOAT:
5487         array = PyMem_Malloc(sizeof(float) * size);
5488         if (do_set) {
5489           for (i = 0; i < size; i++) {
5490             item = PySequence_GetItem(seq, i);
5491             ((float *)array)[i] = (float)PyFloat_AsDouble(item);
5492             Py_DECREF(item);
5493           }
5494 
5495           RNA_property_float_set_array(&self->ptr, self->prop, array);
5496         }
5497         else {
5498           RNA_property_float_get_array(&self->ptr, self->prop, array);
5499 
5500           for (i = 0; i < size; i++) {
5501             item = PyFloat_FromDouble((double)((float *)array)[i]);
5502             PySequence_SetItem(seq, i, item);
5503             Py_DECREF(item);
5504           }
5505         }
5506         break;
5507       case PROP_BOOLEAN:
5508       case PROP_STRING:
5509       case PROP_ENUM:
5510       case PROP_POINTER:
5511       case PROP_COLLECTION:
5512         /* Should never happen. */
5513         BLI_assert(false);
5514         break;
5515     }
5516 
5517     PyMem_Free(array);
5518 
5519     if (PyErr_Occurred()) {
5520       /* Maybe we could make our own error. */
5521       PyErr_Print();
5522       PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence");
5523       return NULL;
5524     }
5525   }
5526   else {
5527     const char f = buf.format ? buf.format[0] : 0;
5528     if ((prop_type == PROP_INT && (buf.itemsize != sizeof(int) || (f != 'l' && f != 'i'))) ||
5529         (prop_type == PROP_FLOAT && (buf.itemsize != sizeof(float) || f != 'f'))) {
5530       PyBuffer_Release(&buf);
5531       PyErr_Format(PyExc_TypeError, "incorrect sequence item type: %s", buf.format);
5532       return NULL;
5533     }
5534 
5535     switch (prop_type) {
5536       case PROP_INT:
5537         if (do_set) {
5538           RNA_property_int_set_array(&self->ptr, self->prop, buf.buf);
5539         }
5540         else {
5541           RNA_property_int_get_array(&self->ptr, self->prop, buf.buf);
5542         }
5543         break;
5544       case PROP_FLOAT:
5545         if (do_set) {
5546           RNA_property_float_set_array(&self->ptr, self->prop, buf.buf);
5547         }
5548         else {
5549           RNA_property_float_get_array(&self->ptr, self->prop, buf.buf);
5550         }
5551         break;
5552       case PROP_BOOLEAN:
5553       case PROP_STRING:
5554       case PROP_ENUM:
5555       case PROP_POINTER:
5556       case PROP_COLLECTION:
5557         /* Should never happen. */
5558         BLI_assert(false);
5559         break;
5560     }
5561 
5562     PyBuffer_Release(&buf);
5563   }
5564 
5565   Py_RETURN_NONE;
5566 }
5567 
5568 PyDoc_STRVAR(pyrna_prop_array_foreach_get_doc,
5569              ".. method:: foreach_get(seq)\n"
5570              "\n"
5571              "   This is a function to give fast access to array data.\n");
pyrna_prop_array_foreach_get(BPy_PropertyArrayRNA * self,PyObject * args)5572 static PyObject *pyrna_prop_array_foreach_get(BPy_PropertyArrayRNA *self, PyObject *args)
5573 {
5574   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
5575 
5576   return pyprop_array_foreach_getset(self, args, false);
5577 }
5578 
5579 PyDoc_STRVAR(pyrna_prop_array_foreach_set_doc,
5580              ".. method:: foreach_set(seq)\n"
5581              "\n"
5582              "   This is a function to give fast access to array data.\n");
pyrna_prop_array_foreach_set(BPy_PropertyArrayRNA * self,PyObject * args)5583 static PyObject *pyrna_prop_array_foreach_set(BPy_PropertyArrayRNA *self, PyObject *args)
5584 {
5585   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
5586 
5587   return pyprop_array_foreach_getset(self, args, true);
5588 }
5589 
5590 /* A bit of a kludge, make a list out of a collection or array,
5591  * then return the list's iter function, not especially fast, but convenient for now. */
pyrna_prop_array_iter(BPy_PropertyArrayRNA * self)5592 static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self)
5593 {
5594   /* Try get values from a collection. */
5595   PyObject *ret;
5596   PyObject *iter = NULL;
5597   int len;
5598 
5599   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
5600 
5601   len = pyrna_prop_array_length(self);
5602   ret = pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
5603 
5604   /* we know this is a list so no need to PyIter_Check
5605    * otherwise it could be NULL (unlikely) if conversion failed */
5606   if (ret) {
5607     iter = PyObject_GetIter(ret);
5608     Py_DECREF(ret);
5609   }
5610 
5611   return iter;
5612 }
5613 
5614 static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self);
5615 
5616 #ifndef USE_PYRNA_ITER
pyrna_prop_collection_iter(BPy_PropertyRNA * self)5617 static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
5618 {
5619   /* Try get values from a collection. */
5620   PyObject *ret;
5621   PyObject *iter = NULL;
5622   ret = pyrna_prop_collection_values(self);
5623 
5624   /* we know this is a list so no need to PyIter_Check
5625    * otherwise it could be NULL (unlikely) if conversion failed */
5626   if (ret) {
5627     iter = PyObject_GetIter(ret);
5628     Py_DECREF(ret);
5629   }
5630 
5631   return iter;
5632 }
5633 #endif /* # !USE_PYRNA_ITER */
5634 
5635 static struct PyMethodDef pyrna_struct_methods[] = {
5636 
5637     /* Only for PointerRNA's with ID'props. */
5638     {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc},
5639     {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, pyrna_struct_values_doc},
5640     {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, pyrna_struct_items_doc},
5641 
5642     {"get", (PyCFunction)pyrna_struct_get, METH_VARARGS, pyrna_struct_get_doc},
5643     {"pop", (PyCFunction)pyrna_struct_pop, METH_VARARGS, pyrna_struct_pop_doc},
5644 
5645     {"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, pyrna_struct_as_pointer_doc},
5646 
5647     /* bpy_rna_anim.c */
5648     {"keyframe_insert",
5649      (PyCFunction)pyrna_struct_keyframe_insert,
5650      METH_VARARGS | METH_KEYWORDS,
5651      pyrna_struct_keyframe_insert_doc},
5652     {"keyframe_delete",
5653      (PyCFunction)pyrna_struct_keyframe_delete,
5654      METH_VARARGS | METH_KEYWORDS,
5655      pyrna_struct_keyframe_delete_doc},
5656     {"driver_add",
5657      (PyCFunction)pyrna_struct_driver_add,
5658      METH_VARARGS,
5659      pyrna_struct_driver_add_doc},
5660     {"driver_remove",
5661      (PyCFunction)pyrna_struct_driver_remove,
5662      METH_VARARGS,
5663      pyrna_struct_driver_remove_doc},
5664 
5665     {"is_property_set",
5666      (PyCFunction)pyrna_struct_is_property_set,
5667      METH_VARARGS | METH_KEYWORDS,
5668      pyrna_struct_is_property_set_doc},
5669     {"property_unset",
5670      (PyCFunction)pyrna_struct_property_unset,
5671      METH_VARARGS,
5672      pyrna_struct_property_unset_doc},
5673     {"is_property_hidden",
5674      (PyCFunction)pyrna_struct_is_property_hidden,
5675      METH_VARARGS,
5676      pyrna_struct_is_property_hidden_doc},
5677     {"is_property_readonly",
5678      (PyCFunction)pyrna_struct_is_property_readonly,
5679      METH_VARARGS,
5680      pyrna_struct_is_property_readonly_doc},
5681     {"is_property_overridable_library",
5682      (PyCFunction)pyrna_struct_is_property_overridable_library,
5683      METH_VARARGS,
5684      pyrna_struct_is_property_overridable_library_doc},
5685     {"property_overridable_library_set",
5686      (PyCFunction)pyrna_struct_property_overridable_library_set,
5687      METH_VARARGS,
5688      pyrna_struct_property_overridable_library_set_doc},
5689     {"path_resolve",
5690      (PyCFunction)pyrna_struct_path_resolve,
5691      METH_VARARGS,
5692      pyrna_struct_path_resolve_doc},
5693     {"path_from_id",
5694      (PyCFunction)pyrna_struct_path_from_id,
5695      METH_VARARGS,
5696      pyrna_struct_path_from_id_doc},
5697     {"type_recast",
5698      (PyCFunction)pyrna_struct_type_recast,
5699      METH_NOARGS,
5700      pyrna_struct_type_recast_doc},
5701     {"bl_rna_get_subclass_py",
5702      (PyCFunction)pyrna_struct_bl_rna_get_subclass_py,
5703      METH_VARARGS | METH_CLASS,
5704      pyrna_struct_bl_rna_get_subclass_py_doc},
5705     {"bl_rna_get_subclass",
5706      (PyCFunction)pyrna_struct_bl_rna_get_subclass,
5707      METH_VARARGS | METH_CLASS,
5708      pyrna_struct_bl_rna_get_subclass_doc},
5709     {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
5710 
5711 /* experimental */
5712 /* unused for now */
5713 #if 0
5714     {"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
5715     {"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
5716 
5717     {"callback_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_CLASS, NULL},
5718     {"callback_remove",
5719      (PyCFunction)pyrna_callback_classmethod_remove,
5720      METH_VARARGS | METH_CLASS,
5721      NULL},
5722 #endif
5723     {NULL, NULL, 0, NULL},
5724 };
5725 
5726 static struct PyMethodDef pyrna_prop_methods[] = {
5727     {"path_from_id",
5728      (PyCFunction)pyrna_prop_path_from_id,
5729      METH_NOARGS,
5730      pyrna_prop_path_from_id_doc},
5731     {"as_bytes", (PyCFunction)pyrna_prop_as_bytes, METH_NOARGS, pyrna_prop_as_bytes_doc},
5732     {"update", (PyCFunction)pyrna_prop_update, METH_NOARGS, pyrna_prop_update_doc},
5733     {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL},
5734     {NULL, NULL, 0, NULL},
5735 };
5736 
5737 static struct PyMethodDef pyrna_prop_array_methods[] = {
5738     {"foreach_get",
5739      (PyCFunction)pyrna_prop_array_foreach_get,
5740      METH_VARARGS,
5741      pyrna_prop_array_foreach_get_doc},
5742     {"foreach_set",
5743      (PyCFunction)pyrna_prop_array_foreach_set,
5744      METH_VARARGS,
5745      pyrna_prop_array_foreach_set_doc},
5746 
5747     {NULL, NULL, 0, NULL},
5748 };
5749 
5750 static struct PyMethodDef pyrna_prop_collection_methods[] = {
5751     {"foreach_get",
5752      (PyCFunction)pyrna_prop_collection_foreach_get,
5753      METH_VARARGS,
5754      pyrna_prop_collection_foreach_get_doc},
5755     {"foreach_set",
5756      (PyCFunction)pyrna_prop_collection_foreach_set,
5757      METH_VARARGS,
5758      pyrna_prop_collection_foreach_set_doc},
5759 
5760     {"keys", (PyCFunction)pyrna_prop_collection_keys, METH_NOARGS, pyrna_prop_collection_keys_doc},
5761     {"items",
5762      (PyCFunction)pyrna_prop_collection_items,
5763      METH_NOARGS,
5764      pyrna_prop_collection_items_doc},
5765     {"values",
5766      (PyCFunction)pyrna_prop_collection_values,
5767      METH_NOARGS,
5768      pyrna_prop_collection_values_doc},
5769 
5770     {"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc},
5771     {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc},
5772     {NULL, NULL, 0, NULL},
5773 };
5774 
5775 static struct PyMethodDef pyrna_prop_collection_idprop_methods[] = {
5776     {"add", (PyCFunction)pyrna_prop_collection_idprop_add, METH_NOARGS, NULL},
5777     {"remove", (PyCFunction)pyrna_prop_collection_idprop_remove, METH_O, NULL},
5778     {"clear", (PyCFunction)pyrna_prop_collection_idprop_clear, METH_NOARGS, NULL},
5779     {"move", (PyCFunction)pyrna_prop_collection_idprop_move, METH_VARARGS, NULL},
5780     {NULL, NULL, 0, NULL},
5781 };
5782 
5783 /* only needed for subtyping, so a new class gets a valid BPy_StructRNA
5784  * todo - also accept useful args */
pyrna_struct_new(PyTypeObject * type,PyObject * args,PyObject * UNUSED (kwds))5785 static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
5786 {
5787   if (PyTuple_GET_SIZE(args) == 1) {
5788     BPy_StructRNA *base = (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0);
5789     if (Py_TYPE(base) == type) {
5790       Py_INCREF(base);
5791       return (PyObject *)base;
5792     }
5793     if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) {
5794       /* this almost never runs, only when using user defined subclasses of built-in object.
5795        * this isn't common since it's NOT related to registerable subclasses. eg:
5796        *
5797        *  >>> class MyObSubclass(bpy.types.Object):
5798        *  ...     def test_func(self):
5799        *  ...         print(100)
5800        *  ...
5801        *  >>> myob = MyObSubclass(bpy.context.object)
5802        *  >>> myob.test_func()
5803        *  100
5804        *
5805        * Keep this since it could be useful.
5806        */
5807       BPy_StructRNA *ret;
5808       if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) {
5809         ret->ptr = base->ptr;
5810       }
5811       /* Pass on exception & NULL if tp_alloc fails. */
5812       return (PyObject *)ret;
5813     }
5814 
5815     /* Error, invalid type given. */
5816     PyErr_Format(PyExc_TypeError,
5817                  "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct",
5818                  type->tp_name);
5819     return NULL;
5820   }
5821 
5822   PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument");
5823   return NULL;
5824 }
5825 
5826 /* only needed for subtyping, so a new class gets a valid BPy_StructRNA
5827  * todo - also accept useful args */
pyrna_prop_new(PyTypeObject * type,PyObject * args,PyObject * UNUSED (kwds))5828 static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
5829 {
5830   BPy_PropertyRNA *base;
5831 
5832   if (!PyArg_ParseTuple(args, "O!:bpy_prop.__new__", &pyrna_prop_Type, &base)) {
5833     return NULL;
5834   }
5835 
5836   if (type == Py_TYPE(base)) {
5837     return Py_INCREF_RET((PyObject *)base);
5838   }
5839   if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
5840     BPy_PropertyRNA *ret = (BPy_PropertyRNA *)type->tp_alloc(type, 0);
5841     ret->ptr = base->ptr;
5842     ret->prop = base->prop;
5843     return (PyObject *)ret;
5844   }
5845 
5846   PyErr_Format(PyExc_TypeError,
5847                "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop",
5848                type->tp_name);
5849   return NULL;
5850 }
5851 
pyrna_param_to_py(PointerRNA * ptr,PropertyRNA * prop,void * data)5852 static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
5853 {
5854   PyObject *ret;
5855   const int type = RNA_property_type(prop);
5856   const int flag = RNA_property_flag(prop);
5857   const int flag_parameter = RNA_parameter_flag(prop);
5858 
5859   if (RNA_property_array_check(prop)) {
5860     int a, len;
5861 
5862     if (flag & PROP_DYNAMIC) {
5863       ParameterDynAlloc *data_alloc = data;
5864       len = data_alloc->array_tot;
5865       data = data_alloc->array;
5866     }
5867     else {
5868       len = RNA_property_array_length(ptr, prop);
5869     }
5870 
5871     /* Resolve the array from a new pytype. */
5872 
5873     /* TODO(Kazanbas): make multi-dimensional sequences here. */
5874 
5875     switch (type) {
5876       case PROP_BOOLEAN:
5877         ret = PyTuple_New(len);
5878         for (a = 0; a < len; a++) {
5879           PyTuple_SET_ITEM(ret, a, PyBool_FromLong(((bool *)data)[a]));
5880         }
5881         break;
5882       case PROP_INT:
5883         ret = PyTuple_New(len);
5884         for (a = 0; a < len; a++) {
5885           PyTuple_SET_ITEM(ret, a, PyLong_FromLong(((int *)data)[a]));
5886         }
5887         break;
5888       case PROP_FLOAT:
5889         switch (RNA_property_subtype(prop)) {
5890 #ifdef USE_MATHUTILS
5891           case PROP_ALL_VECTOR_SUBTYPES:
5892             ret = Vector_CreatePyObject(data, len, NULL);
5893             break;
5894           case PROP_MATRIX:
5895             if (len == 16) {
5896               ret = Matrix_CreatePyObject(data, 4, 4, NULL);
5897               break;
5898             }
5899             else if (len == 9) {
5900               ret = Matrix_CreatePyObject(data, 3, 3, NULL);
5901               break;
5902             }
5903             ATTR_FALLTHROUGH;
5904 #endif
5905           default:
5906             ret = PyTuple_New(len);
5907             for (a = 0; a < len; a++) {
5908               PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble(((float *)data)[a]));
5909             }
5910             break;
5911         }
5912         break;
5913       default:
5914         PyErr_Format(
5915             PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
5916         ret = NULL;
5917         break;
5918     }
5919   }
5920   else {
5921     /* See if we can coerce into a python type - PropertyType. */
5922     switch (type) {
5923       case PROP_BOOLEAN:
5924         ret = PyBool_FromLong(*(bool *)data);
5925         break;
5926       case PROP_INT:
5927         ret = PyLong_FromLong(*(int *)data);
5928         break;
5929       case PROP_FLOAT:
5930         ret = PyFloat_FromDouble(*(float *)data);
5931         break;
5932       case PROP_STRING: {
5933         const char *data_ch;
5934         PyObject *value_coerce = NULL;
5935         const int subtype = RNA_property_subtype(prop);
5936 
5937         if (flag & PROP_THICK_WRAP) {
5938           data_ch = (char *)data;
5939         }
5940         else {
5941           data_ch = *(char **)data;
5942         }
5943 
5944 #ifdef USE_STRING_COERCE
5945         if (subtype == PROP_BYTESTRING) {
5946           ret = PyBytes_FromString(data_ch);
5947         }
5948         else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
5949           ret = PyC_UnicodeFromByte(data_ch);
5950         }
5951         else {
5952           ret = PyUnicode_FromString(data_ch);
5953         }
5954 #else
5955         if (subtype == PROP_BYTESTRING) {
5956           ret = PyBytes_FromString(buf);
5957         }
5958         else {
5959           ret = PyUnicode_FromString(data_ch);
5960         }
5961 #endif
5962 
5963 #ifdef USE_STRING_COERCE
5964         Py_XDECREF(value_coerce);
5965 #endif
5966 
5967         break;
5968       }
5969       case PROP_ENUM: {
5970         ret = pyrna_enum_to_py(ptr, prop, *(int *)data);
5971         break;
5972       }
5973       case PROP_POINTER: {
5974         PointerRNA newptr;
5975         StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
5976 
5977         if (flag_parameter & PARM_RNAPTR) {
5978           /* In this case we get the full ptr. */
5979           newptr = *(PointerRNA *)data;
5980         }
5981         else {
5982           if (RNA_struct_is_ID(ptype)) {
5983             RNA_id_pointer_create(*(void **)data, &newptr);
5984           }
5985           else {
5986             /* note: this is taken from the function's ID pointer
5987              * and will break if a function returns a pointer from
5988              * another ID block, watch this! - it should at least be
5989              * easy to debug since they are all ID's */
5990             RNA_pointer_create(ptr->owner_id, ptype, *(void **)data, &newptr);
5991           }
5992         }
5993 
5994         if (newptr.data) {
5995           ret = pyrna_struct_CreatePyObject(&newptr);
5996         }
5997         else {
5998           ret = Py_None;
5999           Py_INCREF(ret);
6000         }
6001         break;
6002       }
6003       case PROP_COLLECTION: {
6004         CollectionListBase *lb = (CollectionListBase *)data;
6005         CollectionPointerLink *link;
6006 
6007         ret = PyList_New(0);
6008 
6009         for (link = lb->first; link; link = link->next) {
6010           PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr));
6011         }
6012 
6013         break;
6014       }
6015       default:
6016         PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
6017         ret = NULL;
6018         break;
6019     }
6020   }
6021 
6022   return ret;
6023 }
6024 
6025 /**
6026  * Use to replace PyDict_GetItemString() when the overhead of converting a
6027  * string into a Python unicode is higher than a non hash lookup.
6028  * works on small dict's such as keyword args.
6029  */
small_dict_get_item_string(PyObject * dict,const char * key_lookup)6030 static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup)
6031 {
6032   PyObject *key = NULL;
6033   Py_ssize_t pos = 0;
6034   PyObject *value = NULL;
6035 
6036   while (PyDict_Next(dict, &pos, &key, &value)) {
6037     if (PyUnicode_Check(key)) {
6038       if (STREQ(key_lookup, _PyUnicode_AsString(key))) {
6039         return value;
6040       }
6041     }
6042   }
6043 
6044   return NULL;
6045 }
6046 
pyrna_func_call(BPy_FunctionRNA * self,PyObject * args,PyObject * kw)6047 static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw)
6048 {
6049   /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here. */
6050   PointerRNA *self_ptr = &self->ptr;
6051   FunctionRNA *self_func = self->func;
6052 
6053   PointerRNA funcptr;
6054   ParameterList parms;
6055   ParameterIterator iter;
6056   PropertyRNA *parm;
6057   PyObject *ret, *item;
6058   int i, pyargs_len, pykw_len, parms_len, ret_len, flag_parameter, err = 0, kw_tot = 0;
6059   bool kw_arg;
6060 
6061   PropertyRNA *pret_single = NULL;
6062   void *retdata_single = NULL;
6063 
6064   /* enable this so all strings are copied and freed after calling.
6065    * this exposes bugs where the pointer to the string is held and re-used */
6066   /* #define DEBUG_STRING_FREE */
6067 
6068 #ifdef DEBUG_STRING_FREE
6069   PyObject *string_free_ls = PyList_New(0);
6070 #endif
6071 
6072   /* Should never happen, but it does in rare cases. */
6073   BLI_assert(self_ptr != NULL);
6074 
6075   if (self_ptr == NULL) {
6076     PyErr_SetString(PyExc_RuntimeError,
6077                     "RNA functions internal RNA pointer is NULL, this is a bug. aborting");
6078     return NULL;
6079   }
6080 
6081   if (self_func == NULL) {
6082     PyErr_Format(
6083         PyExc_RuntimeError,
6084         "%.200s.<unknown>(): RNA function internal function is NULL, this is a bug. aborting",
6085         RNA_struct_identifier(self_ptr->type));
6086     return NULL;
6087   }
6088 
6089   /* For testing. */
6090 #if 0
6091   {
6092     const char *fn;
6093     int lineno;
6094     PyC_FileAndNum(&fn, &lineno);
6095     printf("pyrna_func_call > %.200s.%.200s : %.200s:%d\n",
6096            RNA_struct_identifier(self_ptr->type),
6097            RNA_function_identifier(self_func),
6098            fn,
6099            lineno);
6100   }
6101 #endif
6102 
6103   /* include the ID pointer for pyrna_param_to_py() so we can include the
6104    * ID pointer on return values, this only works when returned values have
6105    * the same ID as the functions. */
6106   RNA_pointer_create(self_ptr->owner_id, &RNA_Function, self_func, &funcptr);
6107 
6108   pyargs_len = PyTuple_GET_SIZE(args);
6109   pykw_len = kw ? PyDict_Size(kw) : 0;
6110 
6111   RNA_parameter_list_create(&parms, self_ptr, self_func);
6112   RNA_parameter_list_begin(&parms, &iter);
6113   parms_len = RNA_parameter_list_arg_count(&parms);
6114   ret_len = 0;
6115 
6116   if (pyargs_len + pykw_len > parms_len) {
6117     RNA_parameter_list_end(&iter);
6118     PyErr_Format(PyExc_TypeError,
6119                  "%.200s.%.200s(): takes at most %d arguments, got %d",
6120                  RNA_struct_identifier(self_ptr->type),
6121                  RNA_function_identifier(self_func),
6122                  parms_len,
6123                  pyargs_len + pykw_len);
6124     err = -1;
6125   }
6126 
6127   /* Parse function parameters. */
6128   for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) {
6129     parm = iter.parm;
6130     flag_parameter = RNA_parameter_flag(parm);
6131 
6132     /* Only useful for single argument returns, we'll need another list loop for multiple. */
6133     if (flag_parameter & PARM_OUTPUT) {
6134       ret_len++;
6135       if (pret_single == NULL) {
6136         pret_single = parm;
6137         retdata_single = iter.data;
6138       }
6139 
6140       continue;
6141     }
6142 
6143     item = NULL;
6144 
6145     if (i < pyargs_len) {
6146       /* New in 2.8x, optional arguments must be keywords. */
6147       if (UNLIKELY((flag_parameter & PARM_REQUIRED) == 0)) {
6148         PyErr_Format(PyExc_TypeError,
6149                      "%.200s.%.200s(): required parameter \"%.200s\" to be a keyword argument!",
6150                      RNA_struct_identifier(self_ptr->type),
6151                      RNA_function_identifier(self_func),
6152                      RNA_property_identifier(parm));
6153         err = -1;
6154         break;
6155       }
6156 
6157       item = PyTuple_GET_ITEM(args, i);
6158       kw_arg = false;
6159     }
6160     else if (kw != NULL) {
6161 #if 0
6162       item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* Borrow reference. */
6163 #else
6164       item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* Borrow reference. */
6165 #endif
6166       if (item) {
6167         kw_tot++; /* Make sure invalid keywords are not given. */
6168       }
6169 
6170       kw_arg = true;
6171     }
6172 
6173     i++; /* Current argument. */
6174 
6175     if (item == NULL) {
6176       if (flag_parameter & PARM_REQUIRED) {
6177         PyErr_Format(PyExc_TypeError,
6178                      "%.200s.%.200s(): required parameter \"%.200s\" not specified",
6179                      RNA_struct_identifier(self_ptr->type),
6180                      RNA_function_identifier(self_func),
6181                      RNA_property_identifier(parm));
6182         err = -1;
6183         break;
6184       }
6185       /* PyDict_GetItemString wont raise an error. */
6186       continue;
6187     }
6188 
6189 #ifdef DEBUG_STRING_FREE
6190     if (item) {
6191       if (PyUnicode_Check(item)) {
6192         PyList_APPEND(string_free_ls, PyUnicode_FromString(_PyUnicode_AsString(item)));
6193       }
6194     }
6195 #endif
6196     err = pyrna_py_to_prop(&funcptr, parm, iter.data, item, "");
6197 
6198     if (err != 0) {
6199       /* the error generated isn't that useful, so generate it again with a useful prefix
6200        * could also write a function to prepend to error messages */
6201       char error_prefix[512];
6202       PyErr_Clear(); /* Re-raise. */
6203 
6204       if (kw_arg == true) {
6205         BLI_snprintf(error_prefix,
6206                      sizeof(error_prefix),
6207                      "%.200s.%.200s(): error with keyword argument \"%.200s\" - ",
6208                      RNA_struct_identifier(self_ptr->type),
6209                      RNA_function_identifier(self_func),
6210                      RNA_property_identifier(parm));
6211       }
6212       else {
6213         BLI_snprintf(error_prefix,
6214                      sizeof(error_prefix),
6215                      "%.200s.%.200s(): error with argument %d, \"%.200s\" - ",
6216                      RNA_struct_identifier(self_ptr->type),
6217                      RNA_function_identifier(self_func),
6218                      i,
6219                      RNA_property_identifier(parm));
6220       }
6221 
6222       pyrna_py_to_prop(&funcptr, parm, iter.data, item, error_prefix);
6223 
6224       break;
6225     }
6226   }
6227 
6228   RNA_parameter_list_end(&iter);
6229 
6230   /* Check if we gave args that don't exist in the function
6231    * Printing the error is slow, but it should only happen when developing.
6232    * The "if" below is quick check to make sure less keyword args were passed than we gave.
6233    * (Don't overwrite the error if we have one,
6234    * otherwise can skip important messages and confuse with args).
6235    */
6236   if (err == 0 && kw && (pykw_len > kw_tot)) {
6237     PyObject *key, *value;
6238     Py_ssize_t pos = 0;
6239 
6240     DynStr *bad_args = BLI_dynstr_new();
6241     DynStr *good_args = BLI_dynstr_new();
6242 
6243     const char *arg_name, *bad_args_str, *good_args_str;
6244     bool found = false, first = true;
6245 
6246     while (PyDict_Next(kw, &pos, &key, &value)) {
6247 
6248       arg_name = _PyUnicode_AsString(key);
6249       found = false;
6250 
6251       if (arg_name == NULL) { /* Unlikely the argname is not a string, but ignore if it is. */
6252         PyErr_Clear();
6253       }
6254       else {
6255         /* Search for arg_name. */
6256         RNA_parameter_list_begin(&parms, &iter);
6257         for (; iter.valid; RNA_parameter_list_next(&iter)) {
6258           parm = iter.parm;
6259           if (STREQ(arg_name, RNA_property_identifier(parm))) {
6260             found = true;
6261             break;
6262           }
6263         }
6264 
6265         RNA_parameter_list_end(&iter);
6266 
6267         if (found == false) {
6268           BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
6269           first = false;
6270         }
6271       }
6272     }
6273 
6274     /* List good args. */
6275     first = true;
6276 
6277     RNA_parameter_list_begin(&parms, &iter);
6278     for (; iter.valid; RNA_parameter_list_next(&iter)) {
6279       parm = iter.parm;
6280       if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
6281         continue;
6282       }
6283 
6284       BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
6285       first = false;
6286     }
6287     RNA_parameter_list_end(&iter);
6288 
6289     bad_args_str = BLI_dynstr_get_cstring(bad_args);
6290     good_args_str = BLI_dynstr_get_cstring(good_args);
6291 
6292     PyErr_Format(
6293         PyExc_TypeError,
6294         "%.200s.%.200s(): was called with invalid keyword argument(s) (%s), expected (%s)",
6295         RNA_struct_identifier(self_ptr->type),
6296         RNA_function_identifier(self_func),
6297         bad_args_str,
6298         good_args_str);
6299 
6300     BLI_dynstr_free(bad_args);
6301     BLI_dynstr_free(good_args);
6302     MEM_freeN((void *)bad_args_str);
6303     MEM_freeN((void *)good_args_str);
6304 
6305     err = -1;
6306   }
6307 
6308   ret = NULL;
6309   if (err == 0) {
6310     /* Call function. */
6311     ReportList reports;
6312     bContext *C = BPY_context_get();
6313 
6314     BKE_reports_init(&reports, RPT_STORE);
6315     RNA_function_call(C, &reports, self_ptr, self_func, &parms);
6316 
6317     err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
6318 
6319     /* Return value. */
6320     if (err != -1) {
6321       if (ret_len > 0) {
6322         if (ret_len > 1) {
6323           ret = PyTuple_New(ret_len);
6324           i = 0; /* Arg index. */
6325 
6326           RNA_parameter_list_begin(&parms, &iter);
6327 
6328           for (; iter.valid; RNA_parameter_list_next(&iter)) {
6329             parm = iter.parm;
6330 
6331             if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
6332               PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data));
6333             }
6334           }
6335 
6336           RNA_parameter_list_end(&iter);
6337         }
6338         else {
6339           ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single);
6340         }
6341 
6342         /* Possible there is an error in conversion. */
6343         if (ret == NULL) {
6344           err = -1;
6345         }
6346       }
6347     }
6348   }
6349 
6350 #ifdef DEBUG_STRING_FREE
6351 #  if 0
6352   if (PyList_GET_SIZE(string_free_ls)) {
6353     printf("%.200s.%.200s():  has %d strings\n",
6354            RNA_struct_identifier(self_ptr->type),
6355            RNA_function_identifier(self_func),
6356            (int)PyList_GET_SIZE(string_free_ls));
6357   }
6358 #  endif
6359   Py_DECREF(string_free_ls);
6360 #  undef DEBUG_STRING_FREE
6361 #endif
6362 
6363   /* Cleanup. */
6364   RNA_parameter_list_end(&iter);
6365   RNA_parameter_list_free(&parms);
6366 
6367   if (ret) {
6368     return ret;
6369   }
6370 
6371   if (err == -1) {
6372     return NULL;
6373   }
6374 
6375   Py_RETURN_NONE;
6376 }
6377 
pyrna_func_doc_get(BPy_FunctionRNA * self,void * UNUSED (closure))6378 static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure))
6379 {
6380   PyObject *ret;
6381   char *args;
6382 
6383   args = RNA_function_as_string_keywords(NULL, self->func, true, true, INT_MAX);
6384 
6385   ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
6386                              RNA_struct_identifier(self->ptr.type),
6387                              RNA_function_identifier(self->func),
6388                              args,
6389                              RNA_function_ui_description(self->func));
6390 
6391   MEM_freeN(args);
6392 
6393   return ret;
6394 }
6395 
6396 /* Subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass. */
6397 /* note: tp_base member is set to &PyType_Type on init */
6398 PyTypeObject pyrna_struct_meta_idprop_Type = {
6399     PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct_meta_idprop", /* tp_name */
6400 
6401     /* NOTE! would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's */
6402     sizeof(PyHeapTypeObject), /* tp_basicsize */
6403 
6404     0, /* tp_itemsize */
6405     /* methods */
6406     NULL,            /* tp_dealloc */
6407     (printfunc)NULL, /* printfunc tp_print; */
6408     NULL,            /* getattrfunc tp_getattr; */
6409     NULL,            /* setattrfunc tp_setattr; */
6410     NULL,
6411     /* tp_compare */ /* deprecated in Python 3.0! */
6412     NULL,            /* tp_repr */
6413 
6414     /* Method suites for standard classes */
6415     NULL, /* PyNumberMethods *tp_as_number; */
6416     NULL, /* PySequenceMethods *tp_as_sequence; */
6417     NULL, /* PyMappingMethods *tp_as_mapping; */
6418 
6419     /* More standard operations (here for binary compatibility) */
6420     NULL,                                                      /* hashfunc tp_hash; */
6421     NULL,                                                      /* ternaryfunc tp_call; */
6422     NULL,                                                      /* reprfunc tp_str; */
6423     NULL /*(getattrofunc) pyrna_struct_meta_idprop_getattro*/, /* getattrofunc tp_getattro; */
6424     (setattrofunc)pyrna_struct_meta_idprop_setattro,           /* setattrofunc tp_setattro; */
6425 
6426     /* Functions to access object as input/output buffer */
6427     NULL, /* PyBufferProcs *tp_as_buffer; */
6428 
6429     /*** Flags to define presence of optional/expanded features ***/
6430     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
6431 
6432     NULL, /*  char *tp_doc;  Documentation string */
6433     /*** Assigned meaning in release 2.0 ***/
6434     /* call function for all accessible objects */
6435     NULL, /* traverseproc tp_traverse; */
6436 
6437     /* delete references to contained objects */
6438     NULL, /* inquiry tp_clear; */
6439 
6440     /***  Assigned meaning in release 2.1 ***/
6441     /*** rich comparisons ***/
6442     NULL, /* richcmpfunc tp_richcompare; */
6443 
6444     /***  weak reference enabler ***/
6445     0, /* long tp_weaklistoffset; */
6446 
6447     /*** Added in release 2.2 ***/
6448     /*   Iterators */
6449     NULL, /* getiterfunc tp_iter; */
6450     NULL, /* iternextfunc tp_iternext; */
6451 
6452     /*** Attribute descriptor and subclassing stuff ***/
6453     NULL, /* struct PyMethodDef *tp_methods; */
6454     NULL, /* struct PyMemberDef *tp_members; */
6455     NULL, /* struct PyGetSetDef *tp_getset; */
6456 #if defined(_MSC_VER)
6457     NULL, /* defer assignment */
6458 #else
6459     &PyType_Type, /* struct _typeobject *tp_base; */
6460 #endif
6461     NULL, /* PyObject *tp_dict; */
6462     NULL, /* descrgetfunc tp_descr_get; */
6463     NULL, /* descrsetfunc tp_descr_set; */
6464     0,    /* long tp_dictoffset; */
6465     NULL, /* initproc tp_init; */
6466     NULL, /* allocfunc tp_alloc; */
6467     NULL, /* newfunc tp_new; */
6468     /*  Low-level free-memory routine */
6469     NULL, /* freefunc tp_free;  */
6470     /* For PyObject_IS_GC */
6471     NULL, /* inquiry tp_is_gc;  */
6472     NULL, /* PyObject *tp_bases; */
6473     /* method resolution order */
6474     NULL, /* PyObject *tp_mro;  */
6475     NULL, /* PyObject *tp_cache; */
6476     NULL, /* PyObject *tp_subclasses; */
6477     NULL, /* PyObject *tp_weaklist; */
6478     NULL,
6479 };
6480 
6481 /*-----------------------BPy_StructRNA method def------------------------------*/
6482 PyTypeObject pyrna_struct_Type = {
6483     PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct", /* tp_name */
6484     sizeof(BPy_StructRNA),                       /* tp_basicsize */
6485     0,                                           /* tp_itemsize */
6486     /* methods */
6487     (destructor)pyrna_struct_dealloc, /* tp_dealloc */
6488     (printfunc)NULL,                  /* printfunc tp_print; */
6489     NULL,                             /* getattrfunc tp_getattr; */
6490     NULL,                             /* setattrfunc tp_setattr; */
6491     NULL,
6492     /* tp_compare */             /* DEPRECATED in Python 3.0! */
6493     (reprfunc)pyrna_struct_repr, /* tp_repr */
6494 
6495     /* Method suites for standard classes */
6496 
6497     NULL,                      /* PyNumberMethods *tp_as_number; */
6498     &pyrna_struct_as_sequence, /* PySequenceMethods *tp_as_sequence; */
6499     &pyrna_struct_as_mapping,  /* PyMappingMethods *tp_as_mapping; */
6500 
6501     /* More standard operations (here for binary compatibility) */
6502 
6503     (hashfunc)pyrna_struct_hash,         /* hashfunc tp_hash; */
6504     NULL,                                /* ternaryfunc tp_call; */
6505     (reprfunc)pyrna_struct_str,          /* reprfunc tp_str; */
6506     (getattrofunc)pyrna_struct_getattro, /* getattrofunc tp_getattro; */
6507     (setattrofunc)pyrna_struct_setattro, /* setattrofunc tp_setattro; */
6508 
6509     /* Functions to access object as input/output buffer */
6510     NULL, /* PyBufferProcs *tp_as_buffer; */
6511 
6512     /*** Flags to define presence of optional/expanded features ***/
6513     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* long tp_flags; */
6514 
6515     NULL, /*  char *tp_doc;  Documentation string */
6516 /*** Assigned meaning in release 2.0 ***/
6517 /* call function for all accessible objects */
6518 #ifdef USE_PYRNA_STRUCT_REFERENCE
6519     (traverseproc)pyrna_struct_traverse, /* traverseproc tp_traverse; */
6520 
6521     /* delete references to contained objects */
6522     (inquiry)pyrna_struct_clear, /* inquiry tp_clear; */
6523 #else
6524     NULL,         /* traverseproc tp_traverse; */
6525 
6526     /* delete references to contained objects */
6527     NULL, /* inquiry tp_clear; */
6528 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
6529 
6530     /***  Assigned meaning in release 2.1 ***/
6531     /*** rich comparisons ***/
6532     (richcmpfunc)pyrna_struct_richcmp, /* richcmpfunc tp_richcompare; */
6533 
6534 /***  weak reference enabler ***/
6535 #ifdef USE_WEAKREFS
6536     offsetof(BPy_StructRNA, in_weakreflist), /* long tp_weaklistoffset; */
6537 #else
6538     0,
6539 #endif
6540     /*** Added in release 2.2 ***/
6541     /*   Iterators */
6542     NULL, /* getiterfunc tp_iter; */
6543     NULL, /* iternextfunc tp_iternext; */
6544 
6545     /*** Attribute descriptor and subclassing stuff ***/
6546     pyrna_struct_methods,   /* struct PyMethodDef *tp_methods; */
6547     NULL,                   /* struct PyMemberDef *tp_members; */
6548     pyrna_struct_getseters, /* struct PyGetSetDef *tp_getset; */
6549     NULL,                   /* struct _typeobject *tp_base; */
6550     NULL,                   /* PyObject *tp_dict; */
6551     NULL,                   /* descrgetfunc tp_descr_get; */
6552     NULL,                   /* descrsetfunc tp_descr_set; */
6553     0,                      /* long tp_dictoffset; */
6554     NULL,                   /* initproc tp_init; */
6555     NULL,                   /* allocfunc tp_alloc; */
6556     pyrna_struct_new,       /* newfunc tp_new; */
6557     /*  Low-level free-memory routine */
6558     NULL, /* freefunc tp_free;  */
6559     /* For PyObject_IS_GC */
6560     NULL, /* inquiry tp_is_gc;  */
6561     NULL, /* PyObject *tp_bases; */
6562     /* method resolution order */
6563     NULL, /* PyObject *tp_mro;  */
6564     NULL, /* PyObject *tp_cache; */
6565     NULL, /* PyObject *tp_subclasses; */
6566     NULL, /* PyObject *tp_weaklist; */
6567     NULL,
6568 };
6569 
6570 /*-----------------------BPy_PropertyRNA method def------------------------------*/
6571 PyTypeObject pyrna_prop_Type = {
6572     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop", /* tp_name */
6573     sizeof(BPy_PropertyRNA),                   /* tp_basicsize */
6574     0,                                         /* tp_itemsize */
6575     /* methods */
6576     (destructor)pyrna_prop_dealloc, /* tp_dealloc */
6577     (printfunc)NULL,                /* printfunc tp_print; */
6578     NULL,                           /* getattrfunc tp_getattr; */
6579     NULL,                           /* setattrfunc tp_setattr; */
6580     NULL,
6581     /* tp_compare */           /* DEPRECATED in Python 3.0! */
6582     (reprfunc)pyrna_prop_repr, /* tp_repr */
6583 
6584     /* Method suites for standard classes */
6585 
6586     NULL, /* PyNumberMethods *tp_as_number; */
6587     NULL, /* PySequenceMethods *tp_as_sequence; */
6588     NULL, /* PyMappingMethods *tp_as_mapping; */
6589 
6590     /* More standard operations (here for binary compatibility) */
6591 
6592     (hashfunc)pyrna_prop_hash, /* hashfunc tp_hash; */
6593     NULL,                      /* ternaryfunc tp_call; */
6594     (reprfunc)pyrna_prop_str,  /* reprfunc tp_str; */
6595 
6596     /* will only use these if this is a subtype of a py class */
6597     NULL, /* getattrofunc tp_getattro; */
6598     NULL, /* setattrofunc tp_setattro; */
6599 
6600     /* Functions to access object as input/output buffer */
6601     NULL, /* PyBufferProcs *tp_as_buffer; */
6602 
6603     /*** Flags to define presence of optional/expanded features ***/
6604     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
6605 
6606     NULL, /*  char *tp_doc;  Documentation string */
6607     /*** Assigned meaning in release 2.0 ***/
6608     /* call function for all accessible objects */
6609     NULL, /* traverseproc tp_traverse; */
6610 
6611     /* delete references to contained objects */
6612     NULL, /* inquiry tp_clear; */
6613 
6614     /***  Assigned meaning in release 2.1 ***/
6615     /*** rich comparisons ***/
6616     (richcmpfunc)pyrna_prop_richcmp, /* richcmpfunc tp_richcompare; */
6617 
6618 /***  weak reference enabler ***/
6619 #ifdef USE_WEAKREFS
6620     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
6621 #else
6622     0,
6623 #endif
6624 
6625     /*** Added in release 2.2 ***/
6626     /*   Iterators */
6627     NULL, /* getiterfunc tp_iter; */
6628     NULL, /* iternextfunc tp_iternext; */
6629 
6630     /*** Attribute descriptor and subclassing stuff ***/
6631     pyrna_prop_methods,   /* struct PyMethodDef *tp_methods; */
6632     NULL,                 /* struct PyMemberDef *tp_members; */
6633     pyrna_prop_getseters, /* struct PyGetSetDef *tp_getset; */
6634     NULL,                 /* struct _typeobject *tp_base; */
6635     NULL,                 /* PyObject *tp_dict; */
6636     NULL,                 /* descrgetfunc tp_descr_get; */
6637     NULL,                 /* descrsetfunc tp_descr_set; */
6638     0,                    /* long tp_dictoffset; */
6639     NULL,                 /* initproc tp_init; */
6640     NULL,                 /* allocfunc tp_alloc; */
6641     pyrna_prop_new,       /* newfunc tp_new; */
6642     /*  Low-level free-memory routine */
6643     NULL, /* freefunc tp_free;  */
6644     /* For PyObject_IS_GC */
6645     NULL, /* inquiry tp_is_gc;  */
6646     NULL, /* PyObject *tp_bases; */
6647     /* method resolution order */
6648     NULL, /* PyObject *tp_mro;  */
6649     NULL, /* PyObject *tp_cache; */
6650     NULL, /* PyObject *tp_subclasses; */
6651     NULL, /* PyObject *tp_weaklist; */
6652     NULL,
6653 };
6654 
6655 PyTypeObject pyrna_prop_array_Type = {
6656     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_array", /* tp_name */
6657     sizeof(BPy_PropertyArrayRNA),                    /* tp_basicsize */
6658     0,                                               /* tp_itemsize */
6659     /* methods */
6660     (destructor)pyrna_prop_array_dealloc, /* tp_dealloc */
6661     (printfunc)NULL,                      /* printfunc tp_print; */
6662     NULL,                                 /* getattrfunc tp_getattr; */
6663     NULL,                                 /* setattrfunc tp_setattr; */
6664     NULL,
6665     /* tp_compare */                 /* DEPRECATED in Python 3.0! */
6666     (reprfunc)pyrna_prop_array_repr, /* tp_repr */
6667 
6668     /* Method suites for standard classes */
6669 
6670     &pyrna_prop_array_as_number,   /* PyNumberMethods *tp_as_number; */
6671     &pyrna_prop_array_as_sequence, /* PySequenceMethods *tp_as_sequence; */
6672     &pyrna_prop_array_as_mapping,  /* PyMappingMethods *tp_as_mapping; */
6673 
6674     /* More standard operations (here for binary compatibility) */
6675 
6676     NULL, /* hashfunc tp_hash; */
6677     NULL, /* ternaryfunc tp_call; */
6678     NULL, /* reprfunc tp_str; */
6679 
6680     /* will only use these if this is a subtype of a py class */
6681     (getattrofunc)pyrna_prop_array_getattro, /* getattrofunc tp_getattro; */
6682     NULL,                                    /* setattrofunc tp_setattro; */
6683 
6684     /* Functions to access object as input/output buffer */
6685     NULL, /* PyBufferProcs *tp_as_buffer; */
6686 
6687     /*** Flags to define presence of optional/expanded features ***/
6688     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
6689 
6690     NULL, /*  char *tp_doc;  Documentation string */
6691     /*** Assigned meaning in release 2.0 ***/
6692     /* call function for all accessible objects */
6693     NULL, /* traverseproc tp_traverse; */
6694 
6695     /* delete references to contained objects */
6696     NULL, /* inquiry tp_clear; */
6697 
6698     /***  Assigned meaning in release 2.1 ***/
6699     /*** rich comparisons (subclassed) ***/
6700     NULL, /* richcmpfunc tp_richcompare; */
6701 
6702 /***  weak reference enabler ***/
6703 #ifdef USE_WEAKREFS
6704     offsetof(BPy_PropertyArrayRNA, in_weakreflist), /* long tp_weaklistoffset; */
6705 #else
6706     0,
6707 #endif
6708     /*** Added in release 2.2 ***/
6709     /*   Iterators */
6710     (getiterfunc)pyrna_prop_array_iter, /* getiterfunc tp_iter; */
6711     NULL,                               /* iternextfunc tp_iternext; */
6712 
6713     /*** Attribute descriptor and subclassing stuff ***/
6714     pyrna_prop_array_methods,      /* struct PyMethodDef *tp_methods; */
6715     NULL,                          /* struct PyMemberDef *tp_members; */
6716     NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
6717     &pyrna_prop_Type,              /* struct _typeobject *tp_base; */
6718     NULL,                          /* PyObject *tp_dict; */
6719     NULL,                          /* descrgetfunc tp_descr_get; */
6720     NULL,                          /* descrsetfunc tp_descr_set; */
6721     0,                             /* long tp_dictoffset; */
6722     NULL,                          /* initproc tp_init; */
6723     NULL,                          /* allocfunc tp_alloc; */
6724     NULL,                          /* newfunc tp_new; */
6725     /*  Low-level free-memory routine */
6726     NULL, /* freefunc tp_free;  */
6727     /* For PyObject_IS_GC */
6728     NULL, /* inquiry tp_is_gc;  */
6729     NULL, /* PyObject *tp_bases; */
6730     /* method resolution order */
6731     NULL, /* PyObject *tp_mro;  */
6732     NULL, /* PyObject *tp_cache; */
6733     NULL, /* PyObject *tp_subclasses; */
6734     NULL, /* PyObject *tp_weaklist; */
6735     NULL,
6736 };
6737 
6738 PyTypeObject pyrna_prop_collection_Type = {
6739     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection", /* tp_name */
6740     sizeof(BPy_PropertyRNA),                              /* tp_basicsize */
6741     0,                                                    /* tp_itemsize */
6742     /* methods */
6743     (destructor)pyrna_prop_dealloc, /* tp_dealloc */
6744     (printfunc)NULL,                /* printfunc tp_print; */
6745     NULL,                           /* getattrfunc tp_getattr; */
6746     NULL,                           /* setattrfunc tp_setattr; */
6747     NULL,
6748     /* tp_compare */ /* DEPRECATED in Python 3.0! */
6749     NULL,
6750     /* subclassed */ /* tp_repr */
6751 
6752     /* Method suites for standard classes */
6753 
6754     &pyrna_prop_collection_as_number,   /* PyNumberMethods *tp_as_number; */
6755     &pyrna_prop_collection_as_sequence, /* PySequenceMethods *tp_as_sequence; */
6756     &pyrna_prop_collection_as_mapping,  /* PyMappingMethods *tp_as_mapping; */
6757 
6758     /* More standard operations (here for binary compatibility) */
6759 
6760     NULL, /* hashfunc tp_hash; */
6761     NULL, /* ternaryfunc tp_call; */
6762     NULL, /* reprfunc tp_str; */
6763 
6764     /* will only use these if this is a subtype of a py class */
6765     (getattrofunc)pyrna_prop_collection_getattro, /* getattrofunc tp_getattro; */
6766     (setattrofunc)pyrna_prop_collection_setattro, /* setattrofunc tp_setattro; */
6767 
6768     /* Functions to access object as input/output buffer */
6769     NULL, /* PyBufferProcs *tp_as_buffer; */
6770 
6771     /*** Flags to define presence of optional/expanded features ***/
6772     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
6773 
6774     NULL, /*  char *tp_doc;  Documentation string */
6775     /*** Assigned meaning in release 2.0 ***/
6776     /* call function for all accessible objects */
6777     NULL, /* traverseproc tp_traverse; */
6778 
6779     /* delete references to contained objects */
6780     NULL, /* inquiry tp_clear; */
6781 
6782     /***  Assigned meaning in release 2.1 ***/
6783     /*** rich comparisons (subclassed) ***/
6784     NULL, /* richcmpfunc tp_richcompare; */
6785 
6786 /***  weak reference enabler ***/
6787 #ifdef USE_WEAKREFS
6788     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
6789 #else
6790     0,
6791 #endif
6792 
6793     /*** Added in release 2.2 ***/
6794     /*   Iterators */
6795     (getiterfunc)pyrna_prop_collection_iter, /* getiterfunc tp_iter; */
6796     NULL,                                    /* iternextfunc tp_iternext; */
6797 
6798     /*** Attribute descriptor and subclassing stuff ***/
6799     pyrna_prop_collection_methods, /* struct PyMethodDef *tp_methods; */
6800     NULL,                          /* struct PyMemberDef *tp_members; */
6801     NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
6802     &pyrna_prop_Type,              /* struct _typeobject *tp_base; */
6803     NULL,                          /* PyObject *tp_dict; */
6804     NULL,                          /* descrgetfunc tp_descr_get; */
6805     NULL,                          /* descrsetfunc tp_descr_set; */
6806     0,                             /* long tp_dictoffset; */
6807     NULL,                          /* initproc tp_init; */
6808     NULL,                          /* allocfunc tp_alloc; */
6809     NULL,                          /* newfunc tp_new; */
6810     /*  Low-level free-memory routine */
6811     NULL, /* freefunc tp_free;  */
6812     /* For PyObject_IS_GC */
6813     NULL, /* inquiry tp_is_gc;  */
6814     NULL, /* PyObject *tp_bases; */
6815     /* method resolution order */
6816     NULL, /* PyObject *tp_mro;  */
6817     NULL, /* PyObject *tp_cache; */
6818     NULL, /* PyObject *tp_subclasses; */
6819     NULL, /* PyObject *tp_weaklist; */
6820     NULL,
6821 };
6822 
6823 /* only for add/remove/move methods */
6824 static PyTypeObject pyrna_prop_collection_idprop_Type = {
6825     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_idprop", /* tp_name */
6826     sizeof(BPy_PropertyRNA),                                     /* tp_basicsize */
6827     0,                                                           /* tp_itemsize */
6828     /* methods */
6829     (destructor)pyrna_prop_dealloc, /* tp_dealloc */
6830     (printfunc)NULL,                /* printfunc tp_print; */
6831     NULL,                           /* getattrfunc tp_getattr; */
6832     NULL,                           /* setattrfunc tp_setattr; */
6833     NULL,
6834     /* tp_compare */ /* DEPRECATED in Python 3.0! */
6835     NULL,
6836     /* subclassed */ /* tp_repr */
6837 
6838     /* Method suites for standard classes */
6839 
6840     NULL, /* PyNumberMethods *tp_as_number; */
6841     NULL, /* PySequenceMethods *tp_as_sequence; */
6842     NULL, /* PyMappingMethods *tp_as_mapping; */
6843 
6844     /* More standard operations (here for binary compatibility) */
6845 
6846     NULL, /* hashfunc tp_hash; */
6847     NULL, /* ternaryfunc tp_call; */
6848     NULL, /* reprfunc tp_str; */
6849 
6850     /* will only use these if this is a subtype of a py class */
6851     NULL, /* getattrofunc tp_getattro; */
6852     NULL, /* setattrofunc tp_setattro; */
6853 
6854     /* Functions to access object as input/output buffer */
6855     NULL, /* PyBufferProcs *tp_as_buffer; */
6856 
6857     /*** Flags to define presence of optional/expanded features ***/
6858     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
6859 
6860     NULL, /*  char *tp_doc;  Documentation string */
6861     /*** Assigned meaning in release 2.0 ***/
6862     /* call function for all accessible objects */
6863     NULL, /* traverseproc tp_traverse; */
6864 
6865     /* delete references to contained objects */
6866     NULL, /* inquiry tp_clear; */
6867 
6868     /***  Assigned meaning in release 2.1 ***/
6869     /*** rich comparisons (subclassed) ***/
6870     NULL, /* richcmpfunc tp_richcompare; */
6871 
6872 /***  weak reference enabler ***/
6873 #ifdef USE_WEAKREFS
6874     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
6875 #else
6876     0,
6877 #endif
6878 
6879     /*** Added in release 2.2 ***/
6880     /*   Iterators */
6881     NULL, /* getiterfunc tp_iter; */
6882     NULL, /* iternextfunc tp_iternext; */
6883 
6884     /*** Attribute descriptor and subclassing stuff ***/
6885     pyrna_prop_collection_idprop_methods, /* struct PyMethodDef *tp_methods; */
6886     NULL,                                 /* struct PyMemberDef *tp_members; */
6887     NULL /*pyrna_prop_getseters*/,        /* struct PyGetSetDef *tp_getset; */
6888     &pyrna_prop_collection_Type,          /* struct _typeobject *tp_base; */
6889     NULL,                                 /* PyObject *tp_dict; */
6890     NULL,                                 /* descrgetfunc tp_descr_get; */
6891     NULL,                                 /* descrsetfunc tp_descr_set; */
6892     0,                                    /* long tp_dictoffset; */
6893     NULL,                                 /* initproc tp_init; */
6894     NULL,                                 /* allocfunc tp_alloc; */
6895     NULL,                                 /* newfunc tp_new; */
6896     /*  Low-level free-memory routine */
6897     NULL, /* freefunc tp_free;  */
6898     /* For PyObject_IS_GC */
6899     NULL, /* inquiry tp_is_gc;  */
6900     NULL, /* PyObject *tp_bases; */
6901     /* method resolution order */
6902     NULL, /* PyObject *tp_mro;  */
6903     NULL, /* PyObject *tp_cache; */
6904     NULL, /* PyObject *tp_subclasses; */
6905     NULL, /* PyObject *tp_weaklist; */
6906     NULL,
6907 };
6908 
6909 /*-----------------------BPy_PropertyRNA method def------------------------------*/
6910 PyTypeObject pyrna_func_Type = {
6911     PyVarObject_HEAD_INIT(NULL, 0) "bpy_func", /* tp_name */
6912     sizeof(BPy_FunctionRNA),                   /* tp_basicsize */
6913     0,                                         /* tp_itemsize */
6914     /* methods */
6915     NULL,            /* tp_dealloc */
6916     (printfunc)NULL, /* printfunc tp_print; */
6917     NULL,            /* getattrfunc tp_getattr; */
6918     NULL,            /* setattrfunc tp_setattr; */
6919     NULL,
6920     /* tp_compare */           /* DEPRECATED in Python 3.0! */
6921     (reprfunc)pyrna_func_repr, /* tp_repr */
6922 
6923     /* Method suites for standard classes */
6924 
6925     NULL, /* PyNumberMethods *tp_as_number; */
6926     NULL, /* PySequenceMethods *tp_as_sequence; */
6927     NULL, /* PyMappingMethods *tp_as_mapping; */
6928 
6929     /* More standard operations (here for binary compatibility) */
6930 
6931     NULL,                         /* hashfunc tp_hash; */
6932     (ternaryfunc)pyrna_func_call, /* ternaryfunc tp_call; */
6933     NULL,                         /* reprfunc tp_str; */
6934 
6935     /* will only use these if this is a subtype of a py class */
6936     NULL, /* getattrofunc tp_getattro; */
6937     NULL, /* setattrofunc tp_setattro; */
6938 
6939     /* Functions to access object as input/output buffer */
6940     NULL, /* PyBufferProcs *tp_as_buffer; */
6941 
6942     /*** Flags to define presence of optional/expanded features ***/
6943     Py_TPFLAGS_DEFAULT, /* long tp_flags; */
6944 
6945     NULL, /*  char *tp_doc;  Documentation string */
6946     /*** Assigned meaning in release 2.0 ***/
6947     /* call function for all accessible objects */
6948     NULL, /* traverseproc tp_traverse; */
6949 
6950     /* delete references to contained objects */
6951     NULL, /* inquiry tp_clear; */
6952 
6953     /***  Assigned meaning in release 2.1 ***/
6954     /*** rich comparisons ***/
6955     NULL, /* richcmpfunc tp_richcompare; */
6956 
6957 /***  weak reference enabler ***/
6958 #ifdef USE_WEAKREFS
6959     offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
6960 #else
6961     0,
6962 #endif
6963 
6964     /*** Added in release 2.2 ***/
6965     /*   Iterators */
6966     NULL, /* getiterfunc tp_iter; */
6967     NULL, /* iternextfunc tp_iternext; */
6968 
6969     /*** Attribute descriptor and subclassing stuff ***/
6970     NULL,                 /* struct PyMethodDef *tp_methods; */
6971     NULL,                 /* struct PyMemberDef *tp_members; */
6972     pyrna_func_getseters, /* struct PyGetSetDef *tp_getset; */
6973     NULL,                 /* struct _typeobject *tp_base; */
6974     NULL,                 /* PyObject *tp_dict; */
6975     NULL,                 /* descrgetfunc tp_descr_get; */
6976     NULL,                 /* descrsetfunc tp_descr_set; */
6977     0,                    /* long tp_dictoffset; */
6978     NULL,                 /* initproc tp_init; */
6979     NULL,                 /* allocfunc tp_alloc; */
6980     NULL,                 /* newfunc tp_new; */
6981     /*  Low-level free-memory routine */
6982     NULL, /* freefunc tp_free;  */
6983     /* For PyObject_IS_GC */
6984     NULL, /* inquiry tp_is_gc;  */
6985     NULL, /* PyObject *tp_bases; */
6986     /* method resolution order */
6987     NULL, /* PyObject *tp_mro;  */
6988     NULL, /* PyObject *tp_cache; */
6989     NULL, /* PyObject *tp_subclasses; */
6990     NULL, /* PyObject *tp_weaklist; */
6991     NULL,
6992 };
6993 
6994 #ifdef USE_PYRNA_ITER
6995 /* --- collection iterator: start --- */
6996 /* wrap RNA collection iterator functions */
6997 /*
6998  * RNA_property_collection_begin(...)
6999  * RNA_property_collection_next(...)
7000  * RNA_property_collection_end(...)
7001  */
7002 
7003 static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self);
7004 static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self);
7005 
7006 static PyTypeObject pyrna_prop_collection_iter_Type = {
7007     PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_iter", /* tp_name */
7008     sizeof(BPy_PropertyCollectionIterRNA),                     /* tp_basicsize */
7009     0,                                                         /* tp_itemsize */
7010     /* methods */
7011     (destructor)pyrna_prop_collection_iter_dealloc, /* tp_dealloc */
7012     (printfunc)NULL,                                /* printfunc tp_print; */
7013     NULL,                                           /* getattrfunc tp_getattr; */
7014     NULL,                                           /* setattrfunc tp_setattr; */
7015     NULL,
7016     /* tp_compare */ /* DEPRECATED in Python 3.0! */
7017     NULL,
7018     /* subclassed */ /* tp_repr */
7019 
7020     /* Method suites for standard classes */
7021 
7022     NULL, /* PyNumberMethods *tp_as_number; */
7023     NULL, /* PySequenceMethods *tp_as_sequence; */
7024     NULL, /* PyMappingMethods *tp_as_mapping; */
7025 
7026     /* More standard operations (here for binary compatibility) */
7027 
7028     NULL, /* hashfunc tp_hash; */
7029     NULL, /* ternaryfunc tp_call; */
7030     NULL, /* reprfunc tp_str; */
7031 
7032 /* will only use these if this is a subtype of a py class */
7033 #  if defined(_MSC_VER)
7034     NULL, /* defer assignment */
7035 #  else
7036     PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */
7037 #  endif
7038     NULL, /* setattrofunc tp_setattro; */
7039 
7040     /* Functions to access object as input/output buffer */
7041     NULL, /* PyBufferProcs *tp_as_buffer; */
7042 
7043     /*** Flags to define presence of optional/expanded features ***/
7044     Py_TPFLAGS_DEFAULT, /* long tp_flags; */
7045 
7046     NULL, /*  char *tp_doc;  Documentation string */
7047     /*** Assigned meaning in release 2.0 ***/
7048     /* call function for all accessible objects */
7049     NULL, /* traverseproc tp_traverse; */
7050 
7051     /* delete references to contained objects */
7052     NULL, /* inquiry tp_clear; */
7053 
7054     /***  Assigned meaning in release 2.1 ***/
7055     /*** rich comparisons (subclassed) ***/
7056     NULL, /* richcmpfunc tp_richcompare; */
7057 
7058 /***  weak reference enabler ***/
7059 #  ifdef USE_WEAKREFS
7060     offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist), /* long tp_weaklistoffset; */
7061 #  else
7062     0,
7063 #  endif
7064 /*** Added in release 2.2 ***/
7065 /*   Iterators */
7066 #  if defined(_MSC_VER)
7067     NULL, /* defer assignment */
7068 #  else
7069     PyObject_SelfIter, /* getiterfunc tp_iter; */
7070 #  endif
7071     (iternextfunc)pyrna_prop_collection_iter_next, /* iternextfunc tp_iternext; */
7072 
7073     /*** Attribute descriptor and subclassing stuff ***/
7074     NULL, /* struct PyMethodDef *tp_methods; */
7075     NULL, /* struct PyMemberDef *tp_members; */
7076     NULL, /* struct PyGetSetDef *tp_getset; */
7077     NULL, /* struct _typeobject *tp_base; */
7078     NULL, /* PyObject *tp_dict; */
7079     NULL, /* descrgetfunc tp_descr_get; */
7080     NULL, /* descrsetfunc tp_descr_set; */
7081     0,    /* long tp_dictoffset; */
7082     NULL, /* initproc tp_init; */
7083     NULL, /* allocfunc tp_alloc; */
7084     NULL, /* newfunc tp_new; */
7085     /*  Low-level free-memory routine */
7086     NULL, /* freefunc tp_free;  */
7087     /* For PyObject_IS_GC */
7088     NULL, /* inquiry tp_is_gc;  */
7089     NULL, /* PyObject *tp_bases; */
7090     /* method resolution order */
7091     NULL, /* PyObject *tp_mro;  */
7092     NULL, /* PyObject *tp_cache; */
7093     NULL, /* PyObject *tp_subclasses; */
7094     NULL, /* PyObject *tp_weaklist; */
7095     NULL,
7096 };
7097 
pyrna_prop_collection_iter_CreatePyObject(PointerRNA * ptr,PropertyRNA * prop)7098 static PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
7099 {
7100   BPy_PropertyCollectionIterRNA *self = PyObject_New(BPy_PropertyCollectionIterRNA,
7101                                                      &pyrna_prop_collection_iter_Type);
7102 
7103 #  ifdef USE_WEAKREFS
7104   self->in_weakreflist = NULL;
7105 #  endif
7106 
7107   RNA_property_collection_begin(ptr, prop, &self->iter);
7108 
7109   return (PyObject *)self;
7110 }
7111 
pyrna_prop_collection_iter(BPy_PropertyRNA * self)7112 static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
7113 {
7114   return pyrna_prop_collection_iter_CreatePyObject(&self->ptr, self->prop);
7115 }
7116 
pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA * self)7117 static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
7118 {
7119   if (self->iter.valid == false) {
7120     PyErr_SetNone(PyExc_StopIteration);
7121     return NULL;
7122   }
7123 
7124   BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr);
7125 
7126 #  ifdef USE_PYRNA_STRUCT_REFERENCE
7127   if (pyrna) { /* Unlikely, but may fail. */
7128     if ((PyObject *)pyrna != Py_None) {
7129       /* hold a reference to the iterator since it may have
7130        * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's  */
7131       /* TODO, we could have an api call to know if this is
7132        * needed since most collections don't */
7133       pyrna_struct_reference_set(pyrna, (PyObject *)self);
7134     }
7135   }
7136 #  endif /* !USE_PYRNA_STRUCT_REFERENCE */
7137 
7138   RNA_property_collection_next(&self->iter);
7139 
7140   return (PyObject *)pyrna;
7141 }
7142 
pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA * self)7143 static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self)
7144 {
7145 #  ifdef USE_WEAKREFS
7146   if (self->in_weakreflist != NULL) {
7147     PyObject_ClearWeakRefs((PyObject *)self);
7148   }
7149 #  endif
7150 
7151   RNA_property_collection_end(&self->iter);
7152 
7153   PyObject_DEL(self);
7154 }
7155 
7156 /* --- collection iterator: end --- */
7157 #endif /* !USE_PYRNA_ITER */
7158 
pyrna_subtype_set_rna(PyObject * newclass,StructRNA * srna)7159 static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
7160 {
7161   PointerRNA ptr;
7162   PyObject *item;
7163 
7164   Py_INCREF(newclass);
7165 
7166   if (RNA_struct_py_type_get(srna)) {
7167     PyC_ObSpit("RNA WAS SET - ", RNA_struct_py_type_get(srna));
7168   }
7169 
7170   Py_XDECREF(((PyObject *)RNA_struct_py_type_get(srna)));
7171 
7172   RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */
7173 
7174   /* Not 100% needed, but useful,
7175    * having an instance within a type looks wrong, but this instance _is_ an RNA type. */
7176 
7177   /* Python deals with the circular reference. */
7178   RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
7179   item = pyrna_struct_CreatePyObject(&ptr);
7180 
7181   /* Note, must set the class not the __dict__ else the internal slots are not updated correctly.
7182    */
7183   PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item);
7184   Py_DECREF(item);
7185 
7186   /* Add staticmethods and classmethods. */
7187   {
7188     const PointerRNA func_ptr = {NULL, srna, NULL};
7189     const ListBase *lb;
7190     Link *link;
7191 
7192     lb = RNA_struct_type_functions(srna);
7193     for (link = lb->first; link; link = link->next) {
7194       FunctionRNA *func = (FunctionRNA *)link;
7195       const int flag = RNA_function_flag(func);
7196       if ((flag & FUNC_NO_SELF) &&         /* Is staticmethod or classmethod. */
7197           (flag & FUNC_REGISTER) == false) /* Is not for registration. */
7198       {
7199         /* We may want to set the type of this later. */
7200         PyObject *func_py = pyrna_func_to_py(&func_ptr, func);
7201         PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py);
7202         Py_DECREF(func_py);
7203       }
7204     }
7205   }
7206 
7207   /* Done with RNA instance. */
7208 }
7209 
7210 static PyObject *pyrna_srna_Subtype(StructRNA *srna);
7211 
7212 /* Return a borrowed reference. */
pyrna_srna_PyBase(StructRNA * srna)7213 static PyObject *pyrna_srna_PyBase(StructRNA *srna)  //, PyObject *bpy_types_dict)
7214 {
7215   /* Assume RNA_struct_py_type_get(srna) was already checked. */
7216   StructRNA *base;
7217 
7218   PyObject *py_base = NULL;
7219 
7220   /* Get the base type. */
7221   base = RNA_struct_base(srna);
7222 
7223   if (base && base != srna) {
7224     // printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna);
7225     py_base = pyrna_srna_Subtype(base);  //, bpy_types_dict);
7226     Py_DECREF(py_base);                  /* Srna owns, this is only to pass as an arg. */
7227   }
7228 
7229   if (py_base == NULL) {
7230     py_base = (PyObject *)&pyrna_struct_Type;
7231   }
7232 
7233   return py_base;
7234 }
7235 
7236 /* Check if we have a native Python subclass, use it when it exists
7237  * return a borrowed reference. */
7238 static PyObject *bpy_types_dict = NULL;
7239 
pyrna_srna_ExternalType(StructRNA * srna)7240 static PyObject *pyrna_srna_ExternalType(StructRNA *srna)
7241 {
7242   const char *idname = RNA_struct_identifier(srna);
7243   PyObject *newclass;
7244 
7245   if (bpy_types_dict == NULL) {
7246     PyObject *bpy_types = PyImport_ImportModuleLevel("bpy_types", NULL, NULL, NULL, 0);
7247 
7248     if (bpy_types == NULL) {
7249       PyErr_Print();
7250       PyErr_Clear();
7251       CLOG_ERROR(BPY_LOG_RNA, "failed to find 'bpy_types' module");
7252       return NULL;
7253     }
7254     bpy_types_dict = PyModule_GetDict(bpy_types); /* Borrow. */
7255     Py_DECREF(bpy_types);                         /* Fairly safe to assume the dict is kept. */
7256   }
7257 
7258   newclass = PyDict_GetItemString(bpy_types_dict, idname);
7259 
7260   /* Sanity check, could skip this unless in debug mode. */
7261   if (newclass) {
7262     PyObject *base_compare = pyrna_srna_PyBase(srna);
7263     /* Can't do this because it gets superclasses values! */
7264     // PyObject *slots = PyObject_GetAttrString(newclass, "__slots__");
7265     /* Can do this, but faster not to. */
7266     // PyObject *bases = PyObject_GetAttrString(newclass, "__bases__");
7267     PyObject *tp_bases = ((PyTypeObject *)newclass)->tp_bases;
7268     PyObject *tp_slots = PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict,
7269                                         bpy_intern_str___slots__);
7270 
7271     if (tp_slots == NULL) {
7272       CLOG_ERROR(
7273           BPY_LOG_RNA, "expected class '%s' to have __slots__ defined, see bpy_types.py", idname);
7274       newclass = NULL;
7275     }
7276     else if (PyTuple_GET_SIZE(tp_bases)) {
7277       PyObject *base = PyTuple_GET_ITEM(tp_bases, 0);
7278 
7279       if (base_compare != base) {
7280         char pyob_info[256];
7281         PyC_ObSpitStr(pyob_info, sizeof(pyob_info), base_compare);
7282         CLOG_ERROR(BPY_LOG_RNA,
7283                    "incorrect subclassing of SRNA '%s', expected '%s', see bpy_types.py",
7284                    idname,
7285                    pyob_info);
7286         newclass = NULL;
7287       }
7288       else {
7289         CLOG_INFO(BPY_LOG_RNA, 2, "SRNA sub-classed: '%s'", idname);
7290       }
7291     }
7292   }
7293 
7294   return newclass;
7295 }
7296 
pyrna_srna_Subtype(StructRNA * srna)7297 static PyObject *pyrna_srna_Subtype(StructRNA *srna)
7298 {
7299   PyObject *newclass = NULL;
7300 
7301   /* Stupid/simple case. */
7302   if (srna == NULL) {
7303     newclass = NULL; /* Nothing to do. */
7304   }                  /* The class may have already been declared & allocated. */
7305   else if ((newclass = RNA_struct_py_type_get(srna))) {
7306     Py_INCREF(newclass);
7307   } /* Check if bpy_types.py module has the class defined in it. */
7308   else if ((newclass = pyrna_srna_ExternalType(srna))) {
7309     pyrna_subtype_set_rna(newclass, srna);
7310     Py_INCREF(newclass);
7311   } /* create a new class instance with the C api
7312      * mainly for the purposing of matching the C/RNA type hierarchy */
7313   else {
7314     /* subclass equivalents
7315      * - class myClass(myBase):
7316      *     some = 'value' # or ...
7317      * - myClass = type(
7318      *       name='myClass',
7319      *       bases=(myBase,), dict={'__module__': 'bpy.types', '__slots__': ()}
7320      *   )
7321      */
7322 
7323     /* Assume RNA_struct_py_type_get(srna) was already checked. */
7324     PyObject *py_base = pyrna_srna_PyBase(srna);
7325     PyObject *metaclass;
7326     const char *idname = RNA_struct_identifier(srna);
7327 
7328     /* Remove __doc__ for now. */
7329     // const char *descr = RNA_struct_ui_description(srna);
7330     // if (!descr) descr = "(no docs)";
7331     // "__doc__", descr
7332 
7333     if (RNA_struct_idprops_check(srna) &&
7334         !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type)) {
7335       metaclass = (PyObject *)&pyrna_struct_meta_idprop_Type;
7336     }
7337     else {
7338       metaclass = (PyObject *)&PyType_Type;
7339     }
7340 
7341     /* Always use O not N when calling, N causes refcount errors. */
7342 #if 0
7343     newclass = PyObject_CallFunction(
7344         metaclass, "s(O) {sss()}", idname, py_base, "__module__", "bpy.types", "__slots__");
7345 #else
7346     {
7347       /* Longhand of the call above. */
7348       PyObject *args, *item, *value;
7349       int ok;
7350 
7351       args = PyTuple_New(3);
7352 
7353       /* arg[0] (name=...) */
7354       PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(idname));
7355 
7356       /* arg[1] (bases=...) */
7357       PyTuple_SET_ITEM(args, 1, item = PyTuple_New(1));
7358       PyTuple_SET_ITEM(item, 0, Py_INCREF_RET(py_base));
7359 
7360       /* arg[2] (dict=...) */
7361       PyTuple_SET_ITEM(args, 2, item = PyDict_New());
7362       ok = PyDict_SetItem(item, bpy_intern_str___module__, bpy_intern_str_bpy_types);
7363       BLI_assert(ok != -1);
7364       ok = PyDict_SetItem(item, bpy_intern_str___slots__, value = PyTuple_New(0));
7365       Py_DECREF(value);
7366       BLI_assert(ok != -1);
7367 
7368       newclass = PyObject_CallObject(metaclass, args);
7369       Py_DECREF(args);
7370 
7371       (void)ok;
7372     }
7373 #endif
7374 
7375     /* Newclass will now have 2 ref's, ???,
7376      * probably 1 is internal since #Py_DECREF here segfaults. */
7377 
7378     /* PyC_ObSpit("new class ref", newclass); */
7379 
7380     if (newclass) {
7381       /* srna owns one, and the other is owned by the caller. */
7382       pyrna_subtype_set_rna(newclass, srna);
7383 
7384       /* XXX, adding this back segfaults Blender on load. */
7385       // Py_DECREF(newclass); /* let srna own */
7386     }
7387     else {
7388       /* This should not happen. */
7389       CLOG_ERROR(BPY_LOG_RNA, "failed to register '%s'", idname);
7390       PyErr_Print();
7391       PyErr_Clear();
7392     }
7393   }
7394 
7395   return newclass;
7396 }
7397 
7398 /* Use for subtyping so we know which srna is used for a PointerRNA. */
srna_from_ptr(PointerRNA * ptr)7399 static StructRNA *srna_from_ptr(PointerRNA *ptr)
7400 {
7401   if (ptr->type == &RNA_Struct) {
7402     return ptr->data;
7403   }
7404 
7405   return ptr->type;
7406 }
7407 
7408 /* Always returns a new ref, be sure to decref when done. */
pyrna_struct_Subtype(PointerRNA * ptr)7409 static PyObject *pyrna_struct_Subtype(PointerRNA *ptr)
7410 {
7411   return pyrna_srna_Subtype(srna_from_ptr(ptr));
7412 }
7413 
7414 /*-----------------------CreatePyObject---------------------------------*/
pyrna_struct_CreatePyObject(PointerRNA * ptr)7415 PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
7416 {
7417   BPy_StructRNA *pyrna = NULL;
7418 
7419   /* Note: don't rely on this to return None since NULL data with a valid type can often crash. */
7420   if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data. */
7421     Py_RETURN_NONE;
7422   }
7423 
7424   /* New in 2.8x, since not many types support instancing
7425    * we may want to use a flag to avoid looping over all classes. - campbell */
7426   void **instance = ptr->data ? RNA_struct_instance(ptr) : NULL;
7427   if (instance && *instance) {
7428     pyrna = *instance;
7429 
7430     /* Refine may have changed types after the first instance was created. */
7431     if (ptr->type == pyrna->ptr.type) {
7432       Py_INCREF(pyrna);
7433       return (PyObject *)pyrna;
7434     }
7435 
7436     /* Existing users will need to use 'type_recast' method. */
7437     Py_DECREF(pyrna);
7438     *instance = NULL;
7439     /* Continue as if no instance was made. */
7440 #if 0 /* No need to assign, will be written to next... */
7441       pyrna = NULL;
7442 #endif
7443   }
7444 
7445   {
7446     PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
7447 
7448     if (tp) {
7449       pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0);
7450       Py_DECREF(tp); /* srna owns, can't hold a reference. */
7451     }
7452     else {
7453       CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type));
7454       pyrna = (BPy_StructRNA *)PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type);
7455 #ifdef USE_WEAKREFS
7456       pyrna->in_weakreflist = NULL;
7457 #endif
7458     }
7459   }
7460 
7461   if (pyrna == NULL) {
7462     PyErr_SetString(PyExc_MemoryError, "couldn't create bpy_struct object");
7463     return NULL;
7464   }
7465 
7466   /* Blender's instance owns a reference (to avoid Python freeing it). */
7467   if (instance) {
7468     *instance = pyrna;
7469     Py_INCREF(pyrna);
7470   }
7471 
7472   pyrna->ptr = *ptr;
7473 #ifdef PYRNA_FREE_SUPPORT
7474   pyrna->freeptr = false;
7475 #endif
7476 
7477 #ifdef USE_PYRNA_STRUCT_REFERENCE
7478   pyrna->reference = NULL;
7479 #endif
7480 
7481   // PyC_ObSpit("NewStructRNA: ", (PyObject *)pyrna);
7482 
7483 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
7484   if (ptr->owner_id) {
7485     id_weakref_pool_add(ptr->owner_id, (BPy_DummyPointerRNA *)pyrna);
7486   }
7487 #endif
7488   return (PyObject *)pyrna;
7489 }
7490 
pyrna_prop_CreatePyObject(PointerRNA * ptr,PropertyRNA * prop)7491 PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
7492 {
7493   BPy_PropertyRNA *pyrna;
7494 
7495   if (RNA_property_array_check(prop) == 0) {
7496     PyTypeObject *type;
7497 
7498     if (RNA_property_type(prop) != PROP_COLLECTION) {
7499       type = &pyrna_prop_Type;
7500     }
7501     else {
7502       if ((RNA_property_flag(prop) & PROP_IDPROPERTY) == 0) {
7503         type = &pyrna_prop_collection_Type;
7504       }
7505       else {
7506         type = &pyrna_prop_collection_idprop_Type;
7507       }
7508     }
7509 
7510     pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyRNA, type);
7511 #ifdef USE_WEAKREFS
7512     pyrna->in_weakreflist = NULL;
7513 #endif
7514   }
7515   else {
7516     pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type);
7517     ((BPy_PropertyArrayRNA *)pyrna)->arraydim = 0;
7518     ((BPy_PropertyArrayRNA *)pyrna)->arrayoffset = 0;
7519 #ifdef USE_WEAKREFS
7520     ((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist = NULL;
7521 #endif
7522   }
7523 
7524   if (pyrna == NULL) {
7525     PyErr_SetString(PyExc_MemoryError, "couldn't create BPy_rna object");
7526     return NULL;
7527   }
7528 
7529   pyrna->ptr = *ptr;
7530   pyrna->prop = prop;
7531 
7532 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
7533   if (ptr->owner_id) {
7534     id_weakref_pool_add(ptr->owner_id, (BPy_DummyPointerRNA *)pyrna);
7535   }
7536 #endif
7537 
7538   return (PyObject *)pyrna;
7539 }
7540 
7541 /* Utility func to be used by external modules, sneaky! */
pyrna_id_CreatePyObject(ID * id)7542 PyObject *pyrna_id_CreatePyObject(ID *id)
7543 {
7544   if (id) {
7545     PointerRNA ptr;
7546     RNA_id_pointer_create(id, &ptr);
7547     return pyrna_struct_CreatePyObject(&ptr);
7548   }
7549 
7550   Py_RETURN_NONE;
7551 }
7552 
pyrna_id_FromPyObject(PyObject * obj,ID ** id)7553 bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
7554 {
7555   if (pyrna_id_CheckPyObject(obj)) {
7556     *id = ((BPy_StructRNA *)obj)->ptr.owner_id;
7557     return true;
7558   }
7559 
7560   *id = NULL;
7561   return false;
7562 }
7563 
pyrna_id_CheckPyObject(PyObject * obj)7564 bool pyrna_id_CheckPyObject(PyObject *obj)
7565 {
7566   return BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type));
7567 }
7568 
BPY_rna_init(void)7569 void BPY_rna_init(void)
7570 {
7571 #ifdef USE_MATHUTILS /* Register mathutils callbacks, ok to run more than once. */
7572   mathutils_rna_array_cb_index = Mathutils_RegisterCallback(&mathutils_rna_array_cb);
7573   mathutils_rna_matrix_cb_index = Mathutils_RegisterCallback(&mathutils_rna_matrix_cb);
7574 #endif
7575 
7576   /* For some reason MSVC complains of these. */
7577 #if defined(_MSC_VER)
7578   pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type;
7579 
7580   pyrna_prop_collection_iter_Type.tp_iter = PyObject_SelfIter;
7581   pyrna_prop_collection_iter_Type.tp_getattro = PyObject_GenericGetAttr;
7582 #endif
7583 
7584   /* metaclass */
7585   if (PyType_Ready(&pyrna_struct_meta_idprop_Type) < 0) {
7586     return;
7587   }
7588 
7589   if (PyType_Ready(&pyrna_struct_Type) < 0) {
7590     return;
7591   }
7592 
7593   if (PyType_Ready(&pyrna_prop_Type) < 0) {
7594     return;
7595   }
7596 
7597   if (PyType_Ready(&pyrna_prop_array_Type) < 0) {
7598     return;
7599   }
7600 
7601   if (PyType_Ready(&pyrna_prop_collection_Type) < 0) {
7602     return;
7603   }
7604 
7605   if (PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0) {
7606     return;
7607   }
7608 
7609   if (PyType_Ready(&pyrna_func_Type) < 0) {
7610     return;
7611   }
7612 
7613 #ifdef USE_PYRNA_ITER
7614   if (PyType_Ready(&pyrna_prop_collection_iter_Type) < 0) {
7615     return;
7616   }
7617 #endif
7618 }
7619 
7620 /* 'bpy.data' from Python. */
7621 static PointerRNA *rna_module_ptr = NULL;
BPY_rna_module(void)7622 PyObject *BPY_rna_module(void)
7623 {
7624   BPy_StructRNA *pyrna;
7625   PointerRNA ptr;
7626 
7627   /* For now, return the base RNA type rather than a real module. */
7628   RNA_main_pointer_create(G_MAIN, &ptr);
7629   pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
7630 
7631   rna_module_ptr = &pyrna->ptr;
7632   return (PyObject *)pyrna;
7633 }
7634 
BPY_update_rna_module(void)7635 void BPY_update_rna_module(void)
7636 {
7637   if (rna_module_ptr) {
7638 #if 0
7639     RNA_main_pointer_create(G_MAIN, rna_module_ptr);
7640 #else
7641     rna_module_ptr->data = G_MAIN; /* Just set data is enough. */
7642 #endif
7643   }
7644 }
7645 
7646 #if 0
7647 /* This is a way we can access doc-strings for RNA types
7648  * without having the data-types in Blender. */
7649 PyObject *BPY_rna_doc(void)
7650 {
7651   PointerRNA ptr;
7652 
7653   /* For now, return the base RNA type rather than a real module. */
7654   RNA_blender_rna_pointer_create(&ptr);
7655 
7656   return pyrna_struct_CreatePyObject(&ptr);
7657 }
7658 #endif
7659 
7660 /* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a different type
7661  * the self->ptr and self->prop are always set to the "structs" collection */
7662 /* ---------------getattr-------------------------------------------- */
pyrna_basetype_getattro(BPy_BaseTypeRNA * self,PyObject * pyname)7663 static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname)
7664 {
7665   PointerRNA newptr;
7666   PyObject *ret;
7667   const char *name = _PyUnicode_AsString(pyname);
7668 
7669   if (name == NULL) {
7670     PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string");
7671     ret = NULL;
7672   }
7673   else if (RNA_property_collection_lookup_string(&self->ptr, self->prop, name, &newptr)) {
7674     ret = pyrna_struct_Subtype(&newptr);
7675     if (ret == NULL) {
7676       PyErr_Format(PyExc_RuntimeError,
7677                    "bpy.types.%.200s subtype could not be generated, this is a bug!",
7678                    _PyUnicode_AsString(pyname));
7679     }
7680   }
7681   else {
7682 #if 0
7683     PyErr_Format(PyExc_AttributeError,
7684                  "bpy.types.%.200s RNA_Struct does not exist",
7685                  _PyUnicode_AsString(pyname));
7686     return NULL;
7687 #endif
7688     /* The error raised here will be displayed. */
7689     ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
7690   }
7691 
7692   return ret;
7693 }
7694 
7695 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self);
7696 static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class);
7697 static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class);
7698 
7699 static struct PyMethodDef pyrna_basetype_methods[] = {
7700     {"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""},
7701     {NULL, NULL, 0, NULL},
7702 };
7703 
7704 /* Used to call ..._keys() direct, but we need to filter out operator subclasses. */
7705 #if 0
7706 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
7707 {
7708   PyObject *list;
7709 #  if 0
7710   PyMethodDef *meth;
7711 #  endif
7712 
7713   list = pyrna_prop_collection_keys(self); /* Like calling structs.keys(), avoids looping here. */
7714 
7715 #  if 0 /* For now only contains __dir__. */
7716   for (meth = pyrna_basetype_methods; meth->ml_name; meth++) {
7717     PyList_APPEND(list, PyUnicode_FromString(meth->ml_name));
7718   }
7719 #  endif
7720   return list;
7721 }
7722 
7723 #else
7724 
pyrna_basetype_dir(BPy_BaseTypeRNA * self)7725 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
7726 {
7727   PyObject *ret = PyList_New(0);
7728 
7729   RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
7730     StructRNA *srna = itemptr.data;
7731     PyList_APPEND(ret, PyUnicode_FromString(RNA_struct_identifier(srna)));
7732   }
7733   RNA_PROP_END;
7734 
7735   return ret;
7736 }
7737 
7738 #endif
7739 
7740 static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE;
7741 
7742 /**
7743  * Accessed from Python as 'bpy.types'
7744  */
BPY_rna_types(void)7745 PyObject *BPY_rna_types(void)
7746 {
7747   BPy_BaseTypeRNA *self;
7748 
7749   if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY) == 0) {
7750     pyrna_basetype_Type.tp_name = "RNA_Types";
7751     pyrna_basetype_Type.tp_basicsize = sizeof(BPy_BaseTypeRNA);
7752     pyrna_basetype_Type.tp_getattro = (getattrofunc)pyrna_basetype_getattro;
7753     pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
7754     pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
7755 
7756     if (PyType_Ready(&pyrna_basetype_Type) < 0) {
7757       return NULL;
7758     }
7759   }
7760 
7761   /* Static members for the base class. */
7762   /* Add __name__ since help() expects it. */
7763   PyDict_SetItem(pyrna_basetype_Type.tp_dict, bpy_intern_str___name__, bpy_intern_str_bpy_types);
7764 
7765   /* Internal base types we have no other accessors for. */
7766   {
7767     PyTypeObject *pyrna_types[] = {
7768         &pyrna_struct_meta_idprop_Type,
7769         &pyrna_struct_Type,
7770         &pyrna_prop_Type,
7771         &pyrna_prop_array_Type,
7772         &pyrna_prop_collection_Type,
7773         &pyrna_func_Type,
7774     };
7775 
7776     for (int i = 0; i < ARRAY_SIZE(pyrna_types); i += 1) {
7777       PyDict_SetItemString(
7778           pyrna_basetype_Type.tp_dict, pyrna_types[i]->tp_name, (PyObject *)pyrna_types[i]);
7779     }
7780   }
7781 
7782   self = (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type);
7783 
7784   /* Avoid doing this lookup for every getattr. */
7785   RNA_blender_rna_pointer_create(&self->ptr);
7786   self->prop = RNA_struct_find_property(&self->ptr, "structs");
7787 #ifdef USE_WEAKREFS
7788   self->in_weakreflist = NULL;
7789 #endif
7790   return (PyObject *)self;
7791 }
7792 
pyrna_struct_as_srna(PyObject * self,const bool parent,const char * error_prefix)7793 StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
7794 {
7795   BPy_StructRNA *py_srna = NULL;
7796   StructRNA *srna;
7797 
7798   /* Unfortunately PyObject_GetAttrString wont look up this types tp_dict first :/ */
7799   if (PyType_Check(self)) {
7800     py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict,
7801                                               bpy_intern_str_bl_rna);
7802     Py_XINCREF(py_srna);
7803   }
7804 
7805   if (parent) {
7806     /* be very careful with this since it will return a parent classes srna.
7807      * modifying this will do confusing stuff! */
7808     if (py_srna == NULL) {
7809       py_srna = (BPy_StructRNA *)PyObject_GetAttr(self, bpy_intern_str_bl_rna);
7810     }
7811   }
7812 
7813   if (py_srna == NULL) {
7814     PyErr_Format(PyExc_RuntimeError,
7815                  "%.200s, missing bl_rna attribute from '%.200s' instance (may not be registered)",
7816                  error_prefix,
7817                  Py_TYPE(self)->tp_name);
7818     return NULL;
7819   }
7820 
7821   if (!BPy_StructRNA_Check(py_srna)) {
7822     PyErr_Format(PyExc_TypeError,
7823                  "%.200s, bl_rna attribute wrong type '%.200s' on '%.200s'' instance",
7824                  error_prefix,
7825                  Py_TYPE(py_srna)->tp_name,
7826                  Py_TYPE(self)->tp_name);
7827     Py_DECREF(py_srna);
7828     return NULL;
7829   }
7830 
7831   if (py_srna->ptr.type != &RNA_Struct) {
7832     PyErr_Format(PyExc_TypeError,
7833                  "%.200s, bl_rna attribute not a RNA_Struct, on '%.200s'' instance",
7834                  error_prefix,
7835                  Py_TYPE(self)->tp_name);
7836     Py_DECREF(py_srna);
7837     return NULL;
7838   }
7839 
7840   srna = py_srna->ptr.data;
7841   Py_DECREF(py_srna);
7842 
7843   return srna;
7844 }
7845 
7846 /* Orphan functions, not sure where they should go. */
7847 /* Get the srna for methods attached to types. */
7848 /*
7849  * Caller needs to raise error.*/
srna_from_self(PyObject * self,const char * error_prefix)7850 StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
7851 {
7852 
7853   if (self == NULL) {
7854     return NULL;
7855   }
7856   if (PyCapsule_CheckExact(self)) {
7857     return PyCapsule_GetPointer(self, NULL);
7858   }
7859   if (PyType_Check(self) == 0) {
7860     return NULL;
7861   }
7862 
7863   /* These cases above not errors, they just mean the type was not compatible
7864    * After this any errors will be raised in the script */
7865 
7866   PyObject *error_type, *error_value, *error_traceback;
7867   StructRNA *srna;
7868 
7869   PyErr_Fetch(&error_type, &error_value, &error_traceback);
7870   PyErr_Clear();
7871 
7872   srna = pyrna_struct_as_srna(self, false, error_prefix);
7873 
7874   if (!PyErr_Occurred()) {
7875     PyErr_Restore(error_type, error_value, error_traceback);
7876   }
7877 
7878   return srna;
7879 }
7880 
deferred_register_prop(StructRNA * srna,PyObject * key,PyObject * item)7881 static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item)
7882 {
7883   /* We only care about results from C which
7884    * are for sure types, save some time with error */
7885   if (pyrna_is_deferred_prop(item)) {
7886 
7887     PyObject *py_func, *py_kw, *py_srna_cobject, *py_ret;
7888 
7889     if (PyArg_ParseTuple(item, "OO!", &py_func, &PyDict_Type, &py_kw)) {
7890       PyObject *args_fake;
7891 
7892       if (*_PyUnicode_AsString(key) == '_') {
7893         PyErr_Format(PyExc_ValueError,
7894                      "bpy_struct \"%.200s\" registration error: "
7895                      "%.200s could not register because the property starts with an '_'\n",
7896                      RNA_struct_identifier(srna),
7897                      _PyUnicode_AsString(key));
7898         return -1;
7899       }
7900       py_srna_cobject = PyCapsule_New(srna, NULL, NULL);
7901 
7902       /* Not 100% nice :/, modifies the dict passed, should be ok. */
7903       PyDict_SetItem(py_kw, bpy_intern_str_attr, key);
7904 
7905       args_fake = PyTuple_New(1);
7906       PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject);
7907 
7908       PyObject *type = PyDict_GetItemString(py_kw, "type");
7909       StructRNA *type_srna = srna_from_self(type, "");
7910       if (type_srna) {
7911         if (!RNA_struct_idprops_datablock_allowed(srna) &&
7912             (*(PyCFunctionWithKeywords)PyCFunction_GET_FUNCTION(py_func) == BPy_PointerProperty ||
7913              *(PyCFunctionWithKeywords)PyCFunction_GET_FUNCTION(py_func) ==
7914                  BPy_CollectionProperty) &&
7915             RNA_struct_idprops_contains_datablock(type_srna)) {
7916           PyErr_Format(PyExc_ValueError,
7917                        "bpy_struct \"%.200s\" doesn't support datablock properties\n",
7918                        RNA_struct_identifier(srna));
7919           return -1;
7920         }
7921       }
7922 
7923       py_ret = PyObject_Call(py_func, args_fake, py_kw);
7924 
7925       if (py_ret) {
7926         Py_DECREF(py_ret);
7927         Py_DECREF(args_fake); /* Free's py_srna_cobject too. */
7928       }
7929       else {
7930         /* _must_ print before decreffing args_fake. */
7931         PyErr_Print();
7932         PyErr_Clear();
7933 
7934         Py_DECREF(args_fake); /* Free's py_srna_cobject too. */
7935 
7936         // PyC_LineSpit();
7937         PyErr_Format(PyExc_ValueError,
7938                      "bpy_struct \"%.200s\" registration error: "
7939                      "%.200s could not register\n",
7940                      RNA_struct_identifier(srna),
7941                      _PyUnicode_AsString(key));
7942         return -1;
7943       }
7944     }
7945     else {
7946       /* Since this is a class dict, ignore args that can't be passed. */
7947 
7948       /* For testing only. */
7949 #if 0
7950       PyC_ObSpit("Why doesn't this work??", item);
7951       PyErr_Print();
7952 #endif
7953       PyErr_Clear();
7954     }
7955   }
7956 
7957   return 0;
7958 }
7959 
pyrna_deferred_register_props(StructRNA * srna,PyObject * class_dict)7960 static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
7961 {
7962   PyObject *annotations_dict;
7963   PyObject *item, *key;
7964   Py_ssize_t pos = 0;
7965   int ret = 0;
7966 
7967   /* in both cases PyDict_CheckExact(class_dict) will be true even
7968    * though Operators have a metaclass dict namespace */
7969   if ((annotations_dict = PyDict_GetItem(class_dict, bpy_intern_str___annotations__)) &&
7970       PyDict_CheckExact(annotations_dict)) {
7971     while (PyDict_Next(annotations_dict, &pos, &key, &item)) {
7972       ret = deferred_register_prop(srna, key, item);
7973 
7974       if (ret != 0) {
7975         break;
7976       }
7977     }
7978   }
7979 
7980   if (ret == 0) {
7981     /* This block can be removed once 2.8x is released and annotations are in use. */
7982     bool has_warning = false;
7983     while (PyDict_Next(class_dict, &pos, &key, &item)) {
7984       if (pyrna_is_deferred_prop(item)) {
7985         if (!has_warning) {
7986           printf(
7987               "Warning: class %.200s "
7988               "contains a property which should be an annotation!\n",
7989               RNA_struct_identifier(srna));
7990           PyC_LineSpit();
7991           has_warning = true;
7992         }
7993         printf("    assign as a type annotation: %.200s.%.200s\n",
7994                RNA_struct_identifier(srna),
7995                _PyUnicode_AsString(key));
7996       }
7997       ret = deferred_register_prop(srna, key, item);
7998 
7999       if (ret != 0) {
8000         break;
8001       }
8002     }
8003   }
8004 
8005   return ret;
8006 }
8007 
pyrna_deferred_register_class_recursive(StructRNA * srna,PyTypeObject * py_class)8008 static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject *py_class)
8009 {
8010   const int len = PyTuple_GET_SIZE(py_class->tp_bases);
8011   int i, ret;
8012 
8013   /* First scan base classes for registerable properties. */
8014   for (i = 0; i < len; i++) {
8015     PyTypeObject *py_superclass = (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i);
8016 
8017     /* the rules for using these base classes are not clear,
8018      * 'object' is of course not worth looking into and
8019      * existing subclasses of RNA would cause a lot more dictionary
8020      * looping then is needed (SomeOperator would scan Operator.__dict__)
8021      * which is harmless, but not at all useful.
8022      *
8023      * So only scan base classes which are not subclasses if blender types.
8024      * This best fits having 'mix-in' classes for operators and render engines.
8025      */
8026     if (py_superclass != &PyBaseObject_Type &&
8027         !PyObject_IsSubclass((PyObject *)py_superclass, (PyObject *)&pyrna_struct_Type)) {
8028       ret = pyrna_deferred_register_class_recursive(srna, py_superclass);
8029 
8030       if (ret != 0) {
8031         return ret;
8032       }
8033     }
8034   }
8035 
8036   /* Not register out own properties. */
8037   /* getattr(..., "__dict__") returns a proxy. */
8038   return pyrna_deferred_register_props(srna, py_class->tp_dict);
8039 }
8040 
pyrna_deferred_register_class(StructRNA * srna,PyTypeObject * py_class)8041 int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class)
8042 {
8043   /* Panels and Menus don't need this
8044    * save some time and skip the checks here */
8045   if (!RNA_struct_idprops_register_check(srna)) {
8046     return 0;
8047   }
8048 
8049   return pyrna_deferred_register_class_recursive(srna, py_class);
8050 }
8051 
8052 /*-------------------- Type Registration ------------------------*/
8053 
rna_function_arg_count(FunctionRNA * func,int * min_count)8054 static int rna_function_arg_count(FunctionRNA *func, int *min_count)
8055 {
8056   const ListBase *lb = RNA_function_defined_parameters(func);
8057   PropertyRNA *parm;
8058   Link *link;
8059   const int flag = RNA_function_flag(func);
8060   const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
8061   int count = is_staticmethod ? 0 : 1;
8062   bool done_min_count = false;
8063 
8064   for (link = lb->first; link; link = link->next) {
8065     parm = (PropertyRNA *)link;
8066     if (!(RNA_parameter_flag(parm) & PARM_OUTPUT)) {
8067       if (!done_min_count && (RNA_parameter_flag(parm) & PARM_PYFUNC_OPTIONAL)) {
8068         /* From now on, the following parameters are optional in a Python function. */
8069         if (min_count) {
8070           *min_count = count;
8071         }
8072         done_min_count = true;
8073       }
8074       count++;
8075     }
8076   }
8077 
8078   if (!done_min_count && min_count) {
8079     *min_count = count;
8080   }
8081   return count;
8082 }
8083 
bpy_class_validate_recursive(PointerRNA * dummyptr,StructRNA * srna,void * py_data,int * have_function)8084 static int bpy_class_validate_recursive(PointerRNA *dummyptr,
8085                                         StructRNA *srna,
8086                                         void *py_data,
8087                                         int *have_function)
8088 {
8089   const ListBase *lb;
8090   Link *link;
8091   const char *class_type = RNA_struct_identifier(srna);
8092   StructRNA *srna_base = RNA_struct_base(srna);
8093   PyObject *py_class = (PyObject *)py_data;
8094   PyObject *base_class = RNA_struct_py_type_get(srna);
8095   PyObject *item;
8096   int i, arg_count, func_arg_count, func_arg_min_count = 0;
8097   const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */
8098 
8099   if (srna_base) {
8100     if (bpy_class_validate_recursive(dummyptr, srna_base, py_data, have_function) != 0) {
8101       return -1;
8102     }
8103   }
8104 
8105   if (base_class) {
8106     if (!PyObject_IsSubclass(py_class, base_class)) {
8107       PyErr_Format(PyExc_TypeError,
8108                    "expected %.200s subclass of class \"%.200s\"",
8109                    class_type,
8110                    py_class_name);
8111       return -1;
8112     }
8113   }
8114 
8115   /* Verify callback functions. */
8116   lb = RNA_struct_type_functions(srna);
8117   i = 0;
8118   for (link = lb->first; link; link = link->next) {
8119     FunctionRNA *func = (FunctionRNA *)link;
8120     const int flag = RNA_function_flag(func);
8121     if (!(flag & FUNC_REGISTER)) {
8122       continue;
8123     }
8124 
8125     item = PyObject_GetAttrString(py_class, RNA_function_identifier(func));
8126     have_function[i] = (item != NULL);
8127     i++;
8128 
8129     if (item == NULL) {
8130       if ((flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER)) == 0) {
8131         PyErr_Format(PyExc_AttributeError,
8132                      "expected %.200s, %.200s class to have an \"%.200s\" attribute",
8133                      class_type,
8134                      py_class_name,
8135                      RNA_function_identifier(func));
8136         return -1;
8137       }
8138       PyErr_Clear();
8139 
8140       continue;
8141     }
8142 
8143     /* TODO(campbell): this is used for classmethod's too,
8144      * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg.
8145      * Keep this as-is since it's working, but we should be using
8146      * 'FUNC_USE_SELF_TYPE' for many functions. */
8147     const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
8148 
8149     /* Store original so we can decrement its reference before returning. */
8150     PyObject *item_orig = item;
8151 
8152     if (is_staticmethod) {
8153       if (PyMethod_Check(item) == 0) {
8154         PyErr_Format(PyExc_TypeError,
8155                      "expected %.200s, %.200s class \"%.200s\" "
8156                      "attribute to be a static/class method, not a %.200s",
8157                      class_type,
8158                      py_class_name,
8159                      RNA_function_identifier(func),
8160                      Py_TYPE(item)->tp_name);
8161         Py_DECREF(item_orig);
8162         return -1;
8163       }
8164       item = ((PyMethodObject *)item)->im_func;
8165     }
8166     else {
8167       if (PyFunction_Check(item) == 0) {
8168         PyErr_Format(PyExc_TypeError,
8169                      "expected %.200s, %.200s class \"%.200s\" "
8170                      "attribute to be a function, not a %.200s",
8171                      class_type,
8172                      py_class_name,
8173                      RNA_function_identifier(func),
8174                      Py_TYPE(item)->tp_name);
8175         Py_DECREF(item_orig);
8176         return -1;
8177       }
8178     }
8179 
8180     func_arg_count = rna_function_arg_count(func, &func_arg_min_count);
8181 
8182     if (func_arg_count >= 0) { /* -1 if we don't care. */
8183       arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
8184 
8185       /* note, the number of args we check for and the number of args we give to
8186        * '@staticmethods' are different (quirk of Python),
8187        * this is why rna_function_arg_count() doesn't return the value -1*/
8188       if (is_staticmethod) {
8189         func_arg_count++;
8190         func_arg_min_count++;
8191       }
8192 
8193       if (arg_count < func_arg_min_count || arg_count > func_arg_count) {
8194         if (func_arg_min_count != func_arg_count) {
8195           PyErr_Format(
8196               PyExc_ValueError,
8197               "expected %.200s, %.200s class \"%.200s\" function to have between %d and %d "
8198               "args, found %d",
8199               class_type,
8200               py_class_name,
8201               RNA_function_identifier(func),
8202               func_arg_count,
8203               func_arg_min_count,
8204               arg_count);
8205         }
8206         else {
8207           PyErr_Format(
8208               PyExc_ValueError,
8209               "expected %.200s, %.200s class \"%.200s\" function to have %d args, found %d",
8210               class_type,
8211               py_class_name,
8212               RNA_function_identifier(func),
8213               func_arg_count,
8214               arg_count);
8215         }
8216         Py_DECREF(item_orig);
8217         return -1;
8218       }
8219     }
8220     Py_DECREF(item_orig);
8221   }
8222 
8223   /* Verify properties. */
8224   lb = RNA_struct_type_properties(srna);
8225   for (link = lb->first; link; link = link->next) {
8226     const char *identifier;
8227     PropertyRNA *prop = (PropertyRNA *)link;
8228     const int flag = RNA_property_flag(prop);
8229 
8230     if (!(flag & PROP_REGISTER)) {
8231       continue;
8232     }
8233 
8234     /* TODO(campbell): Use Python3.7x _PyObject_LookupAttr(), also in the macro below. */
8235     identifier = RNA_property_identifier(prop);
8236     item = PyObject_GetAttrString(py_class, identifier);
8237 
8238     if (item == NULL) {
8239       PyErr_Clear();
8240       /* Sneaky workaround to use the class name as the bl_idname. */
8241 
8242 #define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
8243   else if (STREQ(identifier, rna_attr)) \
8244   { \
8245     if ((item = PyObject_GetAttr(py_class, py_attr))) { \
8246       if (item != Py_None) { \
8247         if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) { \
8248           Py_DECREF(item); \
8249           return -1; \
8250         } \
8251       } \
8252       Py_DECREF(item); \
8253     } \
8254     else { \
8255       PyErr_Clear(); \
8256     } \
8257   } /* Intentionally allow else here. */
8258 
8259       if (false) {
8260       } /* Needed for macro. */
8261       BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__)
8262       BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__)
8263 
8264 #undef BPY_REPLACEMENT_STRING
8265 
8266       if (item == NULL && (((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL))) {
8267         PyErr_Format(PyExc_AttributeError,
8268                      "expected %.200s, %.200s class to have an \"%.200s\" attribute",
8269                      class_type,
8270                      py_class_name,
8271                      identifier);
8272         return -1;
8273       }
8274 
8275       PyErr_Clear();
8276     }
8277     else {
8278       if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) {
8279         Py_DECREF(item);
8280         return -1;
8281       }
8282       Py_DECREF(item);
8283     }
8284   }
8285 
8286   return 0;
8287 }
8288 
bpy_class_validate(PointerRNA * dummyptr,void * py_data,int * have_function)8289 static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_function)
8290 {
8291   return bpy_class_validate_recursive(dummyptr, dummyptr->type, py_data, have_function);
8292 }
8293 
8294 /* TODO - multiple return values like with RNA functions. */
bpy_class_call(bContext * C,PointerRNA * ptr,FunctionRNA * func,ParameterList * parms)8295 static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
8296 {
8297   PyObject *args;
8298   PyObject *ret = NULL, *py_srna = NULL, *py_class_instance = NULL, *parmitem;
8299   PyTypeObject *py_class;
8300   PropertyRNA *parm;
8301   ParameterIterator iter;
8302   PointerRNA funcptr;
8303   int err = 0, i, ret_len = 0, arg_count;
8304   const int flag = RNA_function_flag(func);
8305   const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
8306   const bool is_classmethod = (flag & FUNC_NO_SELF) && (flag & FUNC_USE_SELF_TYPE);
8307 
8308   PropertyRNA *pret_single = NULL;
8309   void *retdata_single = NULL;
8310 
8311   PyGILState_STATE gilstate;
8312 
8313 #ifdef USE_PEDANTIC_WRITE
8314   const bool is_readonly_init = !(RNA_struct_is_a(ptr->type, &RNA_Operator) ||
8315                                   RNA_struct_is_a(ptr->type, &RNA_Gizmo));
8316   // const char *func_id = RNA_function_identifier(func);  /* UNUSED */
8317   /* Testing, for correctness, not operator and not draw function. */
8318   const bool is_readonly = !(RNA_function_flag(func) & FUNC_ALLOW_WRITE);
8319 #endif
8320 
8321   py_class = RNA_struct_py_type_get(ptr->type);
8322   /* Rare case. can happen when registering subclasses. */
8323   if (py_class == NULL) {
8324     CLOG_WARN(BPY_LOG_RNA,
8325               "unable to get Python class for RNA struct '%.200s'",
8326               RNA_struct_identifier(ptr->type));
8327     return -1;
8328   }
8329 
8330   /* XXX, this is needed because render engine calls without a context
8331    * this should be supported at some point, but at the moment it's not! */
8332   if (C == NULL) {
8333     C = BPY_context_get();
8334   }
8335 
8336   /* Annoying! We need to check if the screen gets set to NULL which is a
8337    * hint that the file was actually re-loaded. */
8338   const bool is_valid_wm = (CTX_wm_manager(C) != NULL);
8339 
8340   bpy_context_set(C, &gilstate);
8341 
8342   if (!(is_staticmethod || is_classmethod)) {
8343     /* Some datatypes (operator, render engine) can store PyObjects for re-use. */
8344     if (ptr->data) {
8345       void **instance = RNA_struct_instance(ptr);
8346 
8347       if (instance) {
8348         if (*instance) {
8349           py_class_instance = *instance;
8350           Py_INCREF(py_class_instance);
8351         }
8352       }
8353     }
8354     /* End exception. */
8355 
8356     if (py_class_instance == NULL) {
8357       py_srna = pyrna_struct_CreatePyObject(ptr);
8358     }
8359 
8360     if (py_class_instance) {
8361       /* Special case, instance is cached. */
8362     }
8363     else if (py_srna == NULL) {
8364       py_class_instance = NULL;
8365     }
8366     else if (py_srna == Py_None) { /* Probably wont ever happen, but possible. */
8367       Py_DECREF(py_srna);
8368       py_class_instance = NULL;
8369     }
8370     else {
8371 #if 1
8372       /* Skip the code below and call init directly on the allocated 'py_srna'
8373        * otherwise __init__() always needs to take a second self argument, see pyrna_struct_new().
8374        * Although this is annoying to have to implement a part of Python's
8375        * typeobject.c:type_call().
8376        */
8377       if (py_class->tp_init) {
8378 #  ifdef USE_PEDANTIC_WRITE
8379         const int prev_write = rna_disallow_writes;
8380         rna_disallow_writes = is_readonly_init ? false :
8381                                                  true; /* Only operators can write on __init__. */
8382 #  endif
8383 
8384         /* True in most cases even when the class itself doesn't define an __init__ function. */
8385         args = PyTuple_New(0);
8386         if (py_class->tp_init(py_srna, args, NULL) < 0) {
8387           Py_DECREF(py_srna);
8388           py_srna = NULL;
8389           /* Err set below. */
8390         }
8391         Py_DECREF(args);
8392 #  ifdef USE_PEDANTIC_WRITE
8393         rna_disallow_writes = prev_write;
8394 #  endif
8395       }
8396       py_class_instance = py_srna;
8397 
8398 #else
8399       const int prev_write = rna_disallow_writes;
8400       rna_disallow_writes = true;
8401 
8402       /* 'almost' all the time calling the class isn't needed.
8403        * We could just do... */
8404 #  if 0
8405       py_class_instance = py_srna;
8406       Py_INCREF(py_class_instance);
8407 #  endif
8408       /*
8409        * This would work fine, but means __init__ functions wouldn't run.
8410        * None of Blender's default scripts use __init__ but it's nice to call it
8411        * for general correctness. just to note why this is here when it could be safely removed.
8412        */
8413       args = PyTuple_New(1);
8414       PyTuple_SET_ITEM(args, 0, py_srna);
8415       py_class_instance = PyObject_Call(py_class, args, NULL);
8416       Py_DECREF(args);
8417 
8418       rna_disallow_writes = prev_write;
8419 
8420 #endif
8421 
8422       if (py_class_instance == NULL) {
8423         err = -1; /* So the error is not overridden below. */
8424       }
8425     }
8426   }
8427 
8428   /* Initializing the class worked, now run its invoke function. */
8429   if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) {
8430     PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func));
8431 
8432     if (item) {
8433       RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
8434 
8435       if (is_staticmethod) {
8436         arg_count =
8437             ((PyCodeObject *)PyFunction_GET_CODE(((PyMethodObject *)item)->im_func))->co_argcount -
8438             1;
8439       }
8440       else {
8441         arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
8442       }
8443 #if 0
8444       /* First arg is included in 'item'. */
8445       args = PyTuple_New(rna_function_arg_count(func));
8446 #endif
8447       args = PyTuple_New(arg_count); /* First arg is included in 'item'. */
8448 
8449       if (is_staticmethod) {
8450         i = 0;
8451       }
8452       else if (is_classmethod) {
8453         PyTuple_SET_ITEM(args, 0, (PyObject *)py_class);
8454         i = 1;
8455       }
8456       else {
8457         PyTuple_SET_ITEM(args, 0, py_class_instance);
8458         i = 1;
8459       }
8460 
8461       RNA_parameter_list_begin(parms, &iter);
8462 
8463       /* Parse function parameters. */
8464       for (; iter.valid; RNA_parameter_list_next(&iter)) {
8465         parm = iter.parm;
8466 
8467         /* Only useful for single argument returns, we'll need another list loop for multiple. */
8468         if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
8469           ret_len++;
8470           if (pret_single == NULL) {
8471             pret_single = parm;
8472             retdata_single = iter.data;
8473           }
8474 
8475           continue;
8476         }
8477 
8478         if (i < arg_count) {
8479           parmitem = pyrna_param_to_py(&funcptr, parm, iter.data);
8480           PyTuple_SET_ITEM(args, i, parmitem);
8481           i++;
8482         }
8483       }
8484 
8485 #ifdef USE_PEDANTIC_WRITE
8486       rna_disallow_writes = is_readonly ? true : false;
8487 #endif
8488       /* *** Main Caller *** */
8489 
8490       ret = PyObject_Call(item, args, NULL);
8491 
8492       /* *** Done Calling *** */
8493 
8494 #ifdef USE_PEDANTIC_WRITE
8495       rna_disallow_writes = false;
8496 #endif
8497 
8498       RNA_parameter_list_end(&iter);
8499       Py_DECREF(item);
8500       Py_DECREF(args);
8501     }
8502     else {
8503       PyErr_Print();
8504       PyErr_Clear();
8505       PyErr_Format(PyExc_TypeError,
8506                    "could not find function %.200s in %.200s to execute callback",
8507                    RNA_function_identifier(func),
8508                    RNA_struct_identifier(ptr->type));
8509       err = -1;
8510     }
8511   }
8512   else {
8513     /* The error may be already set if the class instance couldn't be created. */
8514     if (err != -1) {
8515       PyErr_Format(PyExc_RuntimeError,
8516                    "could not create instance of %.200s to call callback function %.200s",
8517                    RNA_struct_identifier(ptr->type),
8518                    RNA_function_identifier(func));
8519       err = -1;
8520     }
8521   }
8522 
8523   if (ret == NULL) { /* Covers py_class_instance failing too. */
8524     err = -1;
8525   }
8526   else {
8527     if (ret_len == 0 && ret != Py_None) {
8528       PyErr_Format(PyExc_RuntimeError,
8529                    "expected class %.200s, function %.200s to return None, not %.200s",
8530                    RNA_struct_identifier(ptr->type),
8531                    RNA_function_identifier(func),
8532                    Py_TYPE(ret)->tp_name);
8533       err = -1;
8534     }
8535     else if (ret_len == 1) {
8536       err = pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, "");
8537 
8538       /* when calling operator funcs only gives Function.result with
8539        * no line number since the func has finished calling on error,
8540        * re-raise the exception with more info since it would be slow to
8541        * create prefix on every call (when there are no errors) */
8542       if (err == -1) {
8543         PyC_Err_Format_Prefix(PyExc_RuntimeError,
8544                               "class %.200s, function %.200s: incompatible return value ",
8545                               RNA_struct_identifier(ptr->type),
8546                               RNA_function_identifier(func));
8547       }
8548     }
8549     else if (ret_len > 1) {
8550 
8551       if (PyTuple_Check(ret) == 0) {
8552         PyErr_Format(
8553             PyExc_RuntimeError,
8554             "expected class %.200s, function %.200s to return a tuple of size %d, not %.200s",
8555             RNA_struct_identifier(ptr->type),
8556             RNA_function_identifier(func),
8557             ret_len,
8558             Py_TYPE(ret)->tp_name);
8559         err = -1;
8560       }
8561       else if (PyTuple_GET_SIZE(ret) != ret_len) {
8562         PyErr_Format(PyExc_RuntimeError,
8563                      "class %.200s, function %.200s to returned %d items, expected %d",
8564                      RNA_struct_identifier(ptr->type),
8565                      RNA_function_identifier(func),
8566                      PyTuple_GET_SIZE(ret),
8567                      ret_len);
8568         err = -1;
8569       }
8570       else {
8571 
8572         RNA_parameter_list_begin(parms, &iter);
8573 
8574         /* Parse function parameters. */
8575         for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) {
8576           parm = iter.parm;
8577 
8578           /* Only useful for single argument returns, we'll need another list loop for multiple. */
8579           if (RNA_parameter_flag(parm) & PARM_OUTPUT) {
8580             err = pyrna_py_to_prop(
8581                 &funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:");
8582             if (err) {
8583               break;
8584             }
8585           }
8586         }
8587 
8588         RNA_parameter_list_end(&iter);
8589       }
8590     }
8591     Py_DECREF(ret);
8592   }
8593 
8594   if (err != 0) {
8595     ReportList *reports;
8596     /* Alert the user, else they wont know unless they see the console. */
8597     if ((!is_staticmethod) && (!is_classmethod) && (ptr->data) &&
8598         (RNA_struct_is_a(ptr->type, &RNA_Operator)) &&
8599         (is_valid_wm == (CTX_wm_manager(C) != NULL))) {
8600       wmOperator *op = ptr->data;
8601       reports = op->reports;
8602     }
8603     else {
8604       /* Wont alert users, but they can view in 'info' space. */
8605       reports = CTX_wm_reports(C);
8606     }
8607 
8608     BPy_errors_to_report(reports);
8609 
8610     /* Also print in the console for Python. */
8611     PyErr_Print();
8612     PyErr_Clear();
8613   }
8614 
8615   bpy_context_clear(C, &gilstate);
8616 
8617   return err;
8618 }
8619 
bpy_class_free(void * pyob_ptr)8620 static void bpy_class_free(void *pyob_ptr)
8621 {
8622   PyObject *self = (PyObject *)pyob_ptr;
8623   PyGILState_STATE gilstate;
8624 
8625   gilstate = PyGILState_Ensure();
8626 
8627   /* Breaks re-registering classes. */
8628   // PyDict_Clear(((PyTypeObject *)self)->tp_dict);
8629 
8630   /* Remove the RNA attribute instead. */
8631   PyDict_DelItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna);
8632   if (PyErr_Occurred()) {
8633     PyErr_Clear();
8634   }
8635 
8636 #if 0 /* Needs further investigation, too annoying so quiet for now. */
8637   if (G.debug & G_DEBUG_PYTHON) {
8638     if (self->ob_refcnt > 1) {
8639       PyC_ObSpit("zombie class - reference should be 1", self);
8640     }
8641   }
8642 #endif
8643   Py_DECREF((PyObject *)pyob_ptr);
8644 
8645   PyGILState_Release(gilstate);
8646 }
8647 
8648 /**
8649  * \note This isn't essential to run on startup, since subtypes will lazy initialize.
8650  * But keep running in debug mode so we get immediate notification of bad class hierarchy
8651  * or any errors in "bpy_types.py" at load time, so errors don't go unnoticed.
8652  */
pyrna_alloc_types(void)8653 void pyrna_alloc_types(void)
8654 {
8655 #ifdef DEBUG
8656   PyGILState_STATE gilstate;
8657 
8658   PointerRNA ptr;
8659   PropertyRNA *prop;
8660 
8661   gilstate = PyGILState_Ensure();
8662 
8663   /* Avoid doing this lookup for every getattr. */
8664   RNA_blender_rna_pointer_create(&ptr);
8665   prop = RNA_struct_find_property(&ptr, "structs");
8666 
8667   RNA_PROP_BEGIN (&ptr, itemptr, prop) {
8668     PyObject *item = pyrna_struct_Subtype(&itemptr);
8669     if (item == NULL) {
8670       if (PyErr_Occurred()) {
8671         PyErr_Print();
8672         PyErr_Clear();
8673       }
8674     }
8675     else {
8676       Py_DECREF(item);
8677     }
8678   }
8679   RNA_PROP_END;
8680 
8681   PyGILState_Release(gilstate);
8682 #endif /* DEBUG */
8683 }
8684 
pyrna_free_types(void)8685 void pyrna_free_types(void)
8686 {
8687   PointerRNA ptr;
8688   PropertyRNA *prop;
8689 
8690   /* Avoid doing this lookup for every getattr. */
8691   RNA_blender_rna_pointer_create(&ptr);
8692   prop = RNA_struct_find_property(&ptr, "structs");
8693 
8694   RNA_PROP_BEGIN (&ptr, itemptr, prop) {
8695     StructRNA *srna = srna_from_ptr(&itemptr);
8696     void *py_ptr = RNA_struct_py_type_get(srna);
8697 
8698     if (py_ptr) {
8699 #if 0 /* XXX - should be able to do this, but makes Python crash on exit. */
8700       bpy_class_free(py_ptr);
8701 #endif
8702       RNA_struct_py_type_set(srna, NULL);
8703     }
8704   }
8705   RNA_PROP_END;
8706 }
8707 
8708 /* Note! MemLeak XXX
8709  *
8710  * There is currently a bug where moving the registration of a Python class does
8711  * not properly manage reference-counts from the Python class. As the srna owns
8712  * the Python class this should not be so tricky, but changing the references as
8713  * you'd expect when changing ownership crashes blender on exit so I had to comment out
8714  * the decref. This is not so bad because the leak only happens when re-registering (hold F8)
8715  * - Should still be fixed - Campbell
8716  * */
8717 PyDoc_STRVAR(pyrna_register_class_doc,
8718              ".. method:: register_class(cls)\n"
8719              "\n"
8720              "   Register a subclass of a Blender type class.\n"
8721              "\n"
8722              "   :arg cls: Blender type class in:\n"
8723              "      :class:`bpy.types.Panel`, :class:`bpy.types.UIList`,\n"
8724              "      :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n"
8725              "      :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n"
8726              "      :class:`bpy.types.RenderEngine`\n"
8727              "   :type cls: class\n"
8728              "   :raises ValueError:\n"
8729              "      if the class is not a subclass of a registerable blender class.\n"
8730              "\n"
8731              "   .. note::\n"
8732              "\n"
8733              "      If the class has a *register* class method it will be called\n"
8734              "      before registration.\n");
8735 PyMethodDef meth_bpy_register_class = {
8736     "register_class", pyrna_register_class, METH_O, pyrna_register_class_doc};
pyrna_register_class(PyObject * UNUSED (self),PyObject * py_class)8737 static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class)
8738 {
8739   bContext *C = NULL;
8740   ReportList reports;
8741   StructRegisterFunc reg;
8742   StructRNA *srna;
8743   StructRNA *srna_new;
8744   const char *identifier;
8745   PyObject *py_cls_meth;
8746   const char *error_prefix = "register_class(...):";
8747 
8748   if (!PyType_Check(py_class)) {
8749     PyErr_Format(PyExc_ValueError,
8750                  "register_class(...): "
8751                  "expected a class argument, not '%.200s'",
8752                  Py_TYPE(py_class)->tp_name);
8753     return NULL;
8754   }
8755 
8756   if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna)) {
8757     PyErr_Format(PyExc_ValueError,
8758                  "register_class(...): "
8759                  "already registered as a subclass '%.200s'",
8760                  ((PyTypeObject *)py_class)->tp_name);
8761     return NULL;
8762   }
8763 
8764   if (!pyrna_write_check()) {
8765     PyErr_Format(PyExc_RuntimeError,
8766                  "register_class(...): "
8767                  "can't run in readonly state '%.200s'",
8768                  ((PyTypeObject *)py_class)->tp_name);
8769     return NULL;
8770   }
8771 
8772   /* Warning: gets parent classes srna, only for the register function. */
8773   srna = pyrna_struct_as_srna(py_class, true, "register_class(...):");
8774   if (srna == NULL) {
8775     return NULL;
8776   }
8777 
8778   /* Fails in some cases, so can't use this check, but would like to :| */
8779 #if 0
8780   if (RNA_struct_py_type_get(srna)) {
8781     PyErr_Format(PyExc_ValueError,
8782                  "register_class(...): %.200s's parent class %.200s is already registered, this "
8783                  "is not allowed",
8784                  ((PyTypeObject *)py_class)->tp_name,
8785                  RNA_struct_identifier(srna));
8786     return NULL;
8787   }
8788 #endif
8789 
8790   /* Check that we have a register callback for this type. */
8791   reg = RNA_struct_register(srna);
8792 
8793   if (!reg) {
8794     PyErr_Format(PyExc_ValueError,
8795                  "register_class(...): expected a subclass of a registerable "
8796                  "RNA type (%.200s does not support registration)",
8797                  RNA_struct_identifier(srna));
8798     return NULL;
8799   }
8800 
8801   /* Get the context, so register callback can do necessary refreshes. */
8802   C = BPY_context_get();
8803 
8804   /* Call the register callback with reports & identifier. */
8805   BKE_reports_init(&reports, RPT_STORE);
8806 
8807   identifier = ((PyTypeObject *)py_class)->tp_name;
8808 
8809   srna_new = reg(CTX_data_main(C),
8810                  &reports,
8811                  py_class,
8812                  identifier,
8813                  bpy_class_validate,
8814                  bpy_class_call,
8815                  bpy_class_free);
8816 
8817   if (!BLI_listbase_is_empty(&reports.list)) {
8818     const bool has_error = BPy_reports_to_error(&reports, PyExc_RuntimeError, false);
8819     if (!has_error) {
8820       BPy_reports_write_stdout(&reports, error_prefix);
8821     }
8822     BKE_reports_clear(&reports);
8823     if (has_error) {
8824       return NULL;
8825     }
8826   }
8827 
8828   /* Python errors validating are not converted into reports so the check above will fail.
8829    * the cause for returning NULL will be printed as an error */
8830   if (srna_new == NULL) {
8831     return NULL;
8832   }
8833 
8834   /* Takes a reference to 'py_class'. */
8835   pyrna_subtype_set_rna(py_class, srna_new);
8836 
8837   /* Old srna still references us, keep the check in case registering somehow can free it. */
8838   if (RNA_struct_py_type_get(srna)) {
8839     RNA_struct_py_type_set(srna, NULL);
8840 #if 0
8841     /* Should be able to do this XXX since the old RNA adds a new ref. */
8842     Py_DECREF(py_class);
8843 #endif
8844   }
8845 
8846   /* Can't use this because it returns a dict proxy
8847    *
8848    * item = PyObject_GetAttrString(py_class, "__dict__");
8849    */
8850   if (pyrna_deferred_register_class(srna_new, (PyTypeObject *)py_class) != 0) {
8851     return NULL;
8852   }
8853 
8854   /* Call classed register method.
8855    * Note that zero falls through, no attribute, no error. */
8856   switch (_PyObject_LookupAttr(py_class, bpy_intern_str_register, &py_cls_meth)) {
8857     case 1: {
8858       PyObject *ret = PyObject_CallObject(py_cls_meth, NULL);
8859       Py_DECREF(py_cls_meth);
8860       if (ret) {
8861         Py_DECREF(ret);
8862       }
8863       else {
8864         return NULL;
8865       }
8866       break;
8867     }
8868     case -1: {
8869       return NULL;
8870     }
8871   }
8872 
8873   Py_RETURN_NONE;
8874 }
8875 
pyrna_srna_contains_pointer_prop_srna(StructRNA * srna_props,StructRNA * srna,const char ** r_prop_identifier)8876 static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props,
8877                                                  StructRNA *srna,
8878                                                  const char **r_prop_identifier)
8879 {
8880   PropertyRNA *prop;
8881   LinkData *link;
8882 
8883   /* Verify properties. */
8884   const ListBase *lb = RNA_struct_type_properties(srna);
8885 
8886   for (link = lb->first; link; link = link->next) {
8887     prop = (PropertyRNA *)link;
8888     if (RNA_property_type(prop) == PROP_POINTER && !RNA_property_builtin(prop)) {
8889       PointerRNA tptr;
8890       RNA_pointer_create(NULL, &RNA_Struct, srna_props, &tptr);
8891 
8892       if (RNA_property_pointer_type(&tptr, prop) == srna) {
8893         *r_prop_identifier = RNA_property_identifier(prop);
8894         return 1;
8895       }
8896     }
8897   }
8898 
8899   return 0;
8900 }
8901 
8902 PyDoc_STRVAR(pyrna_unregister_class_doc,
8903              ".. method:: unregister_class(cls)\n"
8904              "\n"
8905              "   Unload the Python class from blender.\n"
8906              "\n"
8907              "   If the class has an *unregister* class method it will be called\n"
8908              "   before unregistering.\n");
8909 PyMethodDef meth_bpy_unregister_class = {
8910     "unregister_class",
8911     pyrna_unregister_class,
8912     METH_O,
8913     pyrna_unregister_class_doc,
8914 };
pyrna_unregister_class(PyObject * UNUSED (self),PyObject * py_class)8915 static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_class)
8916 {
8917   bContext *C = NULL;
8918   StructUnregisterFunc unreg;
8919   StructRNA *srna;
8920   PyObject *py_cls_meth;
8921 
8922   if (!PyType_Check(py_class)) {
8923     PyErr_Format(PyExc_ValueError,
8924                  "register_class(...): "
8925                  "expected a class argument, not '%.200s'",
8926                  Py_TYPE(py_class)->tp_name);
8927     return NULL;
8928   }
8929 
8930 #if 0
8931   if (PyDict_GetItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna) == NULL) {
8932     PWM_cursor_wait(0);
8933     PyErr_SetString(PyExc_ValueError, "unregister_class(): not a registered as a subclass");
8934     return NULL;
8935   }
8936 #endif
8937 
8938   if (!pyrna_write_check()) {
8939     PyErr_Format(PyExc_RuntimeError,
8940                  "unregister_class(...): "
8941                  "can't run in readonly state '%.200s'",
8942                  ((PyTypeObject *)py_class)->tp_name);
8943     return NULL;
8944   }
8945 
8946   srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):");
8947   if (srna == NULL) {
8948     return NULL;
8949   }
8950 
8951   /* Check that we have a unregister callback for this type. */
8952   unreg = RNA_struct_unregister(srna);
8953 
8954   if (!unreg) {
8955     PyErr_SetString(
8956         PyExc_ValueError,
8957         "unregister_class(...): "
8958         "expected a Type subclassed from a registerable RNA type (no unregister supported)");
8959     return NULL;
8960   }
8961 
8962   /* Call classed unregister method.
8963    * Note that zero falls through, no attribute, no error. */
8964   switch (_PyObject_LookupAttr(py_class, bpy_intern_str_unregister, &py_cls_meth)) {
8965     case 1: {
8966       PyObject *ret = PyObject_CallObject(py_cls_meth, NULL);
8967       Py_DECREF(py_cls_meth);
8968       if (ret) {
8969         Py_DECREF(ret);
8970       }
8971       else {
8972         return NULL;
8973       }
8974       break;
8975     }
8976     case -1: {
8977       return NULL;
8978     }
8979   }
8980 
8981   /* Should happen all the time, however it's very slow. */
8982   if (G.debug & G_DEBUG_PYTHON) {
8983     /* Remove all properties using this class. */
8984     StructRNA *srna_iter;
8985     PointerRNA ptr_rna;
8986     PropertyRNA *prop_rna;
8987     const char *prop_identifier = NULL;
8988 
8989     RNA_blender_rna_pointer_create(&ptr_rna);
8990     prop_rna = RNA_struct_find_property(&ptr_rna, "structs");
8991 
8992     /* Loop over all structs. */
8993     RNA_PROP_BEGIN (&ptr_rna, itemptr, prop_rna) {
8994       srna_iter = itemptr.data;
8995       if (pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) {
8996         break;
8997       }
8998     }
8999     RNA_PROP_END;
9000 
9001     if (prop_identifier) {
9002       PyErr_Format(PyExc_RuntimeError,
9003                    "unregister_class(...): can't unregister %s because %s.%s pointer property is "
9004                    "using this",
9005                    RNA_struct_identifier(srna),
9006                    RNA_struct_identifier(srna_iter),
9007                    prop_identifier);
9008       return NULL;
9009     }
9010   }
9011 
9012   /* Get the context, so register callback can do necessary refreshes. */
9013   C = BPY_context_get();
9014 
9015   /* Call unregister. */
9016   unreg(CTX_data_main(C), srna); /* Calls bpy_class_free, this decref's py_class. */
9017 
9018   PyDict_DelItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna);
9019   if (PyErr_Occurred()) {
9020     PyErr_Clear();  // return NULL;
9021   }
9022 
9023   Py_RETURN_NONE;
9024 }
9025 
9026 /**
9027  * Extend RNA types with C/API methods, properties.
9028  */
pyrna_struct_type_extend_capi(struct StructRNA * srna,struct PyMethodDef * method,struct PyGetSetDef * getset)9029 void pyrna_struct_type_extend_capi(struct StructRNA *srna,
9030                                    struct PyMethodDef *method,
9031                                    struct PyGetSetDef *getset)
9032 {
9033   /* See 'add_methods' in Python's 'typeobject.c'. */
9034   PyTypeObject *type = (PyTypeObject *)pyrna_srna_Subtype(srna);
9035   PyObject *dict = type->tp_dict;
9036   if (method != NULL) {
9037     for (; method->ml_name != NULL; method++) {
9038       PyObject *py_method;
9039 
9040       if (method->ml_flags & METH_CLASS) {
9041         PyObject *cfunc = PyCFunction_New(method, (PyObject *)type);
9042         py_method = PyClassMethod_New(cfunc);
9043         Py_DECREF(cfunc);
9044       }
9045       else if (method->ml_flags & METH_STATIC) {
9046         py_method = PyCFunction_New(method, NULL);
9047       }
9048       else {
9049         py_method = PyDescr_NewMethod(type, method);
9050       }
9051 
9052       const int err = PyDict_SetItemString(dict, method->ml_name, py_method);
9053       Py_DECREF(py_method);
9054       BLI_assert(!(err < 0));
9055       UNUSED_VARS_NDEBUG(err);
9056     }
9057   }
9058 
9059   if (getset != NULL) {
9060     for (; getset->name != NULL; getset++) {
9061       PyObject *descr = PyDescr_NewGetSet(type, getset);
9062       /* Ensure we're not overwriting anything that already exists. */
9063       BLI_assert(PyDict_GetItem(dict, PyDescr_NAME(descr)) == NULL);
9064       PyDict_SetItem(dict, PyDescr_NAME(descr), descr);
9065       Py_DECREF(descr);
9066     }
9067   }
9068   Py_DECREF(type);
9069 }
9070 
9071 /* Access to 'owner_id' internal global. */
9072 
pyrna_bl_owner_id_get(PyObject * UNUSED (self))9073 static PyObject *pyrna_bl_owner_id_get(PyObject *UNUSED(self))
9074 {
9075   const char *name = RNA_struct_state_owner_get();
9076   if (name) {
9077     return PyUnicode_FromString(name);
9078   }
9079   Py_RETURN_NONE;
9080 }
9081 
pyrna_bl_owner_id_set(PyObject * UNUSED (self),PyObject * value)9082 static PyObject *pyrna_bl_owner_id_set(PyObject *UNUSED(self), PyObject *value)
9083 {
9084   const char *name;
9085   if (value == Py_None) {
9086     name = NULL;
9087   }
9088   else if (PyUnicode_Check(value)) {
9089     name = _PyUnicode_AsString(value);
9090   }
9091   else {
9092     PyErr_Format(PyExc_ValueError,
9093                  "owner_set(...): "
9094                  "expected None or a string, not '%.200s'",
9095                  Py_TYPE(value)->tp_name);
9096     return NULL;
9097   }
9098   RNA_struct_state_owner_set(name);
9099   Py_RETURN_NONE;
9100 }
9101 
9102 PyMethodDef meth_bpy_owner_id_get = {
9103     "_bl_owner_id_get",
9104     (PyCFunction)pyrna_bl_owner_id_get,
9105     METH_NOARGS,
9106     NULL,
9107 };
9108 PyMethodDef meth_bpy_owner_id_set = {
9109     "_bl_owner_id_set",
9110     (PyCFunction)pyrna_bl_owner_id_set,
9111     METH_O,
9112     NULL,
9113 };
9114