[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41945] trunk/blender/source/blender/ python/intern/bpy_rna.c: pyapi feature from 2.4x

Campbell Barton ideasman42 at gmail.com
Thu Nov 17 18:02:49 CET 2011


Hey Dalai, I should have been more clear, current behavior is unchanged.

The way it works is if 2 args are given it does library/local checks -
depending if a library path or None is passed, otherwise it will get
either.

On Fri, Nov 18, 2011 at 2:44 AM, Dalai Felinto <dfelinto at gmail.com> wrote:
> 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 <ideasman42 at gmail.com>:
>> 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
>> Bf-blender-cvs at blender.org
>> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>>
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers
>



-- 
- Campbell


More information about the Bf-committers mailing list