Batch registering multiple classes in blender 2.8


#21

Actually Jacques having ‘auto_load.ignore’ - for ignoring some .py files, or folders would be cool. I will try to implement it.


#22

Not sure if it’s an error in the auto_load script or in my addon:

All my custom nodes are inheriting only from my base node, not from bpy.types.Node:

class LuxCoreNodeMaterial(bpy.types.Node):
    ...

class LuxCoreNodeMatGlass(LuxCoreNodeMaterial):
    ...

Since the auto_load script only checks the direct base classes, it does not register these nodes.
Should auto_load recursively check all base classes of base classes, or should I change my addon like this:

class LuxCoreNodeMaterial:
    ...

class LuxCoreNodeMatGlass(LuxCoreNodeMaterial, bpy.types.Node):
    ...

#23

I think I tried using the class LuxCoreNodeMatGlass(LuxCoreNodeMaterial): in the past and it did not work for me. So I also use the class LuxCoreNodeMatGlass(LuxCoreNodeMaterial, bpy.types.Node): approach in Animation Nodes.

However I just tested it again and found that it works now. So I’d say the bug is in auto_load.

Could you test if it works when you change line 98 from if any(base in base_types for base in cls.__bases__): to if any(issubclass(cls, base) for base in base_types):?

[EDIT:]
Ah, just remembered that then the problem is that it will try to register LuxCoreNodeMaterial as well, but it has no bl_idname, so it will fail… Maybe that was the reason I used the other approach…


#24

This works.

No, this is fine, the old register_module did the same and it worked.
It’s a bit ugly to have base classes registered that are never actually instanced, but I can live with that.

I only noticed problems with the first approach once with node trees, so I wondered if it is discouraged in Blender?


#25

What problems did you notice?

Just looked at Blenders code and seems like it uses the second approach, I have not found any example where it uses the first approach yet. (e.g. see here https://developer.blender.org/diffusion/B/browse/master/release/scripts/startup/bl_ui/properties_object.py)

Personally, I think the first approach should be discouraged. Being a bit more explicit about what is a node/operator/panel/… can’t hurt.

Also that probably makes the automatic class discovery faster. Not sure by how much though, maybe it is not noticeable.


#26

Unfortunately I don’t remember the details, but I think it was about a BoolProperty in the base class. With the first approach the subclasses could not access the BoolProperty, or something like that.

Thanks, I will switch to the second approach. Thank you for investigating.


#27

Again, not sure if I’m doing something wrong or if auto_load is incomplete:
I declare several classes in __init__.py files, and some of these are not registered by auto_load.
Should I move all class declarations out of __init__.py files, or should auto_load check these for classes?


#28

To my knowledge, addon modules can’t read the init.py file.

If you want something registered in one, you do it manually.


#29

Thanks, I’ll move them out into separate files.


#30

To improve registering clases, that are not directly child of bpy.types.Operator, we can change line:
if any(base in base_types for base in cls.__bases__):

to:
if any(base in base_types for base in inspect.getmro(cls)):

This way if my CustomOperator class, is child of some ModdedOperator, which is child of bpy.types.Operator, above line will correctly register it.
@jacqueslucke, can add this to autoload.py ?
The answer found on: https://stackoverflow.com/questions/2611892/how-to-get-the-parents-of-a-python-class


#31

Thanks for the suggestion. However, I’d rather not do this for now, because:

  • Operators should inherit from bpy.types.Operator directly. That seems to be a good practice.
  • The “ModdedOperator” would be recognized as normal operator as well. However, it should not be registered.

To make a “template” for operators just make a class that does not inherit bpy.types.Operator. The real operator then inherits your custom class as well as bpy.types.Operator.