[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34765] trunk/blender/release/scripts: patch [#25809] Auto-Registration as utility function.

Campbell Barton ideasman42 at gmail.com
Fri Feb 11 05:07:59 CET 2011


Doug, just finished getting addons working again without auto
register. (not contrib yet).
But heres an overview of the changes I needed to make.

- bpy.utils.(un)register_module(__name__) as described above is good
enough for most addons, this is equivalent to what auto-register was
doing before.

- Noticed M3 and XNA scripts did lazy operator registering - only
registering the operator when the menu opens, IMHO this is bad
practice since an automated tool may need to enable an addon and
access operators immediately, not only from the menu, changed these to
register when the addon is enabled.

- API Navigator was calling operator in draw function which I
disallowed previously, edited so it calls a function in stead.

- Rigify is currently the only addon which uses manual registration
for all classes.
While testing on the default rig I get this error, but found its
unrelated to recent blender API changes.
AttributeError: 'RigifyParameters' object has no attribute 'use_thigh_twist'

- Most addons which defined their own IDPropertyGroup subclasses
assigned properties after:
eg:

>>> class SomeClassbpy.types.IDPropertyGroup):
>>>     pass
>>> SomeClass.prop = StringProperty(...)

Use cleaner definition:
>>> class SomeClassbpy.types.IDPropertyGroup):
>>>     prop = StringProperty(...)

- Re-Enabling addons now works with IDPropertyGroups
bugfix: http://projects.blender.org/tracker/index.php?func=detail&aid=24132&group_id=9&atid=498

Hope this helps addon authors who maintain their addons outside of blender.

Got Martins mail part way through making these changes, will reply next.

- Campbell

