Hi Campbell, Before this commit one was able to access library elements (and change them \o/) by directly referring to their name (and hope for no namespace conflict).
Is the library field mandatory now? or it's more like an option to solve namespace conflicts? (so if I have a 'Cube' only in the library can I still do bpy.objects['Cube', None])? Also, would be possible to have the None field completely optional? So when working with local data blocks (90% of the time) one can do bpy.data....['data block'] without the need of ['data block', None'] ? Thanks, Dalai 2011/11/17 Campbell Barton <[email protected]>: > Revision: 41945 > > http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41945 > Author: campbellbarton > Date: 2011-11-17 08:47:34 +0000 (Thu, 17 Nov 2011) > Log Message: > ----------- > pyapi feature from 2.4x > > allow collection subscript to contain the library or None. > > eg: > > bpy.data.objects["Mesh", "/subsurf_test.blend"] > > bpy.data.scenes["Scene", None] > > # also works with get() > bpy.data.armatures.get(("some_armature", "//some_lib.blend"), None) > > Modified Paths: > -------------- > trunk/blender/source/blender/python/intern/bpy_rna.c > > Modified: trunk/blender/source/blender/python/intern/bpy_rna.c > =================================================================== > --- trunk/blender/source/blender/python/intern/bpy_rna.c 2011-11-17 > 08:02:36 UTC (rev 41944) > +++ trunk/blender/source/blender/python/intern/bpy_rna.c 2011-11-17 > 08:47:34 UTC (rev 41945) > @@ -64,6 +64,7 @@ > > #include "MEM_guardedalloc.h" > > +#include "BKE_main.h" > #include "BKE_idcode.h" > #include "BKE_context.h" > #include "BKE_global.h" /* evil G.* */ > @@ -2096,6 +2097,84 @@ > } > /* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, > char *keyname) */ > > +/* special case: bpy.data.objects["some_id_name", "//some_lib_name.blend"] > + * also for: bpy.data.objects.get(("some_id_name", > "//some_lib_name.blend"), fallback) */ > +static PyObject > *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject > *key, const char *err_prefix, const short err_not_found) > +{ > + char *keyname; > + > + /* first validate the args, all we know is that they are a tuple */ > + if (PyTuple_GET_SIZE(key) != 2) { > + PyErr_Format(PyExc_KeyError, > + "%s: tuple key must be a pair, not size %d", > + err_prefix, PyTuple_GET_SIZE(key)); > + return NULL; > + } > + else if (self->ptr.type != &RNA_BlendData) { > + PyErr_Format(PyExc_KeyError, > + "%s: is only valid for bpy.data collections, not > %.200s", > + err_prefix, > RNA_struct_identifier(self->ptr.type)); > + return NULL; > + } > + else if ((keyname= _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == > NULL) { > + PyErr_Format(PyExc_KeyError, > + "%s: id must be a string, not %.200s", > + err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, > 0))->tp_name); > + return NULL; > + } > + else { > + PyObject *keylib= PyTuple_GET_ITEM(key, 1); > + Library *lib; > + PyObject *ret= NULL; > + > + if (keylib == Py_None) { > + lib= NULL; > + } > + else if (PyUnicode_Check(keylib)) { > + Main *bmain= self->ptr.data; > + const char *keylib_str= _PyUnicode_AsString(keylib); > + lib= BLI_findstring(&bmain->library, keylib_str, > offsetof(Library, name)); > + if (lib == NULL) { > + if (err_not_found) { > + PyErr_Format(PyExc_KeyError, > + "%s: lib > name '%.240s' " > + "does not > reference a valid library", > + err_prefix, > keylib_str); > + } > + > + return NULL; > + } > + } > + else { > + PyErr_Format(PyExc_KeyError, > + "%s: lib must be a sting or None, not > %.200s", > + err_prefix, Py_TYPE(keylib)->tp_name); > + return NULL; > + } > + > + /* lib is either a valid poniter or NULL, > + * either way can do direct comparison with id.lib */ > + > + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { > + ID *id= itemptr.data; /* always an ID */ > + if (id->lib == lib && (strncmp(keyname, id->name+2, > sizeof(id->name)-2) == 0)) { > + ret= pyrna_struct_CreatePyObject(&itemptr); > + break; > + } > + } > + RNA_PROP_END; > + > + /* we may want to fail silently as with collection.get() */ > + if ((ret == NULL) && err_not_found) { > + /* only runs for getitem access so use fixed string */ > + PyErr_SetString(PyExc_KeyError, > + "bpy_prop_collection[key, lib]: not > found"); > + } > + > + return ret; > + } > +} > + > static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA > *self, Py_ssize_t start, Py_ssize_t stop) > { > CollectionPropertyIterator rna_macro_iter; > @@ -2266,6 +2345,10 @@ > } > } > } > + else if (PyTuple_Check(key)) { > + /* special case, for ID datablocks we */ > + return pyrna_prop_collection_subscript_str_lib_pair(self, > key, "bpy_prop_collection[id, lib]", TRUE); > + } > else { > PyErr_Format(PyExc_TypeError, > "bpy_prop_collection[key]: invalid key, " > @@ -3915,6 +3998,7 @@ > return PyLong_FromVoidPtr(self->ptr.data); > } > > +/* TODO, get (string, lib) pair */ > PyDoc_STRVAR(pyrna_prop_collection_get_doc, > ".. method:: get(key, default=None)\n" > "\n" > @@ -3931,17 +4015,32 @@ > { > PointerRNA newptr; > > - const char *key; > + PyObject *key_ob; > PyObject* def= Py_None; > > PYRNA_PROP_CHECK_OBJ(self); > > - if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) > + if (!PyArg_ParseTuple(args, "O|O:get", &key_ob, &def)) > return NULL; > > - if (RNA_property_collection_lookup_string(&self->ptr, self->prop, > key, &newptr)) > - return pyrna_struct_CreatePyObject(&newptr); > + if (PyUnicode_Check(key_ob)) { > + const char *key= _PyUnicode_AsString(key_ob); > > + if (RNA_property_collection_lookup_string(&self->ptr, > self->prop, key, &newptr)) > + return pyrna_struct_CreatePyObject(&newptr); > + } > + else if (PyTuple_Check(key_ob)) { > + PyObject *ret= > pyrna_prop_collection_subscript_str_lib_pair(self, key_ob, > "bpy_prop_collection.get((id, lib))", FALSE); > + if (ret) { > + return ret; > + } > + } > + else { > + PyErr_Format(PyExc_KeyError, > + "bpy_prop_collection.get(key, ...): key must be > a string or tuple, not %.200s", > + Py_TYPE(key_ob)->tp_name); > + } > + > return Py_INCREF(def), def; > } > > > _______________________________________________ > Bf-blender-cvs mailing list > [email protected] > http://lists.blender.org/mailman/listinfo/bf-blender-cvs > _______________________________________________ Bf-committers mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-committers
