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.
This commit is contained in:
@@ -579,35 +579,40 @@ def user_resource(type, path="", create=False):
|
|||||||
return target_path
|
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):
|
def register_module(module):
|
||||||
import traceback
|
import traceback
|
||||||
total = 0
|
for cls, path, line in _bpy_module_classes(module, is_registered=False):
|
||||||
for cls, path, line in _bpy_types.TypeMap.get(module, ()):
|
try:
|
||||||
if not "bl_rna" in cls.__dict__:
|
register_class(cls)
|
||||||
total += 1
|
except:
|
||||||
try:
|
print("bpy.utils.register_module(): failed to registering class '%s.%s'" % (cls.__module__, cls.__name__))
|
||||||
register_class(cls)
|
print("\t", path, "line", line)
|
||||||
except:
|
traceback.print_exc()
|
||||||
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)
|
raise Exception("register_module(%r): defines no classes" % module)
|
||||||
|
|
||||||
|
|
||||||
def unregister_module(module):
|
def unregister_module(module):
|
||||||
import traceback
|
import traceback
|
||||||
total = 0
|
for cls, path, line in _bpy_module_classes(module, is_registered=True):
|
||||||
for cls, path, line in _bpy_types.TypeMap.get(module, ()):
|
try:
|
||||||
if "bl_rna" in cls.__dict__:
|
unregister_class(cls)
|
||||||
total += 1
|
except:
|
||||||
try:
|
print("bpy.utils.unregister_module(): failed to unregistering class '%s.%s'" % (cls.__module__, cls.__name__))
|
||||||
unregister_class(cls)
|
print("\t", path, "line", line)
|
||||||
except:
|
traceback.print_exc()
|
||||||
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)
|
|
||||||
|
|||||||
@@ -556,9 +556,10 @@ TypeMap = {}
|
|||||||
|
|
||||||
class RNAMeta(type):
|
class RNAMeta(type):
|
||||||
def __new__(cls, name, bases, classdict, **args):
|
def __new__(cls, name, bases, classdict, **args):
|
||||||
import traceback
|
|
||||||
result = type.__new__(cls, name, bases, classdict)
|
result = type.__new__(cls, name, bases, classdict)
|
||||||
if bases and bases[0] != StructRNA:
|
if bases and bases[0] != StructRNA:
|
||||||
|
import traceback
|
||||||
|
import weakref
|
||||||
module = result.__module__
|
module = result.__module__
|
||||||
|
|
||||||
# first part of packages only
|
# first part of packages only
|
||||||
@@ -567,7 +568,7 @@ class RNAMeta(type):
|
|||||||
|
|
||||||
sf = traceback.extract_stack(limit=2)[0]
|
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
|
return result
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user