Cleanup: extra semicolon, comma warnings
[blender.git] / source / blender / python / intern / bpy_rna.c
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 <stddef.h>
30 #include <float.h> /* FLT_MIN/MAX */
31
32 #include "RNA_types.h"
33
34 #include "BLI_bitmap.h"
35 #include "BLI_dynstr.h"
36 #include "BLI_string.h"
37 #include "BLI_listbase.h"
38 #include "BLI_math_rotation.h"
39 #include "BLI_utildefines.h"
40
41 #include "BPY_extern.h"
42 #include "BPY_extern_clog.h"
43
44 #include "bpy_rna.h"
45 #include "bpy_rna_anim.h"
46 #include "bpy_props.h"
47 #include "bpy_capi_utils.h"
48 #include "bpy_rna_callback.h"
49 #include "bpy_intern_string.h"
50
51 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
52 #  include "BLI_ghash.h"
53 #endif
54
55 #include "RNA_enum_types.h"
56 #include "RNA_define.h" /* RNA_def_property_free_identifier */
57 #include "RNA_access.h"
58
59 #include "CLG_log.h"
60
61 #include "MEM_guardedalloc.h"
62
63 #include "BKE_main.h"
64 #include "BKE_idcode.h"
65 #include "BKE_context.h"
66 #include "BKE_global.h" /* evil G.* */
67 #include "BKE_report.h"
68 #include "BKE_idprop.h"
69
70 /* Only for types. */
71 #include "BKE_node.h"
72
73 #include "../generic/idprop_py_api.h" /* For IDprop lookups. */
74 #include "../generic/py_capi_utils.h"
75 #include "../generic/python_utildefines.h"
76
77 #define USE_PEDANTIC_WRITE
78 #define USE_MATHUTILS
79 #define USE_STRING_COERCE
80
81 BPy_StructRNA *bpy_context_module = NULL; /* for fast access */
82
83 static PyObject *pyrna_struct_Subtype(PointerRNA *ptr);
84 static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
85
86 #define BPY_DOC_ID_PROP_TYPE_NOTE \
87   "   .. note::\n" \
88   "\n" \
89   "      Only the :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \
90   "      :class:`bpy.types.PoseBone` classes support custom properties.\n"
91
92 int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
93 {
94   if (pysrna->ptr.type) {
95     return 0;
96   }
97   PyErr_Format(
98       PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name);
99   return -1;
100 }
101
102 int pyrna_prop_validity_check(BPy_PropertyRNA *self)
103 {
104   if (self->ptr.type) {
105     return 0;
106   }
107   PyErr_Format(PyExc_ReferenceError,
108                "PropertyRNA of type %.200s.%.200s has been removed",
109                Py_TYPE(self)->tp_name,
110                RNA_property_identifier(self->prop));
111   return -1;
112 }
113
114 void pyrna_invalidate(BPy_DummyPointerRNA *self)
115 {
116   RNA_POINTER_INVALIDATE(&self->ptr);
117 }
118
119 #ifdef USE_PYRNA_INVALIDATE_GC
120 #  define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1))
121
122 /* Only for sizeof(). */
123 struct gc_generation {
124   PyGC_Head head;
125   int threshold;
126   int count;
127 } gc_generation;
128
129 static void id_release_gc(struct ID *id)
130 {
131   unsigned int j;
132   // unsigned int i = 0;
133   for (j = 0; j < 3; j++) {
134     /* Hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed. */
135     PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
136     PyGC_Head *g = gen->gc.gc_next;
137     while ((g = g->gc.gc_next) != gen) {
138       PyObject *ob = FROM_GC(g);
139       if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) ||
140           PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
141         BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob;
142         if (ob_ptr->ptr.owner_id == id) {
143           pyrna_invalidate(ob_ptr);
144           // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
145           // i++;
146         }
147       }
148     }
149   }
150   // printf("id_release_gc freed '%s': %d\n", id->name, i);
151 }
152 #endif
153
154 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
155 //#define DEBUG_RNA_WEAKREF
156
157 struct GHash *id_weakref_pool = NULL;
158 static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref);
159 static PyMethodDef id_free_weakref_cb_def = {
160     "id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL};
161
162 /* Adds a reference to the list, remember to decref. */
163 static GHash *id_weakref_pool_get(ID *id)
164 {
165   GHash *weakinfo_hash = NULL;
166
167   if (id_weakref_pool) {
168     weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
169   }
170   else {
171     /* First time, allocate pool. */
172     id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool");
173     weakinfo_hash = NULL;
174   }
175
176   if (weakinfo_hash == NULL) {
177     /* We use a ghash as a set, we could use libHX's HXMAP_SINGULAR, but would be an extra dep. */
178     weakinfo_hash = BLI_ghash_ptr_new("rna_id");
179     BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash);
180   }
181
182   return weakinfo_hash;
183 }
184
185 /* Called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject(). */
186 static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna)
187 {
188   PyObject *weakref;
189   PyObject *weakref_capsule;
190   PyObject *weakref_cb_py;
191
192   /* Create a new function instance and insert the list as 'self'
193    * so we can remove ourself from it. */
194   GHash *weakinfo_hash = id_weakref_pool_get(id); /* New or existing. */
195
196   weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL);
197   weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule);
198   Py_DECREF(weakref_capsule);
199
200   /* Add weakref to weakinfo_hash list. */
201   weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py);
202
203   Py_DECREF(weakref_cb_py); /* Function owned by the weakref now. */
204
205   /* Important to add at the end of the hash, since first removal looks at the end. */
206
207   /* Using a hash table as a set, all 'id's are the same. */
208   BLI_ghash_insert(weakinfo_hash, weakref, id);
209   /* weakinfo_hash owns the weakref */
210 }
211
212 /* Workaround to get the last id without a lookup. */
213 static ID *_id_tmp_ptr;
214 static void value_id_set(void *id)
215 {
216   _id_tmp_ptr = (ID *)id;
217 }
218
219 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash);
220 static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref)
221 {
222   /* Important to search backwards. */
223   GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL);
224
225   if (BLI_ghash_len(weakinfo_hash) > 1) {
226     BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL);
227   }
228   else { /* Get the last id and free it. */
229     BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set);
230     id_release_weakref_list(_id_tmp_ptr, weakinfo_hash);
231   }
232
233   Py_DECREF(weakref);
234
235   Py_RETURN_NONE;
236 }
237
238 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
239 {
240   GHashIterator weakinfo_hash_iter;
241
242   BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
243
244 #  ifdef DEBUG_RNA_WEAKREF
245   fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_len(weakinfo_hash));
246 #  endif
247
248   while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) {
249     PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
250     PyObject *item = PyWeakref_GET_OBJECT(weakref);
251     if (item != Py_None) {
252
253 #  ifdef DEBUG_RNA_WEAKREF
254       PyC_ObSpit("id_release_weakref item ", item);
255 #  endif
256
257       pyrna_invalidate((BPy_DummyPointerRNA *)item);
258     }
259
260     Py_DECREF(weakref);
261
262     BLI_ghashIterator_step(&weakinfo_hash_iter);
263   }
264
265   BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
266   BLI_ghash_free(weakinfo_hash, NULL, NULL);
267
268   if (BLI_ghash_len(id_weakref_pool) == 0) {
269     BLI_ghash_free(id_weakref_pool, NULL, NULL);
270     id_weakref_pool = NULL;
271 #  ifdef DEBUG_RNA_WEAKREF
272     printf("id_release_weakref freeing pool\n");
273 #  endif
274   }
275 }
276
277 static void id_release_weakref(struct ID *id)
278 {
279   GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
280   if (weakinfo_hash) {
281     id_release_weakref_list(id, weakinfo_hash);
282   }
283 }
284
285 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
286
287 void BPY_id_release(struct ID *id)
288 {
289 #ifdef USE_PYRNA_INVALIDATE_GC
290   id_release_gc(id);
291 #endif
292
293 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
294   if (id_weakref_pool) {
295     PyGILState_STATE gilstate = PyGILState_Ensure();
296
297     id_release_weakref(id);
298
299     PyGILState_Release(gilstate);
300   }
301 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
302
303   (void)id;
304 }
305
306 #ifdef USE_PEDANTIC_WRITE
307 static bool rna_disallow_writes = false;
308
309 static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
310 {
311   ID *id = ptr->owner_id;
312   if (id) {
313     const short idcode = GS(id->name);
314     /* May need more ID types added here. */
315     if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
316       const char *idtype = BKE_idcode_to_name(idcode);
317       const char *pyname;
318       if (key && PyUnicode_Check(key)) {
319         pyname = _PyUnicode_AsString(key);
320       }
321       else {
322         pyname = "<UNKNOWN>";
323       }
324
325       /* Make a nice string error. */
326       BLI_assert(idtype != NULL);
327       PyErr_Format(PyExc_AttributeError,
328                    "Writing to ID classes in this context is not allowed: "
329                    "%.200s, %.200s datablock, error setting %.200s.%.200s",
330                    id->name + 2,
331                    idtype,
332                    RNA_struct_identifier(ptr->type),
333                    pyname);
334
335       return true;
336     }
337   }
338   return false;
339 }
340 #endif /* USE_PEDANTIC_WRITE */
341
342 #ifdef USE_PEDANTIC_WRITE
343 bool pyrna_write_check(void)
344 {
345   return !rna_disallow_writes;
346 }
347
348 void pyrna_write_set(bool val)
349 {
350   rna_disallow_writes = !val;
351 }
352 #else  /* USE_PEDANTIC_WRITE */
353 bool pyrna_write_check(void)
354 {
355   return true;
356 }
357 void pyrna_write_set(bool UNUSED(val))
358 {
359   /* pass */
360 }
361 #endif /* USE_PEDANTIC_WRITE */
362
363 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
364 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
365 static int pyrna_py_to_prop(
366     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
367 static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
368
369 #ifdef USE_MATHUTILS
370 #  include "../mathutils/mathutils.h" /* So we can have mathutils callbacks. */
371
372 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self,
373                                                   PointerRNA *ptr,
374                                                   PropertyRNA *prop,
375                                                   Py_ssize_t start,
376                                                   Py_ssize_t stop,
377                                                   Py_ssize_t length);
378 static short pyrna_rotation_euler_order_get(PointerRNA *ptr,
379                                             const short order_fallback,
380                                             PropertyRNA **r_prop_eul_order);
381
382 /* bpyrna vector/euler/quat callbacks. */
383 static unsigned char mathutils_rna_array_cb_index = -1; /* Index for our callbacks. */
384
385 /* Subtype not used much yet. */
386 #  define MATHUTILS_CB_SUBTYPE_EUL 0
387 #  define MATHUTILS_CB_SUBTYPE_VEC 1
388 #  define MATHUTILS_CB_SUBTYPE_QUAT 2
389 #  define MATHUTILS_CB_SUBTYPE_COLOR 3
390
391 static int mathutils_rna_generic_check(BaseMathObject *bmo)
392 {
393   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
394
395   PYRNA_PROP_CHECK_INT(self);
396
397   return self->prop ? 0 : -1;
398 }
399
400 static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
401 {
402   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
403
404   PYRNA_PROP_CHECK_INT(self);
405
406   if (self->prop == NULL) {
407     return -1;
408   }
409
410   RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
411
412   /* Euler order exception. */
413   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
414     EulerObject *eul = (EulerObject *)bmo;
415     PropertyRNA *prop_eul_order = NULL;
416     eul->order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
417   }
418
419   return 0;
420 }
421
422 static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
423 {
424   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
425   float min, max;
426
427   PYRNA_PROP_CHECK_INT(self);
428
429   if (self->prop == NULL) {
430     return -1;
431   }
432
433 #  ifdef USE_PEDANTIC_WRITE
434   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
435     return -1;
436   }
437 #  endif /* USE_PEDANTIC_WRITE */
438
439   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
440     PyErr_Format(PyExc_AttributeError,
441                  "bpy_prop \"%.200s.%.200s\" is read-only",
442                  RNA_struct_identifier(self->ptr.type),
443                  RNA_property_identifier(self->prop));
444     return -1;
445   }
446
447   RNA_property_float_range(&self->ptr, self->prop, &min, &max);
448
449   if (min != -FLT_MAX || max != FLT_MAX) {
450     int i, len = RNA_property_array_length(&self->ptr, self->prop);
451     for (i = 0; i < len; i++) {
452       CLAMP(bmo->data[i], min, max);
453     }
454   }
455
456   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
457   if (RNA_property_update_check(self->prop)) {
458     RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
459   }
460
461   /* Euler order exception. */
462   if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
463     EulerObject *eul = (EulerObject *)bmo;
464     PropertyRNA *prop_eul_order = NULL;
465     short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
466     if (order != eul->order) {
467       RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
468       if (RNA_property_update_check(prop_eul_order)) {
469         RNA_property_update(BPy_GetContext(), &self->ptr, prop_eul_order);
470       }
471     }
472   }
473   return 0;
474 }
475
476 static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
477 {
478   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
479
480   PYRNA_PROP_CHECK_INT(self);
481
482   if (self->prop == NULL) {
483     return -1;
484   }
485
486   bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index);
487   return 0;
488 }
489
490 static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
491 {
492   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
493
494   PYRNA_PROP_CHECK_INT(self);
495
496   if (self->prop == NULL) {
497     return -1;
498   }
499
500 #  ifdef USE_PEDANTIC_WRITE
501   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
502     return -1;
503   }
504 #  endif /* USE_PEDANTIC_WRITE */
505
506   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
507     PyErr_Format(PyExc_AttributeError,
508                  "bpy_prop \"%.200s.%.200s\" is read-only",
509                  RNA_struct_identifier(self->ptr.type),
510                  RNA_property_identifier(self->prop));
511     return -1;
512   }
513
514   RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
515   RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]);
516
517   if (RNA_property_update_check(self->prop)) {
518     RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
519   }
520
521   return 0;
522 }
523
524 static Mathutils_Callback mathutils_rna_array_cb = {
525     (BaseMathCheckFunc)mathutils_rna_generic_check,
526     (BaseMathGetFunc)mathutils_rna_vector_get,
527     (BaseMathSetFunc)mathutils_rna_vector_set,
528     (BaseMathGetIndexFunc)mathutils_rna_vector_get_index,
529     (BaseMathSetIndexFunc)mathutils_rna_vector_set_index,
530 };
531
532 /* bpyrna matrix callbacks */
533 static unsigned char mathutils_rna_matrix_cb_index = -1; /* Index for our callbacks. */
534
535 static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype))
536 {
537   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
538
539   PYRNA_PROP_CHECK_INT(self);
540
541   if (self->prop == NULL) {
542     return -1;
543   }
544
545   RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
546   return 0;
547 }
548
549 static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
550 {
551   BPy_PropertyRNA *self = (BPy_PropertyRNA *)bmo->cb_user;
552
553   PYRNA_PROP_CHECK_INT(self);
554
555   if (self->prop == NULL) {
556     return -1;
557   }
558
559 #  ifdef USE_PEDANTIC_WRITE
560   if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
561     return -1;
562   }
563 #  endif /* USE_PEDANTIC_WRITE */
564
565   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
566     PyErr_Format(PyExc_AttributeError,
567                  "bpy_prop \"%.200s.%.200s\" is read-only",
568                  RNA_struct_identifier(self->ptr.type),
569                  RNA_property_identifier(self->prop));
570     return -1;
571   }
572
573   /* Can ignore clamping here. */
574   RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
575
576   if (RNA_property_update_check(self->prop)) {
577     RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
578   }
579   return 0;
580 }
581
582 static Mathutils_Callback mathutils_rna_matrix_cb = {
583     mathutils_rna_generic_check,
584     mathutils_rna_matrix_get,
585     mathutils_rna_matrix_set,
586     NULL,
587     NULL,
588 };
589
590 static short pyrna_rotation_euler_order_get(PointerRNA *ptr,
591                                             const short order_fallback,
592                                             PropertyRNA **r_prop_eul_order)
593 {
594   /* Attempt to get order. */
595   if (*r_prop_eul_order == NULL) {
596     *r_prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode");
597   }
598
599   if (*r_prop_eul_order) {
600     short order = RNA_property_enum_get(ptr, *r_prop_eul_order);
601     /* Could be quat or axisangle. */
602     if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) {
603       return order;
604     }
605   }
606
607   return order_fallback;
608 }
609
610 #endif /* USE_MATHUTILS */
611
612 /**
613  * Note that #PROP_NONE is included as a vector subtype. this is because it is handy to
614  * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4.
615  */
616 #define PROP_ALL_VECTOR_SUBTYPES \
617   PROP_COORDS: \
618   case PROP_TRANSLATION: \
619   case PROP_DIRECTION: \
620   case PROP_VELOCITY: \
621   case PROP_ACCELERATION: \
622   case PROP_XYZ: \
623   case PROP_XYZ_LENGTH
624
625 PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
626 {
627   PyObject *ret = NULL;
628
629 #ifdef USE_MATHUTILS
630   int subtype, totdim;
631   int len;
632   const int flag = RNA_property_flag(prop);
633   const int type = RNA_property_type(prop);
634   const bool is_thick = (flag & PROP_THICK_WRAP) != 0;
635
636   /* disallow dynamic sized arrays to be wrapped since the size could change
637    * to a size mathutils does not support */
638   if (flag & PROP_DYNAMIC) {
639     return NULL;
640   }
641
642   len = RNA_property_array_length(ptr, prop);
643   if (type == PROP_FLOAT) {
644     /* pass */
645   }
646   else if (type == PROP_INT) {
647     if (is_thick) {
648       goto thick_wrap_slice;
649     }
650     else {
651       return NULL;
652     }
653   }
654   else {
655     return NULL;
656   }
657
658   subtype = RNA_property_subtype(prop);
659   totdim = RNA_property_array_dimension(ptr, prop, NULL);
660
661   if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
662     if (!is_thick) {
663       /* Owned by the mathutils PyObject. */
664       ret = pyrna_prop_CreatePyObject(ptr, prop);
665     }
666
667     switch (subtype) {
668       case PROP_ALL_VECTOR_SUBTYPES:
669         if (len >= 2 && len <= 4) {
670           if (is_thick) {
671             ret = Vector_CreatePyObject(NULL, len, NULL);
672             RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
673           }
674           else {
675             PyObject *vec_cb = Vector_CreatePyObject_cb(
676                 ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC);
677             Py_DECREF(ret); /* The vector owns 'ret' now. */
678             ret = vec_cb;   /* Return the vector instead. */
679           }
680         }
681         break;
682       case PROP_MATRIX:
683         if (len == 16) {
684           if (is_thick) {
685             ret = Matrix_CreatePyObject(NULL, 4, 4, NULL);
686             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
687           }
688           else {
689             PyObject *mat_cb = Matrix_CreatePyObject_cb(
690                 ret, 4, 4, mathutils_rna_matrix_cb_index, 0);
691             Py_DECREF(ret); /* The matrix owns 'ret' now. */
692             ret = mat_cb;   /* Return the matrix instead. */
693           }
694         }
695         else if (len == 9) {
696           if (is_thick) {
697             ret = Matrix_CreatePyObject(NULL, 3, 3, NULL);
698             RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
699           }
700           else {
701             PyObject *mat_cb = Matrix_CreatePyObject_cb(
702                 ret, 3, 3, mathutils_rna_matrix_cb_index, 0);
703             Py_DECREF(ret); /* The matrix owns 'ret' now. */
704             ret = mat_cb;   /* Return the matrix instead. */
705           }
706         }
707         break;
708       case PROP_EULER:
709       case PROP_QUATERNION:
710         if (len == 3) { /* Euler. */
711           if (is_thick) {
712             /* Attempt to get order,
713              * only needed for thick types since wrapped with update via callbacks. */
714             PropertyRNA *prop_eul_order = NULL;
715             short order = pyrna_rotation_euler_order_get(ptr, EULER_ORDER_XYZ, &prop_eul_order);
716
717             ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA. */
718             RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
719           }
720           else {
721             /* Order will be updated from callback on use. */
722             // TODO, get order from RNA
723             PyObject *eul_cb = Euler_CreatePyObject_cb(
724                 ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL);
725             Py_DECREF(ret); /* The euler owns 'ret' now. */
726             ret = eul_cb;   /* Return the euler instead. */
727           }
728         }
729         else if (len == 4) {
730           if (is_thick) {
731             ret = Quaternion_CreatePyObject(NULL, NULL);
732             RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
733           }
734           else {
735             PyObject *quat_cb = Quaternion_CreatePyObject_cb(
736                 ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT);
737             Py_DECREF(ret); /* The quat owns 'ret' now. */
738             ret = quat_cb;  /* Return the quat instead. */
739           }
740         }
741         break;
742       case PROP_COLOR:
743       case PROP_COLOR_GAMMA:
744         if (len == 3) { /* Color. */
745           if (is_thick) {
746             ret = Color_CreatePyObject(NULL, NULL);
747             RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col);
748           }
749           else {
750             PyObject *col_cb = Color_CreatePyObject_cb(
751                 ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR);
752             Py_DECREF(ret); /* The color owns 'ret' now. */
753             ret = col_cb;   /* Return the color instead. */
754           }
755         }
756         break;
757       default:
758         break;
759     }
760   }
761
762   if (ret == NULL) {
763     if (is_thick) {
764       /* This is an array we can't reference (since it is not thin wrappable)
765        * and cannot be coerced into a mathutils type, so return as a list. */
766     thick_wrap_slice:
767       ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
768     }
769     else {
770       ret = pyrna_prop_CreatePyObject(ptr, prop); /* Owned by the mathutils PyObject. */
771     }
772   }
773 #else  /* USE_MATHUTILS */
774   (void)ptr;
775   (void)prop;
776 #endif /* USE_MATHUTILS */
777
778   return ret;
779 }
780
781 /**
782  * Same as #RNA_enum_value_from_id, but raises an exception.
783  */
784 int pyrna_enum_value_from_id(const EnumPropertyItem *item,
785                              const char *identifier,
786                              int *r_value,
787                              const char *error_prefix)
788 {
789   if (RNA_enum_value_from_id(item, identifier, r_value) == 0) {
790     const char *enum_str = BPy_enum_as_string(item);
791     PyErr_Format(
792         PyExc_ValueError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
793     MEM_freeN((void *)enum_str);
794     return -1;
795   }
796
797   return 0;
798 }
799
800 /* note on __cmp__:
801  * checking the 'ptr->data' matches works in almost all cases,
802  * however there are a few RNA properties that are fake sub-structs and
803  * share the pointer with the parent, in those cases this happens 'a.b == a'
804  * see: r43352 for example.
805  *
806  * So compare the 'ptr->type' as well to avoid this problem.
807  * It's highly unlikely this would happen that 'ptr->data' and 'ptr->prop' would match,
808  * but _not_ 'ptr->type' but include this check for completeness.
809  * - campbell */
810
811 static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
812 {
813   return (((a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ? 0 : -1);
814 }
815
816 static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
817 {
818   return (((a->prop == b->prop) && (a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ?
819               0 :
820               -1);
821 }
822
823 static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
824 {
825   PyObject *res;
826   int ok = -1; /* Zero is true. */
827
828   if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) {
829     ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
830   }
831
832   switch (op) {
833     case Py_NE:
834       ok = !ok;
835       ATTR_FALLTHROUGH;
836     case Py_EQ:
837       res = ok ? Py_False : Py_True;
838       break;
839
840     case Py_LT:
841     case Py_LE:
842     case Py_GT:
843     case Py_GE:
844       res = Py_NotImplemented;
845       break;
846     default:
847       PyErr_BadArgument();
848       return NULL;
849   }
850
851   return Py_INCREF_RET(res);
852 }
853
854 static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
855 {
856   PyObject *res;
857   int ok = -1; /* Zero is true. */
858
859   if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) {
860     ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
861   }
862
863   switch (op) {
864     case Py_NE:
865       ok = !ok;
866       ATTR_FALLTHROUGH;
867     case Py_EQ:
868       res = ok ? Py_False : Py_True;
869       break;
870
871     case Py_LT:
872     case Py_LE:
873     case Py_GT:
874     case Py_GE:
875       res = Py_NotImplemented;
876       break;
877     default:
878       PyErr_BadArgument();
879       return NULL;
880   }
881
882   return Py_INCREF_RET(res);
883 }
884
885 /*----------------------repr--------------------------------------------*/
886 static PyObject *pyrna_struct_str(BPy_StructRNA *self)
887 {
888   PyObject *ret;
889   const char *name;
890
891   if (!PYRNA_STRUCT_IS_VALID(self)) {
892     return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name);
893   }
894
895   /* Print name if available. */
896   name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL);
897   if (name) {
898     ret = PyUnicode_FromFormat(
899         "<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name);
900     MEM_freeN((void *)name);
901     return ret;
902   }
903
904   return PyUnicode_FromFormat(
905       "<bpy_struct, %.200s at %p>", RNA_struct_identifier(self->ptr.type), self->ptr.data);
906 }
907
908 static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
909 {
910   ID *id = self->ptr.owner_id;
911   PyObject *tmp_str;
912   PyObject *ret;
913
914   if (id == NULL || !PYRNA_STRUCT_IS_VALID(self)) {
915     /* fallback */
916     return pyrna_struct_str(self);
917   }
918
919   tmp_str = PyUnicode_FromString(id->name + 2);
920
921   if (RNA_struct_is_ID(self->ptr.type) && (id->flag & LIB_PRIVATE_DATA) == 0) {
922     ret = PyUnicode_FromFormat(
923         "bpy.data.%s[%R]", BKE_idcode_to_name_plural(GS(id->name)), tmp_str);
924   }
925   else {
926     const char *path;
927     ID *real_id = NULL;
928     path = RNA_path_from_real_ID_to_struct(G_MAIN, &self->ptr, &real_id);
929     if (path) {
930       if (real_id != id) {
931         Py_DECREF(tmp_str);
932         tmp_str = PyUnicode_FromString(real_id->name + 2);
933       }
934       ret = PyUnicode_FromFormat(
935           "bpy.data.%s[%R].%s", BKE_idcode_to_name_plural(GS(real_id->name)), tmp_str, path);
936
937       MEM_freeN((void *)path);
938     }
939     else {
940       /* Can't find the path, print something useful as a fallback. */
941       ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
942                                  BKE_idcode_to_name_plural(GS(id->name)),
943                                  tmp_str,
944                                  RNA_struct_identifier(self->ptr.type));
945     }
946   }
947
948   Py_DECREF(tmp_str);
949
950   return ret;
951 }
952
953 static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
954 {
955   PyObject *ret;
956   PointerRNA ptr;
957   const char *name;
958   const char *type_id = NULL;
959   char type_fmt[64] = "";
960   int type;
961
962   PYRNA_PROP_CHECK_OBJ(self);
963
964   type = RNA_property_type(self->prop);
965
966   if (RNA_enum_id_from_value(rna_enum_property_type_items, type, &type_id) == 0) {
967     /* Should never happen. */
968     PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error");
969     return NULL;
970   }
971   else {
972     /* This should never fail. */
973     int len = -1;
974     char *c = type_fmt;
975
976     while ((*c++ = tolower(*type_id++))) {
977     }
978
979     if (type == PROP_COLLECTION) {
980       len = pyrna_prop_collection_length(self);
981     }
982     else if (RNA_property_array_check(self->prop)) {
983       len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
984     }
985
986     if (len != -1) {
987       sprintf(--c, "[%d]", len);
988     }
989   }
990
991   /* If a pointer, try to print name of pointer target too. */
992   if (type == PROP_POINTER) {
993     ptr = RNA_property_pointer_get(&self->ptr, self->prop);
994     name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL);
995
996     if (name) {
997       ret = PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>",
998                                  type_fmt,
999                                  RNA_struct_identifier(self->ptr.type),
1000                                  RNA_property_identifier(self->prop),
1001                                  name);
1002       MEM_freeN((void *)name);
1003       return ret;
1004     }
1005   }
1006   if (type == PROP_COLLECTION) {
1007     PointerRNA r_ptr;
1008     if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
1009       return PyUnicode_FromFormat(
1010           "<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type));
1011     }
1012   }
1013
1014   return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>",
1015                               type_fmt,
1016                               RNA_struct_identifier(self->ptr.type),
1017                               RNA_property_identifier(self->prop));
1018 }
1019
1020 static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, const int index)
1021 {
1022   ID *id = self->ptr.owner_id;
1023   PyObject *tmp_str;
1024   PyObject *ret;
1025   const char *path;
1026
1027   PYRNA_PROP_CHECK_OBJ(self);
1028
1029   if (id == NULL) {
1030     /* Fallback. */
1031     return pyrna_prop_str(self);
1032   }
1033
1034   tmp_str = PyUnicode_FromString(id->name + 2);
1035
1036   /* Note that using G_MAIN is absolutely not ideal, but we have no access to actual Main DB from
1037    * here. */
1038   ID *real_id = NULL;
1039   path = RNA_path_from_real_ID_to_property_index(
1040       G_MAIN, &self->ptr, self->prop, index_dim, index, &real_id);
1041
1042   if (path) {
1043     if (real_id != id) {
1044       Py_DECREF(tmp_str);
1045       tmp_str = PyUnicode_FromString(real_id->name + 2);
1046     }
1047     const char *data_delim = (path[0] == '[') ? "" : ".";
1048     ret = PyUnicode_FromFormat("bpy.data.%s[%R]%s%s",
1049                                BKE_idcode_to_name_plural(GS(real_id->name)),
1050                                tmp_str,
1051                                data_delim,
1052                                path);
1053
1054     MEM_freeN((void *)path);
1055   }
1056   else {
1057     /* Can't find the path, print something useful as a fallback. */
1058     ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
1059                                BKE_idcode_to_name_plural(GS(id->name)),
1060                                tmp_str,
1061                                RNA_property_identifier(self->prop));
1062   }
1063
1064   Py_DECREF(tmp_str);
1065
1066   return ret;
1067 }
1068
1069 static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
1070 {
1071   return pyrna_prop_repr_ex(self, 0, -1);
1072 }
1073
1074 static PyObject *pyrna_prop_array_repr(BPy_PropertyArrayRNA *self)
1075 {
1076   return pyrna_prop_repr_ex((BPy_PropertyRNA *)self, self->arraydim, self->arrayoffset);
1077 }
1078
1079 static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
1080 {
1081   return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
1082                               Py_TYPE(self)->tp_name,
1083                               RNA_struct_identifier(self->ptr.type),
1084                               RNA_function_identifier(self->func));
1085 }
1086
1087 static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self)
1088 {
1089   return _Py_HashPointer(self->ptr.data);
1090 }
1091
1092 /* From Python's meth_hash v3.1.2. */
1093 static long pyrna_prop_hash(BPy_PropertyRNA *self)
1094 {
1095   long x, y;
1096   if (self->ptr.data == NULL) {
1097     x = 0;
1098   }
1099   else {
1100     x = _Py_HashPointer(self->ptr.data);
1101     if (x == -1) {
1102       return -1;
1103     }
1104   }
1105   y = _Py_HashPointer((void *)(self->prop));
1106   if (y == -1) {
1107     return -1;
1108   }
1109   x ^= y;
1110   if (x == -1) {
1111     x = -2;
1112   }
1113   return x;
1114 }
1115
1116 #ifdef USE_PYRNA_STRUCT_REFERENCE
1117 static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
1118 {
1119   Py_VISIT(self->reference);
1120   return 0;
1121 }
1122
1123 static int pyrna_struct_clear(BPy_StructRNA *self)
1124 {
1125   Py_CLEAR(self->reference);
1126   return 0;
1127 }
1128 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1129
1130 /* Use our own dealloc so we can free a property if we use one. */
1131 static void pyrna_struct_dealloc(BPy_StructRNA *self)
1132 {
1133 #ifdef PYRNA_FREE_SUPPORT
1134   if (self->freeptr && self->ptr.data) {
1135     IDP_FreeProperty(self->ptr.data);
1136     self->ptr.data = NULL;
1137   }
1138 #endif /* PYRNA_FREE_SUPPORT */
1139
1140 #ifdef USE_WEAKREFS
1141   if (self->in_weakreflist != NULL) {
1142     PyObject_ClearWeakRefs((PyObject *)self);
1143   }
1144 #endif
1145
1146 #ifdef USE_PYRNA_STRUCT_REFERENCE
1147   if (self->reference) {
1148     PyObject_GC_UnTrack(self);
1149     pyrna_struct_clear(self);
1150   }
1151 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1152
1153   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1154   Py_TYPE(self)->tp_free(self);
1155 }
1156
1157 #ifdef USE_PYRNA_STRUCT_REFERENCE
1158 static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
1159 {
1160   if (self->reference) {
1161     //      PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */
1162     pyrna_struct_clear(self);
1163   }
1164   /* Reference is now NULL. */
1165
1166   if (reference) {
1167     self->reference = reference;
1168     Py_INCREF(reference);
1169     //      PyObject_GC_Track(self);  /* INITIALIZED TRACKED ? */
1170   }
1171 }
1172 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1173
1174 /* Use our own dealloc so we can free a property if we use one. */
1175 static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
1176 {
1177 #ifdef USE_WEAKREFS
1178   if (self->in_weakreflist != NULL) {
1179     PyObject_ClearWeakRefs((PyObject *)self);
1180   }
1181 #endif
1182   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1183   Py_TYPE(self)->tp_free(self);
1184 }
1185
1186 static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
1187 {
1188 #ifdef USE_WEAKREFS
1189   if (self->in_weakreflist != NULL) {
1190     PyObject_ClearWeakRefs((PyObject *)self);
1191   }
1192 #endif
1193   /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */
1194   Py_TYPE(self)->tp_free(self);
1195 }
1196
1197 static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
1198 {
1199   const EnumPropertyItem *item;
1200   const char *result;
1201   bool free = false;
1202
1203   RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1204   if (item) {
1205     result = BPy_enum_as_string(item);
1206   }
1207   else {
1208     result = "";
1209   }
1210
1211   if (free) {
1212     MEM_freeN((void *)item);
1213   }
1214
1215   return result;
1216 }
1217
1218 static int pyrna_string_to_enum(
1219     PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *r_value, const char *error_prefix)
1220 {
1221   const char *param = _PyUnicode_AsString(item);
1222
1223   if (param == NULL) {
1224     PyErr_Format(PyExc_TypeError,
1225                  "%.200s expected a string enum, not %.200s",
1226                  error_prefix,
1227                  Py_TYPE(item)->tp_name);
1228     return -1;
1229   }
1230   else {
1231     if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, r_value)) {
1232       const char *enum_str = pyrna_enum_as_string(ptr, prop);
1233       PyErr_Format(PyExc_TypeError,
1234                    "%.200s enum \"%.200s\" not found in (%s)",
1235                    error_prefix,
1236                    param,
1237                    enum_str);
1238       MEM_freeN((void *)enum_str);
1239       return -1;
1240     }
1241   }
1242
1243   return 0;
1244 }
1245
1246 /**
1247  * Takes a set of strings and map it to and array of booleans.
1248  *
1249  * Useful when the values aren't flags.
1250  *
1251  * \param type_convert_sign: Maps signed to unsigned range,
1252  * needed when we want to use the full range of a signed short/char.
1253  */
1254 BLI_bitmap *pyrna_set_to_enum_bitmap(const EnumPropertyItem *items,
1255                                      PyObject *value,
1256                                      int type_size,
1257                                      bool type_convert_sign,
1258                                      int bitmap_size,
1259                                      const char *error_prefix)
1260 {
1261   /* Set looping. */
1262   Py_ssize_t pos = 0;
1263   Py_ssize_t hash = 0;
1264   PyObject *key;
1265
1266   BLI_bitmap *bitmap = BLI_BITMAP_NEW(bitmap_size, __func__);
1267
1268   while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1269     const char *param = _PyUnicode_AsString(key);
1270     if (param == NULL) {
1271       PyErr_Format(PyExc_TypeError,
1272                    "%.200s expected a string, not %.200s",
1273                    error_prefix,
1274                    Py_TYPE(key)->tp_name);
1275       goto error;
1276     }
1277
1278     int ret;
1279     if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
1280       goto error;
1281     }
1282
1283     int index = ret;
1284
1285     if (type_convert_sign) {
1286       if (type_size == 2) {
1287         union {
1288           signed short as_signed;
1289           unsigned short as_unsigned;
1290         } ret_convert;
1291         ret_convert.as_signed = (signed short)ret;
1292         index = (int)ret_convert.as_unsigned;
1293       }
1294       else if (type_size == 1) {
1295         union {
1296           signed char as_signed;
1297           unsigned char as_unsigned;
1298         } ret_convert;
1299         ret_convert.as_signed = (signed char)ret;
1300         index = (int)ret_convert.as_unsigned;
1301       }
1302       else {
1303         BLI_assert(0);
1304       }
1305     }
1306     BLI_assert(index < bitmap_size);
1307     BLI_BITMAP_ENABLE(bitmap, index);
1308   }
1309
1310   return bitmap;
1311
1312 error:
1313   MEM_freeN(bitmap);
1314   return NULL;
1315 }
1316
1317 /* 'value' _must_ be a set type, error check before calling. */
1318 int pyrna_set_to_enum_bitfield(const EnumPropertyItem *items,
1319                                PyObject *value,
1320                                int *r_value,
1321                                const char *error_prefix)
1322 {
1323   /* Set of enum items, concatenate all values with OR. */
1324   int ret, flag = 0;
1325
1326   /* Set looping. */
1327   Py_ssize_t pos = 0;
1328   Py_ssize_t hash = 0;
1329   PyObject *key;
1330
1331   *r_value = 0;
1332
1333   while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1334     const char *param = _PyUnicode_AsString(key);
1335
1336     if (param == NULL) {
1337       PyErr_Format(PyExc_TypeError,
1338                    "%.200s expected a string, not %.200s",
1339                    error_prefix,
1340                    Py_TYPE(key)->tp_name);
1341       return -1;
1342     }
1343
1344     if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
1345       return -1;
1346     }
1347
1348     flag |= ret;
1349   }
1350
1351   *r_value = flag;
1352   return 0;
1353 }
1354
1355 static int pyrna_prop_to_enum_bitfield(
1356     PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
1357 {
1358   const EnumPropertyItem *item;
1359   int ret;
1360   bool free = false;
1361
1362   *r_value = 0;
1363
1364   if (!PyAnySet_Check(value)) {
1365     PyErr_Format(PyExc_TypeError,
1366                  "%.200s, %.200s.%.200s expected a set, not a %.200s",
1367                  error_prefix,
1368                  RNA_struct_identifier(ptr->type),
1369                  RNA_property_identifier(prop),
1370                  Py_TYPE(value)->tp_name);
1371     return -1;
1372   }
1373
1374   RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1375
1376   if (item) {
1377     ret = pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix);
1378   }
1379   else {
1380     if (PySet_GET_SIZE(value)) {
1381       PyErr_Format(PyExc_TypeError,
1382                    "%.200s: empty enum \"%.200s\" could not have any values assigned",
1383                    error_prefix,
1384                    RNA_property_identifier(prop));
1385       ret = -1;
1386     }
1387     else {
1388       ret = 0;
1389     }
1390   }
1391
1392   if (free) {
1393     MEM_freeN((void *)item);
1394   }
1395
1396   return ret;
1397 }
1398
1399 PyObject *pyrna_enum_bitfield_to_py(const EnumPropertyItem *items, int value)
1400 {
1401   PyObject *ret = PySet_New(NULL);
1402   const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1403
1404   if (RNA_enum_bitflag_identifiers(items, value, identifier)) {
1405     PyObject *item;
1406     int index;
1407     for (index = 0; identifier[index]; index++) {
1408       item = PyUnicode_FromString(identifier[index]);
1409       PySet_Add(ret, item);
1410       Py_DECREF(item);
1411     }
1412   }
1413
1414   return ret;
1415 }
1416
1417 static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
1418 {
1419   PyObject *item, *ret = NULL;
1420
1421   if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1422     const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1423
1424     ret = PySet_New(NULL);
1425
1426     if (RNA_property_enum_bitflag_identifiers(BPy_GetContext(), ptr, prop, val, identifier)) {
1427       int index;
1428
1429       for (index = 0; identifier[index]; index++) {
1430         item = PyUnicode_FromString(identifier[index]);
1431         PySet_Add(ret, item);
1432         Py_DECREF(item);
1433       }
1434     }
1435   }
1436   else {
1437     const char *identifier;
1438     if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) {
1439       ret = PyUnicode_FromString(identifier);
1440     }
1441     else {
1442       /* Static, no need to free. */
1443       const EnumPropertyItem *enum_item;
1444       bool free_dummy;
1445       RNA_property_enum_items_ex(NULL, ptr, prop, true, &enum_item, NULL, &free_dummy);
1446       BLI_assert(!free_dummy);
1447
1448       /* Do not print warning in case of DummyRNA_NULL_items,
1449        * this one will never match any value... */
1450       if (enum_item != DummyRNA_NULL_items) {
1451         const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
1452
1453         /* Prefer not to fail silently in case of API errors, maybe disable it later. */
1454         CLOG_WARN(BPY_LOG_RNA,
1455                   "current value '%d' "
1456                   "matches no enum in '%s', '%s', '%s'",
1457                   val,
1458                   RNA_struct_identifier(ptr->type),
1459                   ptr_name,
1460                   RNA_property_identifier(prop));
1461
1462 #if 0 /* Gives Python decoding errors while generating docs :( */
1463         char error_str[256];
1464         BLI_snprintf(error_str,
1465                      sizeof(error_str),
1466                      "RNA Warning: Current value \"%d\" "
1467                      "matches no enum in '%s', '%s', '%s'",
1468                      val,
1469                      RNA_struct_identifier(ptr->type),
1470                      ptr_name,
1471                      RNA_property_identifier(prop));
1472
1473         PyErr_Warn(PyExc_RuntimeWarning, error_str);
1474 #endif
1475
1476         if (ptr_name) {
1477           MEM_freeN((void *)ptr_name);
1478         }
1479       }
1480
1481       ret = PyUnicode_FromString("");
1482 #if 0
1483       PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
1484       ret = NULL;
1485 #endif
1486     }
1487   }
1488
1489   return ret;
1490 }
1491
1492 PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
1493 {
1494   PyObject *ret;
1495   const int type = RNA_property_type(prop);
1496
1497   if (RNA_property_array_check(prop)) {
1498     return pyrna_py_from_array(ptr, prop);
1499   }
1500
1501   /* See if we can coerce into a Python type - 'PropertyType'. */
1502   switch (type) {
1503     case PROP_BOOLEAN:
1504       ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
1505       break;
1506     case PROP_INT:
1507       ret = PyLong_FromLong(RNA_property_int_get(ptr, prop));
1508       break;
1509     case PROP_FLOAT:
1510       ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
1511       break;
1512     case PROP_STRING: {
1513       const int subtype = RNA_property_subtype(prop);
1514       const char *buf;
1515       int buf_len;
1516       char buf_fixed[32];
1517
1518       buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
1519 #ifdef USE_STRING_COERCE
1520       /* Only file paths get special treatment, they may contain non utf-8 chars. */
1521       if (subtype == PROP_BYTESTRING) {
1522         ret = PyBytes_FromStringAndSize(buf, buf_len);
1523       }
1524       else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1525         ret = PyC_UnicodeFromByteAndSize(buf, buf_len);
1526       }
1527       else {
1528         ret = PyUnicode_FromStringAndSize(buf, buf_len);
1529       }
1530 #else  /* USE_STRING_COERCE */
1531       if (subtype == PROP_BYTESTRING) {
1532         ret = PyBytes_FromStringAndSize(buf, buf_len);
1533       }
1534       else {
1535         ret = PyUnicode_FromStringAndSize(buf, buf_len);
1536       }
1537 #endif /* USE_STRING_COERCE */
1538       if (buf_fixed != buf) {
1539         MEM_freeN((void *)buf);
1540       }
1541       break;
1542     }
1543     case PROP_ENUM: {
1544       ret = pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop));
1545       break;
1546     }
1547     case PROP_POINTER: {
1548       PointerRNA newptr;
1549       newptr = RNA_property_pointer_get(ptr, prop);
1550       if (newptr.data) {
1551         ret = pyrna_struct_CreatePyObject(&newptr);
1552       }
1553       else {
1554         ret = Py_None;
1555         Py_INCREF(ret);
1556       }
1557       break;
1558     }
1559     case PROP_COLLECTION:
1560       ret = pyrna_prop_CreatePyObject(ptr, prop);
1561       break;
1562     default:
1563       PyErr_Format(PyExc_TypeError,
1564                    "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)",
1565                    type);
1566       ret = NULL;
1567       break;
1568   }
1569
1570   return ret;
1571 }
1572
1573 /**
1574  * This function is used by operators and converting dicts into collections.
1575  * It takes keyword args and fills them with property values.
1576  */
1577 int pyrna_pydict_to_props(PointerRNA *ptr,
1578                           PyObject *kw,
1579                           const bool all_args,
1580                           const char *error_prefix)
1581 {
1582   int error_val = 0;
1583   int totkw;
1584   const char *arg_name = NULL;
1585   PyObject *item;
1586
1587   totkw = kw ? PyDict_Size(kw) : 0;
1588
1589   RNA_STRUCT_BEGIN (ptr, prop) {
1590     arg_name = RNA_property_identifier(prop);
1591
1592     if (STREQ(arg_name, "rna_type")) {
1593       continue;
1594     }
1595
1596     if (kw == NULL) {
1597       PyErr_Format(PyExc_TypeError,
1598                    "%.200s: no keywords, expected \"%.200s\"",
1599                    error_prefix,
1600                    arg_name ? arg_name : "<UNKNOWN>");
1601       error_val = -1;
1602       break;
1603     }
1604
1605     item = PyDict_GetItemString(kw, arg_name); /* Wont set an error. */
1606
1607     if (item == NULL) {
1608       if (all_args) {
1609         PyErr_Format(PyExc_TypeError,
1610                      "%.200s: keyword \"%.200s\" missing",
1611                      error_prefix,
1612                      arg_name ? arg_name : "<UNKNOWN>");
1613         error_val = -1; /* pyrna_py_to_prop sets the error. */
1614         break;
1615       }
1616     }
1617     else {
1618       if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
1619         error_val = -1;
1620         break;
1621       }
1622       totkw--;
1623     }
1624   }
1625   RNA_STRUCT_END;
1626
1627   if (error_val == 0 && totkw > 0) { /* Some keywords were given that were not used :/. */
1628     PyObject *key, *value;
1629     Py_ssize_t pos = 0;
1630
1631     while (PyDict_Next(kw, &pos, &key, &value)) {
1632       arg_name = _PyUnicode_AsString(key);
1633       if (RNA_struct_find_property(ptr, arg_name) == NULL) {
1634         break;
1635       }
1636       arg_name = NULL;
1637     }
1638
1639     PyErr_Format(PyExc_TypeError,
1640                  "%.200s: keyword \"%.200s\" unrecognized",
1641                  error_prefix,
1642                  arg_name ? arg_name : "<UNKNOWN>");
1643     error_val = -1;
1644   }
1645
1646   return error_val;
1647 }
1648
1649 static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
1650 {
1651   BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *)PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
1652   pyfunc->ptr = *ptr;
1653   pyfunc->func = func;
1654   return (PyObject *)pyfunc;
1655 }
1656
1657 static int pyrna_py_to_prop(
1658     PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1659 {
1660   /* XXX hard limits should be checked here. */
1661   const int type = RNA_property_type(prop);
1662
1663   if (RNA_property_array_check(prop)) {
1664     /* Done getting the length. */
1665     if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) {
1666       return -1;
1667     }
1668   }
1669   else {
1670     /* Normal Property (not an array). */
1671
1672     /* See if we can coerce into a Python type - 'PropertyType'. */
1673     switch (type) {
1674       case PROP_BOOLEAN: {
1675         int param;
1676         /* Prefer not to have an exception here
1677          * however so many poll functions return None or a valid Object.
1678          * It's a hassle to convert these into a bool before returning. */
1679         if (RNA_parameter_flag(prop) & PARM_OUTPUT) {
1680           param = PyObject_IsTrue(value);
1681         }
1682         else {
1683           param = PyC_Long_AsI32(value);
1684
1685           if (UNLIKELY(param & ~1)) { /* Only accept 0/1. */
1686             param = -1;               /* Error out below. */
1687           }
1688         }
1689
1690         if (param == -1) {
1691           PyErr_Format(PyExc_TypeError,
1692                        "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1693                        error_prefix,
1694                        RNA_struct_identifier(ptr->type),
1695                        RNA_property_identifier(prop),
1696                        Py_TYPE(value)->tp_name);
1697           return -1;
1698         }
1699         else {
1700           if (data) {
1701             *((bool *)data) = param;
1702           }
1703           else {
1704             RNA_property_boolean_set(ptr, prop, param);
1705           }
1706         }
1707         break;
1708       }
1709       case PROP_INT: {
1710         int overflow;
1711         long param = PyLong_AsLongAndOverflow(value, &overflow);
1712         if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1713           PyErr_Format(PyExc_ValueError,
1714                        "%.200s %.200s.%.200s value not in 'int' range "
1715                        "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1716                        error_prefix,
1717                        RNA_struct_identifier(ptr->type),
1718                        RNA_property_identifier(prop));
1719           return -1;
1720         }
1721         else if (param == -1 && PyErr_Occurred()) {
1722           PyErr_Format(PyExc_TypeError,
1723                        "%.200s %.200s.%.200s expected an int type, not %.200s",
1724                        error_prefix,
1725                        RNA_struct_identifier(ptr->type),
1726                        RNA_property_identifier(prop),
1727                        Py_TYPE(value)->tp_name);
1728           return -1;
1729         }
1730         else {
1731           int param_i = (int)param;
1732           if (data) {
1733             RNA_property_int_clamp(ptr, prop, &param_i);
1734             *((int *)data) = param_i;
1735           }
1736           else {
1737             RNA_property_int_set(ptr, prop, param_i);
1738           }
1739         }
1740         break;
1741       }
1742       case PROP_FLOAT: {
1743         float param = PyFloat_AsDouble(value);
1744         if (PyErr_Occurred()) {
1745           PyErr_Format(PyExc_TypeError,
1746                        "%.200s %.200s.%.200s expected a float type, not %.200s",
1747                        error_prefix,
1748                        RNA_struct_identifier(ptr->type),
1749                        RNA_property_identifier(prop),
1750                        Py_TYPE(value)->tp_name);
1751           return -1;
1752         }
1753         else {
1754           if (data) {
1755             RNA_property_float_clamp(ptr, prop, (float *)&param);
1756             *((float *)data) = param;
1757           }
1758           else {
1759             RNA_property_float_set(ptr, prop, param);
1760           }
1761         }
1762         break;
1763       }
1764       case PROP_STRING: {
1765         const int subtype = RNA_property_subtype(prop);
1766         const char *param;
1767
1768         if (value == Py_None) {
1769           if ((RNA_property_flag(prop) & PROP_NEVER_NULL) == 0) {
1770             if (data) {
1771               if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1772                 *(char *)data = 0;
1773               }
1774               else {
1775                 *((char **)data) = (char *)NULL;
1776               }
1777             }
1778             else {
1779               RNA_property_string_set(ptr, prop, NULL);
1780             }
1781           }
1782           else {
1783             PyC_Err_Format_Prefix(PyExc_TypeError,
1784                                   "%.200s %.200s.%.200s doesn't support None from string types",
1785                                   error_prefix,
1786                                   RNA_struct_identifier(ptr->type),
1787                                   RNA_property_identifier(prop));
1788             return -1;
1789           }
1790         }
1791         else if (subtype == PROP_BYTESTRING) {
1792
1793           /* Byte String. */
1794
1795           param = PyBytes_AsString(value);
1796
1797           if (param == NULL) {
1798             if (PyBytes_Check(value)) {
1799               /* there was an error assigning a string type,
1800                * rather than setting a new error, prefix the existing one
1801                */
1802               PyC_Err_Format_Prefix(PyExc_TypeError,
1803                                     "%.200s %.200s.%.200s error assigning bytes",
1804                                     error_prefix,
1805                                     RNA_struct_identifier(ptr->type),
1806                                     RNA_property_identifier(prop));
1807             }
1808             else {
1809               PyErr_Format(PyExc_TypeError,
1810                            "%.200s %.200s.%.200s expected a bytes type, not %.200s",
1811                            error_prefix,
1812                            RNA_struct_identifier(ptr->type),
1813                            RNA_property_identifier(prop),
1814                            Py_TYPE(value)->tp_name);
1815             }
1816
1817             return -1;
1818           }
1819           else {
1820             if (data) {
1821               if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1822                 BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
1823               }
1824               else {
1825                 *((char **)data) = (char *)param;
1826               }
1827             }
1828             else {
1829               RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value));
1830             }
1831           }
1832         }
1833         else {
1834           /* Unicode String. */
1835 #ifdef USE_STRING_COERCE
1836           PyObject *value_coerce = NULL;
1837           if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1838             /* TODO, get size. */
1839             param = PyC_UnicodeAsByte(value, &value_coerce);
1840           }
1841           else {
1842             param = _PyUnicode_AsString(value);
1843           }
1844 #else  /* USE_STRING_COERCE */
1845           param = _PyUnicode_AsString(value);
1846 #endif /* USE_STRING_COERCE */
1847
1848           if (param == NULL) {
1849             if (PyUnicode_Check(value)) {
1850               /* there was an error assigning a string type,
1851                * rather than setting a new error, prefix the existing one
1852                */
1853               PyC_Err_Format_Prefix(PyExc_TypeError,
1854                                     "%.200s %.200s.%.200s error assigning string",
1855                                     error_prefix,
1856                                     RNA_struct_identifier(ptr->type),
1857                                     RNA_property_identifier(prop));
1858             }
1859             else {
1860               PyErr_Format(PyExc_TypeError,
1861                            "%.200s %.200s.%.200s expected a string type, not %.200s",
1862                            error_prefix,
1863                            RNA_struct_identifier(ptr->type),
1864                            RNA_property_identifier(prop),
1865                            Py_TYPE(value)->tp_name);
1866             }
1867
1868             return -1;
1869           }
1870           else {
1871             /* Same as bytes. */
1872             /* XXX, this is suspect, but needed for function calls,
1873              * need to see if there's a better way. */
1874             if (data) {
1875               if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
1876                 BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
1877               }
1878               else {
1879                 *((char **)data) = (char *)param;
1880               }
1881             }
1882             else {
1883               RNA_property_string_set(ptr, prop, param);
1884             }
1885           }
1886 #ifdef USE_STRING_COERCE
1887           Py_XDECREF(value_coerce);
1888 #endif /* USE_STRING_COERCE */
1889         }
1890         break;
1891       }
1892       case PROP_ENUM: {
1893         int val = 0;
1894
1895         /* Type checking is done by each function. */
1896         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1897           /* Set of enum items, concatenate all values with OR. */
1898           if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
1899             return -1;
1900           }
1901         }
1902         else {
1903           /* Simple enum string. */
1904           if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
1905             return -1;
1906           }
1907         }
1908
1909         if (data) {
1910           *((int *)data) = val;
1911         }
1912         else {
1913           RNA_property_enum_set(ptr, prop, val);
1914         }
1915
1916         break;
1917       }
1918       case PROP_POINTER: {
1919         PyObject *value_new = NULL;
1920
1921         StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop);
1922         int flag = RNA_property_flag(prop);
1923         int flag_parameter = RNA_parameter_flag(prop);
1924
1925         /* This is really nasty! Done so we can fake the operator having direct properties, eg:
1926          * layout.prop(self, "filepath")
1927          * ... which in fact should be:
1928          * layout.prop(self.properties, "filepath")
1929          *
1930          * we need to do this trick.
1931          * if the prop is not an operator type and the pyobject is an operator,
1932          * use its properties in place of itself.
1933          *
1934          * This is so bad that it is almost a good reason to do away with fake
1935          * 'self.properties -> self'
1936          * class mixing. If this causes problems in the future it should be removed.
1937          */
1938         if ((ptr_type == &RNA_AnyType) && (BPy_StructRNA_Check(value))) {
1939           const StructRNA *base_type = RNA_struct_base_child_of(
1940               ((const BPy_StructRNA *)value)->ptr.type, NULL);
1941           if (ELEM(base_type, &RNA_Operator, &RNA_Gizmo)) {
1942             value = PyObject_GetAttr(value, bpy_intern_str_properties);
1943             value_new = value;
1944           }
1945         }
1946
1947         /* if property is an OperatorProperties/GizmoProperties pointer and value is a map,
1948          * forward back to pyrna_pydict_to_props */
1949         if (PyDict_Check(value)) {
1950           const StructRNA *base_type = RNA_struct_base_child_of(ptr_type, NULL);
1951           if (base_type == &RNA_OperatorProperties) {
1952             PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1953             return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
1954           }
1955           else if (base_type == &RNA_GizmoProperties) {
1956             PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
1957             return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
1958           }
1959         }
1960
1961         /* Another exception, allow to pass a collection as an RNA property. */
1962         if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */
1963           PointerRNA c_ptr;
1964           BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value;
1965           if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1966             value = pyrna_struct_CreatePyObject(&c_ptr);
1967             value_new = value;
1968           }
1969           else {
1970             PyErr_Format(PyExc_TypeError,
1971                          "%.200s %.200s.%.200s collection has no type, "
1972                          "can't be used as a %.200s type",
1973                          error_prefix,
1974                          RNA_struct_identifier(ptr->type),
1975                          RNA_property_identifier(prop),
1976                          RNA_struct_identifier(ptr_type));
1977             return -1;
1978           }
1979         }
1980
1981         if (!BPy_StructRNA_Check(value) && value != Py_None) {
1982           PyErr_Format(PyExc_TypeError,
1983                        "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1984                        error_prefix,
1985                        RNA_struct_identifier(ptr->type),
1986                        RNA_property_identifier(prop),
1987                        RNA_struct_identifier(ptr_type),
1988                        Py_TYPE(value)->tp_name);
1989           Py_XDECREF(value_new);
1990           return -1;
1991         }
1992         else if ((flag & PROP_NEVER_NULL) && value == Py_None) {
1993           PyErr_Format(PyExc_TypeError,
1994                        "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
1995                        error_prefix,
1996                        RNA_struct_identifier(ptr->type),
1997                        RNA_property_identifier(prop),
1998                        RNA_struct_identifier(ptr_type));
1999           Py_XDECREF(value_new);
2000           return -1;
2001         }
2002         else if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) &&
2003                                         ptr->owner_id == ((BPy_StructRNA *)value)->ptr.owner_id)) {
2004           PyErr_Format(PyExc_TypeError,
2005                        "%.200s %.200s.%.200s ID type does not support assignment to itself",
2006                        error_prefix,
2007                        RNA_struct_identifier(ptr->type),
2008                        RNA_property_identifier(prop));
2009           Py_XDECREF(value_new);
2010           return -1;
2011         }
2012         else {
2013           BPy_StructRNA *param = (BPy_StructRNA *)value;
2014           bool raise_error = false;
2015           if (data) {
2016
2017             if (flag_parameter & PARM_RNAPTR) {
2018               if (flag & PROP_THICK_WRAP) {
2019                 if (value == Py_None) {
2020                   memset(data, 0, sizeof(PointerRNA));
2021                 }
2022                 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
2023                   *((PointerRNA *)data) = param->ptr;
2024                 }
2025                 else {
2026                   raise_error = true;
2027                 }
2028               }
2029               else {
2030                 /* For function calls, we sometimes want to pass the 'ptr' directly,
2031                  * but watch out that it remains valid!
2032                  * We could possibly support this later if needed. */
2033                 BLI_assert(value_new == NULL);
2034                 if (value == Py_None) {
2035                   *((void **)data) = NULL;
2036                 }
2037                 else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
2038                   *((PointerRNA **)data) = &param->ptr;
2039                 }
2040                 else {
2041                   raise_error = true;
2042                 }
2043               }
2044             }
2045             else if (value == Py_None) {
2046               *((void **)data) = NULL;
2047             }
2048             else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
2049               *((void **)data) = param->ptr.data;
2050             }
2051             else {
2052               raise_error = true;
2053             }
2054           }
2055           else {
2056             /* Data == NULL, assign to RNA. */
2057             if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) {
2058               ReportList reports;
2059               BKE_reports_init(&reports, RPT_STORE);
2060               RNA_property_pointer_set(
2061                   ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports);
2062               int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
2063               if (err == -1) {
2064                 Py_XDECREF(value_new);
2065                 return -1;
2066               }
2067             }
2068             else {
2069               raise_error = true;
2070             }
2071           }
2072
2073           if (raise_error) {
2074             if (pyrna_struct_validity_check(param) == -1) {
2075               /* Error set. */
2076             }
2077             else {
2078               PointerRNA tmp;
2079               RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
2080               PyErr_Format(PyExc_TypeError,
2081                            "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
2082                            error_prefix,
2083                            RNA_struct_identifier(ptr->type),
2084                            RNA_property_identifier(prop),
2085                            RNA_struct_identifier(tmp.type),
2086                            RNA_struct_identifier(param->ptr.type));
2087             }
2088             Py_XDECREF(value_new);
2089             return -1;
2090           }
2091         }
2092
2093         Py_XDECREF(value_new);
2094
2095         break;
2096       }
2097       case PROP_COLLECTION: {
2098         Py_ssize_t seq_len, i;
2099         PyObject *item;
2100         PointerRNA itemptr;
2101         ListBase *lb;
2102         CollectionPointerLink *link;
2103
2104         lb = (data) ? (ListBase *)data : NULL;
2105
2106         /* Convert a sequence of dict's into a collection. */
2107         if (!PySequence_Check(value)) {
2108           PyErr_Format(
2109               PyExc_TypeError,
2110               "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
2111               error_prefix,
2112               RNA_struct_identifier(ptr->type),
2113               RNA_property_identifier(prop),
2114               Py_TYPE(value)->tp_name);
2115           return -1;
2116         }
2117
2118         seq_len = PySequence_Size(value);
2119         for (i = 0; i < seq_len; i++) {
2120           item = PySequence_GetItem(value, i);
2121
2122           if (item == NULL) {
2123             PyErr_Format(
2124                 PyExc_TypeError,
2125                 "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
2126                 error_prefix,
2127                 RNA_struct_identifier(ptr->type),
2128                 RNA_property_identifier(prop),
2129                 i);
2130             Py_XDECREF(item);
2131             return -1;
2132           }
2133
2134           if (PyDict_Check(item) == 0) {
2135             PyErr_Format(PyExc_TypeError,
2136                          "%.200s %.200s.%.200s expected a each sequence "
2137                          "member to be a dict for an RNA collection, not %.200s",
2138                          error_prefix,
2139                          RNA_struct_identifier(ptr->type),
2140                          RNA_property_identifier(prop),
2141                          Py_TYPE(item)->tp_name);
2142             Py_XDECREF(item);
2143             return -1;
2144           }
2145
2146           if (lb) {
2147             link = MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
2148             link->ptr = itemptr;
2149             BLI_addtail(lb, link);
2150           }
2151           else {
2152             RNA_property_collection_add(ptr, prop, &itemptr);
2153           }
2154
2155           if (pyrna_pydict_to_props(
2156                   &itemptr, item, true, "Converting a Python list to an RNA collection") == -1) {
2157             PyObject *msg = PyC_ExceptionBuffer();
2158             const char *msg_char = _PyUnicode_AsString(msg);
2159
2160             PyErr_Format(PyExc_TypeError,
2161                          "%.200s %.200s.%.200s error converting a member of a collection "
2162                          "from a dicts into an RNA collection, failed with: %s",
2163                          error_prefix,
2164                          RNA_struct_identifier(ptr->type),
2165                          RNA_property_identifier(prop),
2166                          msg_char);
2167
2168             Py_DECREF(item);
2169             Py_DECREF(msg);
2170             return -1;
2171           }
2172           Py_DECREF(item);
2173         }
2174
2175         break;
2176       }
2177       default:
2178         PyErr_Format(PyExc_AttributeError,
2179                      "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
2180                      error_prefix,
2181                      RNA_struct_identifier(ptr->type),
2182                      RNA_property_identifier(prop));
2183         return -1;
2184     }
2185   }
2186
2187   /* Run RNA property functions. */
2188   if (RNA_property_update_check(prop)) {
2189     RNA_property_update(BPy_GetContext(), ptr, prop);
2190   }
2191
2192   return 0;
2193 }
2194
2195 static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
2196 {
2197   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2198   return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
2199 }
2200
2201 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
2202 {
2203   int ret = 0;
2204   PointerRNA *ptr = &self->ptr;
2205   PropertyRNA *prop = self->prop;
2206
2207   const int totdim = RNA_property_array_dimension(ptr, prop, NULL);
2208
2209   if (totdim > 1) {
2210     // char error_str[512];
2211     if (pyrna_py_to_array_index(
2212             &self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) {
2213       /* Error is set. */
2214       ret = -1;
2215     }
2216   }
2217   else {
2218     /* See if we can coerce into a Python type - 'PropertyType'. */
2219     switch (RNA_property_type(prop)) {
2220       case PROP_BOOLEAN: {
2221         int param = PyC_Long_AsBool(value);
2222
2223         if (param == -1) {
2224           /* Error is set. */
2225           ret = -1;
2226         }
2227         else {
2228           RNA_property_boolean_set_index(ptr, prop, index, param);
2229         }
2230         break;
2231       }
2232       case PROP_INT: {
2233         int param = PyC_Long_AsI32(value);
2234         if (param == -1 && PyErr_Occurred()) {
2235           PyErr_SetString(PyExc_TypeError, "expected an int type");
2236           ret = -1;
2237         }
2238         else {
2239           RNA_property_int_clamp(ptr, prop, &param);
2240           RNA_property_int_set_index(ptr, prop, index, param);
2241         }
2242         break;
2243       }
2244       case PROP_FLOAT: {
2245         float param = PyFloat_AsDouble(value);
2246         if (PyErr_Occurred()) {
2247           PyErr_SetString(PyExc_TypeError, "expected a float type");
2248           ret = -1;
2249         }
2250         else {
2251           RNA_property_float_clamp(ptr, prop, &param);
2252           RNA_property_float_set_index(ptr, prop, index, param);
2253         }
2254         break;
2255       }
2256       default:
2257         PyErr_SetString(PyExc_AttributeError, "not an array type");
2258         ret = -1;
2259         break;
2260     }
2261   }
2262
2263   /* Run RNA property functions. */
2264   if (RNA_property_update_check(prop)) {
2265     RNA_property_update(BPy_GetContext(), ptr, prop);
2266   }
2267
2268   return ret;
2269 }
2270
2271 /* ---------------sequence------------------------------------------- */
2272 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
2273 {
2274   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2275
2276   if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1) {
2277     return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
2278   }
2279   else {
2280     return RNA_property_array_length(&self->ptr, self->prop);
2281   }
2282 }
2283
2284 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
2285 {
2286   PYRNA_PROP_CHECK_INT(self);
2287
2288   return RNA_property_collection_length(&self->ptr, self->prop);
2289 }
2290
2291 /* bool functions are for speed, so we can avoid getting the length
2292  * of 1000's of items in a linked list for eg. */
2293 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
2294 {
2295   PYRNA_PROP_CHECK_INT(self);
2296
2297   return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
2298 }
2299
2300 static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
2301 {
2302   /* No callback defined, just iterate and find the nth item. */
2303   CollectionPropertyIterator iter;
2304   int test;
2305
2306   PYRNA_PROP_CHECK_INT(self);
2307
2308   RNA_property_collection_begin(&self->ptr, self->prop, &iter);
2309   test = iter.valid;
2310   RNA_property_collection_end(&iter);
2311   return test;
2312 }
2313
2314 /* notice getting the length of the collection is avoided unless negative
2315  * index is used or to detect internal error with a valid index.
2316  * This is done for faster lookups. */
2317 #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
2318   if (keynum < 0) { \
2319     keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
2320     if (keynum_abs < 0) { \
2321       PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum); \
2322       return ret_err; \
2323     } \
2324   } \
2325   (void)0
2326
2327 /* Internal use only. */
2328 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
2329 {
2330   PointerRNA newptr;
2331   Py_ssize_t keynum_abs = keynum;
2332
2333   PYRNA_PROP_CHECK_OBJ(self);
2334
2335   PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
2336
2337   if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
2338     return pyrna_struct_CreatePyObject(&newptr);
2339   }
2340   else {
2341     const int len = RNA_property_collection_length(&self->ptr, self->prop);
2342     if (keynum_abs >= len) {
2343       PyErr_Format(PyExc_IndexError,
2344                    "bpy_prop_collection[index]: "
2345                    "index %d out of range, size %d",
2346                    keynum,
2347                    len);
2348     }
2349     else {
2350       PyErr_Format(PyExc_RuntimeError,
2351                    "bpy_prop_collection[index]: internal error, "
2352                    "valid index %d given in %d sized collection, but value not found",
2353                    keynum_abs,
2354                    len);
2355     }
2356
2357     return NULL;
2358   }
2359 }
2360
2361 /* Values type must have been already checked. */
2362 static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self,
2363                                                    Py_ssize_t keynum,
2364                                                    PyObject *value)
2365 {
2366   Py_ssize_t keynum_abs = keynum;
2367   const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
2368
2369   PYRNA_PROP_CHECK_INT(self);
2370
2371   PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
2372
2373   if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
2374     const int len = RNA_property_collection_length(&self->ptr, self->prop);
2375     if (keynum_abs >= len) {
2376       PyErr_Format(PyExc_IndexError,
2377                    "bpy_prop_collection[index] = value: "
2378                    "index %d out of range, size %d",
2379                    keynum,
2380                    len);
2381     }
2382     else {
2383
2384       PyErr_Format(PyExc_IndexError,
2385                    "bpy_prop_collection[index] = value: "
2386                    "failed assignment (unknown reason)",
2387                    keynum);
2388     }
2389     return -1;
2390   }
2391
2392   return 0;
2393 }
2394
2395 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
2396 {
2397   int len;
2398
2399   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2400
2401   len = pyrna_prop_array_length(self);
2402
2403   if (keynum < 0) {
2404     keynum += len;
2405   }
2406
2407   if (keynum >= 0 && keynum < len) {
2408     return pyrna_prop_array_to_py_index(self, keynum);
2409   }
2410
2411   PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum);
2412   return NULL;
2413 }
2414
2415 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2416 {
2417   PointerRNA newptr;
2418
2419   PYRNA_PROP_CHECK_OBJ(self);
2420
2421   if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
2422     return pyrna_struct_CreatePyObject(&newptr);
2423   }
2424
2425   PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2426   return NULL;
2427 }
2428 // static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname)
2429
2430 /**
2431  * Special case: `bpy.data.objects["some_id_name", "//some_lib_name.blend"]`
2432  * also for:     `bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)`
2433  *
2434  * \note
2435  * error codes since this is not to be called directly from Python,
2436  * this matches Python's `__contains__` values C-API.
2437  * - -1: exception set
2438  * -  0: not found
2439  * -  1: found
2440  */
2441 static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self,
2442                                                             PyObject *key,
2443                                                             const char *err_prefix,
2444                                                             const short err_not_found,
2445                                                             PointerRNA *r_ptr)
2446 {
2447   const char *keyname;
2448
2449   /* First validate the args, all we know is that they are a tuple. */
2450   if (PyTuple_GET_SIZE(key) != 2) {
2451     PyErr_Format(PyExc_KeyError,
2452                  "%s: tuple key must be a pair, not size %d",
2453                  err_prefix,
2454                  PyTuple_GET_SIZE(key));
2455     return -1;
2456   }
2457   else if (self->ptr.type != &RNA_BlendData) {
2458     PyErr_Format(PyExc_KeyError,
2459                  "%s: is only valid for bpy.data collections, not %.200s",
2460                  err_prefix,
2461                  RNA_struct_identifier(self->ptr.type));
2462     return -1;
2463   }
2464   else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
2465     PyErr_Format(PyExc_KeyError,
2466                  "%s: id must be a string, not %.200s",
2467                  err_prefix,
2468                  Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
2469     return -1;
2470   }
2471   else {
2472     PyObject *keylib = PyTuple_GET_ITEM(key, 1);
2473     Library *lib;
2474     bool found = false;
2475
2476     if (keylib == Py_None) {
2477       lib = NULL;
2478     }
2479     else if (PyUnicode_Check(keylib)) {
2480       Main *bmain = self->ptr.data;
2481       const char *keylib_str = _PyUnicode_AsString(keylib);
2482       lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, name));
2483       if (lib == NULL) {
2484         if (err_not_found) {
2485           PyErr_Format(PyExc_KeyError,
2486                        "%s: lib name '%.240s' "
2487                        "does not reference a valid library",
2488                        err_prefix,
2489                        keylib_str);
2490           return -1;
2491         }
2492         else {
2493           return 0;
2494         }
2495       }
2496     }
2497     else {
2498       PyErr_Format(PyExc_KeyError,
2499                    "%s: lib must be a string or None, not %.200s",
2500                    err_prefix,
2501                    Py_TYPE(keylib)->tp_name);
2502       return -1;
2503     }
2504
2505     /* lib is either a valid pointer or NULL,
2506      * either way can do direct comparison with id.lib */
2507
2508     RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
2509       ID *id = itemptr.data; /* Always an ID. */
2510       if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
2511         found = true;
2512         if (r_ptr) {
2513           *r_ptr = itemptr;
2514         }
2515         break;
2516       }
2517     }
2518     RNA_PROP_END;
2519
2520     /* We may want to fail silently as with collection.get(). */
2521     if ((found == false) && err_not_found) {
2522       /* Only runs for getitem access so use fixed string. */
2523       PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found");
2524       return -1;
2525     }
2526     else {
2527       return found; /* 1 / 0, no exception. */
2528     }
2529   }
2530 }
2531
2532 static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self,
2533                                                               PyObject *key,
2534                                                               const char *err_prefix,
2535                                                               const bool err_not_found)
2536 {
2537   PointerRNA ptr;
2538   const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(
2539       self, key, err_prefix, err_not_found, &ptr);
2540
2541   if (contains == 1) {
2542     return pyrna_struct_CreatePyObject(&ptr);
2543   }
2544   else {
2545     return NULL;
2546   }
2547 }
2548
2549 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self,
2550                                                        Py_ssize_t start,
2551                                                        Py_ssize_t stop)
2552 {
2553   CollectionPropertyIterator rna_macro_iter;
2554   int count;
2555
2556   PyObject *list;
2557   PyObject *item;
2558
2559   PYRNA_PROP_CHECK_OBJ(self);
2560
2561   list = PyList_New(0);
2562
2563   /* Skip to start. */
2564   RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
2565   RNA_property_collection_skip(&rna_macro_iter, start);
2566
2567   /* Add items until stop. */
2568   for (count = start; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
2569     item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2570     PyList_APPEND(list, item);
2571
2572     count++;
2573     if (count == stop) {
2574       break;
2575     }
2576   }
2577
2578   RNA_property_collection_end(&rna_macro_iter);
2579
2580   return list;
2581 }
2582
2583 /** TODO - dimensions
2584  * \note Could also use pyrna_prop_array_to_py_index(self, count) in a loop, but it's much slower
2585  * since at the moment it reads (and even allocates) the entire array for each index.
2586  */
2587 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self,
2588                                                   PointerRNA *ptr,
2589                                                   PropertyRNA *prop,
2590                                                   Py_ssize_t start,
2591                                                   Py_ssize_t stop,
2592                                                   Py_ssize_t length)
2593 {
2594   int count, totdim;
2595   PyObject *tuple;
2596
2597   /* Isn't needed, internal use only. */
2598   // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2599
2600   tuple = PyTuple_New(stop - start);
2601
2602   totdim = RNA_property_array_dimension(ptr, prop, NULL);
2603
2604   if (totdim > 1) {
2605     for (count = start; count < stop; count++) {
2606       PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2607     }
2608   }
2609   else {
2610     switch (RNA_property_type(prop)) {
2611       case PROP_FLOAT: {
2612         float values_stack[PYRNA_STACK_ARRAY];
2613         float *values;
2614         if (length > PYRNA_STACK_ARRAY) {
2615           values = PyMem_MALLOC(sizeof(float) * length);
2616         }
2617         else {
2618           values = values_stack;
2619         }
2620         RNA_property_float_get_array(ptr, prop, values);
2621
2622         for (count = start; count < stop; count++) {
2623           PyTuple_SET_ITEM(tuple, count - start, PyFloat_FromDouble(values[count]));
2624         }
2625
2626         if (values != values_stack) {
2627           PyMem_FREE(values);
2628         }
2629         break;
2630       }
2631       case PROP_BOOLEAN: {
2632         bool values_stack[PYRNA_STACK_ARRAY];
2633         bool *values;
2634         if (length > PYRNA_STACK_ARRAY) {
2635           values = PyMem_MALLOC(sizeof(bool) * length);
2636         }
2637         else {
2638           values = values_stack;
2639         }
2640
2641         RNA_property_boolean_get_array(ptr, prop, values);
2642         for (count = start; count < stop; count++) {
2643           PyTuple_SET_ITEM(tuple, count - start, PyBool_FromLong(values[count]));
2644         }
2645
2646         if (values != values_stack) {
2647           PyMem_FREE(values);
2648         }
2649         break;
2650       }
2651       case PROP_INT: {
2652         int values_stack[PYRNA_STACK_ARRAY];
2653         int *values;
2654         if (length > PYRNA_STACK_ARRAY) {
2655           values = PyMem_MALLOC(sizeof(int) * length);
2656         }
2657         else {
2658           values = values_stack;
2659         }
2660
2661         RNA_property_int_get_array(ptr, prop, values);
2662         for (count = start; count < stop; count++) {
2663           PyTuple_SET_ITEM(tuple, count - start, PyLong_FromLong(values[count]));
2664         }
2665
2666         if (values != values_stack) {
2667           PyMem_FREE(values);
2668         }
2669         break;
2670       }
2671       default:
2672         BLI_assert(!"Invalid array type");
2673
2674         PyErr_SetString(PyExc_TypeError, "not an array type");
2675         Py_DECREF(tuple);
2676         tuple = NULL;
2677         break;
2678     }
2679   }
2680   return tuple;
2681 }
2682
2683 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
2684 {
2685   PYRNA_PROP_CHECK_OBJ(self);
2686
2687   if (PyUnicode_Check(key)) {
2688     return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2689   }
2690   else if (PyIndex_Check(key)) {
2691     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2692     if (i == -1 && PyErr_Occurred()) {
2693       return NULL;
2694     }
2695
2696     return pyrna_prop_collection_subscript_int(self, i);
2697   }
2698   else if (PySlice_Check(key)) {
2699     PySliceObject *key_slice = (PySliceObject *)key;
2700     Py_ssize_t step = 1;
2701
2702     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2703       return NULL;
2704     }
2705     else if (step != 1) {
2706       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2707       return NULL;
2708     }
2709     else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2710       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2711     }
2712     else {
2713       Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2714
2715       /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2716       if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
2717         return NULL;
2718       }
2719       if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
2720         return NULL;
2721       }
2722
2723       if (start < 0 || stop < 0) {
2724         /* Only get the length for negative values. */
2725         Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2726         if (start < 0) {
2727           start += len;
2728         }
2729         if (stop < 0) {
2730           stop += len;
2731         }
2732       }
2733
2734       if (stop - start <= 0) {
2735         return PyList_New(0);
2736       }
2737       else {
2738         return pyrna_prop_collection_subscript_slice(self, start, stop);
2739       }
2740     }
2741   }
2742   else if (PyTuple_Check(key)) {
2743     /* Special case, for ID datablocks we. */
2744     return pyrna_prop_collection_subscript_str_lib_pair(
2745         self, key, "bpy_prop_collection[id, lib]", true);
2746   }
2747   else {
2748     PyErr_Format(PyExc_TypeError,
2749                  "bpy_prop_collection[key]: invalid key, "
2750                  "must be a string or an int, not %.200s",
2751                  Py_TYPE(key)->tp_name);
2752     return NULL;
2753   }
2754 }
2755
2756 /* generic check to see if a PyObject is compatible with a collection
2757  * -1 on failure, 0 on success, sets the error */
2758 static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
2759 {
2760   StructRNA *prop_srna;
2761
2762   if (value == Py_None) {
2763     if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2764       PyErr_Format(PyExc_TypeError,
2765                    "bpy_prop_collection[key] = value: invalid, "
2766                    "this collection doesn't support None assignment");
2767       return -1;
2768     }
2769     else {
2770       return 0; /* None is OK. */
2771     }
2772   }
2773   else if (BPy_StructRNA_Check(value) == 0) {
2774     PyErr_Format(PyExc_TypeError,
2775                  "bpy_prop_collection[key] = value: invalid, "
2776                  "expected a StructRNA type or None, not a %.200s",
2777                  Py_TYPE(value)->tp_name);
2778     return -1;
2779   }
2780   else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
2781     StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
2782     if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2783       PyErr_Format(PyExc_TypeError,
2784                    "bpy_prop_collection[key] = value: invalid, "
2785                    "expected a '%.200s' type or None, not a '%.200s'",
2786                    RNA_struct_identifier(prop_srna),
2787                    RNA_struct_identifier(value_srna));
2788       return -1;
2789     }
2790     else {
2791       return 0; /* OK, this is the correct type! */
2792     }
2793   }
2794
2795   PyErr_Format(PyExc_TypeError,
2796                "bpy_prop_collection[key] = value: internal error, "
2797                "failed to get the collection type");
2798   return -1;
2799 }
2800
2801 /* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
2802  * large blocks commented, we may support slice/key indices later */
2803 static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self,
2804                                                PyObject *key,
2805                                                PyObject *value)
2806 {
2807   PYRNA_PROP_CHECK_INT(self);
2808
2809   /* Validate the assigned value. */
2810   if (value == NULL) {
2811     PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported");
2812     return -1;
2813   }
2814   else if (pyrna_prop_collection_type_check(self, value) == -1) {
2815     return -1; /* Exception is set. */
2816   }
2817
2818 #if 0
2819   if (PyUnicode_Check(key)) {
2820     return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2821   }
2822   else
2823 #endif
2824   if (PyIndex_Check(key)) {
2825     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2826     if (i == -1 && PyErr_Occurred()) {
2827       return -1;
2828     }
2829
2830     return pyrna_prop_collection_ass_subscript_int(self, i, value);
2831   }
2832 #if 0 /* TODO, fake slice assignment. */
2833   else if (PySlice_Check(key)) {
2834     PySliceObject *key_slice = (PySliceObject *)key;
2835     Py_ssize_t step = 1;
2836
2837     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2838       return NULL;
2839     }
2840     else if (step != 1) {
2841       PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2842       return NULL;
2843     }
2844     else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2845       return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2846     }
2847     else {
2848       Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2849
2850       /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2851       if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
2852         return NULL;
2853       }
2854       if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
2855         return NULL;
2856       }
2857
2858       if (start < 0 || stop < 0) {
2859         /* Only get the length for negative values. */
2860         Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2861         if (start < 0) {
2862           start += len;
2863         }
2864         if (stop < 0) {
2865           stop += len;
2866         }
2867       }
2868
2869       if (stop - start <= 0) {
2870         return PyList_New(0);
2871       }
2872       else {
2873         return pyrna_prop_collection_subscript_slice(self, start, stop);
2874       }
2875     }
2876   }
2877 #endif
2878   else {
2879     PyErr_Format(PyExc_TypeError,
2880                  "bpy_prop_collection[key]: invalid key, "
2881                  "must be a string or an int, not %.200s",
2882                  Py_TYPE(key)->tp_name);
2883     return -1;
2884   }
2885 }
2886
2887 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
2888 {
2889   PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2890
2891 #if 0
2892   if (PyUnicode_Check(key)) {
2893     return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
2894   }
2895   else
2896 #endif
2897   if (PyIndex_Check(key)) {
2898     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2899     if (i == -1 && PyErr_Occurred()) {
2900       return NULL;
2901     }
2902     return pyrna_prop_array_subscript_int(self, i);
2903   }
2904   else if (PySlice_Check(key)) {
2905     Py_ssize_t step = 1;
2906     PySliceObject *key_slice = (PySliceObject *)key;
2907
2908     if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2909       return NULL;
2910     }
2911     else if (step != 1) {
2912       PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2913       return NULL;
2914     }
2915     else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2916       /* Note: no significant advantage with optimizing [:] slice as with collections,
2917        * but include here for consistency with collection slice func */
2918       Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
2919       return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2920     }
2921     else {
2922       int len = pyrna_prop_array_length(self);
2923       Py_ssize_t start, stop, slicelength;
2924
2925       if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
2926         return NULL;
2927       }
2928
2929       if (slicelength <= 0) {
2930         return PyTuple_New(0);
2931       }
2932       else {
2933         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2934       }
2935     }
2936   }
2937   else {
2938     PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2939     return NULL;
2940   }
2941 }
2942
2943 /**
2944  * Helpers for #prop_subscript_ass_array_slice
2945  */
2946
2947 static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, int length)
2948 {
2949   PyObject *value_fast;
2950   if (!(value_fast = PySequence_Fast(value,
2951                                      "bpy_prop_array[slice] = value: "
2952                                      "element in assignment is not a sequence type"))) {
2953     return NULL;
2954   }
2955   else if (PySequence_Fast_GET_SIZE(value_fast) != length) {
2956     Py_DECREF(value_fast);
2957     PyErr_SetString(PyExc_ValueError,
2958                     "bpy_prop_array[slice] = value: "
2959                     "re-sizing bpy_struct element in arrays isn't supported");
2960
2961     return NULL;
2962   }
2963   else {
2964     return value_fast;
2965   }
2966 }
2967
2968 static int prop_subscript_ass_array_slice__float_recursive(
2969     PyObject **value_items, float *value, int totdim, const int dimsize[], const float range[2])
2970 {
2971   const int length = dimsize[0];
2972   if (totdim > 1) {
2973     int index = 0;
2974     int i;
2975     for (i = 0; i != length; i++) {
2976       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
2977       if (UNLIKELY(subvalue == NULL)) {
2978         return 0;
2979       }
2980
2981       index += prop_subscript_ass_array_slice__float_recursive(
2982           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range);
2983
2984       Py_DECREF(subvalue);
2985     }
2986     return index;
2987   }
2988   else {
2989     BLI_assert(totdim == 1);
2990     const float min = range[0], max = range[1];
2991     int i;
2992     for (i = 0; i != length; i++) {
2993       float v = PyFloat_AsDouble(value_items[i]);
2994       CLAMP(v, min, max);
2995       value[i] = v;
2996     }
2997     return i;
2998   }
2999 }
3000
3001 static int prop_subscript_ass_array_slice__int_recursive(
3002     PyObject **value_items, int *value, int totdim, const int dimsize[], const int range[2])
3003 {
3004   const int length = dimsize[0];
3005   if (totdim > 1) {
3006     int index = 0;
3007     int i;
3008     for (i = 0; i != length; i++) {
3009       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
3010       if (UNLIKELY(subvalue == NULL)) {
3011         return 0;
3012       }
3013
3014       index += prop_subscript_ass_array_slice__int_recursive(
3015           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1], range);
3016
3017       Py_DECREF(subvalue);
3018     }
3019     return index;
3020   }
3021   else {
3022     BLI_assert(totdim == 1);
3023     const int min = range[0], max = range[1];
3024     int i;
3025     for (i = 0; i != length; i++) {
3026       int v = PyLong_AsLong(value_items[i]);
3027       CLAMP(v, min, max);
3028       value[i] = v;
3029     }
3030     return i;
3031   }
3032 }
3033
3034 static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items,
3035                                                           bool *value,
3036                                                           int totdim,
3037                                                           const int dimsize[])
3038 {
3039   const int length = dimsize[0];
3040   if (totdim > 1) {
3041     int index = 0;
3042     int i;
3043     for (i = 0; i != length; i++) {
3044       PyObject *subvalue = prop_subscript_ass_array_slice__as_seq_fast(value_items[i], dimsize[1]);
3045       if (UNLIKELY(subvalue == NULL)) {
3046         return 0;
3047       }
3048
3049       index += prop_subscript_ass_array_slice__bool_recursive(
3050           PySequence_Fast_ITEMS(subvalue), &value[index], totdim - 1, &dimsize[1]);
3051
3052       Py_DECREF(subvalue);
3053     }
3054     return index;
3055   }
3056   else {
3057     BLI_assert(totdim == 1);
3058     int i;
3059     for (i = 0; i != length; i++) {
3060       int v = PyLong_AsLong(value_items[i]);
3061       value[i] = v;
3062     }
3063     return i;
3064   }
3065 }
3066
3067 /* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */
3068 static int prop_subscript_ass_array_slice(PointerRNA *ptr,
3069                                           PropertyRNA *prop,
3070                                           int arraydim,
3071                                           int arrayoffset,
3072                                           int start,
3073                                           int stop,
3074                                           int length,
3075                                           PyObject *value_orig)
3076 {
3077   const int length_flat = RNA_property_array_length(ptr, prop);
3078   PyObject *value;
3079   PyObject **value_items;
3080   void *values_alloc = NULL;
3081   int ret = 0;
3082
3083   if (value_orig == NULL) {
3084     PyErr_SetString(
3085         PyExc_TypeError,
3086         "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
3087     return -1;
3088   }
3089
3090   if (!(value = PySequence_Fast(
3091             value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
3092     return -1;
3093   }
3094
3095   if (PySequence_Fast_GET_SIZE(value) != stop - start) {
3096     Py_DECREF(value);
3097     PyErr_SetString(PyExc_TypeError,
3098                     "bpy_prop_array[slice] = value: re-sizing bpy_struct arrays isn't supported");
3099     return -1;
3100   }
3101
3102   int dimsize[3];
3103   int totdim = RNA_property_array_dimension(ptr, prop, dimsize);
3104   if (totdim > 1) {
3105     BLI_assert(dimsize[arraydim] == length);
3106   }
3107
3108   int span = 1;
3109   if (totdim > 1) {
3110     for (int i = arraydim + 1; i < totdim; i++) {
3111       span *= dimsize[i];
3112     }
3113   }
3114
3115   value_items = PySequence_Fast_ITEMS(value);
3116   switch (RNA_property_type(prop)) {
3117     case PROP_FLOAT: {
3118       float values_stack[PYRNA_STACK_ARRAY];
3119       float *values = (length_flat > PYRNA_STACK_ARRAY) ?
3120                           (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) :
3121                           values_stack;
3122       if (start != 0 || stop != length) {
3123         /* Partial assignment? - need to get the array. */
3124         RNA_property_float_get_array(ptr, prop, values);
3125       }
3126
3127       float range[2];
3128       RNA_property_float_range(ptr, prop, &range[0], &range[1]);
3129
3130       dimsize[arraydim] = stop - start;
3131       prop_subscript_ass_array_slice__float_recursive(value_items,
3132                                                       &values[arrayoffset + (start * span)],
3133                                                       totdim - arraydim,
3134                                                       &dimsize[arraydim],
3135                                                       range);
3136
3137       if (PyErr_Occurred()) {
3138         ret = -1;
3139       }
3140       else {
3141         RNA_property_float_set_array(ptr, prop, values);
3142       }
3143       break;
3144     }
3145     case PROP_INT: {
3146       int values_stack[PYRNA_STACK_ARRAY];
3147       int *values = (length_flat > PYRNA_STACK_ARRAY) ?
3148                         (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) :
3149                         values_stack;
3150       if (start != 0 || stop != length) {
3151         /* Partial assignment? - need to get the array. */
3152         RNA_property_int_get_array(ptr, prop, values);
3153       }
3154
3155       int range[2];
3156       RNA_property_int_range(ptr, prop, &range[0], &range[1]);
3157
3158       dimsize[arraydim] = stop - start;
3159       prop_subscript_ass_array_slice__int_recursive(value_items,
3160                                                     &values[arrayoffset + (start * span)],
3161                                                     totdim - arraydim,
3162                                                     &dimsize[arraydim],
3163                                                     range);
3164
3165       if (PyErr_Occurred()) {
3166         ret = -1;
3167       }
3168       else {
3169         RNA_property_int_set_array(ptr, prop, values);
3170       }
3171       break;
3172     }
3173     case PROP_BOOLEAN: {
3174       bool values_stack[PYRNA_STACK_ARRAY];
3175       bool *values = (length_flat > PYRNA_STACK_ARRAY) ?
3176                          (values_alloc = PyMem_MALLOC(sizeof(bool) * length_flat)) :
3177                          values_stack;
3178
3179       if (start != 0 || stop != length) {
3180         /* Partial assignment? - need to get the array. */
3181         RNA_property_boolean_get_array(ptr, prop, values);
3182       }
3183
3184       dimsize[arraydim] = stop - start;
3185       prop_subscript_ass_array_slice__bool_recursive(value_items,
3186                                                      &values[arrayoffset + (start * span)],
3187                                                      totdim - arraydim,
3188                                                      &dimsize[arraydim]);
3189
3190       if (PyErr_Occurred()) {
3191         ret = -1;
3192       }
3193       else {
3194         RNA_property_boolean_set_array(ptr, prop, values);
3195       }
3196       break;
3197     }
3198     default:
3199       PyErr_SetString(PyExc_TypeError, "not an array type");
3200       ret = -1;
3201       break;
3202   }
3203
3204   Py_DECREF(value);
3205
3206   if (values_alloc) {
3207     PyMem_FREE(values_alloc);
3208   }
3209
3210   return ret;
3211 }
3212
3213 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self,
3214                                         Py_ssize_t keynum,
3215                                         PyObject *value)
3216 {
3217   int len;
3218
3219   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
3220
3221   len = pyrna_prop_array_length(self);
3222
3223   if (keynum < 0) {
3224     keynum += len;
3225   }
3226
3227   if (keynum >= 0 && keynum < len) {
3228     return pyrna_py_to_prop_array_index(self, keynum, value);
3229   }
3230
3231   PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
3232   return -1;
3233 }
3234
3235 static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
3236                                           PyObject *key,
3237                                           PyObject *value)
3238 {
3239   // char *keyname = NULL; /* Not supported yet. */
3240   int ret = -1;
3241
3242   PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
3243
3244   if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
3245     PyErr_Format(PyExc_AttributeError,
3246                  "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
3247                  RNA_property_identifier(self->prop),
3248                  RNA_struct_identifier(self->ptr.type));
3249     ret = -1;
3250   }
3251
3252   else if (PyIndex_Check(key)) {
3253     Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
3254     if (i == -1 && PyErr_Occurred()) {
3255       ret = -1;
3256     }
3257     else {
3258       ret = prop_subscript_ass_array_int(self, i, value);
3259     }
3260   }
3261   else if (PySlice_Check(key)) {
3262     Py_ssize_t len = pyrna_prop_array_length(self);
3263     Py_ssize_t start, stop, step, slicelength;
3264
3265     if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
3266       ret = -1;
3267     }
3268     else if (slicelength <= 0) {
3269       ret = 0; /* Do nothing. */
3270     }
3271     else if (step == 1) {
3272       ret = prop_subscript_ass_array_slice(
3273           &self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value);
3274     }
3275     else {
3276       PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA");
3277       ret = -1;
3278     }
3279   }
3280   else {
3281     PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
3282     ret = -1;
3283   }
3284
3285   if (ret != -1) {
3286     if (RNA_property_update_check(self->prop)) {
3287       RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
3288     }
3289   }
3290
3291   return ret;
3292 }
3293
3294 /* For slice only. */
3295 static PyMappingMethods pyrna_prop_array_as_mapping = {
3296     (lenfunc)pyrna_prop_array_length,              /* mp_length */
3297     (binaryfunc)pyrna_prop_array_subscript,        /* mp_subscript */
3298     (objobjargproc)pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
3299 };
3300
3301 static PyMappingMethods pyrna_prop_collection_as_mapping = {
3302     (lenfunc)pyrna_prop_collection_length,              /* mp_length */
3303     (binaryfunc)pyrna_prop_collection_subscript,        /* mp_subscript */
3304     (objobjargproc)pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */
3305 };
3306
3307 /* Only for fast bool's, large structs, assign nb_bool on init. */
3308 static PyNumberMethods pyrna_prop_array_as_number = {
3309     NULL,                           /* nb_add */
3310     NULL,                           /* nb_subtract */
3311     NULL,                           /* nb_multiply */
3312     NULL,                           /* nb_remainder */
3313     NULL,                           /* nb_divmod */
3314     NULL,                           /* nb_power */
3315     NULL,                           /* nb_negative */
3316     NULL,                           /* nb_positive */
3317     NULL,                           /* nb_absolute */
3318     (inquiry)pyrna_prop_array_bool, /* nb_bool */
3319 };
3320 static PyNumberMethods pyrna_prop_collection_as_number = {
3321     NULL,                                /* nb_add */
3322     NULL,                                /* nb_subtract */
3323     NULL,                                /* nb_multiply */
3324     NULL,                                /* nb_remainder */
3325     NULL,                                /* nb_divmod */
3326     NULL,                                /* nb_power */
3327     NULL,                                /* nb_negative */
3328     NULL,                                /* nb_positive */
3329     NULL,                                /* nb_absolute */
3330     (inquiry)pyrna_prop_collection_bool, /* nb_bool */
3331 };
3332
3333 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
3334 {
3335   return pyrna_array_contains_py(&self->ptr, self->prop, value);
3336 }
3337
3338 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
3339 {
3340   PointerRNA newptr; /* Not used, just so RNA_property_collection_lookup_string runs. */
3341
3342   if (PyTuple_Check(key)) {
3343     /* Special case, for ID data-blocks. */
3344     return pyrna_prop_collection_subscript_str_lib_pair_ptr(
3345         self, key, "(id, lib) in bpy_prop_collection", false, NULL);
3346   }
3347   else {
3348
3349     /* Key in dict style check. */
3350     const char *keyname = _PyUnicode_AsString(key);
3351
3352     if (keyname == NULL) {
3353       PyErr_SetString(PyExc_TypeError,
3354                       "bpy_prop_collection.__contains__: expected a string or a tuple of strings");
3355       return -1;
3356     }
3357
3358     if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
3359       return 1;
3360     }
3361
3362     return 0;
3363   }
3364 }
3365
3366 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
3367 {
3368   IDProperty *group;
3369   const char *name = _PyUnicode_AsString(value);
3370
3371   PYRNA_STRUCT_CHECK_INT(self);
3372
3373   if (!name) {
3374     PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
3375     return -1;
3376   }
3377
3378   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3379     PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
3380     return -1;
3381   }
3382
3383   group = RNA_struct_idprops(&self->ptr, 0);
3384
3385   if (!group) {
3386     return 0;
3387   }
3388
3389   return IDP_GetPropertyFromGroup(group, name) ? 1 : 0;
3390 }
3391
3392 static PySequenceMethods pyrna_prop_array_as_sequence = {
3393     (lenfunc)pyrna_prop_array_length,
3394     NULL, /* sq_concat */
3395     NULL, /* sq_repeat */
3396     (ssizeargfunc)pyrna_prop_array_subscript_int,
3397     /* sq_item */ /* Only set this so PySequence_Check() returns True */
3398     NULL,         /* sq_slice */
3399     (ssizeobjargproc)prop_subscript_ass_array_int, /* sq_ass_item */
3400     NULL,                                          /* *was* sq_ass_slice */
3401     (objobjproc)pyrna_prop_array_contains,         /* sq_contains */
3402     (binaryfunc)NULL,                              /* sq_inplace_concat */
3403     (ssizeargfunc)NULL,                            /* sq_inplace_repeat */
3404 };
3405
3406 static PySequenceMethods pyrna_prop_collection_as_sequence = {
3407     (lenfunc)pyrna_prop_collection_length,
3408     NULL, /* sq_concat */
3409     NULL, /* sq_repeat */
3410     (ssizeargfunc)pyrna_prop_collection_subscript_int,
3411     /* sq_item */                         /* Only set this so PySequence_Check() returns True */
3412     NULL,                                 /* *was* sq_slice */
3413     (ssizeobjargproc)                     /* pyrna_prop_collection_ass_subscript_int */
3414     NULL /* let mapping take this one */, /* sq_ass_item */
3415     NULL,                                 /* *was* sq_ass_slice */
3416     (objobjproc)pyrna_prop_collection_contains, /* sq_contains */
3417     (binaryfunc)NULL,                           /* sq_inplace_concat */
3418     (ssizeargfunc)NULL,                         /* sq_inplace_repeat */
3419 };
3420
3421 static PySequenceMethods pyrna_struct_as_sequence = {
3422     NULL, /* Can't set the len otherwise it can evaluate as false */
3423     NULL, /* sq_concat */
3424     NULL, /* sq_repeat */
3425     NULL,
3426     /* sq_item */                      /* Only set this so PySequence_Check() returns True */
3427     NULL,                              /* *was* sq_slice */
3428     NULL,                              /* sq_ass_item */
3429     NULL,                              /* *was* sq_ass_slice */
3430     (objobjproc)pyrna_struct_contains, /* sq_contains */
3431     (binaryfunc)NULL,                  /* sq_inplace_concat */
3432     (ssizeargfunc)NULL,                /* sq_inplace_repeat */
3433 };
3434
3435 static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
3436 {
3437   /* Mostly copied from BPy_IDGroup_Map_GetItem. */
3438   IDProperty *group, *idprop;
3439   const char *name = _PyUnicode_AsString(key);
3440
3441   PYRNA_STRUCT_CHECK_OBJ(self);
3442
3443   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3444     PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
3445     return NULL;
3446   }
3447
3448   if (name == NULL) {
3449     PyErr_SetString(PyExc_TypeError,
3450                     "bpy_struct[key]: only strings are allowed as keys of ID properties");
3451     return NULL;
3452   }
3453
3454   group = RNA_struct_idprops(&self->ptr, 0);
3455
3456   if (group == NULL) {
3457     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
3458     return NULL;
3459   }
3460
3461   idprop = IDP_GetPropertyFromGroup(group, name);
3462
3463   if (idprop == NULL) {
3464     PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
3465     return NULL;
3466   }
3467
3468   return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
3469 }
3470
3471 static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
3472 {
3473   IDProperty *group;
3474
3475   PYRNA_STRUCT_CHECK_INT(self);
3476
3477   group = RNA_struct_idprops(&self->ptr, 1);
3478
3479 #ifdef USE_PEDANTIC_WRITE
3480   if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
3481     return -1;
3482   }
3483 #endif /* USE_PEDANTIC_WRITE */
3484
3485   if (group == NULL) {
3486     PyErr_SetString(PyExc_TypeError,
3487                     "bpy_struct[key] = val: id properties not supported for this type");
3488     return -1;
3489   }
3490
3491   if (value && BPy_StructRNA_Check(value)) {
3492     BPy_StructRNA *val = (BPy_StructRNA *)value;
3493     if (val && self->ptr.type && val->ptr.type) {
3494       if (!RNA_struct_idprops_datablock_allowed(self->ptr.type) &&
3495           RNA_struct_idprops_contains_datablock(val->ptr.type)) {
3496         PyErr_SetString(
3497             PyExc_TypeError,
3498             "bpy_struct[key] = val: datablock id properties not supported for this type");
3499         return -1;
3500       }
3501     }
3502   }
3503
3504   return BPy_Wrap_SetMapItem(group, key, value);
3505 }
3506
3507 static PyMappingMethods pyrna_struct_as_mapping = {
3508     (lenfunc)NULL,                             /* mp_length */
3509     (binaryfunc)pyrna_struct_subscript,        /* mp_subscript */
3510     (objobjargproc)pyrna_struct_ass_subscript, /* mp_ass_subscript */
3511 };
3512
3513 PyDoc_STRVAR(pyrna_struct_keys_doc,
3514              ".. method:: keys()\n"
3515              "\n"
3516              "   Returns the keys of this objects custom properties (matches Python's\n"
3517              "   dictionary function of the same name).\n"
3518              "\n"
3519              "   :return: custom property keys.\n"
3520              "   :rtype: list of strings\n"
3521              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
3522 static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
3523 {
3524   IDProperty *group;
3525
3526   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3527     PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
3528     return NULL;
3529   }
3530
3531   group = RNA_struct_idprops(&self->ptr, 0);
3532
3533   if (group == NULL) {
3534     return PyList_New(0);
3535   }
3536
3537   return BPy_Wrap_GetKeys(group);
3538 }
3539
3540 PyDoc_STRVAR(pyrna_struct_items_doc,
3541              ".. method:: items()\n"
3542              "\n"
3543              "   Returns the items of this objects custom properties (matches Python's\n"
3544              "   dictionary function of the same name).\n"
3545              "\n"
3546              "   :return: custom property key, value pairs.\n"
3547              "   :rtype: list of key, value tuples\n"
3548              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
3549 static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
3550 {
3551   IDProperty *group;
3552
3553   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3554     PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
3555     return NULL;
3556   }
3557
3558   group = RNA_struct_idprops(&self->ptr, 0);
3559
3560   if (group == NULL) {
3561     return PyList_New(0);
3562   }
3563
3564   return BPy_Wrap_GetItems(self->ptr.owner_id, group);
3565 }
3566
3567 PyDoc_STRVAR(pyrna_struct_values_doc,
3568              ".. method:: values()\n"
3569              "\n"
3570              "   Returns the values of this objects custom properties (matches Python's\n"
3571              "   dictionary function of the same name).\n"
3572              "\n"
3573              "   :return: custom property values.\n"
3574              "   :rtype: list\n"
3575              "\n" BPY_DOC_ID_PROP_TYPE_NOTE);
3576 static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
3577 {
3578   IDProperty *group;
3579
3580   if (RNA_struct_idprops_check(self->ptr.type) == 0) {
3581     PyErr_SetString(PyExc_TypeError,
3582                     "bpy_struct.values(): this type doesn't support IDProperties");
3583     return NULL;
3584   }
3585
3586   group = RNA_struct_idprops(&self->ptr, 0);
3587
3588   if (group == NULL) {
3589     return PyList_New(0);
3590   }
3591
3592   return BPy_Wrap_GetValues(self->ptr.owner_id, group);
3593 }
3594
3595 PyDoc_STRVAR(pyrna_struct_is_property_set_doc,
3596              ".. method:: is_property_set(property)\n"
3597              "\n"
3598              "   Check if a property is set, use for testing operator properties.\n"
3599              "\n"
3600              "   :return: True when the property has been set.\n"
3601              "   :rtype: boolean\n");
3602 static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
3603 {
3604   PropertyRNA *prop;
3605   const char *name;
3606
3607   PYRNA_STRUCT_CHECK_OBJ(self);
3608
3609   if (!PyArg_ParseTuple(args, "s:is_property_set", &name)) {
3610     return NULL;
3611   }
3612
3613   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3614     PyErr_Format(PyExc_TypeError,
3615                  "%.200s.is_property_set(\"%.200s\") not found",
3616                  RNA_struct_identifier(self->ptr.type),
3617                  name);
3618     return NULL;
3619   }
3620
3621   return PyBool_FromLong(RNA_property_is_set(&self->ptr, prop));
3622 }
3623
3624 PyDoc_STRVAR(pyrna_struct_property_unset_doc,
3625              ".. method:: property_unset(property)\n"
3626              "\n"
3627              "   Unset a property, will use default value afterward.\n");
3628 static PyObject *pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args)
3629 {
3630   PropertyRNA *prop;
3631   const char *name;
3632
3633   PYRNA_STRUCT_CHECK_OBJ(self);
3634
3635   if (!PyArg_ParseTuple(args, "s:property_unset", &name)) {
3636     return NULL;
3637   }
3638
3639   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3640     PyErr_Format(PyExc_TypeError,
3641                  "%.200s.property_unset(\"%.200s\") not found",
3642                  RNA_struct_identifier(self->ptr.type),
3643                  name);
3644     return NULL;
3645   }
3646
3647   RNA_property_unset(&self->ptr, prop);
3648
3649   Py_RETURN_NONE;
3650 }
3651
3652 PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc,
3653              ".. method:: is_property_hidden(property)\n"
3654              "\n"
3655              "   Check if a property is hidden.\n"
3656              "\n"
3657              "   :return: True when the property is hidden.\n"
3658              "   :rtype: boolean\n");
3659 static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
3660 {
3661   PropertyRNA *prop;
3662   const char *name;
3663
3664   PYRNA_STRUCT_CHECK_OBJ(self);
3665
3666   if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) {
3667     return NULL;
3668   }
3669
3670   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3671     PyErr_Format(PyExc_TypeError,
3672                  "%.200s.is_property_hidden(\"%.200s\") not found",
3673                  RNA_struct_identifier(self->ptr.type),
3674                  name);
3675     return NULL;
3676   }
3677
3678   return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN);
3679 }
3680
3681 PyDoc_STRVAR(pyrna_struct_is_property_readonly_doc,
3682              ".. method:: is_property_readonly(property)\n"
3683              "\n"
3684              "   Check if a property is readonly.\n"
3685              "\n"
3686              "   :return: True when the property is readonly (not writable).\n"
3687              "   :rtype: boolean\n");
3688 static PyObject *pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject *args)
3689 {
3690   PropertyRNA *prop;
3691   const char *name;
3692
3693   PYRNA_STRUCT_CHECK_OBJ(self);
3694
3695   if (!PyArg_ParseTuple(args, "s:is_property_readonly", &name)) {
3696     return NULL;
3697   }
3698
3699   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3700     PyErr_Format(PyExc_TypeError,
3701                  "%.200s.is_property_readonly(\"%.200s\") not found",
3702                  RNA_struct_identifier(self->ptr.type),
3703                  name);
3704     return NULL;
3705   }
3706
3707   return PyBool_FromLong(!RNA_property_editable(&self->ptr, prop));
3708 }
3709
3710 PyDoc_STRVAR(pyrna_struct_is_property_overridable_library_doc,
3711              ".. method:: is_property_overridable_library(property)\n"
3712              "\n"
3713              "   Check if a property is statically overridable.\n"
3714              "\n"
3715              "   :return: True when the property is statically overridable.\n"
3716              "   :rtype: boolean\n");
3717 static PyObject *pyrna_struct_is_property_overridable_library(BPy_StructRNA *self, PyObject *args)
3718 {
3719   PropertyRNA *prop;
3720   const char *name;
3721
3722   PYRNA_STRUCT_CHECK_OBJ(self);
3723
3724   if (!PyArg_ParseTuple(args, "s:is_property_overridable_library", &name)) {
3725     return NULL;
3726   }
3727
3728   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3729     PyErr_Format(PyExc_TypeError,
3730                  "%.200s.is_property_overridable_library(\"%.200s\") not found",
3731                  RNA_struct_identifier(self->ptr.type),
3732                  name);
3733     return NULL;
3734   }
3735
3736   return PyBool_FromLong((long)RNA_property_overridable_get(&self->ptr, prop));
3737 }
3738
3739 PyDoc_STRVAR(
3740     pyrna_struct_property_overridable_library_set_doc,
3741     ".. method:: property_overridable_library_set(property)\n"
3742     "\n"
3743     "   Define a property as statically overridable or not (only for custom properties!).\n"
3744     "\n"
3745     "   :return: True when the overridable status of the property was successfully set.\n"
3746     "   :rtype: boolean\n");
3747 static PyObject *pyrna_struct_property_overridable_library_set(BPy_StructRNA *self, PyObject *args)
3748 {
3749   PropertyRNA *prop;
3750   const char *name;
3751   int is_overridable;
3752
3753   PYRNA_STRUCT_CHECK_OBJ(self);
3754
3755   if (!PyArg_ParseTuple(args, "sp:property_overridable_library_set", &name, &is_overridable)) {
3756     return NULL;
3757   }
3758
3759   if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
3760     PyErr_Format(PyExc_TypeError,
3761                  "%.200s.property_overridable_library_set(\"%.200s\") not found",
3762                  RNA_struct_identifier(self->ptr.type),
3763                  name);
3764     return NULL;
3765   }
3766
3767   return PyBool_FromLong(
3768       (long)RNA_property_overridable_library_set(&self->ptr, prop, (bool)is_overridable));
3769 }
3770
3771 PyDoc_STRVAR(pyrna_struct_path_resolve_doc,
3772              ".. method:: path_resolve(path, coerce=True)\n"
3773              "\n"
3774              "   Returns the property from the path, raise an exception when not found.\n"
3775              "\n"
3776              "   :arg path: path which this property resolves.\n"
3777              "   :type path: string\n"
3778              "   :arg coerce: optional argument, when True, the property will be converted\n"
3779              "      into its Python representation.\n"
3780              "   :type coerce: boolean\n");
3781 static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
3782 {
3783   const char *path;
3784   PyObject *coerce = Py_True;
3785   PointerRNA r_ptr;
3786   PropertyRNA *r_prop;
3787   int index = -1;
3788
3789   PYRNA_STRUCT_CHECK_OBJ(self);
3790
3791   if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce)) {
3792     return NULL;
3793   }
3794
3795   if (RNA_path_resolve_full(&self->ptr, path, &r_ptr, &r_prop, &index)) {
3796     if (r_prop) {
3797       if (index != -1) {
3798         if (index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) {
3799           PyErr_Format(PyExc_IndexError,
3800                        "%.200s.path_resolve(\"%.200s\") index out of range",
3801                        RNA_struct_identifier(self->ptr.type),
3802                        path);
3803           return NULL;
3804         }
3805         else {
3806           return pyrna_array_index(&r_ptr, r_prop, index);
3807         }
3808       }
3809       else {
3810         if (coerce == Py_False) {
3811           return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
3812         }
3813         else {
3814           return pyrna_prop_to_py(&r_ptr, r_prop);
3815         }
3816       }
3817     }
3818     else {
3819       return pyrna_struct_CreatePyObject(&r_ptr);
3820     }
3821   }
3822   else {
3823     PyErr_Format(PyExc_ValueError,
3824                  "%.200s.path_resolve(\"%.200s\") could not be resolved",
3825                  RNA_struct_identifier(self->ptr.type),
3826                  path);
3827     return NULL;
3828   }
3829 }
3830
3831 PyDoc_STRVAR(pyrna_struct_path_from_id_doc,
3832              ".. method:: path_from_id(property=\"\")\n"
3833              "\n"
3834              "   Returns the data path from the ID to this object (string).\n"
3835              "\n"
3836              "   :arg property: Optional property name which can be used if the path is\n"
3837              "      to a property of this object.\n"
3838              "   :type property: string\n"
3839              "   :return: The path from :class:`bpy.types.bpy_struct.id_data`\n"
3840              "      to this struct and property (when given).\n"
3841              "   :rtype: str\n");
3842 static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
3843 {
3844   const char *name = NULL;
3845   const char *path;
3846   PropertyRNA *prop;
3847   PyObject *ret;
3848
3849   PYRNA_STRUCT_CHECK_OBJ(self);
3850
3851   if (!PyArg_ParseTuple(args, "|s:path_from_id", &name)) {
3852     return NULL;
3853   }
3854
3855   if (name) {
3856     prop = RNA_struct_find_property(&self->ptr, name);
3857     if (prop == NULL) {
3858       PyErr_Format(PyExc_AttributeError,
3859                    "%.200s.path_from_id(\"%.200s\") not found",
3860                    RNA_struct_identifier(self->ptr.type),
3861                    name);
3862       return NULL;
3863     }
3864
3865     path = RNA_path_from_ID_to_property(&self->ptr, prop);
3866   }
3867   else {
3868     path = RNA_path_from_ID_to_struct(&self->ptr);
3869   }
3870
3871   if (path == NULL) {
3872     if (name) {
3873       PyErr_Format(PyExc_ValueError,
3874                    "%.200s.path_from_id(\"%s\") found, but does not support path creation",
3875                    RNA_struct_identifier(self->ptr.type),
3876                    name);
3877     }
3878     else {
3879       PyErr_Format(PyExc_ValueError,
3880                    "%.200s.path_from_id() does not support path creation for this type",
3881                    RNA_struct_identifier(self->ptr.type));
3882     }
3883     return NULL;
3884   }
3885
3886   ret = PyUnicode_FromString(path);
3887   MEM_freeN((void *)path);
3888
3889   return ret;
3890 }
3891
3892 PyDoc_STRVAR(pyrna_prop_path_from_id_doc,
3893              ".. method:: path_from_id()\n"
3894              "\n"
3895              "   Returns the data path from the ID to this property (string).\n"
3896              "\n"
3897              "   :return: The path from :class:`bpy.types.bpy_struct.id_data` to this property.\n"
3898              "   :rtype: str\n");
3899 static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
3900 {
3901   const char *path;
3902   PropertyRNA *prop = self->prop;
3903   PyObject *ret;
3904
3905   path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
3906
3907   if (path == NULL) {
3908     PyErr_Format(PyExc_ValueError,
3909                  "%.200s.%.200s.path_from_id() does not support path creation for this type",
3910                  RNA_struct_identifier(self->ptr.type),
3911                  RNA_property_identifier(prop));
3912     return NULL;
3913   }
3914
3915   ret = PyUnicode_FromString(path);
3916   MEM_freeN((void *)path);
3917
3918   return ret;
3919 }
3920
3921 PyDoc_STRVAR(pyrna_prop_as_bytes_doc,
3922              ".. method:: as_bytes()\n"
3923              "\n"
3924              "   Returns this string property as a byte rather than a Python string.\n"
3925              "\n"
3926              "   :return: The string as bytes.\n"
3927              "   :rtype: bytes\n");
3928 static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self)
3929 {
3930
3931   if (RNA_property_type(self->prop) != PROP_STRING) {
3932     PyErr_Format(PyExc_TypeError,
3933                  "%.200s.%.200s.as_bytes() must be a string",
3934                  RNA_struct_identifier(self->ptr.type),
3935                  RNA_property_identifier(self->prop));
3936     return NULL;
3937   }
3938   else {
3939     PyObject *ret;
3940     char buf_fixed[256], *buf;
3941     int buf_len;
3942
3943     buf = RNA_property_string_get_alloc(
3944         &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len);
3945
3946     ret = PyBytes_FromStringAndSize(buf, buf_len);
3947
3948     if (buf_fixed != buf) {
3949       MEM_freeN(buf);
3950     }
3951
3952     return ret;
3953   }
3954 }
3955
3956 PyDoc_STRVAR(pyrna_prop_update_doc,
3957              ".. method:: update()\n"
3958              "\n"
3959              "   Execute the properties update callback.\n"
3960              "\n"
3961              "   .. note::\n"
3962              "      This is called when assigning a property,\n"
3963              "      however in rare cases it's useful to call explicitly.\n");
3964 static PyObject *pyrna_prop_update(BPy_PropertyRNA *self)
3965 {
3966   RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
3967   Py_RETURN_NONE;
3968 }
3969
3970 PyDoc_STRVAR(pyrna_struct_type_recast_doc,
3971              ".. method:: type_recast()\n"
3972              "\n"
3973              "   Return a new instance, this is needed because types\n"
3974              "   such as textures can be changed at runtime.\n"
3975              "\n"
3976              "   :return: a new instance of this object with the type initialized again.\n"
3977              "   :rtype: subclass of :class:`bpy.types.bpy_struct`\n");
3978 static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
3979 {
3980   PointerRNA r_ptr;
3981
3982   PYRNA_STRUCT_CHECK_OBJ(self);
3983
3984   RNA_pointer_recast(&self->ptr, &r_ptr);
3985   return pyrna_struct_CreatePyObject(&r_ptr);
3986 }
3987
3988 /**
3989  * \note Return value is borrowed, caller must incref.
3990  */
3991 static PyObject *pyrna_struct_bl_rna_find_subclass_recursive(PyObject *cls, const char *id)
3992 {
3993   PyObject *ret_test = NULL;
3994   PyObject *subclasses = ((PyTypeObject *)cls)->tp_subclasses;
3995   if (subclasses) {
3996     /* Unfortunately we can't use the dict key because Python class names
3997      * don't match the bl_idname used internally. */
3998     BLI_assert(PyDict_CheckExact(subclasses));
3999     PyObject *key = NULL;
4000     Py_ssize_t pos = 0;
4001     PyObject *value = NULL;
4002     while (PyDict_Next(subclasses, &pos, &key, &value)) {
4003       BLI_assert(PyWeakref_CheckRef(value));
4004       PyObject *subcls = PyWeakref_GET_OBJECT(value);
4005       if (subcls != Py_None) {
4006         BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)subcls)->tp_dict,
4007                                                                  bpy_intern_str_bl_rna);
4008         if (py_srna) {
4009           StructRNA *srna = py_srna->ptr.data;
4010           if (STREQ(id, RNA_struct_identifier(srna))) {
4011             ret_test = subcls;
4012             break;
4013           }
4014         }
4015         ret_test = pyrna_struct_bl_rna_find_subclass_recursive(subcls, id);
4016         if (ret_test) {
4017           break;
4018         }
4019       }
4020     }
4021   }
4022   return ret_test;
4023 }
4024
4025 PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_py_doc,
4026              ".. classmethod:: bl_rna_get_subclass_py(id, default=None)\n"
4027              "\n"
4028              "   :arg id: The RNA type identifier.\n"
4029              "   :type id: string\n"
4030              "   :return: The class or default when not found.\n"
4031              "   :rtype: type\n");
4032 static PyObject *pyrna_struct_bl_rna_get_subclass_py(PyObject *cls, PyObject *args)
4033 {
4034   char *id;
4035   PyObject *ret_default = Py_None;
4036
4037   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass_py", &id, &ret_default)) {
4038     return NULL;
4039   }
4040   PyObject *ret = pyrna_struct_bl_rna_find_subclass_recursive(cls, id);
4041   if (ret == NULL) {
4042     ret = ret_default;
4043   }
4044   return Py_INCREF_RET(ret);
4045 }
4046
4047 PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_doc,
4048              ".. classmethod:: bl_rna_get_subclass(id, default=None)\n"
4049              "\n"
4050              "   :arg id: The RNA type identifier.\n"
4051              "   :type id: string\n"
4052              "   :return: The RNA type or default when not found.\n"
4053              "   :rtype: :class:`bpy.types.Struct` subclass\n");
4054 static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args)
4055 {
4056   char *id;
4057   PyObject *ret_default = Py_None;
4058
4059   if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass", &id, &ret_default)) {
4060     return NULL;
4061   }
4062
4063   const BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)cls)->tp_dict,
4064                                                                  bpy_intern_str_bl_rna);
4065   if (py_srna == NULL) {
4066     PyErr_SetString(PyExc_ValueError, "Not a registered class");
4067     return NULL;
4068   }
4069   const StructRNA *srna_base = py_srna->ptr.data;
4070
4071   PointerRNA ptr;
4072   if (srna_base == &RNA_Node) {
4073     bNodeType *nt = nodeTypeFind(id);
4074     if (nt) {
4075       RNA_pointer_create(NULL, &RNA_Struct, nt->ext.srna, &ptr);
4076       return pyrna_struct_CreatePyObject(&ptr);
4077     }
4078   }
4079   else {
4080     /* TODO, panels, menus etc. */
4081     PyErr_Format(
4082         PyExc_ValueError, "Class type \"%.200s\" not supported", RNA_struct_identifier(srna_base));
4083     return NULL;
4084   }
4085
4086   return Py_INCREF_RET(ret_default);
4087 }
4088
4089 static void pyrna_dir_members_py__add_keys(PyObject *list, PyObject *dict)
4090 {
4091   PyObject *list_tmp;
4092
4093   list_tmp = PyDict_Keys(dict);
4094   PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
4095   Py_DECREF(list_tmp);
4096 }
4097
4098 static void pyrna_dir_members_py(PyObject *list, PyObject *self)
4099 {
4100   PyObject *dict;
4101   PyObject **dict_ptr;
4102
4103   dict_ptr = _PyObject_GetDictPtr((PyObject *)self);
4104
4105   if (dict_ptr && (dict = *dict_ptr)) {
4106     pyrna_dir_members_py__add_keys(list, dict);
4107   }
4108
4109   dict = ((PyTypeObject *)Py_TYPE(self))->tp_dict;
4110   if (dict) {
4111     pyrna_dir_members_py__add_keys(list, dict);
4112   }
4113
4114   /* Since this is least common case, handle it last. */
4115   if (BPy_PropertyRNA_Check(self)) {
4116     BPy_PropertyRNA *self_prop = (BPy_PropertyRNA *)self;
4117     if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) {
4118       PointerRNA r_ptr;
4119
4120       if (RNA_property_collection_type_get(&self_prop->ptr, self_prop->prop, &r_ptr)) {
4121         PyObject *cls = pyrna_struct_Subtype(&r_ptr); /* borrows */
4122         dict = ((PyTypeObject *)cls)->tp_dict;
4123         pyrna_dir_members_py__add_keys(list, dict);
4124         Py_DECREF(cls);
4125       }
4126     }
4127   }
4128 }
4129
4130 static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
4131 {
4132   const char *idname;
4133
4134   /* For looping over attrs and funcs. */
4135   PointerRNA tptr;
4136   PropertyRNA *iterprop;
4137
4138   {
4139     RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
4140     iterprop = RNA_struct_find_property(&tptr, "functions");
4141
4142     RNA_PROP_BEGIN (&tptr, itemptr, iterprop) {
4143       FunctionRNA *func = itemptr.data;
4144       if (RNA_function_defined(func)) {
4145         idname = RNA_function_identifier(itemptr.data);
4146         PyList_APPEND(list, PyUnicode_FromString(idname));
4147       }
4148     }
4149     RNA_PROP_END;
4150   }
4151
4152   {
4153     /*
4154      * Collect RNA attributes
4155      */
4156     char name[256], *nameptr;
4157     int namelen;
4158
4159     iterprop = RNA_struct_iterator_property(ptr->type);
4160
4161     RNA_PROP_BEGIN (ptr, itemptr, iterprop) {
4162       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
4163
4164       if (nameptr) {
4165         PyList_APPEND(list, PyUnicode_FromStringAndSize(nameptr, namelen));