[Bf-committers] Python RNA Type Registration

Martin Poirier theeth at yahoo.com
Sun Feb 28 19:45:11 CET 2010


--- On Sun, 2/28/10, Ton Roosendaal <ton at blender.org> wrote:

> 3) Python registry
> - Martin feels like there is useless duplication in
> registry of  
> scripts, and proposes another method. Will send proposal to
> list!

I'll try to explain the situation again.

RNA Types are defined by subclassing from a blender type, like this:

class SEQUENCER_HT_header(bpy.types.Header):

The class then has to be registered with blender like this:


and unregistered like this:


Registration and Unregistration needs to be done in global register() and unregister() methods defined per module (this enables loading and unloading extensions). For large modules, this is done by having a large list of all types to register at the bottom of the file and looping over that (look in release/scripts/ui/properties_material.py for example).

The change I propose is to use metaclassing to gather registration info. Meaning that deriving a class from a RNA type (like bpy.types.Panel) is enough to tell the system to register it on load and unregister it on unload. There is already a patch available [1] that does all that and gets rid of the lists at the bottom of each file. The global register() and unregister() methods are still used for menu registration (that could be made automatic too) and theorically can be used for global module initialization (say, DB connection or whatnot), so it is not proposed to get rid of them (although they could be made optional).

Here's a shortlist of the pros and cons of the current method vs metaclassing. I expect other people will add more. I'm trying to keep those as objective as possible.

Explicit registration (current method):

- For types where order of registration is important (like panels), it's slightly easier to redefine the order; just need to change the list vs moving class definitions. [For the record, I think that it's a bad design to have that being dependent on registration order]

- Duplicated information. Have to maintain a separate list of classes when adding or removing code.
- Relies on script writers to properly maintain their register() and unregister() module functions. Prone to errors that would go undetected.
- In general, I would argue that this is bad design but this is more objective.

Metaclassing (proposed method):

- Class definition is enough to tell the system what types need registration. No need to maintain a separate list.
- List of types are automatically maintained per module (by the metaclass), if changes are needed to the loading or unloading process, there's a single piece of code to modify and not having to modify all the scripts.
- Simplifies coding process and removes the need of having to explain the registration system in the API docs.

- When using other base classes to define common behaviors (used a lot for panels, look for MaterialButtonsPanel in the properties_material.py), the base class should not inherit from an RNA type (it shouldn't be registered). This means using it more as a mixin, with the real panel inheriting from the python class defining common behaviors and from the RNA type ([2] for examples).
- It also means you can't define a class somewhere and register it in another module. This was done for some rna properties wm operators and for Animviz planels. This is trivially fixed by moving the code around [3]. Registering outside of the definition is shady anyway, it means the load/unload module method won't work correctly.

That's pretty much what I can think of for now. I might add more after other people chip in.

IMPORTANT NOTE: This will not get resolved purely based on a democratic vote, so please refrain from just replying with "+1" without explaining why/adding arguments.

Thanks for taking the time to read what turned out to be a longer email than I originally planed.


[1] http://blenderartists.org/~theeth/bf/register.patch

[2] Like this:

class MaterialButtonsPanel():

class MATERIAL_PT_preview(MaterialButtonsPanel, bpy.types.Panel):

class MATERIAL_PT_context_material(MaterialButtonsPanel, bpy.types.Panel):

Instead of:

class MaterialButtonsPanel(bpy.types.Panel):

class MATERIAL_PT_preview(MaterialButtonsPanel):

class MATERIAL_PT_context_material(MaterialButtonsPanel):

[3] See the animviz panels in the patch especially, it defines the behavior class in properties_animviz.py and the real panels in the object and armature UI files. IMHO, this by itself is a good change, regardless of the change to the registration process.

[4] There is no [4] in the text, stop reading footnotes and reply with comments.

Looking for the perfect gift? Give the gift of Flickr! 


More information about the Bf-committers mailing list