I'm trying to figure out how to generate a dynamic property group class, but I keep getting the annotations error: Warning: class PropBools contains a property which should be an annotation!
. And following this error, I get the following printed line for each property: assign as a type annotation: PropBools.******
.
Here is the code I have so far. I can show details about the list of data if it will help at all, but I don't think it will influence the error I'm getting.
PropBools = type(
# typename
'PropBools',
# base class
( bpy.types.PropertyGroup , ),
# dictionary of bool properties
{
ft.ID : bpy.props.BoolProperty(
default = False,
name = ft.Name,
description = ft.Desc,
) for ft in prop_list_data
}
)
Is it possible to do this without throwing the warning/error? Has anyone successfully generated a dynamic property group since the annotation requirement update?
Edit: I found Blender 2.8 - Field property declaration and dynamic class creation , which may be the only solution. Here is the same code, updated to define an annotations dictionary:
PropBools = type(
# typename
'PropBools',
# base class
( bpy.types.PropertyGroup , ),
# dictionary of bool properties
{
'__annotations__' :
{
ft.ID : ( BoolProperty,
{
'default' : False,
'name' : ft.Name,
'description' : ft.Desc
} ) for ft in fuse.Type.Index
}
}
)
You can even unpack dictionaries of extra parameters into it (this is a different dynamic class):
PropValues = type(
# typename
'PropValues',
# base class
( bpy.types.PropertyGroup , ),
# generate dictionary of override properties
{
'__annotations__' :
{
ft.ID : ( ft.Prop.Func,
{
'default' : ft.Default,
'name' : ft.Name,
'description' : ft.Desc,
# specify our property event function for updates
'update' : ft.ValUpdate,
# unpack dictionary of keyword arguments to this property function
**ft.xop
} ) for ft in fuse.Type.Index
}
}
)
No warnings or errors using these yet, so seems promising.
Edit: This works great. The problems listed below were caused by an issue in the property list data, which was causing a silent error, which prevented ALL of the properties from registering, making the dynamic class appear empty. After finding and fixing the silent error, everything appears to be working.
However, the properties don't exist as they typically would in an instanced property group (of either dynamic class). Attempting to access a property using the syntax (A silent property error was causing this).my_prop_group["id_name"]
throws an error as if it doesn't exist.
I'm not sure if I need to manually assign each one to default values (.my_prop_group["id_name"] = DEFAULT
)
Not sure if I need to include the entire dictionary of properties along with the (silent error was causing properties to not register).__annotations__
dictionary of the same properties. Printing dir(*)
of non-dynamic property groups seems to indicate that they should have both defined
my_prop_group.id_name
gives me the error'PropValues' object has no attribute 'id_name'
, even when I attempt to manually set its default value first (usingmy_prop_group.id_name = x
). By comparing my dynamic class to non-dynamic classes (usingdir()
), it looks like there is still information missing. Non-dynamic classes have the properties listed in their primary members, where my dynamic class only has them listed inside of the annotations member. So it seems like something is still missing. I really appreciate the help, though. Please let me know if you have any ideas. $\endgroup$class Foo:
give it an empty dictionary as the__annotations__
member. Then populate withFoo.__annotations__[propname] = bpy.props.SomeProperty(**kwargs)
$\endgroup$