Batch registering multiple classes in blender 2.8


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


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):


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):?

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…


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?


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

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.


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.


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


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

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


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


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__):

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 ?
The answer found on:


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.