On Fri, Feb 11, 2011 at 1:15 AM, Campbell Barton <ideasman42 at gmail.com> wrote:
> Hi Doug, I should have been more clear that I'll be updating addons next.
>
> In most cases 'bpy.utils.register_module' /
> 'bpy.utils.unregister_module' just need adding.
> example from OBJ i/o (menu registration functions we're already there).
>
> def register():
>    bpy.utils.register_module(__name__)
>
>    bpy.types.INFO_MT_file_import.append(menu_func_import)
>    bpy.types.INFO_MT_file_export.append(menu_func_export)
>
>
> def unregister():
>    bpy.utils.unregister_module(__name__)
>
>    bpy.types.INFO_MT_file_import.remove(menu_func_import)
>    bpy.types.INFO_MT_file_export.remove(menu_func_export)
>
> On Fri, Feb 11, 2011 at 12:09 AM, Doug Hammond
> <doughammond at hamsterfight.co.uk> wrote:
>> HEY!!
>>
>> How about letting addon developers know how this new opt-in implementation
>> is supposed to work before ploughing ahead and seriously breaking
>> everything, again.
>>
>> I'm not arguing here about whether this is better or not - but as it stands
>> now I've no idea now how to initalise my addon !
>>
>> Yours sincerely annoyed, again,
>> Doug.
>>
>>
>> On 10 February 2011 23:48, Campbell Barton <ideasman42 at gmail.com> wrote:
>>
>>> Revision: 34765
>>>
>>> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=34765
>>> Author:   campbellbarton
>>> Date:     2011-02-10 23:48:22 +0000 (Thu, 10 Feb 2011)
>>> Log Message:
>>> -----------
>>> patch [#25809] Auto-Registration as utility function.
>>> This removes auto-registration, committed by Martin r30961.
>>> Realize this is a contentious topic but Brecht and myself both would rather
>>> opt-in registration.
>>>
>>> TODO:
>>> - addons need updating.
>>> - class list will be modified to use weakrefs (should have been done for
>>> existing system too).
>>> - will move bpy.types.(un)register functions into
>>> bpy.utils.(un)register_class, currently including these functions in a type
>>> list is internally ugly, scripts which loop over types also need to check
>>> for these.
>>>
>>> Revision Links:
>>> --------------
>>>
>>> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=30961
>>>
>>> Modified Paths:
>>> --------------
>>>    trunk/blender/release/scripts/io/netrender/ui.py
>>>    trunk/blender/release/scripts/modules/bpy/utils.py
>>>    trunk/blender/release/scripts/modules/bpy_types.py
>>>    trunk/blender/release/scripts/op/animsys_update.py
>>>    trunk/blender/release/scripts/op/fcurve_euler_filter.py
>>>    trunk/blender/release/scripts/op/image.py
>>>    trunk/blender/release/scripts/op/mesh.py
>>>    trunk/blender/release/scripts/op/nla.py
>>>    trunk/blender/release/scripts/op/object.py
>>>    trunk/blender/release/scripts/op/object_align.py
>>>    trunk/blender/release/scripts/op/object_randomize_transform.py
>>>    trunk/blender/release/scripts/op/presets.py
>>>    trunk/blender/release/scripts/op/screen_play_rendered_anim.py
>>>    trunk/blender/release/scripts/op/sequencer.py
>>>    trunk/blender/release/scripts/op/uv.py
>>>    trunk/blender/release/scripts/op/uvcalc_follow_active.py
>>>    trunk/blender/release/scripts/op/uvcalc_smart_project.py
>>>    trunk/blender/release/scripts/op/vertexpaint_dirt.py
>>>    trunk/blender/release/scripts/op/wm.py
>>>    trunk/blender/release/scripts/ui/properties_animviz.py
>>>    trunk/blender/release/scripts/ui/properties_data_armature.py
>>>    trunk/blender/release/scripts/ui/properties_data_bone.py
>>>    trunk/blender/release/scripts/ui/properties_data_camera.py
>>>    trunk/blender/release/scripts/ui/properties_data_curve.py
>>>    trunk/blender/release/scripts/ui/properties_data_empty.py
>>>    trunk/blender/release/scripts/ui/properties_data_lamp.py
>>>    trunk/blender/release/scripts/ui/properties_data_lattice.py
>>>    trunk/blender/release/scripts/ui/properties_data_mesh.py
>>>    trunk/blender/release/scripts/ui/properties_data_metaball.py
>>>    trunk/blender/release/scripts/ui/properties_data_modifier.py
>>>    trunk/blender/release/scripts/ui/properties_game.py
>>>    trunk/blender/release/scripts/ui/properties_material.py
>>>    trunk/blender/release/scripts/ui/properties_object.py
>>>    trunk/blender/release/scripts/ui/properties_object_constraint.py
>>>    trunk/blender/release/scripts/ui/properties_particle.py
>>>    trunk/blender/release/scripts/ui/properties_physics_cloth.py
>>>    trunk/blender/release/scripts/ui/properties_physics_common.py
>>>    trunk/blender/release/scripts/ui/properties_physics_field.py
>>>    trunk/blender/release/scripts/ui/properties_physics_fluid.py
>>>    trunk/blender/release/scripts/ui/properties_physics_smoke.py
>>>    trunk/blender/release/scripts/ui/properties_physics_softbody.py
>>>    trunk/blender/release/scripts/ui/properties_render.py
>>>    trunk/blender/release/scripts/ui/properties_scene.py
>>>    trunk/blender/release/scripts/ui/properties_texture.py
>>>    trunk/blender/release/scripts/ui/properties_world.py
>>>    trunk/blender/release/scripts/ui/space_console.py
>>>    trunk/blender/release/scripts/ui/space_dopesheet.py
>>>    trunk/blender/release/scripts/ui/space_filebrowser.py
>>>    trunk/blender/release/scripts/ui/space_graph.py
>>>    trunk/blender/release/scripts/ui/space_image.py
>>>    trunk/blender/release/scripts/ui/space_info.py
>>>    trunk/blender/release/scripts/ui/space_logic.py
>>>    trunk/blender/release/scripts/ui/space_nla.py
>>>    trunk/blender/release/scripts/ui/space_node.py
>>>    trunk/blender/release/scripts/ui/space_outliner.py
>>>    trunk/blender/release/scripts/ui/space_sequencer.py
>>>    trunk/blender/release/scripts/ui/space_text.py
>>>    trunk/blender/release/scripts/ui/space_time.py
>>>    trunk/blender/release/scripts/ui/space_userpref.py
>>>    trunk/blender/release/scripts/ui/space_userpref_keymap.py
>>>    trunk/blender/release/scripts/ui/space_view3d.py
>>>    trunk/blender/release/scripts/ui/space_view3d_toolbar.py
>>>
>>> Modified: trunk/blender/release/scripts/io/netrender/ui.py
>>> ===================================================================
>>> --- trunk/blender/release/scripts/io/netrender/ui.py    2011-02-10 20:54:02
>>> UTC (rev 34764)
>>> +++ trunk/blender/release/scripts/io/netrender/ui.py    2011-02-10 23:48:22
>>> UTC (rev 34765)
>>> @@ -363,16 +363,21 @@
>>>
>>>     draw = properties_render.RENDER_PT_output.draw
>>>
>>> -class NetRenderSettings(bpy.types.IDPropertyGroup):
>>> -    pass
>>>
>>> -class NetRenderSlave(bpy.types.IDPropertyGroup):
>>> -    pass
>>> +def addProperties():
>>> +    class NetRenderSettings(bpy.types.IDPropertyGroup):
>>> +        pass
>>>
>>> -class NetRenderJob(bpy.types.IDPropertyGroup):
>>> -    pass
>>> +    class NetRenderSlave(bpy.types.IDPropertyGroup):
>>> +        pass
>>>
>>> -def addProperties():
>>> +    class NetRenderJob(bpy.types.IDPropertyGroup):
>>> +        pass
>>> +
>>> +    bpy.types.register(NetRenderSettings)
>>> +    bpy.types.register(NetRenderSlave)
>>> +    bpy.types.register(NetRenderJob)
>>> +
>>>     from bpy.props import PointerProperty, StringProperty, BoolProperty,
>>> EnumProperty, IntProperty, CollectionProperty
>>>     bpy.types.Scene.network_render =
>>> PointerProperty(type=NetRenderSettings, name="Network Render",
>>> description="Network Render Settings")
>>>
>>>
>>> Modified: trunk/blender/release/scripts/modules/bpy/utils.py
>>> ===================================================================
>>> --- trunk/blender/release/scripts/modules/bpy/utils.py  2011-02-10 20:54:02
>>> UTC (rev 34764)
>>> +++ trunk/blender/release/scripts/modules/bpy/utils.py  2011-02-10 23:48:22
>>> UTC (rev 34765)
>>> @@ -100,9 +100,6 @@
>>>     import traceback
>>>     import time
>>>
>>> -    # must be set back to True on exits
>>> -    _bpy_types._register_immediate = False
>>> -
>>>     t_main = time.time()
>>>
>>>     loaded_modules = set()
>>> @@ -112,7 +109,6 @@
>>>
>>>     if reload_scripts:
>>>         _bpy_types.TypeMap.clear()
>>> -        _bpy_types.PropertiesMap.clear()
>>>
>>>         # just unload, dont change user defaults, this means we can sync to
>>> reload.
>>>         # note that they will only actually reload of the modification time
>>> changes.
>>> @@ -121,7 +117,6 @@
>>>             addon_disable(module_name, default_set=False)
>>>
>>>     def register_module_call(mod):
>>> -        _bpy_types._register_module(mod.__name__)
>>>         register = getattr(mod, "register", None)
>>>         if register:
>>>             try:
>>> @@ -132,7 +127,6 @@
>>>             print("\nWarning! '%s' has no register function, this is now a
>>> requirement for registerable scripts." % mod.__file__)
>>>
>>>     def unregister_module_call(mod):
>>> -        _bpy_types._unregister_module(mod.__name__)
>>>         unregister = getattr(mod, "unregister", None)
>>>         if unregister:
>>>             try:
>>> @@ -199,8 +193,6 @@
>>>                 for mod in modules_from_path(path, loaded_modules):
>>>                     test_register(mod)
>>>
>>> -    _bpy_types._register_immediate = True
>>> -
>>>     # deal with addons seperately
>>>     addon_reset_all(reload_scripts)
>>>
>>> @@ -367,12 +359,9 @@
>>>     import bpy_types as _bpy_types
>>>     import imp
>>>
>>> -    _bpy_types._register_immediate = False
>>> -
>>>     def handle_error():
>>>         import traceback
>>>         traceback.print_exc()
>>> -        _bpy_types._register_immediate = True
>>>
>>>     # reload if the mtime changes
>>>     mod = sys.modules.get(module_name)
>>> @@ -402,19 +391,13 @@
>>>         return None
>>>
>>>     # 2) try register collected modules
>>> -    try:
>>> -        _bpy_types._register_module(module_name)
>>> -    except:
>>> -        handle_error()
>>> -        del sys.modules[module_name]
>>> -        return None
>>> +    # removed, addons need to handle own registration now.
>>>
>>>     # 3) try run the modules register function
>>>     try:
>>>         mod.register()
>>>     except:
>>>         handle_error()
>>> -        _bpy_types._unregister_module(module_name)
>>>         del sys.modules[module_name]
>>>         return None
>>>
>>> @@ -426,8 +409,6 @@
>>>             ext = _bpy.context.user_preferences.addons.new()
>>>             ext.module = module_name
>>>
>>> -    _bpy_types._register_immediate = True
>>> -
>>>     mod.__addon_enabled__ = True
>>>
>>>     if _bpy.app.debug:
>>> @@ -454,7 +435,6 @@
>>>         mod.__addon_enabled__ = False
>>>
>>>         try:
>>> -            _bpy_types._unregister_module(module_name, free=False)  # dont
>>> free because we may want to enable again.
>>>             mod.unregister()
>>>         except:
>>>             traceback.print_exc()
>>> @@ -594,3 +574,42 @@
>>>                 target_path = ""
>>>
>>>     return target_path
>>> +
>>> +
>>> +_register_types = _bpy.types.Panel, _bpy.types.Operator, _bpy.types.Menu,
>>> _bpy.types.Header, _bpy.types.RenderEngine
>>> +
>>> +
>>> +def register_module(module):
>>> +    import traceback
>>> +    total = 0
>>> +    register = _bpy.types.register
>>> +    for cls, path, line in _bpy_types.TypeMap.get(module, ()):
>>> +        if not "bl_rna" in cls.__dict__:
>>> +            total += 1
>>> +            try:
>>> +                register(cls)
>>> +            except:
>>> +                print("bpy.utils.register_module(): failed to registering
>>> class '%s.%s'" % (cls.__module__, cls.__name__))
>>> +                print("\t", path, "line", line)
>>> +                traceback.print_exc()
>>> +
>>> +    if total == 0:
>>> +        raise Exception("register_module(%r): defines no classes" %
>>> module)
>>> +
>>> +
>>> +def unregister_module(module):
>>> +    import traceback
>>> +    unregister = _bpy.types.unregister
>>> +    total = 0
>>> +    for cls, path, line in _bpy_types.TypeMap.get(module, ()):
>>> +        if "bl_rna" in cls.__dict__:
>>> +            total += 1
>>> +            try:
>>> +                unregister(cls)
>>> +            except:
>>> +                print("bpy.utils.unregister_module(): failed to
>>> unregistering class '%s.%s'" % (cls.__module__, cls.__name__))
>>> +                print("\t", path, "line", line)
>>> +                traceback.print_exc()
>>> +
>>> +    if total == 0:
>>> +        raise Exception("unregister_module(%r): defines no classes" %
>>> module)
>>>
>>> Modified: trunk/blender/release/scripts/modules/bpy_types.py
>>> ===================================================================
>>> --- trunk/blender/release/scripts/modules/bpy_types.py  2011-02-10 20:54:02
>>> UTC (rev 34764)
>>> +++ trunk/blender/release/scripts/modules/bpy_types.py  2011-02-10 23:48:22
>>> UTC (rev 34765)
>>> @@ -550,87 +550,35 @@
>>>         import bpy
>>>         return tuple(obj for obj in bpy.data.objects if self in [cont.text
>>> for cont in obj.game.controllers if cont.type == 'PYTHON'])
>>>
>>> -import collections
>>> -
>>> +# values are module: [(cls, path, line), ...]
>>>  TypeMap = {}
>>> -# Properties (IDPropertyGroup) are different from types because they need
>>> to be registered
>>> -# before adding sub properties to them, so they are registered on
>>> definition
>>> -# and unregistered on unload
>>> -PropertiesMap = {}
>>>
>>> -# Using our own loading function we set this to false
>>> -# so when running a script directly in the text editor
>>> -# registers moduals instantly.
>>> -_register_immediate = True
>>>
>>> -
>>> -def _unregister_module(module, free=True):
>>> -    for t in TypeMap.get(module, ()):
>>> -        try:
>>> -            bpy_types.unregister(t)
>>> -        except:
>>> -            import traceback
>>> -            print("bpy.utils._unregister_module(): Module '%s' failed to
>>> unregister class '%s.%s'" % (module, t.__module__, t.__name__))
>>> -            traceback.print_exc()
>>> -
>>> -    if free == True and module in TypeMap:
>>> -        del TypeMap[module]
>>> -
>>> -    for t in PropertiesMap.get(module, ()):
>>> -        try:
>>> -            bpy_types.unregister(t)
>>> -        except:
>>> -            import traceback
>>> -            print("bpy.utils._unload_module(): Module '%s' failed to
>>> unregister class '%s.%s'" % (module, t.__module__, t.__name__))
>>> -            traceback.print_exc()
>>> -
>>> -    if free == True and module in PropertiesMap:
>>> -        del PropertiesMap[module]
>>> -
>>> -
>>> -def _register_module(module):
>>> -    for t in TypeMap.get(module, ()):
>>> -        try:
>>> -            bpy_types.register(t)
>>> -        except:
>>> -            import traceback
>>> -            import sys
>>> -            print("bpy.utils._register_module(): '%s' failed to register
>>> class '%s.%s'" % (sys.modules[module].__file__, t.__module__, t.__name__))
>>> -            traceback.print_exc()
>>> -
>>> -
>>>  class RNAMeta(type):
>>> -    @classmethod
>>> -    def _register_immediate(cls):
>>> -        return _register_immediate
>>> -
>>>     def __new__(cls, name, bases, classdict, **args):
>>> +        import traceback
>>>         result = type.__new__(cls, name, bases, classdict)
>>>         if bases and bases[0] != StructRNA:
>>>             module = result.__module__
>>>
>>> -            ClassMap = TypeMap
>>> -
>>> -            # Register right away if needed
>>> -            if cls._register_immediate():
>>> -                bpy_types.register(result)
>>> -                ClassMap = PropertiesMap
>>> -
>>>             # first part of packages only
>>>             if "." in module:
>>>                 module = module[:module.index(".")]
>>>
>>> -            ClassMap.setdefault(module, []).append(result)
>>> +            sf = traceback.extract_stack(limit=2)[0]
>>>
>>> +            TypeMap.setdefault(module, []).append((result, sf[0], sf[1]))
>>> +
>>>         return result
>>>
>>>
>>> -class RNAMetaRegister(RNAMeta, StructMetaIDProp):
>>> -    @classmethod
>>> -    def _register_immediate(cls):
>>> -        return True
>>> +import collections
>>>
>>>
>>> +class RNAMetaIDProp(RNAMeta, StructMetaIDProp):
>>> +    pass
>>> +
>>> +
>>>  class OrderedMeta(RNAMeta):
>>>
>>>     def __init__(cls, name, bases, attributes):
>>> @@ -685,7 +633,7 @@
>>>         return ops.macro_define(self, opname)
>>>
>>>
>>> -class IDPropertyGroup(StructRNA, metaclass=RNAMetaRegister):
>>> +class IDPropertyGroup(StructRNA, metaclass=RNAMetaIDProp):
>>>         __slots__ = ()
>>>
>>>
>>>
>>> Modified: trunk/blender/release/scripts/op/animsys_update.py
>>> ===================================================================
>>> --- trunk/blender/release/scripts/op/animsys_update.py  2011-02-10 20:54:02
>>> UTC (rev 34764)
>>> +++ trunk/blender/release/scripts/op/animsys_update.py  2011-02-10 23:48:22
>>> UTC (rev 34765)
>>> @@ -701,4 +701,8 @@
>>>
>>>
>>>  def register():
>>> -    pass
>>> +    bpy.utils.register_module(__name__)
>>> +
>>> +
>>> +def unregister():
>>> +    bpy.utils.unregister_module(__name__)
>>>
>>> Modified: trunk/blender/release/scripts/op/fcurve_euler_filter.py
>>> ===================================================================
>>> --- trunk/blender/release/scripts/op/fcurve_euler_filter.py     2011-02-10
>>> 20:54:02 UTC (rev 34764)
>>> +++ trunk/blender/release/scripts/op/fcurve_euler_filter.py     2011-02-10
>>> 23:48:22 UTC (rev 34765)
>>> @@ -78,13 +78,12 @@
>>>         main(context)
>>>         return {'FINISHED'}
>>>
>>> -
>>>  def register():
>>> -    pass
>>> +    bpy.utils.register_module(__name__)
>>>
>>>
>>>  def unregister():
>>> -    pass
>>> +    bpy.utils.unregister_module(__name__)
>>>
>>>  if __name__ == "__main__":
>>>     register()
>>>
>>> Modified: trunk/blender/release/scripts/op/image.py
>>> ===================================================================
>>> --- trunk/blender/release/scripts/op/image.py   2011-02-10 20:54:02 UTC
>>> (rev 34764)
>>>
>>> @@ Diff output truncated at 10240 characters. @@
>>> _______________________________________________
>>> Bf-blender-cvs mailing list
>>> Bf-blender-cvs at blender.org
>>> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>>>
>> _______________________________________________
>> Bf-committers mailing list
>> Bf-committers at blender.org
>> http://lists.blender.org/mailman/listinfo/bf-committers
>>
>
>
>
> --
> - Campbell
>



-- 
- Campbell


More information about the Bf-committers mailing list