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

Reply via email to