Page MenuHome
Paste P455

Patch to help remove register_module use in 2.8
ActivePublic

Authored by Campbell Barton (campbellbarton) on Mar 18 2017, 9:59 AM.
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 80e48697b2f..3dabc2421bf 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -34,6 +34,7 @@ __all__ = (
"refresh_script_paths",
"app_template_paths",
"register_class",
+ "register_module",
"register_manual_map",
"unregister_manual_map",
"register_classes_factory",
@@ -49,6 +50,7 @@ __all__ = (
"smpte_from_seconds",
"units",
"unregister_class",
+ "unregister_module",
"user_resource",
)
@@ -164,6 +166,10 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
for module_name in [ext.module for ext in _user_preferences.addons]:
_addon_utils.disable(module_name)
+ # *AFTER* unregistering all add-ons, otherwise all calls to
+ # unregister_module() will silently fail (do nothing).
+ _bpy_types.TypeMap.clear()
+
def register_module_call(mod):
register = getattr(mod, "register", None)
if register:
@@ -649,6 +655,85 @@ def user_resource(resource_type, path="", create=False):
return target_path
+def _bpy_module_classes(module, is_registered=False):
+ typemap_list = _bpy_types.TypeMap.get(module, ())
+ i = 0
+ while i < len(typemap_list):
+ cls_weakref = typemap_list[i]
+ cls = cls_weakref()
+
+ if cls is None:
+ del typemap_list[i]
+ else:
+ if is_registered == cls.is_registered:
+ yield cls
+ i += 1
+
+
+def register_module(module, verbose=False):
+ if verbose:
+ print("bpy.utils.register_module(%r): ..." % module)
+
+ # Always print this text
+ if True:
+ print("# bpy.utils.register_module is deprecated! replace code with this:")
+ mod_prev = None
+ ls = list(_bpy_module_classes(module, is_registered=False))
+ ls.sort(key=lambda cls: cls.__module__)
+ for cls in ls:
+ if mod_prev != cls.__module__:
+ if mod_prev is not None:
+ print(")\n")
+ print("#", cls.__module__.replace(".", "/") + ".py")
+ print("classes = (")
+ mod_prev = cls.__module__
+ print(" %s," % cls.__name__)
+ print(")\n")
+ print("def register():")
+ print(" from bpy.utils import register_class")
+ print(" for cls in classes:")
+ print(" register_class(cls)")
+ print("\n")
+ print("def unregister():")
+ print(" from bpy.utils import unregister_class")
+ print(" for cls in classes:")
+ print(" unregister_class(cls)")
+ print("\n")
+
+ cls = None
+ for cls in _bpy_module_classes(module, is_registered=False):
+ if verbose:
+ print(" %r" % cls)
+ try:
+ register_class(cls)
+ except:
+ print("bpy.utils.register_module(): "
+ "failed to registering class %r" % cls)
+ import traceback
+ traceback.print_exc()
+ if verbose:
+ print("done.\n")
+ if cls is None:
+ raise Exception("register_module(%r): defines no classes" % module)
+
+
+def unregister_module(module, verbose=False):
+ if verbose:
+ print("bpy.utils.unregister_module(%r): ..." % module)
+ for cls in _bpy_module_classes(module, is_registered=True):
+ if verbose:
+ print(" %r" % cls)
+ try:
+ unregister_class(cls)
+ except:
+ print("bpy.utils.unregister_module(): "
+ "failed to unregistering class %r" % cls)
+ import traceback
+ traceback.print_exc()
+ if verbose:
+ print("done.\n")
+
+
def register_classes_factory(classes):
"""
Utility function to create register and unregister functions
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index d6d4ecd6fce..f07e32f4137 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -533,6 +533,10 @@ class Text(bpy_types.ID):
self.write(string)
+# values are module: [(cls, path, line), ...]
+TypeMap = {}
+
+
class Sound(bpy_types.ID):
__slots__ = ()
@@ -544,7 +548,21 @@ class Sound(bpy_types.ID):
class RNAMeta(type):
- # TODO(campbell): move to C-API
+
+ def __new__(cls, name, bases, classdict, **args):
+ result = type.__new__(cls, name, bases, classdict)
+ if bases and bases[0] is not StructRNA:
+ from _weakref import ref as ref
+ module = result.__module__
+
+ # first part of packages only
+ if "." in module:
+ module = module[:module.index(".")]
+
+ TypeMap.setdefault(module, []).append(ref(result))
+
+ return result
+
@property
def is_registered(cls):
return "bl_rna" in cls.__dict__

Event Timeline

Campbell Barton (campbellbarton) changed the title of this paste from Patch to help remove register_module use to Patch to help remove register_module use in 2.8.Aug 13 2018, 4:57 AM
Campbell Barton (campbellbarton) edited the content of this paste. (Show Details)