py api - added PyC_UnicodeFromByteAndSize() to match PyUnicode_FromStringAndSize()
[blender.git] / source / blender / python / intern / bpy_rna.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Campbell Barton
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file blender/python/intern/bpy_rna.c
26  *  \ingroup pythonintern
27  */
28
29
30 #include <Python.h>
31
32 #include <stddef.h>
33 #include <float.h> /* FLT_MIN/MAX */
34
35 #include "RNA_types.h"
36
37 #include "bpy_rna.h"
38 #include "bpy_rna_anim.h"
39 #include "bpy_props.h"
40 #include "bpy_util.h"
41 #include "bpy_rna_callback.h"
42 #include "bpy_intern_string.h"
43
44 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
45 #include "MEM_guardedalloc.h"
46 #endif
47
48 #include "BLI_dynstr.h"
49 #include "BLI_string.h"
50 #include "BLI_listbase.h"
51 #include "BLI_math_rotation.h"
52 #include "BLI_utildefines.h"
53
54 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
55 #include "BLI_ghash.h"
56 #endif
57
58 #include "RNA_enum_types.h"
59 #include "RNA_define.h" /* RNA_def_property_free_identifier */
60 #include "RNA_access.h"
61
62 #include "MEM_guardedalloc.h"
63
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 #include "BKE_animsys.h"
71 #include "BKE_fcurve.h"
72
73 #include "../generic/IDProp.h" /* for IDprop lookups */
74 #include "../generic/py_capi_utils.h"
75
76 #ifdef WITH_INTERNATIONAL
77 #include "UI_interface.h" /* bad level call into editors */
78 #endif
79
80 #define USE_PEDANTIC_WRITE
81 #define USE_MATHUTILS
82 #define USE_STRING_COERCE
83
84 static PyObject* pyrna_struct_Subtype(PointerRNA *ptr);
85 static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
86
87 #define BPY_DOC_ID_PROP_TYPE_NOTE \
88 "   .. note::\n" \
89 "\n" \
90 "      Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \
91 "      :class:`bpy.types.PoseBone` classes support custom properties.\n"
92
93
94 int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
95 {
96         if (pysrna->ptr.type) {
97                 return 0;
98         }
99         PyErr_Format(PyExc_ReferenceError,
100                      "StructRNA of type %.200s has been removed",
101                      Py_TYPE(pysrna)->tp_name);
102         return -1;
103 }
104
105 int pyrna_prop_validity_check(BPy_PropertyRNA *self)
106 {
107         if (self->ptr.type) {
108                 return 0;
109         }
110         PyErr_Format(PyExc_ReferenceError,
111                      "PropertyRNA of type %.200s.%.200s has been removed",
112                      Py_TYPE(self)->tp_name, RNA_property_identifier(self->prop));
113         return -1;
114 }
115
116 #if defined(USE_PYRNA_INVALIDATE_GC) || defined(USE_PYRNA_INVALIDATE_WEAKREF)
117 static void pyrna_invalidate(BPy_DummyPointerRNA *self)
118 {
119         self->ptr.type= NULL; /* this is checked for validity */
120         self->ptr.id.data= NULL; /* should not be needed but prevent bad pointer access, just incase */
121 }
122 #endif
123
124 #ifdef USE_PYRNA_INVALIDATE_GC
125 #define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
126
127 /* only for sizeof() */
128 struct gc_generation {
129         PyGC_Head head;
130         int threshold;
131         int count;
132 } gc_generation;
133
134 static void id_release_gc(struct ID *id)
135 {
136         unsigned int j;
137         // unsigned int i= 0;
138         for (j=0; j<3; j++) {
139                 /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */
140                 PyGC_Head *gen= (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
141                 PyGC_Head *g= gen->gc.gc_next;
142                 while ((g= g->gc.gc_next) != gen) {
143                         PyObject *ob= FROM_GC(g);
144                         if (PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
145                                 BPy_DummyPointerRNA *ob_ptr= (BPy_DummyPointerRNA *)ob;
146                                 if (ob_ptr->ptr.id.data == id) {
147                                         pyrna_invalidate(ob_ptr);
148                                         // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
149                                         // i++;
150                                 }
151                         }
152                 }
153         }
154         // printf("id_release_gc freed '%s': %d\n", id->name, i);
155 }
156 #endif
157
158 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
159 //#define DEBUG_RNA_WEAKREF
160
161 struct GHash *id_weakref_pool= NULL;
162 static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref);
163 static PyMethodDef id_free_weakref_cb_def= {"id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL};
164
165 /* adds a reference to the list, remember to decref */
166 static GHash *id_weakref_pool_get(ID *id)
167 {
168         GHash *weakinfo_hash= NULL;
169
170         if (id_weakref_pool) {
171                 weakinfo_hash= BLI_ghash_lookup(id_weakref_pool, (void *)id);
172         }
173         else {
174                 /* first time, allocate pool */
175                 id_weakref_pool= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_global_pool");
176                 weakinfo_hash= NULL;
177         }
178
179         if (weakinfo_hash==NULL) {
180                 /* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */
181                 weakinfo_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_id");
182                 BLI_ghash_insert(id_weakref_pool, (void *)id, weakinfo_hash);
183         }
184
185         return weakinfo_hash;
186 }
187
188 /* called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject() */
189 void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna)
190 {
191         PyObject *weakref;
192         PyObject *weakref_capsule;
193         PyObject *weakref_cb_py;
194
195         /* create a new function instance and insert the list as 'self' so we can remove ourself from it */
196         GHash *weakinfo_hash= id_weakref_pool_get(id); /* new or existing */
197
198         weakref_capsule= PyCapsule_New(weakinfo_hash, NULL, NULL);
199         weakref_cb_py= PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule);
200         Py_DECREF(weakref_capsule);
201
202         /* add weakref to weakinfo_hash list */
203         weakref= PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py);
204
205         Py_DECREF(weakref_cb_py); /* function owned by the weakref now */
206
207         /* important to add at the end, since first removal looks at the end */
208         BLI_ghash_insert(weakinfo_hash, (void *)weakref, id); /* using a hash table as a set, all 'id's are the same */
209         /* weakinfo_hash owns the weakref */
210
211 }
212
213 /* workaround to get the last id without a lookup */
214 static ID *_id_tmp_ptr;
215 static void value_id_set(void *id)
216 {
217         _id_tmp_ptr= (ID *)id;
218 }
219
220 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash);
221 static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref)
222 {
223         /* important to search backwards */
224         GHash *weakinfo_hash= PyCapsule_GetPointer(weakinfo_capsule, NULL);
225
226
227         if (BLI_ghash_size(weakinfo_hash) > 1) {
228                 BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL);
229         }
230         else { /* get the last id and free it */
231                 BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set);
232                 id_release_weakref_list(_id_tmp_ptr, weakinfo_hash);
233         }
234
235         Py_DECREF(weakref);
236
237         Py_RETURN_NONE;
238 }
239
240 static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
241 {
242         GHashIterator weakinfo_hash_iter;
243
244         BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
245
246 #ifdef DEBUG_RNA_WEAKREF
247         fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
248 #endif
249
250         while (!BLI_ghashIterator_isDone(&weakinfo_hash_iter)) {
251                 PyObject *weakref= (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
252                 PyObject *item= PyWeakref_GET_OBJECT(weakref);
253                 if (item != Py_None) {
254
255 #ifdef DEBUG_RNA_WEAKREF
256                         PyC_ObSpit("id_release_weakref item ", item);
257 #endif
258
259                         pyrna_invalidate((BPy_DummyPointerRNA *)item);
260                 }
261
262                 Py_DECREF(weakref);
263
264                 BLI_ghashIterator_step(&weakinfo_hash_iter);
265         }
266
267         BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
268         BLI_ghash_free(weakinfo_hash, NULL, NULL);
269
270         if (BLI_ghash_size(id_weakref_pool) == 0) {
271                 BLI_ghash_free(id_weakref_pool, NULL, NULL);
272                 id_weakref_pool= NULL;
273 #ifdef DEBUG_RNA_WEAKREF
274                 printf("id_release_weakref freeing pool\n");
275 #endif
276         }
277 }
278
279 static void id_release_weakref(struct ID *id)
280 {
281         GHash *weakinfo_hash= BLI_ghash_lookup(id_weakref_pool, (void *)id);
282         if (weakinfo_hash) {
283                 id_release_weakref_list(id, weakinfo_hash);
284         }
285 }
286
287 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
288
289 void BPY_id_release(struct ID *id)
290 {
291 #ifdef USE_PYRNA_INVALIDATE_GC
292         id_release_gc(id);
293 #endif
294
295 #ifdef USE_PYRNA_INVALIDATE_WEAKREF
296         if (id_weakref_pool) {
297                 PyGILState_STATE gilstate= PyGILState_Ensure();
298
299                 id_release_weakref(id);
300
301                 PyGILState_Release(gilstate);
302         }
303 #endif /* USE_PYRNA_INVALIDATE_WEAKREF */
304
305         (void)id;
306 }
307
308 #ifdef USE_PEDANTIC_WRITE
309 static short rna_disallow_writes= FALSE;
310
311 static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
312 {
313         ID *id= ptr->id.data;
314         if (id) {
315                 const short idcode= GS(id->name);
316                 if (!ELEM(idcode, ID_WM, ID_SCR)) { /* may need more added here */
317                         const char *idtype= BKE_idcode_to_name(idcode);
318                         const char *pyname;
319                         if (key && PyUnicode_Check(key)) pyname= _PyUnicode_AsString(key);
320                         else                             pyname= "<UNKNOWN>";
321
322                         /* make a nice string error */
323                         BLI_assert(idtype != NULL);
324                         PyErr_Format(PyExc_AttributeError,
325                                      "Writing to ID classes in this context is not allowed: "
326                                      "%.200s, %.200s datablock, error setting %.200s.%.200s",
327                                      id->name+2, idtype, RNA_struct_identifier(ptr->type), pyname);
328
329                         return TRUE;
330                 }
331         }
332         return FALSE;
333 }
334 #endif // USE_PEDANTIC_WRITE
335
336
337 #ifdef USE_PEDANTIC_WRITE
338 int pyrna_write_check(void)
339 {
340         return !rna_disallow_writes;
341 }
342
343 void pyrna_write_set(int val)
344 {
345         rna_disallow_writes= !val;
346 }
347 #else // USE_PEDANTIC_WRITE
348 int pyrna_write_check(void)
349 {
350         return TRUE;
351 }
352 void pyrna_write_set(int UNUSED(val))
353 {
354         /* nothing */
355 }
356 #endif // USE_PEDANTIC_WRITE
357
358 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
359 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
360 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
361 static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
362
363 #ifdef USE_MATHUTILS
364 #include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */
365
366 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
367 static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
368
369 /* bpyrna vector/euler/quat callbacks */
370 static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
371
372 /* subtype not used much yet */
373 #define MATHUTILS_CB_SUBTYPE_EUL 0
374 #define MATHUTILS_CB_SUBTYPE_VEC 1
375 #define MATHUTILS_CB_SUBTYPE_QUAT 2
376 #define MATHUTILS_CB_SUBTYPE_COLOR 3
377
378 static int mathutils_rna_generic_check(BaseMathObject *bmo)
379 {
380         BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
381
382         PYRNA_PROP_CHECK_INT(self);
383
384         return self->prop ? 0 : -1;
385 }
386
387 static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
388 {
389         BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
390
391         PYRNA_PROP_CHECK_INT(self);
392
393         if (self->prop==NULL)
394                 return -1;
395
396         RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
397
398         /* Euler order exception */
399         if (subtype==MATHUTILS_CB_SUBTYPE_EUL) {
400                 EulerObject *eul= (EulerObject *)bmo;
401                 PropertyRNA *prop_eul_order= NULL;
402                 eul->order= pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order);
403         }
404
405         return 0;
406 }
407
408 static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
409 {
410         BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
411         float min, max;
412
413         PYRNA_PROP_CHECK_INT(self);
414
415         if (self->prop==NULL)
416                 return -1;
417
418 #ifdef USE_PEDANTIC_WRITE
419         if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
420                 return -1;
421         }
422 #endif // USE_PEDANTIC_WRITE
423
424         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
425                 PyErr_Format(PyExc_AttributeError,
426                              "bpy_prop \"%.200s.%.200s\" is read-only",
427                              RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
428                 return -1;
429         }
430
431         RNA_property_float_range(&self->ptr, self->prop, &min, &max);
432
433         if (min != FLT_MIN || max != FLT_MAX) {
434                 int i, len= RNA_property_array_length(&self->ptr, self->prop);
435                 for (i=0; i<len; i++) {
436                         CLAMP(bmo->data[i], min, max);
437                 }
438         }
439
440         RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
441         if (RNA_property_update_check(self->prop)) {
442                 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
443         }
444
445         /* Euler order exception */
446         if (subtype==MATHUTILS_CB_SUBTYPE_EUL) {
447                 EulerObject *eul= (EulerObject *)bmo;
448                 PropertyRNA *prop_eul_order= NULL;
449                 short order= pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order);
450                 if (order != eul->order) {
451                         RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
452                         if (RNA_property_update_check(prop_eul_order)) {
453                                 RNA_property_update(BPy_GetContext(), &self->ptr, prop_eul_order);
454                         }
455                 }
456         }
457         return 0;
458 }
459
460 static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
461 {
462         BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
463
464         PYRNA_PROP_CHECK_INT(self);
465
466         if (self->prop==NULL)
467                 return -1;
468
469         bmo->data[index]= RNA_property_float_get_index(&self->ptr, self->prop, index);
470         return 0;
471 }
472
473 static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
474 {
475         BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
476
477         PYRNA_PROP_CHECK_INT(self);
478
479         if (self->prop==NULL)
480                 return -1;
481
482 #ifdef USE_PEDANTIC_WRITE
483         if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
484                 return -1;
485         }
486 #endif // USE_PEDANTIC_WRITE
487
488         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
489                 PyErr_Format(PyExc_AttributeError,
490                              "bpy_prop \"%.200s.%.200s\" is read-only",
491                              RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
492                 return -1;
493         }
494
495         RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
496         RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]);
497
498         if (RNA_property_update_check(self->prop)) {
499                 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
500         }
501
502         return 0;
503 }
504
505 static Mathutils_Callback mathutils_rna_array_cb= {
506         (BaseMathCheckFunc)             mathutils_rna_generic_check,
507         (BaseMathGetFunc)               mathutils_rna_vector_get,
508         (BaseMathSetFunc)               mathutils_rna_vector_set,
509         (BaseMathGetIndexFunc)  mathutils_rna_vector_get_index,
510         (BaseMathSetIndexFunc)  mathutils_rna_vector_set_index
511 };
512
513
514 /* bpyrna matrix callbacks */
515 static int mathutils_rna_matrix_cb_index= -1; /* index for our callbacks */
516
517 static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype))
518 {
519         BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
520
521         PYRNA_PROP_CHECK_INT(self);
522
523         if (self->prop==NULL)
524                 return -1;
525
526         RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
527         return 0;
528 }
529
530 static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
531 {
532         BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
533
534         PYRNA_PROP_CHECK_INT(self);
535
536         if (self->prop==NULL)
537                 return -1;
538
539 #ifdef USE_PEDANTIC_WRITE
540         if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
541                 return -1;
542         }
543 #endif // USE_PEDANTIC_WRITE
544
545         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
546                 PyErr_Format(PyExc_AttributeError,
547                              "bpy_prop \"%.200s.%.200s\" is read-only",
548                              RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
549                 return -1;
550         }
551
552         /* can ignore clamping here */
553         RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
554
555         if (RNA_property_update_check(self->prop)) {
556                 RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
557         }
558         return 0;
559 }
560
561 static Mathutils_Callback mathutils_rna_matrix_cb= {
562         mathutils_rna_generic_check,
563         mathutils_rna_matrix_get,
564         mathutils_rna_matrix_set,
565         NULL,
566         NULL
567 };
568
569 static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback)
570 {
571         /* attempt to get order */
572         if (*prop_eul_order==NULL)
573                 *prop_eul_order= RNA_struct_find_property(ptr, "rotation_mode");
574
575         if (*prop_eul_order) {
576                 short order= RNA_property_enum_get(ptr, *prop_eul_order);
577                 if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) /* could be quat or axisangle */
578                         return order;
579         }
580
581         return order_fallback;
582 }
583
584 #endif // USE_MATHUTILS
585
586 /* note that PROP_NONE is included as a vector subtype. this is because its handy to
587  * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. */
588 #define PROP_ALL_VECTOR_SUBTYPES PROP_COORDS: case PROP_TRANSLATION: case PROP_DIRECTION: case PROP_VELOCITY: case PROP_ACCELERATION: case PROP_XYZ: case PROP_XYZ_LENGTH
589
590 PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
591 {
592         PyObject *ret= NULL;
593
594 #ifdef USE_MATHUTILS
595         int subtype, totdim;
596         int len;
597         int is_thick;
598         int flag= RNA_property_flag(prop);
599
600         /* disallow dynamic sized arrays to be wrapped since the size could change
601          * to a size mathutils does not support */
602         if ((RNA_property_type(prop) != PROP_FLOAT) || (flag & PROP_DYNAMIC))
603                 return NULL;
604
605         len= RNA_property_array_length(ptr, prop);
606         subtype= RNA_property_subtype(prop);
607         totdim= RNA_property_array_dimension(ptr, prop, NULL);
608         is_thick= (flag & PROP_THICK_WRAP);
609
610         if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
611                 if (!is_thick)
612                         ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
613
614                 switch(RNA_property_subtype(prop)) {
615                 case PROP_ALL_VECTOR_SUBTYPES:
616                         if (len>=2 && len <= 4) {
617                                 if (is_thick) {
618                                         ret= newVectorObject(NULL, len, Py_NEW, NULL);
619                                         RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
620                                 }
621                                 else {
622                                         PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC);
623                                         Py_DECREF(ret); /* the vector owns now */
624                                         ret= vec_cb; /* return the vector instead */
625                                 }
626                         }
627                         break;
628                 case PROP_MATRIX:
629                         if (len==16) {
630                                 if (is_thick) {
631                                         ret= newMatrixObject(NULL, 4, 4, Py_NEW, NULL);
632                                         RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr);
633                                 }
634                                 else {
635                                         PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
636                                         Py_DECREF(ret); /* the matrix owns now */
637                                         ret= mat_cb; /* return the matrix instead */
638                                 }
639                         }
640                         else if (len==9) {
641                                 if (is_thick) {
642                                         ret= newMatrixObject(NULL, 3, 3, Py_NEW, NULL);
643                                         RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr);
644                                 }
645                                 else {
646                                         PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
647                                         Py_DECREF(ret); /* the matrix owns now */
648                                         ret= mat_cb; /* return the matrix instead */
649                                 }
650                         }
651                         break;
652                 case PROP_EULER:
653                 case PROP_QUATERNION:
654                         if (len==3) { /* euler */
655                                 if (is_thick) {
656                                         /* attempt to get order, only needed for thick types since wrapped with update via callbacks */
657                                         PropertyRNA *prop_eul_order= NULL;
658                                         short order= pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ);
659
660                                         ret= newEulerObject(NULL, order, Py_NEW, NULL); // TODO, get order from RNA
661                                         RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
662                                 }
663                                 else {
664                                         /* order will be updated from callback on use */
665                                         PyObject *eul_cb= newEulerObject_cb(ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
666                                         Py_DECREF(ret); /* the euler owns now */
667                                         ret= eul_cb; /* return the euler instead */
668                                 }
669                         }
670                         else if (len==4) {
671                                 if (is_thick) {
672                                         ret= newQuaternionObject(NULL, Py_NEW, NULL);
673                                         RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
674                                 }
675                                 else {
676                                         PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT);
677                                         Py_DECREF(ret); /* the quat owns now */
678                                         ret= quat_cb; /* return the quat instead */
679                                 }
680                         }
681                         break;
682                 case PROP_COLOR:
683                 case PROP_COLOR_GAMMA:
684                         if (len==3) { /* color */
685                                 if (is_thick) {
686                                         ret= newColorObject(NULL, Py_NEW, NULL); // TODO, get order from RNA
687                                         RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col);
688                                 }
689                                 else {
690                                         PyObject *col_cb= newColorObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR);
691                                         Py_DECREF(ret); /* the color owns now */
692                                         ret= col_cb; /* return the color instead */
693                                 }
694                         }
695                 default:
696                         break;
697                 }
698         }
699
700         if (ret==NULL) {
701                 if (is_thick) {
702                         /* this is an array we cant reference (since its not thin wrappable)
703                          * and cannot be coerced into a mathutils type, so return as a list */
704                         ret= pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
705                 }
706                 else {
707                         ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
708                 }
709         }
710 #else // USE_MATHUTILS
711         (void)ptr;
712         (void)prop;
713 #endif // USE_MATHUTILS
714
715         return ret;
716 }
717
718 /* same as RNA_enum_value_from_id but raises an exception */
719 int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
720 {
721         if (RNA_enum_value_from_id(item, identifier, value) == 0) {
722                 const char *enum_str= BPy_enum_as_string(item);
723                 PyErr_Format(PyExc_TypeError,
724                              "%s: '%.200s' not found in (%s)",
725                              error_prefix, identifier, enum_str);
726                 MEM_freeN((void *)enum_str);
727                 return -1;
728         }
729
730         return 0;
731 }
732
733 static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
734 {
735         return (a->ptr.data==b->ptr.data) ? 0 : -1;
736 }
737
738 static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
739 {
740         return (a->prop==b->prop && a->ptr.data==b->ptr.data) ? 0 : -1;
741 }
742
743 static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
744 {
745         PyObject *res;
746         int ok= -1; /* zero is true */
747
748         if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b))
749                 ok= pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
750
751         switch (op) {
752         case Py_NE:
753                 ok= !ok; /* pass through */
754         case Py_EQ:
755                 res= ok ? Py_False : Py_True;
756                 break;
757
758         case Py_LT:
759         case Py_LE:
760         case Py_GT:
761         case Py_GE:
762                 res= Py_NotImplemented;
763                 break;
764         default:
765                 PyErr_BadArgument();
766                 return NULL;
767         }
768
769         return Py_INCREF(res), res;
770 }
771
772 static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
773 {
774         PyObject *res;
775         int ok= -1; /* zero is true */
776
777         if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b))
778                 ok= pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
779
780         switch (op) {
781         case Py_NE:
782                 ok= !ok; /* pass through */
783         case Py_EQ:
784                 res= ok ? Py_False : Py_True;
785                 break;
786
787         case Py_LT:
788         case Py_LE:
789         case Py_GT:
790         case Py_GE:
791                 res= Py_NotImplemented;
792                 break;
793         default:
794                 PyErr_BadArgument();
795                 return NULL;
796         }
797
798         return Py_INCREF(res), res;
799 }
800
801 /*----------------------repr--------------------------------------------*/
802 static PyObject *pyrna_struct_str(BPy_StructRNA *self)
803 {
804         PyObject *ret;
805         const char *name;
806
807         if (!PYRNA_STRUCT_IS_VALID(self)) {
808                 return PyUnicode_FromFormat("<bpy_struct, %.200s dead>",
809                                             Py_TYPE(self)->tp_name);
810         }
811
812         /* print name if available */
813         name= RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL);
814         if (name) {
815                 ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>",
816                                           RNA_struct_identifier(self->ptr.type),
817                                           name);
818                 MEM_freeN((void *)name);
819                 return ret;
820         }
821
822         return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>",
823                                     RNA_struct_identifier(self->ptr.type),
824                                     self->ptr.data);
825 }
826
827 static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
828 {
829         ID *id= self->ptr.id.data;
830         PyObject *tmp_str;
831         PyObject *ret;
832
833         if (id == NULL || !PYRNA_STRUCT_IS_VALID(self))
834                 return pyrna_struct_str(self); /* fallback */
835
836         tmp_str= PyUnicode_FromString(id->name+2);
837
838         if (RNA_struct_is_ID(self->ptr.type)) {
839                 ret= PyUnicode_FromFormat("bpy.data.%s[%R]",
840                                             BKE_idcode_to_name_plural(GS(id->name)),
841                                             tmp_str);
842         }
843         else {
844                 const char *path;
845                 path= RNA_path_from_ID_to_struct(&self->ptr);
846                 if (path) {
847                         ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s",
848                                                   BKE_idcode_to_name_plural(GS(id->name)),
849                                                   tmp_str,
850                                                   path);
851                         MEM_freeN((void *)path);
852                 }
853                 else { /* cant find, print something sane */
854                         ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
855                                                   BKE_idcode_to_name_plural(GS(id->name)),
856                                                   tmp_str,
857                                                   RNA_struct_identifier(self->ptr.type));
858                 }
859         }
860
861         Py_DECREF(tmp_str);
862
863         return ret;
864 }
865
866 static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
867 {
868         PyObject *ret;
869         PointerRNA ptr;
870         const char *name;
871         const char *type_id= NULL;
872         char type_fmt[64]= "";
873         int type;
874
875         PYRNA_PROP_CHECK_OBJ(self);
876
877         type= RNA_property_type(self->prop);
878
879         if (RNA_enum_id_from_value(property_type_items, type, &type_id)==0) {
880                 PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); /* should never happen */
881                 return NULL;
882         }
883         else {
884                 /* this should never fail */
885                 int len= -1;
886                 char *c= type_fmt;
887
888                 while ((*c++= tolower(*type_id++))) {} ;
889
890                 if (type==PROP_COLLECTION) {
891                         len= pyrna_prop_collection_length(self);
892                 }
893                 else if (RNA_property_array_check(self->prop)) {
894                         len= pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
895                 }
896
897                 if (len != -1)
898                         sprintf(--c, "[%d]", len);
899         }
900
901         /* if a pointer, try to print name of pointer target too */
902         if (RNA_property_type(self->prop) == PROP_POINTER) {
903                 ptr= RNA_property_pointer_get(&self->ptr, self->prop);
904                 name= RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL);
905
906                 if (name) {
907                         ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>",
908                                                   type_fmt,
909                                                   RNA_struct_identifier(self->ptr.type),
910                                                   RNA_property_identifier(self->prop),
911                                                   name);
912                         MEM_freeN((void *)name);
913                         return ret;
914                 }
915         }
916         if (RNA_property_type(self->prop) == PROP_COLLECTION) {
917                 PointerRNA r_ptr;
918                 if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
919                         return PyUnicode_FromFormat("<bpy_%.200s, %.200s>",
920                                                     type_fmt,
921                                                     RNA_struct_identifier(r_ptr.type));
922                 }
923         }
924
925         return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>",
926                                     type_fmt,
927                                     RNA_struct_identifier(self->ptr.type),
928                                     RNA_property_identifier(self->prop));
929 }
930
931 static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
932 {
933         ID *id= self->ptr.id.data;
934         PyObject *tmp_str;
935         PyObject *ret;
936         const char *path;
937
938         PYRNA_PROP_CHECK_OBJ(self);
939
940         if (id == NULL)
941                 return pyrna_prop_str(self); /* fallback */
942
943         tmp_str= PyUnicode_FromString(id->name+2);
944
945         path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
946         if (path) {
947                 ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s",
948                                           BKE_idcode_to_name_plural(GS(id->name)),
949                                           tmp_str,
950                                           path);
951                 MEM_freeN((void *)path);
952         }
953         else { /* cant find, print something sane */
954                 ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
955                                           BKE_idcode_to_name_plural(GS(id->name)),
956                                           tmp_str,
957                                           RNA_property_identifier(self->prop));
958         }
959
960         Py_DECREF(tmp_str);
961
962         return ret;
963 }
964
965
966 static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
967 {
968         return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
969                                     Py_TYPE(self)->tp_name,
970                                     RNA_struct_identifier(self->ptr.type),
971                                     RNA_function_identifier(self->func));
972 }
973
974
975 static long pyrna_struct_hash(BPy_StructRNA *self)
976 {
977         return _Py_HashPointer(self->ptr.data);
978 }
979
980 /* from python's meth_hash v3.1.2 */
981 static long pyrna_prop_hash(BPy_PropertyRNA *self)
982 {
983         long x, y;
984         if (self->ptr.data == NULL)
985                 x= 0;
986         else {
987                 x= _Py_HashPointer(self->ptr.data);
988                 if (x == -1)
989                         return -1;
990         }
991         y= _Py_HashPointer((void*)(self->prop));
992         if (y == -1)
993                 return -1;
994         x ^= y;
995         if (x == -1)
996                 x= -2;
997         return x;
998 }
999
1000 #ifdef USE_PYRNA_STRUCT_REFERENCE
1001 static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
1002 {
1003         Py_VISIT(self->reference);
1004         return 0;
1005 }
1006
1007 static int pyrna_struct_clear(BPy_StructRNA *self)
1008 {
1009         Py_CLEAR(self->reference);
1010         return 0;
1011 }
1012 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1013
1014 /* use our own dealloc so we can free a property if we use one */
1015 static void pyrna_struct_dealloc(BPy_StructRNA *self)
1016 {
1017 #ifdef PYRNA_FREE_SUPPORT
1018         if (self->freeptr && self->ptr.data) {
1019                 IDP_FreeProperty(self->ptr.data);
1020                 MEM_freeN(self->ptr.data);
1021                 self->ptr.data= NULL;
1022         }
1023 #endif /* PYRNA_FREE_SUPPORT */
1024
1025 #ifdef USE_WEAKREFS
1026         if (self->in_weakreflist != NULL) {
1027                 PyObject_ClearWeakRefs((PyObject *)self);
1028         }
1029 #endif
1030
1031 #ifdef USE_PYRNA_STRUCT_REFERENCE
1032         if (self->reference) {
1033                 PyObject_GC_UnTrack(self);
1034                 pyrna_struct_clear(self);
1035         }
1036 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1037
1038         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1039         Py_TYPE(self)->tp_free(self);
1040 }
1041
1042 #ifdef USE_PYRNA_STRUCT_REFERENCE
1043 static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
1044 {
1045         if (self->reference) {
1046 //              PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED? */
1047                 pyrna_struct_clear(self);
1048         }
1049         /* reference is now NULL */
1050
1051         if (reference) {
1052                 self->reference= reference;
1053                 Py_INCREF(reference);
1054 //              PyObject_GC_Track(self);  /* INITIALIZED TRACKED? */
1055         }
1056 }
1057 #endif /* !USE_PYRNA_STRUCT_REFERENCE */
1058
1059 /* use our own dealloc so we can free a property if we use one */
1060 static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
1061 {
1062 #ifdef USE_WEAKREFS
1063         if (self->in_weakreflist != NULL) {
1064                 PyObject_ClearWeakRefs((PyObject *)self);
1065         }
1066 #endif
1067         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1068         Py_TYPE(self)->tp_free(self);
1069 }
1070
1071 static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
1072 {
1073 #ifdef USE_WEAKREFS
1074         if (self->in_weakreflist != NULL) {
1075                 PyObject_ClearWeakRefs((PyObject *)self);
1076         }
1077 #endif
1078         /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
1079         Py_TYPE(self)->tp_free(self);
1080 }
1081
1082 static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
1083 {
1084         EnumPropertyItem *item;
1085         const char *result;
1086         int free= FALSE;
1087
1088         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1089         if (item) {
1090                 result= BPy_enum_as_string(item);
1091         }
1092         else {
1093                 result= "";
1094         }
1095
1096         if (free)
1097                 MEM_freeN(item);
1098
1099         return result;
1100 }
1101
1102
1103 static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
1104 {
1105         const char *param= _PyUnicode_AsString(item);
1106
1107         if (param==NULL) {
1108                 const char *enum_str= pyrna_enum_as_string(ptr, prop);
1109                 PyErr_Format(PyExc_TypeError,
1110                              "%.200s expected a string enum type in (%.200s)",
1111                              error_prefix, enum_str);
1112                 MEM_freeN((void *)enum_str);
1113                 return 0;
1114         }
1115         else {
1116                 /* hack so that dynamic enums used for operator properties will be able to be built (i.e. context will be supplied to itemf)
1117                  * and thus running defining operator buttons for such operators in UI will work */
1118                 RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
1119
1120                 if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
1121                         const char *enum_str= pyrna_enum_as_string(ptr, prop);
1122                         PyErr_Format(PyExc_TypeError,
1123                                      "%.200s enum \"%.200s\" not found in (%.200s)",
1124                                      error_prefix, param, enum_str);
1125                         MEM_freeN((void *)enum_str);
1126                         return 0;
1127                 }
1128         }
1129
1130         return 1;
1131 }
1132
1133 /* 'value' _must_ be a set type, error check before calling */
1134 int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
1135 {
1136         /* set of enum items, concatenate all values with OR */
1137         int ret, flag= 0;
1138
1139         /* set looping */
1140         Py_ssize_t pos= 0;
1141         Py_ssize_t hash= 0;
1142         PyObject *key;
1143
1144         *r_value= 0;
1145
1146         while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1147                 const char *param= _PyUnicode_AsString(key);
1148
1149                 if (param==NULL) {
1150                         PyErr_Format(PyExc_TypeError,
1151                                      "%.200s expected a string, not %.200s",
1152                                      error_prefix, Py_TYPE(key)->tp_name);
1153                         return -1;
1154                 }
1155
1156                 if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) {
1157                         return -1;
1158                 }
1159
1160                 flag |= ret;
1161         }
1162
1163         *r_value= flag;
1164         return 0;
1165 }
1166
1167 static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObject *value, int *r_value, const char *error_prefix)
1168 {
1169         EnumPropertyItem *item;
1170         int ret;
1171         int free= FALSE;
1172
1173         *r_value= 0;
1174
1175         if (!PyAnySet_Check(value)) {
1176                 PyErr_Format(PyExc_TypeError,
1177                              "%.200s, %.200s.%.200s expected a set, not a %.200s",
1178                              error_prefix, RNA_struct_identifier(ptr->type),
1179                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1180                 return -1;
1181         }
1182
1183         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
1184
1185         if (item) {
1186                 ret= pyrna_set_to_enum_bitfield(item, value, r_value, error_prefix);
1187         }
1188         else {
1189                 if (PySet_GET_SIZE(value)) {
1190                         PyErr_Format(PyExc_TypeError,
1191                                      "%.200s: empty enum \"%.200s\" could not have any values assigned",
1192                                      error_prefix, RNA_property_identifier(prop));
1193                         ret= -1;
1194                 }
1195                 else {
1196                         ret= 0;
1197                 }
1198         }
1199
1200         if (free)
1201                 MEM_freeN(item);
1202
1203         return ret;
1204 }
1205
1206 PyObject *pyrna_enum_bitfield_to_py(EnumPropertyItem *items, int value)
1207 {
1208         PyObject *ret= PySet_New(NULL);
1209         const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1210
1211         if (RNA_enum_bitflag_identifiers(items, value, identifier)) {
1212                 PyObject *item;
1213                 int index;
1214                 for (index=0; identifier[index]; index++) {
1215                         item= PyUnicode_FromString(identifier[index]);
1216                         PySet_Add(ret, item);
1217                         Py_DECREF(item);
1218                 }
1219         }
1220
1221         return ret;
1222 }
1223
1224 static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
1225 {
1226         PyObject *item, *ret= NULL;
1227
1228         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1229                 const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
1230
1231                 ret= PySet_New(NULL);
1232
1233                 if (RNA_property_enum_bitflag_identifiers(BPy_GetContext(), ptr, prop, val, identifier)) {
1234                         int index;
1235
1236                         for (index=0; identifier[index]; index++) {
1237                                 item= PyUnicode_FromString(identifier[index]);
1238                                 PySet_Add(ret, item);
1239                                 Py_DECREF(item);
1240                         }
1241
1242                 }
1243         }
1244         else {
1245                 const char *identifier;
1246                 if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) {
1247                         ret= PyUnicode_FromString(identifier);
1248                 }
1249                 else {
1250                         EnumPropertyItem *enum_item;
1251                         int free= FALSE;
1252
1253                         /* don't throw error here, can't trust blender 100% to give the
1254                          * right values, python code should not generate error for that */
1255                         RNA_property_enum_items(BPy_GetContext(), ptr, prop, &enum_item, NULL, &free);
1256                         if (enum_item && enum_item->identifier) {
1257                                 ret= PyUnicode_FromString(enum_item->identifier);
1258                         }
1259                         else {
1260                                 const char *ptr_name= RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
1261
1262                                 /* prefer not fail silently incase of api errors, maybe disable it later */
1263                                 printf("RNA Warning: Current value \"%d\" "
1264                                            "matches no enum in '%s', '%s', '%s'\n",
1265                                            val, RNA_struct_identifier(ptr->type),
1266                                            ptr_name, RNA_property_identifier(prop));
1267
1268 #if 0                   // gives python decoding errors while generating docs :(
1269                                 char error_str[256];
1270                                 BLI_snprintf(error_str, sizeof(error_str),
1271                                                          "RNA Warning: Current value \"%d\" "
1272                                                          "matches no enum in '%s', '%s', '%s'",
1273                                                          val, RNA_struct_identifier(ptr->type),
1274                                                          ptr_name, RNA_property_identifier(prop));
1275
1276                                 PyErr_Warn(PyExc_RuntimeWarning, error_str);
1277 #endif
1278
1279                                 if (ptr_name)
1280                                         MEM_freeN((void *)ptr_name);
1281
1282                                 ret= PyUnicode_FromString("");
1283                         }
1284
1285                         if (free)
1286                                 MEM_freeN(enum_item);
1287                         /*
1288                         PyErr_Format(PyExc_AttributeError,
1289                                      "RNA Error: Current value \"%d\" matches no enum", val);
1290                         ret= NULL;
1291                         */
1292                 }
1293         }
1294
1295         return ret;
1296 }
1297
1298 PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
1299 {
1300         PyObject *ret;
1301         int type= RNA_property_type(prop);
1302
1303         if (RNA_property_array_check(prop)) {
1304                 return pyrna_py_from_array(ptr, prop);
1305         }
1306
1307         /* see if we can coorce into a python type - PropertyType */
1308         switch (type) {
1309         case PROP_BOOLEAN:
1310                 ret= PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
1311                 break;
1312         case PROP_INT:
1313                 ret= PyLong_FromSsize_t((Py_ssize_t)RNA_property_int_get(ptr, prop));
1314                 break;
1315         case PROP_FLOAT:
1316                 ret= PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
1317                 break;
1318         case PROP_STRING:
1319         {
1320                 int subtype= RNA_property_subtype(prop);
1321                 const char *buf;
1322                 int buf_len;
1323                 char buf_fixed[32];
1324
1325                 buf= RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
1326 #ifdef USE_STRING_COERCE
1327                 /* only file paths get special treatment, they may contain non utf-8 chars */
1328                 if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1329                         ret= PyC_UnicodeFromByteAndSize(buf, buf_len);
1330                 }
1331                 else {
1332                         ret= PyUnicode_FromStringAndSize(buf, buf_len);
1333                 }
1334 #else // USE_STRING_COERCE
1335                 ret= PyUnicode_FromStringAndSize(buf, buf_len);
1336 #endif // USE_STRING_COERCE
1337                 if (buf_fixed != buf) {
1338                         MEM_freeN((void *)buf);
1339                 }
1340                 break;
1341         }
1342         case PROP_ENUM:
1343         {
1344                 ret= pyrna_enum_to_py(ptr, prop, RNA_property_enum_get(ptr, prop));
1345                 break;
1346         }
1347         case PROP_POINTER:
1348         {
1349                 PointerRNA newptr;
1350                 newptr= RNA_property_pointer_get(ptr, prop);
1351                 if (newptr.data) {
1352                         ret= pyrna_struct_CreatePyObject(&newptr);
1353                 }
1354                 else {
1355                         ret= Py_None;
1356                         Py_INCREF(ret);
1357                 }
1358                 break;
1359         }
1360         case PROP_COLLECTION:
1361                 ret= pyrna_prop_CreatePyObject(ptr, prop);
1362                 break;
1363         default:
1364                 PyErr_Format(PyExc_TypeError,
1365                              "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)", type);
1366                 ret= NULL;
1367                 break;
1368         }
1369
1370         return ret;
1371 }
1372
1373 /* This function is used by operators and converting dicts into collections.
1374  * Its takes keyword args and fills them with property values */
1375 int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix)
1376 {
1377         int error_val= 0;
1378         int totkw;
1379         const char *arg_name= NULL;
1380         PyObject *item;
1381
1382         totkw= kw ? PyDict_Size(kw):0;
1383
1384         RNA_STRUCT_BEGIN(ptr, prop) {
1385                 arg_name= RNA_property_identifier(prop);
1386
1387                 if (strcmp(arg_name, "rna_type")==0) continue;
1388
1389                 if (kw==NULL) {
1390                         PyErr_Format(PyExc_TypeError,
1391                                      "%.200s: no keywords, expected \"%.200s\"",
1392                                      error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1393                         error_val= -1;
1394                         break;
1395                 }
1396
1397                 item= PyDict_GetItemString(kw, arg_name); /* wont set an error */
1398
1399                 if (item == NULL) {
1400                         if (all_args) {
1401                                 PyErr_Format(PyExc_TypeError,
1402                                              "%.200s: keyword \"%.200s\" missing",
1403                                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1404                                 error_val= -1; /* pyrna_py_to_prop sets the error */
1405                                 break;
1406                         }
1407                 }
1408                 else {
1409                         if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
1410                                 error_val= -1;
1411                                 break;
1412                         }
1413                         totkw--;
1414                 }
1415         }
1416         RNA_STRUCT_END;
1417
1418         if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */
1419                 PyObject *key, *value;
1420                 Py_ssize_t pos= 0;
1421
1422                 while (PyDict_Next(kw, &pos, &key, &value)) {
1423                         arg_name= _PyUnicode_AsString(key);
1424                         if (RNA_struct_find_property(ptr, arg_name) == NULL) break;
1425                         arg_name= NULL;
1426                 }
1427
1428                 PyErr_Format(PyExc_TypeError,
1429                              "%.200s: keyword \"%.200s\" unrecognized",
1430                              error_prefix, arg_name ? arg_name : "<UNKNOWN>");
1431                 error_val= -1;
1432         }
1433
1434         return error_val;
1435 }
1436
1437
1438 static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
1439 {
1440         BPy_FunctionRNA* pyfunc= (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
1441         pyfunc->ptr= *ptr;
1442         pyfunc->func= func;
1443         return (PyObject *)pyfunc;
1444 }
1445
1446
1447 static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
1448 {
1449         /* XXX hard limits should be checked here */
1450         int type= RNA_property_type(prop);
1451
1452
1453         if (RNA_property_array_check(prop)) {
1454                 /* done getting the length */
1455                 if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) {
1456                         return -1;
1457                 }
1458         }
1459         else {
1460                 /* Normal Property (not an array) */
1461
1462                 /* see if we can coorce into a python type - PropertyType */
1463                 switch (type) {
1464                 case PROP_BOOLEAN:
1465                 {
1466                         int param;
1467                         /* prefer not to have an exception here
1468                          * however so many poll functions return None or a valid Object.
1469                          * its a hassle to convert these into a bool before returning, */
1470                         if (RNA_property_flag(prop) & PROP_OUTPUT)
1471                                 param= PyObject_IsTrue(value);
1472                         else
1473                                 param= PyLong_AsLong(value);
1474
1475                         if (param < 0) {
1476                                 PyErr_Format(PyExc_TypeError,
1477                                              "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
1478                                              error_prefix, RNA_struct_identifier(ptr->type),
1479                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1480                                 return -1;
1481                         }
1482                         else {
1483                                 if (data)  *((int*)data)= param;
1484                                 else       RNA_property_boolean_set(ptr, prop, param);
1485                         }
1486                         break;
1487                 }
1488                 case PROP_INT:
1489                 {
1490                         int overflow;
1491                         long param= PyLong_AsLongAndOverflow(value, &overflow);
1492                         if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
1493                                 PyErr_Format(PyExc_ValueError,
1494                                              "%.200s %.200s.%.200s value not in 'int' range "
1495                                              "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
1496                                              error_prefix, RNA_struct_identifier(ptr->type),
1497                                              RNA_property_identifier(prop));
1498                                 return -1;
1499                         }
1500                         else if (param==-1 && PyErr_Occurred()) {
1501                                 PyErr_Format(PyExc_TypeError,
1502                                              "%.200s %.200s.%.200s expected an int type, not %.200s",
1503                                              error_prefix, RNA_struct_identifier(ptr->type),
1504                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1505                                 return -1;
1506                         }
1507                         else {
1508                                 int param_i= (int)param;
1509                                 RNA_property_int_clamp(ptr, prop, &param_i);
1510                                 if (data)  *((int*)data)= param_i;
1511                                 else       RNA_property_int_set(ptr, prop, param_i);
1512                         }
1513                         break;
1514                 }
1515                 case PROP_FLOAT:
1516                 {
1517                         float param= PyFloat_AsDouble(value);
1518                         if (PyErr_Occurred()) {
1519                                 PyErr_Format(PyExc_TypeError,
1520                                              "%.200s %.200s.%.200s expected a float type, not %.200s",
1521                                              error_prefix, RNA_struct_identifier(ptr->type),
1522                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1523                                 return -1;
1524                         }
1525                         else {
1526                                 RNA_property_float_clamp(ptr, prop, (float *)&param);
1527                                 if (data)   *((float*)data)= param;
1528                                 else        RNA_property_float_set(ptr, prop, param);
1529                         }
1530                         break;
1531                 }
1532                 case PROP_STRING:
1533                 {
1534                         const char *param;
1535 #ifdef USE_STRING_COERCE
1536                         PyObject *value_coerce= NULL;
1537                         int subtype= RNA_property_subtype(prop);
1538                         if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
1539                                 /* TODO, get size */
1540                                 param= PyC_UnicodeAsByte(value, &value_coerce);
1541                         }
1542                         else {
1543                                 param= _PyUnicode_AsString(value);
1544 #ifdef WITH_INTERNATIONAL
1545                                 if (subtype == PROP_TRANSLATE) {
1546                                         param= IFACE_(param);
1547                                 }
1548 #endif // WITH_INTERNATIONAL
1549
1550                         }
1551 #else // USE_STRING_COERCE
1552                         param= _PyUnicode_AsString(value);
1553 #endif // USE_STRING_COERCE
1554
1555                         if (param==NULL) {
1556                                 if (PyUnicode_Check(value)) {
1557                                         /* there was an error assigning a string type,
1558                                          * rather than setting a new error, prefix the existing one
1559                                          */
1560                                         PyC_Err_Format_Prefix(PyExc_TypeError,
1561                                                               "%.200s %.200s.%.200s error assigning string",
1562                                                                                   error_prefix, RNA_struct_identifier(ptr->type),
1563                                                                                   RNA_property_identifier(prop));
1564                                 }
1565                                 else {
1566                                         PyErr_Format(PyExc_TypeError,
1567                                                                  "%.200s %.200s.%.200s expected a string type, not %.200s",
1568                                                                  error_prefix, RNA_struct_identifier(ptr->type),
1569                                                                  RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1570                                 }
1571
1572                                 return -1;
1573                         }
1574                         else {
1575                                 if (data)   *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
1576                                 else        RNA_property_string_set(ptr, prop, param);
1577                         }
1578 #ifdef USE_STRING_COERCE
1579                         Py_XDECREF(value_coerce);
1580 #endif // USE_STRING_COERCE
1581                         break;
1582                 }
1583                 case PROP_ENUM:
1584                 {
1585                         int val= 0;
1586
1587                         /* type checkins is done by each function */
1588                         if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
1589                                 /* set of enum items, concatenate all values with OR */
1590                                 if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
1591                                         return -1;
1592                                 }
1593                         }
1594                         else {
1595                                 /* simple enum string */
1596                                 if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
1597                                         return -1;
1598                                 }
1599                         }
1600
1601                         if (data)  *((int*)data)= val;
1602                         else       RNA_property_enum_set(ptr, prop, val);
1603
1604                         break;
1605                 }
1606                 case PROP_POINTER:
1607                 {
1608                         PyObject *value_new= NULL;
1609
1610                         StructRNA *ptr_type= RNA_property_pointer_type(ptr, prop);
1611                         int flag= RNA_property_flag(prop);
1612
1613                         /* this is really nasty!, so we can fake the operator having direct properties eg:
1614                          * layout.prop(self, "filepath")
1615                          * ... which infact should be
1616                          * layout.prop(self.properties, "filepath")
1617                          *
1618                          * we need to do this trick.
1619                          * if the prop is not an operator type and the pyobject is an operator, use its properties in place of its self.
1620                          *
1621                          * this is so bad that its almost a good reason to do away with fake 'self.properties -> self' class mixing
1622                          * if this causes problems in the future it should be removed.
1623                          */
1624                         if ((ptr_type == &RNA_AnyType) &&
1625                                 (BPy_StructRNA_Check(value)) &&
1626                                 (RNA_struct_is_a(((BPy_StructRNA *)value)->ptr.type, &RNA_Operator))
1627                         ) {
1628                                 value= PyObject_GetAttrString(value, "properties");
1629                                 value_new= value;
1630                         }
1631
1632
1633                         /* if property is an OperatorProperties pointer and value is a map, forward back to pyrna_pydict_to_props */
1634                         if (RNA_struct_is_a(ptr_type, &RNA_OperatorProperties) && PyDict_Check(value)) {
1635                                 PointerRNA opptr= RNA_property_pointer_get(ptr, prop);
1636                                 return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
1637                         }
1638
1639                         /* another exception, allow to pass a collection as an RNA property */
1640                         if (Py_TYPE(value)==&pyrna_prop_collection_Type) { /* ok to ignore idprop collections */
1641                                 PointerRNA c_ptr;
1642                                 BPy_PropertyRNA *value_prop= (BPy_PropertyRNA *)value;
1643                                 if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
1644                                         value= pyrna_struct_CreatePyObject(&c_ptr);
1645                                         value_new= value;
1646                                 }
1647                                 else {
1648                                         PyErr_Format(PyExc_TypeError,
1649                                                      "%.200s %.200s.%.200s collection has no type, "
1650                                                      "cant be used as a %.200s type",
1651                                                      error_prefix, RNA_struct_identifier(ptr->type),
1652                                                      RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1653                                         return -1;
1654                                 }
1655                         }
1656
1657                         if (!BPy_StructRNA_Check(value) && value != Py_None) {
1658                                 PyErr_Format(PyExc_TypeError,
1659                                              "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1660                                              error_prefix, RNA_struct_identifier(ptr->type),
1661                                              RNA_property_identifier(prop), RNA_struct_identifier(ptr_type),
1662                                              Py_TYPE(value)->tp_name);
1663                                 Py_XDECREF(value_new); return -1;
1664                         }
1665                         else if ((flag & PROP_NEVER_NULL) && value == Py_None) {
1666                                 PyErr_Format(PyExc_TypeError,
1667                                              "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
1668                                              error_prefix, RNA_struct_identifier(ptr->type),
1669                                              RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
1670                                 Py_XDECREF(value_new); return -1;
1671                         }
1672                         else if (value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
1673                                 PyErr_Format(PyExc_TypeError,
1674                                              "%.200s %.200s.%.200s ID type does not support assignment to its self",
1675                                              error_prefix, RNA_struct_identifier(ptr->type),
1676                                              RNA_property_identifier(prop));
1677                                 Py_XDECREF(value_new); return -1;
1678                         }
1679                         else {
1680                                 BPy_StructRNA *param= (BPy_StructRNA*)value;
1681                                 int raise_error= FALSE;
1682                                 if (data) {
1683
1684                                         if (flag & PROP_RNAPTR) {
1685                                                 if (value == Py_None)
1686                                                         memset(data, 0, sizeof(PointerRNA));
1687                                                 else
1688                                                         *((PointerRNA*)data)= param->ptr;
1689                                         }
1690                                         else if (value == Py_None) {
1691                                                 *((void**)data)= NULL;
1692                                         }
1693                                         else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1694                                                 *((void**)data)= param->ptr.data;
1695                                         }
1696                                         else {
1697                                                 raise_error= TRUE;
1698                                         }
1699                                 }
1700                                 else {
1701                                         /* data==NULL, assign to RNA */
1702                                         if (value == Py_None) {
1703                                                 PointerRNA valueptr= {{NULL}};
1704                                                 RNA_property_pointer_set(ptr, prop, valueptr);
1705                                         }
1706                                         else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
1707                                                 RNA_property_pointer_set(ptr, prop, param->ptr);
1708                                         }
1709                                         else {
1710                                                 PointerRNA tmp;
1711                                                 RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1712                                                 PyErr_Format(PyExc_TypeError,
1713                                                              "%.200s %.200s.%.200s expected a %.200s type. not %.200s",
1714                                                              error_prefix, RNA_struct_identifier(ptr->type),
1715                                                              RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1716                                                              RNA_struct_identifier(param->ptr.type));
1717                                                 Py_XDECREF(value_new); return -1;
1718                                         }
1719                                 }
1720
1721                                 if (raise_error) {
1722                                         PointerRNA tmp;
1723                                         RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
1724                                         PyErr_Format(PyExc_TypeError,
1725                                                      "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
1726                                                      error_prefix, RNA_struct_identifier(ptr->type),
1727                                                      RNA_property_identifier(prop), RNA_struct_identifier(tmp.type),
1728                                                      RNA_struct_identifier(param->ptr.type));
1729                                         Py_XDECREF(value_new); return -1;
1730                                 }
1731                         }
1732
1733                         Py_XDECREF(value_new);
1734
1735                         break;
1736                 }
1737                 case PROP_COLLECTION:
1738                 {
1739                         Py_ssize_t seq_len, i;
1740                         PyObject *item;
1741                         PointerRNA itemptr;
1742                         ListBase *lb;
1743                         CollectionPointerLink *link;
1744
1745                         lb= (data)? (ListBase*)data: NULL;
1746
1747                         /* convert a sequence of dict's into a collection */
1748                         if (!PySequence_Check(value)) {
1749                                 PyErr_Format(PyExc_TypeError,
1750                                              "%.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s",
1751                                              error_prefix, RNA_struct_identifier(ptr->type),
1752                                              RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
1753                                 return -1;
1754                         }
1755
1756                         seq_len= PySequence_Size(value);
1757                         for (i=0; i < seq_len; i++) {
1758                                 item= PySequence_GetItem(value, i);
1759
1760                                 if (item==NULL) {
1761                                         PyErr_Format(PyExc_TypeError,
1762                                                      "%.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection",
1763                                                      error_prefix, RNA_struct_identifier(ptr->type),
1764                                                      RNA_property_identifier(prop), i);
1765                                         Py_XDECREF(item);
1766                                         return -1;
1767                                 }
1768
1769                                 if (PyDict_Check(item)==0) {
1770                                         PyErr_Format(PyExc_TypeError,
1771                                                      "%.200s %.200s.%.200s expected a each sequence "
1772                                                      "member to be a dict for an RNA collection, not %.200s",
1773                                                      error_prefix, RNA_struct_identifier(ptr->type),
1774                                                      RNA_property_identifier(prop), Py_TYPE(item)->tp_name);
1775                                         Py_XDECREF(item);
1776                                         return -1;
1777                                 }
1778
1779                                 if (lb) {
1780                                         link= MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
1781                                         link->ptr= itemptr;
1782                                         BLI_addtail(lb, link);
1783                                 }
1784                                 else
1785                                         RNA_property_collection_add(ptr, prop, &itemptr);
1786
1787                                 if (pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection")==-1) {
1788                                         PyObject *msg= PyC_ExceptionBuffer();
1789                                         const char *msg_char= _PyUnicode_AsString(msg);
1790
1791                                         PyErr_Format(PyExc_TypeError,
1792                                                      "%.200s %.200s.%.200s error converting a member of a collection "
1793                                                      "from a dicts into an RNA collection, failed with: %s",
1794                                                      error_prefix, RNA_struct_identifier(ptr->type),
1795                                                      RNA_property_identifier(prop), msg_char);
1796
1797                                         Py_DECREF(item);
1798                                         Py_DECREF(msg);
1799                                         return -1;
1800                                 }
1801                                 Py_DECREF(item);
1802                         }
1803
1804                         break;
1805                 }
1806                 default:
1807                         PyErr_Format(PyExc_AttributeError,
1808                                      "%.200s %.200s.%.200s unknown property type (pyrna_py_to_prop)",
1809                                      error_prefix, RNA_struct_identifier(ptr->type),
1810                                      RNA_property_identifier(prop));
1811                         return -1;
1812                         break;
1813                 }
1814         }
1815
1816         /* Run rna property functions */
1817         if (RNA_property_update_check(prop)) {
1818                 RNA_property_update(BPy_GetContext(), ptr, prop);
1819         }
1820
1821         return 0;
1822 }
1823
1824 static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
1825 {
1826         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
1827         return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
1828 }
1829
1830 static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
1831 {
1832         int ret= 0;
1833         PointerRNA *ptr= &self->ptr;
1834         PropertyRNA *prop= self->prop;
1835
1836         const int totdim= RNA_property_array_dimension(ptr, prop, NULL);
1837
1838         if (totdim > 1) {
1839                 /* char error_str[512]; */
1840                 if (pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) {
1841                         /* error is set */
1842                         ret= -1;
1843                 }
1844         }
1845         else {
1846                 /* see if we can coerce into a python type - PropertyType */
1847                 switch (RNA_property_type(prop)) {
1848                 case PROP_BOOLEAN:
1849                         {
1850                                 int param= PyLong_AsLong(value);
1851
1852                                 if (param < 0 || param > 1) {
1853                                         PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
1854                                         ret= -1;
1855                                 }
1856                                 else {
1857                                         RNA_property_boolean_set_index(ptr, prop, index, param);
1858                                 }
1859                                 break;
1860                         }
1861                 case PROP_INT:
1862                         {
1863                                 int param= PyLong_AsLong(value);
1864                                 if (param==-1 && PyErr_Occurred()) {
1865                                         PyErr_SetString(PyExc_TypeError, "expected an int type");
1866                                         ret= -1;
1867                                 }
1868                                 else {
1869                                         RNA_property_int_clamp(ptr, prop, &param);
1870                                         RNA_property_int_set_index(ptr, prop, index, param);
1871                                 }
1872                                 break;
1873                         }
1874                 case PROP_FLOAT:
1875                         {
1876                                 float param= PyFloat_AsDouble(value);
1877                                 if (PyErr_Occurred()) {
1878                                         PyErr_SetString(PyExc_TypeError, "expected a float type");
1879                                         ret= -1;
1880                                 }
1881                                 else {
1882                                         RNA_property_float_clamp(ptr, prop, &param);
1883                                         RNA_property_float_set_index(ptr, prop, index, param);
1884                                 }
1885                                 break;
1886                         }
1887                 default:
1888                         PyErr_SetString(PyExc_AttributeError, "not an array type");
1889                         ret= -1;
1890                         break;
1891                 }
1892         }
1893
1894         /* Run rna property functions */
1895         if (RNA_property_update_check(prop)) {
1896                 RNA_property_update(BPy_GetContext(), ptr, prop);
1897         }
1898
1899         return ret;
1900 }
1901
1902 //---------------sequence-------------------------------------------
1903 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
1904 {
1905         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
1906
1907         if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
1908                 return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
1909         else
1910                 return RNA_property_array_length(&self->ptr, self->prop);
1911 }
1912
1913 static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
1914 {
1915         PYRNA_PROP_CHECK_INT(self);
1916
1917         return RNA_property_collection_length(&self->ptr, self->prop);
1918 }
1919
1920 /* bool functions are for speed, so we can avoid getting the length
1921  * of 1000's of items in a linked list for eg. */
1922 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
1923 {
1924         PYRNA_PROP_CHECK_INT(self);
1925
1926         return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
1927 }
1928
1929 static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
1930 {
1931         /* no callback defined, just iterate and find the nth item */
1932         CollectionPropertyIterator iter;
1933         int test;
1934
1935         PYRNA_PROP_CHECK_INT(self);
1936
1937         RNA_property_collection_begin(&self->ptr, self->prop, &iter);
1938         test= iter.valid;
1939         RNA_property_collection_end(&iter);
1940         return test;
1941 }
1942
1943
1944 /* notice getting the length of the collection is avoided unless negative
1945  * index is used or to detect internal error with a valid index.
1946  * This is done for faster lookups. */
1947 #define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err)                              \
1948         if (keynum < 0) {                                                         \
1949                 keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
1950                 if (keynum_abs < 0) {                                                 \
1951                         PyErr_Format(PyExc_IndexError,                                    \
1952                                      "bpy_prop_collection[%d]: out of range.", keynum);   \
1953                         return ret_err;                                                   \
1954                 }                                                                     \
1955         }                                                                         \
1956
1957
1958 /* internal use only */
1959 static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
1960 {
1961         PointerRNA newptr;
1962         Py_ssize_t keynum_abs= keynum;
1963
1964         PYRNA_PROP_CHECK_OBJ(self);
1965
1966         PYRNA_PROP_COLLECTION_ABS_INDEX(NULL);
1967
1968         if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
1969                 return pyrna_struct_CreatePyObject(&newptr);
1970         }
1971         else {
1972                 const int len= RNA_property_collection_length(&self->ptr, self->prop);
1973                 if (keynum_abs >= len) {
1974                         PyErr_Format(PyExc_IndexError,
1975                                      "bpy_prop_collection[index]: "
1976                                      "index %d out of range, size %d", keynum, len);
1977                 }
1978                 else {
1979                         PyErr_Format(PyExc_RuntimeError,
1980                                      "bpy_prop_collection[index]: internal error, "
1981                                      "valid index %d given in %d sized collection but value not found",
1982                                      keynum_abs, len);
1983                 }
1984
1985                 return NULL;
1986         }
1987 }
1988
1989 /* values type must have been already checked */
1990 static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value)
1991 {
1992         Py_ssize_t keynum_abs= keynum;
1993         const PointerRNA *ptr= (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
1994
1995         PYRNA_PROP_CHECK_INT(self);
1996
1997         PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
1998
1999         if (RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr) == 0) {
2000                 const int len= RNA_property_collection_length(&self->ptr, self->prop);
2001                 if (keynum_abs >= len) {
2002                         PyErr_Format(PyExc_IndexError,
2003                                      "bpy_prop_collection[index] = value: "
2004                                      "index %d out of range, size %d", keynum, len);
2005                 }
2006                 else {
2007
2008                         PyErr_Format(PyExc_IndexError,
2009                                      "bpy_prop_collection[index] = value: "
2010                                      "failed assignment (unknown reason)", keynum);
2011                 }
2012                 return -1;
2013         }
2014
2015         return 0;
2016 }
2017
2018 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
2019 {
2020         int len;
2021
2022         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2023
2024         len= pyrna_prop_array_length(self);
2025
2026         if (keynum < 0) keynum += len;
2027
2028         if (keynum >= 0 && keynum < len)
2029                 return pyrna_prop_array_to_py_index(self, keynum);
2030
2031         PyErr_Format(PyExc_IndexError,
2032                      "bpy_prop_array[index]: index %d out of range", keynum);
2033         return NULL;
2034 }
2035
2036 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
2037 {
2038         PointerRNA newptr;
2039
2040         PYRNA_PROP_CHECK_OBJ(self);
2041
2042         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2043                 return pyrna_struct_CreatePyObject(&newptr);
2044
2045         PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
2046         return NULL;
2047 }
2048 /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
2049
2050 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
2051 {
2052         CollectionPropertyIterator rna_macro_iter;
2053         int count= 0;
2054
2055         PyObject *list;
2056         PyObject *item;
2057
2058         PYRNA_PROP_CHECK_OBJ(self);
2059
2060         list= PyList_New(0);
2061
2062         /* first loop up-until the start */
2063         for (RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
2064                 /* PointerRNA itemptr= rna_macro_iter.ptr; */
2065                 if (count == start) {
2066                         break;
2067                 }
2068                 count++;
2069         }
2070
2071         /* add items until stop */
2072         for (; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
2073                 item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
2074                 PyList_Append(list, item);
2075                 Py_DECREF(item);
2076
2077                 count++;
2078                 if (count == stop) {
2079                         break;
2080                 }
2081         }
2082
2083         RNA_property_collection_end(&rna_macro_iter);
2084
2085         return list;
2086 }
2087
2088 /* TODO - dimensions
2089  * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
2090  * since at the moment it reads (and even allocates) the entire array for each index.
2091  */
2092 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
2093 {
2094         int count, totdim;
2095         PyObject *tuple;
2096
2097         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2098
2099         tuple= PyTuple_New(stop - start);
2100
2101         /* PYRNA_PROP_CHECK_OBJ(self); isn't needed, internal use only */
2102
2103         totdim= RNA_property_array_dimension(ptr, prop, NULL);
2104
2105         if (totdim > 1) {
2106                 for (count= start; count < stop; count++)
2107                         PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
2108         }
2109         else {
2110                 switch (RNA_property_type(prop)) {
2111                 case PROP_FLOAT:
2112                         {
2113                                 float values_stack[PYRNA_STACK_ARRAY];
2114                                 float *values;
2115                                 if (length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(float) * length); }
2116                                 else                            { values= values_stack; }
2117                                 RNA_property_float_get_array(ptr, prop, values);
2118
2119                                 for (count=start; count<stop; count++)
2120                                         PyTuple_SET_ITEM(tuple, count-start, PyFloat_FromDouble(values[count]));
2121
2122                                 if (values != values_stack) {
2123                                         PyMem_FREE(values);
2124                                 }
2125                                 break;
2126                         }
2127                 case PROP_BOOLEAN:
2128                         {
2129                                 int values_stack[PYRNA_STACK_ARRAY];
2130                                 int *values;
2131                                 if (length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); }
2132                                 else                            { values= values_stack; }
2133
2134                                 RNA_property_boolean_get_array(ptr, prop, values);
2135                                 for (count=start; count<stop; count++)
2136                                         PyTuple_SET_ITEM(tuple, count-start, PyBool_FromLong(values[count]));
2137
2138                                 if (values != values_stack) {
2139                                         PyMem_FREE(values);
2140                                 }
2141                                 break;
2142                         }
2143                 case PROP_INT:
2144                         {
2145                                 int values_stack[PYRNA_STACK_ARRAY];
2146                                 int *values;
2147                                 if (length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); }
2148                                 else                            { values= values_stack; }
2149
2150                                 RNA_property_int_get_array(ptr, prop, values);
2151                                 for (count=start; count<stop; count++)
2152                                         PyTuple_SET_ITEM(tuple, count-start, PyLong_FromSsize_t(values[count]));
2153
2154                                 if (values != values_stack) {
2155                                         PyMem_FREE(values);
2156                                 }
2157                                 break;
2158                         }
2159                 default:
2160                         BLI_assert(!"Invalid array type");
2161
2162                         PyErr_SetString(PyExc_TypeError, "not an array type");
2163                         Py_DECREF(tuple);
2164                         tuple= NULL;
2165                 }
2166         }
2167         return tuple;
2168 }
2169
2170 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
2171 {
2172         PYRNA_PROP_CHECK_OBJ(self);
2173
2174         if (PyUnicode_Check(key)) {
2175                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2176         }
2177         else if (PyIndex_Check(key)) {
2178                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2179                 if (i == -1 && PyErr_Occurred())
2180                         return NULL;
2181
2182                 return pyrna_prop_collection_subscript_int(self, i);
2183         }
2184         else if (PySlice_Check(key)) {
2185                 PySliceObject *key_slice= (PySliceObject *)key;
2186                 Py_ssize_t step= 1;
2187
2188                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2189                         return NULL;
2190                 }
2191                 else if (step != 1) {
2192                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2193                         return NULL;
2194                 }
2195                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2196                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2197                 }
2198                 else {
2199                         Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
2200
2201                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2202                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2203                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))    return NULL;
2204
2205                         if (start < 0 || stop < 0) {
2206                                 /* only get the length for negative values */
2207                                 Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2208                                 if (start < 0) start += len;
2209                                 if (stop < 0) start += len;
2210                         }
2211
2212                         if (stop - start <= 0) {
2213                                 return PyList_New(0);
2214                         }
2215                         else {
2216                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2217                         }
2218                 }
2219         }
2220         else {
2221                 PyErr_Format(PyExc_TypeError,
2222                              "bpy_prop_collection[key]: invalid key, "
2223                              "must be a string or an int, not %.200s",
2224                              Py_TYPE(key)->tp_name);
2225                 return NULL;
2226         }
2227 }
2228
2229 /* generic check to see if a PyObject is compatible with a collection
2230  * -1 on failure, 0 on success, sets the error */
2231 static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *value)
2232 {
2233         StructRNA *prop_srna;
2234
2235         if (value == Py_None) {
2236                 if (RNA_property_flag(self->prop) & PROP_NEVER_NULL) {
2237                         PyErr_Format(PyExc_TypeError,
2238                                      "bpy_prop_collection[key] = value: invalid, "
2239                                      "this collection doesnt support None assignment");
2240                         return -1;
2241                 }
2242                 else {
2243                         return 0; /* None is OK */
2244                 }
2245         }
2246         else if (BPy_StructRNA_Check(value) == 0) {
2247                 PyErr_Format(PyExc_TypeError,
2248                              "bpy_prop_collection[key] = value: invalid, "
2249                              "expected a StructRNA type or None, not a %.200s",
2250                              Py_TYPE(value)->tp_name);
2251                 return -1;
2252         }
2253         else if ((prop_srna= RNA_property_pointer_type(&self->ptr, self->prop))) {
2254                 StructRNA *value_srna= ((BPy_StructRNA *)value)->ptr.type;
2255                 if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
2256                         PyErr_Format(PyExc_TypeError,
2257                                      "bpy_prop_collection[key] = value: invalid, "
2258                                      "expected a '%.200s' type or None, not a '%.200s'",
2259                                      RNA_struct_identifier(prop_srna),
2260                                      RNA_struct_identifier(value_srna)
2261                                      );
2262                         return -1;
2263                 }
2264                 else {
2265                         return 0; /* OK, this is the correct type!*/
2266                 }
2267         }
2268
2269         PyErr_Format(PyExc_TypeError,
2270                      "bpy_prop_collection[key] = value: internal error, "
2271                      "failed to get the collection type");
2272         return -1;
2273 }
2274
2275 /* note: currently this is a copy of 'pyrna_prop_collection_subscript' with
2276  * large blocks commented, we may support slice/key indicies later */
2277 static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyObject *key, PyObject *value)
2278 {
2279         PYRNA_PROP_CHECK_INT(self);
2280
2281         /* validate the assigned value */
2282         if (value == NULL) {
2283                 PyErr_SetString(PyExc_TypeError,
2284                                 "del bpy_prop_collection[key]: not supported");
2285                 return -1;
2286         }
2287         else if (pyrna_prop_collection_type_check(self, value) == -1) {
2288                 return -1; /* exception is set */
2289         }
2290
2291 #if 0
2292         if (PyUnicode_Check(key)) {
2293                 return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
2294         }
2295         else
2296 #endif
2297         if (PyIndex_Check(key)) {
2298                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2299                 if (i == -1 && PyErr_Occurred())
2300                         return -1;
2301
2302                 return pyrna_prop_collection_ass_subscript_int(self, i, value);
2303         }
2304 #if 0 /* TODO, fake slice assignment */
2305         else if (PySlice_Check(key)) {
2306                 PySliceObject *key_slice= (PySliceObject *)key;
2307                 Py_ssize_t step= 1;
2308
2309                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2310                         return NULL;
2311                 }
2312                 else if (step != 1) {
2313                         PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
2314                         return NULL;
2315                 }
2316                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2317                         return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2318                 }
2319                 else {
2320                         Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
2321
2322                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2323                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start))       return NULL;
2324                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))          return NULL;
2325
2326                         if (start < 0 || stop < 0) {
2327                                 /* only get the length for negative values */
2328                                 Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
2329                                 if (start < 0) start += len;
2330                                 if (stop < 0) start += len;
2331                         }
2332
2333                         if (stop - start <= 0) {
2334                                 return PyList_New(0);
2335                         }
2336                         else {
2337                                 return pyrna_prop_collection_subscript_slice(self, start, stop);
2338                         }
2339                 }
2340         }
2341 #endif
2342         else {
2343                 PyErr_Format(PyExc_TypeError,
2344                              "bpy_prop_collection[key]: invalid key, "
2345                              "must be a string or an int, not %.200s",
2346                              Py_TYPE(key)->tp_name);
2347                 return -1;
2348         }
2349 }
2350
2351 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
2352 {
2353         PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
2354
2355         /*if (PyUnicode_Check(key)) {
2356                 return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
2357         }
2358         else */
2359         if (PyIndex_Check(key)) {
2360                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2361                 if (i == -1 && PyErr_Occurred())
2362                         return NULL;
2363                 return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
2364         }
2365         else if (PySlice_Check(key)) {
2366                 Py_ssize_t step= 1;
2367                 PySliceObject *key_slice= (PySliceObject *)key;
2368
2369                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2370                         return NULL;
2371                 }
2372                 else if (step != 1) {
2373                         PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
2374                         return NULL;
2375                 }
2376                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2377                         /* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
2378                         Py_ssize_t len= (Py_ssize_t)pyrna_prop_array_length(self);
2379                         return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
2380                 }
2381                 else {
2382                         int len= pyrna_prop_array_length(self);
2383                         Py_ssize_t start, stop, slicelength;
2384
2385                         if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0)
2386                                 return NULL;
2387
2388                         if (slicelength <= 0) {
2389                                 return PyTuple_New(0);
2390                         }
2391                         else {
2392                                 return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
2393                         }
2394                 }
2395         }
2396         else {
2397                 PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
2398                 return NULL;
2399         }
2400 }
2401
2402 /* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
2403 static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length, PyObject *value_orig)
2404 {
2405         PyObject *value;
2406         int count;
2407         void *values_alloc= NULL;
2408         int ret= 0;
2409
2410         if (value_orig == NULL) {
2411                 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]= value: deleting with list types is not supported by bpy_struct");
2412                 return -1;
2413         }
2414
2415         if (!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice]= value: assignment is not a sequence type"))) {
2416                 return -1;
2417         }
2418
2419         if (PySequence_Fast_GET_SIZE(value) != stop-start) {
2420                 Py_DECREF(value);
2421                 PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]= value: resizing bpy_struct arrays isn't supported");
2422                 return -1;
2423         }
2424
2425         switch (RNA_property_type(prop)) {
2426                 case PROP_FLOAT:
2427                 {
2428                         float values_stack[PYRNA_STACK_ARRAY];
2429                         float *values, fval;
2430
2431                         float min, max;
2432                         RNA_property_float_range(ptr, prop, &min, &max);
2433
2434                         if (length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(float) * length); }
2435                         else                            { values= values_stack; }
2436                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2437                                 RNA_property_float_get_array(ptr, prop, values);
2438
2439                         for (count=start; count<stop; count++) {
2440                                 fval= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
2441                                 CLAMP(fval, min, max);
2442                                 values[count]= fval;
2443                         }
2444
2445                         if (PyErr_Occurred()) ret= -1;
2446                         else                  RNA_property_float_set_array(ptr, prop, values);
2447                         break;
2448                 }
2449                 case PROP_BOOLEAN:
2450                 {
2451                         int values_stack[PYRNA_STACK_ARRAY];
2452                         int *values;
2453                         if (length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
2454                         else                            { values= values_stack; }
2455
2456                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2457                                 RNA_property_boolean_get_array(ptr, prop, values);
2458
2459                         for (count=start; count<stop; count++)
2460                                 values[count]= PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
2461
2462                         if (PyErr_Occurred()) ret= -1;
2463                         else                  RNA_property_boolean_set_array(ptr, prop, values);
2464                         break;
2465                 }
2466                 case PROP_INT:
2467                 {
2468                         int values_stack[PYRNA_STACK_ARRAY];
2469                         int *values, ival;
2470
2471                         int min, max;
2472                         RNA_property_int_range(ptr, prop, &min, &max);
2473
2474                         if (length > PYRNA_STACK_ARRAY) { values= values_alloc= PyMem_MALLOC(sizeof(int) * length); }
2475                         else                            { values= values_stack; }
2476
2477                         if (start != 0 || stop != length) /* partial assignment? - need to get the array */
2478                                 RNA_property_int_get_array(ptr, prop, values);
2479
2480                         for (count=start; count<stop; count++) {
2481                                 ival= PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
2482                                 CLAMP(ival, min, max);
2483                                 values[count]= ival;
2484                         }
2485
2486                         if (PyErr_Occurred()) ret= -1;
2487                         else                  RNA_property_int_set_array(ptr, prop, values);
2488                         break;
2489                 }
2490                 default:
2491                         PyErr_SetString(PyExc_TypeError, "not an array type");
2492                         ret= -1;
2493         }
2494
2495         Py_DECREF(value);
2496
2497         if (values_alloc) {
2498                 PyMem_FREE(values_alloc);
2499         }
2500
2501         return ret;
2502
2503 }
2504
2505 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
2506 {
2507         int len;
2508
2509         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2510
2511         len= pyrna_prop_array_length(self);
2512
2513         if (keynum < 0) keynum += len;
2514
2515         if (keynum >= 0 && keynum < len)
2516                 return pyrna_py_to_prop_array_index(self, keynum, value);
2517
2518         PyErr_SetString(PyExc_IndexError,
2519                         "bpy_prop_array[index] = value: index out of range");
2520         return -1;
2521 }
2522
2523 static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
2524 {
2525         /* char *keyname= NULL; */ /* not supported yet */
2526         int ret= -1;
2527
2528         PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
2529
2530         if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
2531                 PyErr_Format(PyExc_AttributeError,
2532                              "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
2533                              RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type));
2534                 ret= -1;
2535         }
2536
2537         else if (PyIndex_Check(key)) {
2538                 Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
2539                 if (i == -1 && PyErr_Occurred()) {
2540                         ret= -1;
2541                 }
2542                 else {
2543                         ret= prop_subscript_ass_array_int(self, i, value);
2544                 }
2545         }
2546         else if (PySlice_Check(key)) {
2547                 int len= RNA_property_array_length(&self->ptr, self->prop);
2548                 Py_ssize_t start, stop, step, slicelength;
2549
2550                 if (PySlice_GetIndicesEx((void *)key, len, &start, &stop, &step, &slicelength) < 0) {
2551                         ret= -1;
2552                 }
2553                 else if (slicelength <= 0) {
2554                         ret= 0; /* do nothing */
2555                 }
2556                 else if (step == 1) {
2557                         ret= prop_subscript_ass_array_slice(&self->ptr, self->prop, start, stop, len, value);
2558                 }
2559                 else {
2560                         PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
2561                         ret= -1;
2562                 }
2563         }
2564         else {
2565                 PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
2566                 ret= -1;
2567         }
2568
2569         if (ret != -1) {
2570                 if (RNA_property_update_check(self->prop)) {
2571                         RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
2572                 }
2573         }
2574
2575         return ret;
2576 }
2577
2578 /* for slice only */
2579 static PyMappingMethods pyrna_prop_array_as_mapping= {
2580         (lenfunc) pyrna_prop_array_length,      /* mp_length */
2581         (binaryfunc) pyrna_prop_array_subscript,        /* mp_subscript */
2582         (objobjargproc) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
2583 };
2584
2585 static PyMappingMethods pyrna_prop_collection_as_mapping= {
2586         (lenfunc) pyrna_prop_collection_length, /* mp_length */
2587         (binaryfunc) pyrna_prop_collection_subscript,   /* mp_subscript */
2588         (objobjargproc) pyrna_prop_collection_ass_subscript,    /* mp_ass_subscript */
2589 };
2590
2591 /* only for fast bool's, large structs, assign nb_bool on init */
2592 static PyNumberMethods pyrna_prop_array_as_number= {
2593         NULL, /* nb_add */
2594         NULL, /* nb_subtract */
2595         NULL, /* nb_multiply */
2596         NULL, /* nb_remainder */
2597         NULL, /* nb_divmod */
2598         NULL, /* nb_power */
2599         NULL, /* nb_negative */
2600         NULL, /* nb_positive */
2601         NULL, /* nb_absolute */
2602         (inquiry) pyrna_prop_array_bool, /* nb_bool */
2603 };
2604 static PyNumberMethods pyrna_prop_collection_as_number= {
2605         NULL, /* nb_add */
2606         NULL, /* nb_subtract */
2607         NULL, /* nb_multiply */
2608         NULL, /* nb_remainder */
2609         NULL, /* nb_divmod */
2610         NULL, /* nb_power */
2611         NULL, /* nb_negative */
2612         NULL, /* nb_positive */
2613         NULL, /* nb_absolute */
2614         (inquiry) pyrna_prop_collection_bool, /* nb_bool */
2615 };
2616
2617 static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
2618 {
2619         return pyrna_array_contains_py(&self->ptr, self->prop, value);
2620 }
2621
2622 static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value)
2623 {
2624         PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
2625
2626         /* key in dict style check */
2627         const char *keyname= _PyUnicode_AsString(value);
2628
2629         if (keyname==NULL) {
2630                 PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
2631                 return -1;
2632         }
2633
2634         if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
2635                 return 1;
2636
2637         return 0;
2638 }
2639
2640 static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
2641 {
2642         IDProperty *group;
2643         const char *name= _PyUnicode_AsString(value);
2644
2645         PYRNA_STRUCT_CHECK_INT(self);
2646
2647         if (!name) {
2648                 PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
2649                 return -1;
2650         }
2651
2652         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2653                 PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
2654                 return -1;
2655         }
2656
2657         group= RNA_struct_idprops(&self->ptr, 0);
2658
2659         if (!group)
2660                 return 0;
2661
2662         return IDP_GetPropertyFromGroup(group, name) ? 1:0;
2663 }
2664
2665 static PySequenceMethods pyrna_prop_array_as_sequence= {
2666         (lenfunc)pyrna_prop_array_length,               /* Cant set the len otherwise it can evaluate as false */
2667         NULL,           /* sq_concat */
2668         NULL,           /* sq_repeat */
2669         (ssizeargfunc)pyrna_prop_array_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2670         NULL,           /* sq_slice */
2671         (ssizeobjargproc)prop_subscript_ass_array_int,          /* sq_ass_item */
2672         NULL,           /* *was* sq_ass_slice */
2673         (objobjproc)pyrna_prop_array_contains,  /* sq_contains */
2674         (binaryfunc) NULL, /* sq_inplace_concat */
2675         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2676 };
2677
2678 static PySequenceMethods pyrna_prop_collection_as_sequence= {
2679         (lenfunc)pyrna_prop_collection_length,          /* Cant set the len otherwise it can evaluate as false */
2680         NULL,           /* sq_concat */
2681         NULL,           /* sq_repeat */
2682         (ssizeargfunc)pyrna_prop_collection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */
2683         NULL,           /* *was* sq_slice */
2684         (ssizeobjargproc)/* pyrna_prop_collection_ass_subscript_int */ NULL /* let mapping take this one */, /* sq_ass_item */
2685         NULL,           /* *was* sq_ass_slice */
2686         (objobjproc)pyrna_prop_collection_contains,     /* sq_contains */
2687         (binaryfunc) NULL, /* sq_inplace_concat */
2688         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2689 };
2690
2691 static PySequenceMethods pyrna_struct_as_sequence= {
2692         NULL,           /* Cant set the len otherwise it can evaluate as false */
2693         NULL,           /* sq_concat */
2694         NULL,           /* sq_repeat */
2695         NULL,           /* sq_item */ /* Only set this so PySequence_Check() returns True */
2696         NULL,           /* *was* sq_slice */
2697         NULL,           /* sq_ass_item */
2698         NULL,           /* *was* sq_ass_slice */
2699         (objobjproc)pyrna_struct_contains,      /* sq_contains */
2700         (binaryfunc) NULL, /* sq_inplace_concat */
2701         (ssizeargfunc) NULL, /* sq_inplace_repeat */
2702 };
2703
2704 static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
2705 {
2706         /* mostly copied from BPy_IDGroup_Map_GetItem */
2707         IDProperty *group, *idprop;
2708         const char *name= _PyUnicode_AsString(key);
2709
2710         PYRNA_STRUCT_CHECK_OBJ(self);
2711
2712         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2713                 PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
2714                 return NULL;
2715         }
2716
2717         if (name==NULL) {
2718                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
2719                 return NULL;
2720         }
2721
2722         group= RNA_struct_idprops(&self->ptr, 0);
2723
2724         if (group==NULL) {
2725                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2726                 return NULL;
2727         }
2728
2729         idprop= IDP_GetPropertyFromGroup(group, name);
2730
2731         if (idprop==NULL) {
2732                 PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
2733                 return NULL;
2734         }
2735
2736         return BPy_IDGroup_WrapData(self->ptr.id.data, idprop);
2737 }
2738
2739 static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
2740 {
2741         IDProperty *group;
2742
2743         PYRNA_STRUCT_CHECK_INT(self);
2744
2745         group= RNA_struct_idprops(&self->ptr, 1);
2746
2747 #ifdef USE_PEDANTIC_WRITE
2748         if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
2749                 return -1;
2750         }
2751 #endif // USE_STRING_COERCE
2752
2753         if (group==NULL) {
2754                 PyErr_SetString(PyExc_TypeError, "bpy_struct[key]= val: id properties not supported for this type");
2755                 return -1;
2756         }
2757
2758         return BPy_Wrap_SetMapItem(group, key, value);
2759 }
2760
2761 static PyMappingMethods pyrna_struct_as_mapping= {
2762         (lenfunc) NULL, /* mp_length */
2763         (binaryfunc) pyrna_struct_subscript,    /* mp_subscript */
2764         (objobjargproc) pyrna_struct_ass_subscript,     /* mp_ass_subscript */
2765 };
2766
2767 PyDoc_STRVAR(pyrna_struct_keys_doc,
2768 ".. method:: keys()\n"
2769 "\n"
2770 "   Returns the keys of this objects custom properties (matches pythons\n"
2771 "   dictionary function of the same name).\n"
2772 "\n"
2773 "   :return: custom property keys.\n"
2774 "   :rtype: list of strings\n"
2775 "\n"
2776 BPY_DOC_ID_PROP_TYPE_NOTE
2777 );
2778 static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
2779 {
2780         IDProperty *group;
2781
2782         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2783                 PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
2784                 return NULL;
2785         }
2786
2787         group= RNA_struct_idprops(&self->ptr, 0);
2788
2789         if (group==NULL)
2790                 return PyList_New(0);
2791
2792         return BPy_Wrap_GetKeys(group);
2793 }
2794
2795 PyDoc_STRVAR(pyrna_struct_items_doc,
2796 ".. method:: items()\n"
2797 "\n"
2798 "   Returns the items of this objects custom properties (matches pythons\n"
2799 "   dictionary function of the same name).\n"
2800 "\n"
2801 "   :return: custom property key, value pairs.\n"
2802 "   :rtype: list of key, value tuples\n"
2803 "\n"
2804 BPY_DOC_ID_PROP_TYPE_NOTE
2805 );
2806 static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
2807 {
2808         IDProperty *group;
2809
2810         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2811                 PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
2812                 return NULL;
2813         }
2814
2815         group= RNA_struct_idprops(&self->ptr, 0);
2816
2817         if (group==NULL)
2818                 return PyList_New(0);
2819
2820         return BPy_Wrap_GetItems(self->ptr.id.data, group);
2821 }
2822
2823 PyDoc_STRVAR(pyrna_struct_values_doc,
2824 ".. method:: values()\n"
2825 "\n"
2826 "   Returns the values of this objects custom properties (matches pythons\n"
2827 "   dictionary function of the same name).\n"
2828 "\n"
2829 "   :return: custom property values.\n"
2830 "   :rtype: list\n"
2831 "\n"
2832 BPY_DOC_ID_PROP_TYPE_NOTE
2833 );
2834 static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
2835 {
2836         IDProperty *group;
2837
2838         if (RNA_struct_idprops_check(self->ptr.type)==0) {
2839                 PyErr_SetString(PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties");
2840                 return NULL;
2841         }
2842
2843         group= RNA_struct_idprops(&self->ptr, 0);
2844
2845         if (group==NULL)
2846                 return PyList_New(0);
2847
2848         return BPy_Wrap_GetValues(self->ptr.id.data, group);
2849 }
2850
2851
2852 PyDoc_STRVAR(pyrna_struct_is_property_set_doc,
2853 ".. method:: is_property_set(property)\n"
2854 "\n"
2855 "   Check if a property is set, use for testing operator properties.\n"
2856 "\n"
2857 "   :return: True when the property has been set.\n"
2858 "   :rtype: boolean\n"
2859 );
2860 static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
2861 {
2862         PropertyRNA *prop;
2863         const char *name;
2864         int ret;
2865
2866         PYRNA_STRUCT_CHECK_OBJ(self);
2867
2868         if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
2869                 return NULL;
2870
2871         if ((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) {
2872                 PyErr_Format(PyExc_TypeError,
2873                              "%.200s.is_property_set(\"%.200s\") not found",
2874                              RNA_struct_identifier(self->ptr.type), name);
2875                 return NULL;
2876         }
2877
2878         /* double property lookup, could speed up */
2879         /* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */
2880         if (RNA_property_flag(prop) & PROP_IDPROPERTY) {
2881                 IDProperty *group= RNA_struct_idprops(&self->ptr, 0);
2882                 if (group) {
2883                         ret= IDP_GetPropertyFromGroup(group, name) ? 1:0;
2884                 }
2885                 else {
2886                         ret= 0;
2887                 }
2888         }
2889         else {
2890                 ret= 1;
2891         }
2892
2893         return PyBool_FromLong(ret);
2894 }
2895
2896 PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc,
2897 ".. method:: is_property_hidden(property)\n"
2898 "\n"
2899 "   Check if a property is hidden.\n"
2900 "\n"
2901 "   :return: True when the property is hidden.\n"
2902 "   :rtype: boolean\n"
2903 );
2904 static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
2905 {
2906         PropertyRNA *prop;
2907         const char *name;
2908
2909         PYRNA_STRUCT_CHECK_OBJ(self);
2910
2911         if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name))
2912                 return NULL;
2913
2914         if ((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) {
2915                 PyErr_Format(PyExc_TypeError,
2916                              "%.200s.is_property_hidden(\"%.200s\") not found",
2917                              RNA_struct_identifier(self->ptr.type), name);
2918                 return NULL;
2919         }
2920
2921         return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN);
2922 }
2923
2924 PyDoc_STRVAR(pyrna_struct_path_resolve_doc,
2925 ".. method:: path_resolve(path, coerce=True)\n"
2926 "\n"
2927 "   Returns the property from the path, raise an exception when not found.\n"
2928 "\n"
2929 "   :arg path: path which this property resolves.\n"
2930 "   :type path: string\n"
2931 "   :arg coerce: optional argument, when True, the property will be converted\n"
2932 "      into its python representation.\n"
2933 "   :type coerce: boolean\n"
2934 );
2935 static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
2936 {
2937         const char *path;
2938         PyObject *coerce= Py_True;
2939         PointerRNA r_ptr;
2940         PropertyRNA *r_prop;
2941         int index= -1;
2942
2943         PYRNA_STRUCT_CHECK_OBJ(self);
2944
2945         if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce))
2946                 return NULL;
2947
2948         if (RNA_path_resolve_full(&self->ptr, path, &r_ptr, &r_prop, &index)) {
2949                 if (r_prop) {
2950                         if (index != -1) {
2951                                 if (index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) {
2952                                         PyErr_Format(PyExc_IndexError,
2953                                                      "%.200s.path_resolve(\"%.200s\") index out of range",
2954                                                      RNA_struct_identifier(self->ptr.type), path);
2955                                         return NULL;
2956                                 }
2957                                 else {
2958                                         return pyrna_array_index(&r_ptr, r_prop, index);
2959                                 }
2960                         }
2961                         else {
2962                                 if (coerce == Py_False) {
2963                                         return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
2964                                 }
2965                                 else {
2966                                         return pyrna_prop_to_py(&r_ptr, r_prop);
2967                                 }
2968                         }
2969                 }
2970                 else {
2971                         return pyrna_struct_CreatePyObject(&r_ptr);
2972                 }
2973         }
2974         else {
2975                 PyErr_Format(PyExc_ValueError,
2976                              "%.200s.path_resolve(\"%.200s\") could not be resolved",
2977                              RNA_struct_identifier(self->ptr.type), path);
2978                 return NULL;
2979         }
2980 }
2981
2982 PyDoc_STRVAR(pyrna_struct_path_from_id_doc,
2983 ".. method:: path_from_id(property=\"\")\n"
2984 "\n"
2985 "   Returns the data path from the ID to this object (string).\n"
2986 "\n"
2987 "   :arg property: Optional property name which can be used if the path is\n"
2988 "      to a property of this object.\n"
2989 "   :type property: string\n"
2990 "   :return: The path from :class:`bpy.types.bpy_struct.id_data`\n"
2991 "      to this struct and property (when given).\n"
2992 "   :rtype: str\n"
2993 );
2994 static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
2995 {
2996         const char *name= NULL;
2997         const char *path;
2998         PropertyRNA *prop;
2999         PyObject *ret;
3000
3001         PYRNA_STRUCT_CHECK_OBJ(self);
3002
3003         if (!PyArg_ParseTuple(args, "|s:path_from_id", &name))
3004                 return NULL;
3005
3006         if (name) {
3007                 prop= RNA_struct_find_property(&self->ptr, name);
3008                 if (prop==NULL) {
3009                         PyErr_Format(PyExc_AttributeError,
3010                                      "%.200s.path_from_id(\"%.200s\") not found",
3011                                      RNA_struct_identifier(self->ptr.type), name);
3012                         return NULL;
3013                 }
3014
3015                 path= RNA_path_from_ID_to_property(&self->ptr, prop);
3016         }
3017         else {
3018                 path= RNA_path_from_ID_to_struct(&self->ptr);
3019         }
3020
3021         if (path==NULL) {
3022                 if (name) {
3023                         PyErr_Format(PyExc_ValueError,
3024                                      "%.200s.path_from_id(\"%s\") found but does not support path creation",
3025                                      RNA_struct_identifier(self->ptr.type), name);
3026                 }
3027                 else {
3028                         PyErr_Format(PyExc_ValueError,
3029                                      "%.200s.path_from_id() does not support path creation for this type",
3030                                      RNA_struct_identifier(self->ptr.type));
3031                 }
3032                 return NULL;
3033         }
3034
3035         ret= PyUnicode_FromString(path);
3036         MEM_freeN((void *)path);
3037
3038         return ret;
3039 }
3040
3041 PyDoc_STRVAR(pyrna_prop_path_from_id_doc,
3042 ".. method:: path_from_id()\n"
3043 "\n"
3044 "   Returns the data path from the ID to this property (string).\n"
3045 "\n"
3046 "   :return: The path from :class:`bpy.types.bpy_struct.id_data` to this property.\n"
3047 "   :rtype: str\n"
3048 );
3049 static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
3050 {
3051         const char *path;
3052         PropertyRNA *prop= self->prop;
3053         PyObject *ret;
3054
3055         path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
3056
3057         if (path==NULL) {
3058                 PyErr_Format(PyExc_ValueError,
3059                              "%.200s.%.200s.path_from_id() does not support path creation for this type",
3060                              RNA_struct_identifier(self->ptr.type), RNA_property_identifier(prop));
3061                 return NULL;
3062         }
3063
3064         ret= PyUnicode_FromString(path);
3065         MEM_freeN((void *)path);
3066
3067         return ret;
3068 }
3069
3070 PyDoc_STRVAR(pyrna_struct_type_recast_doc,
3071 ".. method:: type_recast()\n"
3072 "\n"
3073 "   Return a new instance, this is needed because types\n"
3074 "   such as textures can be changed at runtime.\n"
3075 "\n"
3076 "   :return: a new instance of this object with the type initialized again.\n"
3077 "   :rtype: subclass of :class:`bpy.types.bpy_struct`\n"
3078 );
3079 static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
3080 {
3081         PointerRNA r_ptr;
3082
3083         PYRNA_STRUCT_CHECK_OBJ(self);
3084
3085         RNA_pointer_recast(&self->ptr, &r_ptr);
3086         return pyrna_struct_CreatePyObject(&r_ptr);
3087 }
3088
3089 static void pyrna_dir_members_py(PyObject *list, PyObject *self)
3090 {
3091         PyObject *dict;
3092         PyObject **dict_ptr;
3093         PyObject *list_tmp;
3094
3095         dict_ptr= _PyObject_GetDictPtr((PyObject *)self);
3096
3097         if (dict_ptr && (dict=*dict_ptr)) {
3098                 list_tmp= PyDict_Keys(dict);
3099                 PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
3100                 Py_DECREF(list_tmp);
3101         }
3102
3103         dict= ((PyTypeObject *)Py_TYPE(self))->tp_dict;
3104         if (dict) {
3105                 list_tmp= PyDict_Keys(dict);
3106                 PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
3107                 Py_DECREF(list_tmp);
3108         }
3109 }
3110
3111 static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
3112 {
3113         PyObject *pystring;
3114         const char *idname;
3115
3116         /* for looping over attrs and funcs */
3117         PointerRNA tptr;
3118         PropertyRNA *iterprop;
3119
3120         {
3121                 RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
3122                 iterprop= RNA_struct_find_property(&tptr, "functions");
3123
3124                 RNA_PROP_BEGIN(&tptr, itemptr, iterprop) {
3125                         idname= RNA_function_identifier(itemptr.data);
3126
3127                         pystring= PyUnicode_FromString(idname);
3128                         PyList_Append(list, pystring);
3129                         Py_DECREF(pystring);
3130                 }
3131                 RNA_PROP_END;
3132         }
3133
3134         {
3135                 /*
3136                  * Collect RNA attributes
3137                  */
3138                 char name[256], *nameptr;
3139                 int namelen;
3140
3141                 iterprop= RNA_struct_iterator_property(ptr->type);
3142
3143                 RNA_PROP_BEGIN(ptr, itemptr, iterprop) {
3144                         nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
3145
3146                         if (nameptr) {
3147                                 pystring= PyUnicode_FromStringAndSize(nameptr, namelen);
3148                                 PyList_Append(list, pystring);
3149                                 Py_DECREF(pystring);
3150
3151                                 if (name != nameptr) {
3152                                         MEM_freeN(nameptr);
3153