From b1cdf5c34478204fbec5272b97754abc548da195 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Feb 2011 00:39:07 +0000 Subject: use weak references for the internal metaclass typemap, this should help with blender leaking memory with python classes though the bug is still not fixed. --- release/scripts/modules/bpy/utils.py | 53 ++++++++++++++++++++---------------- release/scripts/modules/bpy_types.py | 5 ++-- 2 files changed, 32 insertions(+), 26 deletions(-) (limited to 'release') diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index c806aa1e0e6..a86cfacb56b 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -579,35 +579,40 @@ def user_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, path, line = typemap_list[i] + cls = cls_weakref() + + if cls is None: + del typemap_list[i] + elif is_registered == ("bl_rna" in cls.__dict__): + yield (cls, path, line) + i += 1 + + def register_module(module): import traceback - total = 0 - for cls, path, line in _bpy_types.TypeMap.get(module, ()): - if not "bl_rna" in cls.__dict__: - total += 1 - try: - register_class(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() + for cls, path, line in _bpy_module_classes(module, is_registered=False): + try: + register_class(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: + if "cls" not in locals(): raise Exception("register_module(%r): defines no classes" % module) def unregister_module(module): import traceback - total = 0 - for cls, path, line in _bpy_types.TypeMap.get(module, ()): - if "bl_rna" in cls.__dict__: - total += 1 - try: - unregister_class(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) + for cls, path, line in _bpy_module_classes(module, is_registered=True): + try: + unregister_class(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() diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index b11ef203df5..fcc3166b066 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -556,9 +556,10 @@ TypeMap = {} class RNAMeta(type): def __new__(cls, name, bases, classdict, **args): - import traceback result = type.__new__(cls, name, bases, classdict) if bases and bases[0] != StructRNA: + import traceback + import weakref module = result.__module__ # first part of packages only @@ -567,7 +568,7 @@ class RNAMeta(type): sf = traceback.extract_stack(limit=2)[0] - TypeMap.setdefault(module, []).append((result, sf[0], sf[1])) + TypeMap.setdefault(module, []).append((weakref.ref(result), sf[0], sf[1])) return result -- cgit v1.2.3