Page MenuHome

Dynamic PropertyGroup classes no longer possible in 2.93
Closed, ArchivedPublic

Description

System Information
Operating system: *
Graphics card: *

Blender Version
Broken: Blender 2.93 (after https://developer.blender.org/rBc44c611c6d8c6ae071b48efb5fc07168f18cd17e)
Worked: (newest version of Blender that worked as expected)

Short description of error
This is somewhat rare, but IMO perfectly valid Python use case of dynamically creating a new class and then wanting to register it. That is, we want to dynamically subtype a PropertyGroup class, add some properties to it, and then register the class

One example of "why", is for example MaterialX gives us a whole bunch of shader node types specified in xml files that we would like to create custom node types from, so we write a small script to parse the XML and create node classes on the fly.

Exact steps for others to reproduce the error

import bpy

data = {
             'bl_label': "MyNewType",
             'bl_idname': "test.MyNewType",
             '__annotations__': {
                "MyIntVal": (bpy.props.IntProperty, {'name': "MyIntVal", 'default': 42})
             }
         }

my_new_type = type("MyNewType", (bpy.types.PropertyGroup,), data)

bpy.utils.register_class(my_new_type)

bpy.types.Object.my_prop_grp = bpy.props.PointerProperty(type=my_new_type)
print(bpy.data.objects[0].my_prop_grp.MyIntVal)

also attached a blend file with the above script. In 2.93 does not seem like it registers the int property.

. I'm tagging @Campbell Barton (campbellbarton) in this because it seems related to the DeferredProperty when we inspect deeper. If there is another way to achieve creating the properties for these dynamic types let me know.

Event Timeline

Philipp Oeser (lichtwerk) changed the task status from Needs Triage to Confirmed.Wed, Apr 7, 12:38 PM
Philipp Oeser (lichtwerk) triaged this task as High priority.

Looks like a valid usecase, but not sure how to classify.
Will confirm for now though and even dare setting this to High priority -- since I would not be aware of a way around this "new limitation/regression" for now.

Campbell Barton (campbellbarton) closed this task as Archived.EditedWed, Apr 7, 3:03 PM

Creating classes dynamically is still supported. The example given relied on an internal representation of properties which was never documented or intended for script authors to depend on.

This works as expected:

import bpy

data = {
    'bl_label': "MyNewType",
    'bl_idname': "test.MyNewType",
    '__annotations__': {
        "MyIntVal": bpy.props.IntProperty(name="MyIntVal",default=42),
    }
}

my_new_type = type("MyNewType", (bpy.types.PropertyGroup,), data)

bpy.utils.register_class(my_new_type)

bpy.types.Object.my_prop_grp = bpy.props.PointerProperty(type=my_new_type)
print(bpy.data.objects[0].my_prop_grp.MyIntVal)

This example is working, thanks!