Blender 2.8 TypeError trying to access a property group via PointerProperty in UILayout.prop

addons
python

#1

An Addon I am updating has various layers, it can operate over collections of objects in some cases and on individual objects in others.
I have an AddonPreferences class which is registering fine and accessible and rather than attach other properties to the scene I thought it better to have a PointerProperty held in my Prefs class

It is setup pretty much as follows (trimmed to be illustrative):

class ObjMgr_props(bpy.types.PropertyGroup):
   model_source : bpy.props.EnumProperty(
      name="Model Source",
      description="use the selected object as the source",
      items=enum_items,
      get=ut.source_getter,
      set=ut.source_setter)

def some_setup_method():
    prefs =  bpy,context.preferences.addons['myaddon'].preferences
    ob_props = PointerProperty(
        name="object helper settings",
        description="settings class for the object helper addon",
        type=ObjMgr_props)
    prefs.obj_mgr_properties = ob_props

Later this gets used in a draw method of a panel

def draw(self, context):
    prefs=get_addon_preferences()
    ob_props = prefs.obj_mgr_properties
    layout = self.layout
    layout.operator("create_models_from_selection")
    layout.label(text="Assume selected model is...")
    layout.prop(ob_props, 'model_source', expand=True)

At runtime this will fail with a TypeError exception
TypeError: UILayout.prop(): error with argument 1, “data” - Function.data expected a AnyType type, not a tuple()

I tried using the property group directly and got
TypeError: UILayout.prop(): error with argument 1, “data” - Function.data expected a AnyType type, not RNAMetaPropGroup

In 2.79 I have more or less the same construct. instead of having the PointerProperty hanging off of the preferences, it is assigned to bpy.types.Scene; examining bpy.types.Scene.obj_mgr_properties shows it to be of the same form (a tuple of built-in function: pointer property and the associated data). Yet it works without a complaint from layout.prop

Has something changed in the inheritance of the pointer property that is no longer allowing it to work? I I must be missing something here, something to do with the bpy.types space perhaps?

I have tried manual registration, I have tried Jacque’s auto_load and once I worked through the differences in those methods I ended up back at the same issue with UILayout.prop.

Any suggestions would be gratefully received as I suspect code blindness is becoming terminal.

Beq


#3

Thanks, @brecht not sure where your reply went, but it put me on the right track.

I needed to have the PointerProperty hung beneath the Scene type, then when referenced from the context of the current scene it works as expected.
For any who may follow in my path this is how I got it to work. (There may well be better ways)

Your Property Pointer needs to be an attribute of the Scene type. Then you can use it iin the right context per discrete scene, something like this:

try:
    vars = bpy.context.scene.myaddon_vars
except AttributeError:
    setattr(bpy.types.Scene, 'myaddon_vars', bpy.props.PointerProperty(type=MyAddonProps)
    vars = bpy.context.scene.myaddon_vars
label.prop(vars,'my_prop', expand=True) # etc etc

setattr is not strictly needed when used as above, you can use bpy.types.Scene.myaddon_vars but in my case, I am building the name from a generic utility function.