2
$\begingroup$

In an exporter script i also want to export "custom properties". In my script i have the active object:

x = bpy.context.active_object

I can access the custom properties by their keys:

k = x.keys()

Blender / Cycles seems to reserve some own properties in here with the keys:

  • cycles
  • _RNA_UI

The values of these seem to be of type IDPropertyGroup, investigation in the python console gives:

>>> type(x['cycles'])
<class 'IDPropertyGroup'>

In my script i want to handle this as a special case and for values of IDPropertyGroup rather use value.to_dict().

So in my script i have:

for k in x.keys():
    val = x[k]
    print("k %s type %s" % (k, type(val)))
    if isinstance(val, bpy.types.IDPropertyGroup):
        val = val.to_dict()

But this gives an error that i don't understand: line 194, in execute: if isinstance(val, bpy.types.IDPropertyGroup):

AttributeError: 'RNA_Types' object has no attribute 'IDPropertyGroup'

Googling for IDPropertyGroup i get this relationship: class bpy.types.IDPropertyGroup(bpy_struct)

I wonder where this error comes from, i would expect this to work.

Thanks for any hints, Torsten

$\endgroup$

1 Answer 1

3
$\begingroup$

There is no such thing as bpy.types.IDPropertyGroup in bpy.types, hence this line:

if isinstance(val, bpy.types.IDPropertyGroup):
    ...

fails. Try from bpy.types import IDPropertyGroup you will get an ImportError.

>>> from bpy.types import IDPropertyGroup
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
ImportError: cannot import name 'IDPropertyGroup'

This is why that isinstance fails. I agree this is a little bit weird, but this changes the question a little.

Why isn't it there and how would I use isinstance to test complexity of an ID property. Are there alternatives?

Because ID properties are a limited collection of types, it's perhaps no less crazy to check for int, float, str, list.

import bpy

x = bpy.context.active_object

for k in x.keys():
    val = x[k]

    if isinstance(val, (int, float, str, list)):
        print('simple', val)
    else:
        print('complex', val.to_dict())

You could also check if the ID property has an attribute to_dict instead, else it's a basic type.

import bpy

x = bpy.context.active_object

for k in x.keys():
    val = x[k]
    if hasattr(val, 'to_dict'):
        val = val.to_dict()
    print(k, val)

Even use the (always present) class type returned by type(x['cycles'])

import bpy

x = bpy.context.active_object
IDPropertyGroup = type(x['cycles'])  # <--- use this type's return in isinstance

for k in x.keys():
    val = x[k]
    print("k %s type %s" % (k, type(val)))
    if isinstance(val, IDPropertyGroup):
        val = val.to_dict()

    print(k, val)
$\endgroup$
3
  • $\begingroup$ Thanks for your hints. The last example (isinstance with IDPropertyGroup) is what i tried (see my code above) and which gave an error. This part does not seem to work and i don't understand why (i also tried writing just IDPropertyGroup). $\endgroup$ Jan 1, 2016 at 21:20
  • 1
    $\begingroup$ it's not the same. read my third example again. $\endgroup$
    – zeffii
    Jan 1, 2016 at 22:17
  • $\begingroup$ You're right, thanks. I did not yet try it but it should work. $\endgroup$ Jan 4, 2016 at 11:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .