Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2010-09-08 11:30:20 +0400
committerCampbell Barton <ideasman42@gmail.com>2010-09-08 11:30:20 +0400
commitb58f41e1203500d2b54e9ae8a3a07ea66e43671f (patch)
tree34d09eeeec83d18d9041265edbf416e092cc42b0 /release
parent1a41d2fc2938710fe2673bae9702a534f7f94d58 (diff)
addon improvements/fixes
- better error reporting when an addon fails to load - upload an addon which loads partly but then fails (eg, module loads but class register fails) - bugfix addon loading, failier to load would leave _bpy_types._register_immediate = False - added which change on disk are reloaded when enabling. - bpy.path.module_names() now returns (module_name, module_path) pairs.
Diffstat (limited to 'release')
-rw-r--r--release/scripts/modules/bpy/path.py14
-rw-r--r--release/scripts/modules/bpy/utils.py2
-rw-r--r--release/scripts/modules/bpy_types.py3
-rw-r--r--release/scripts/ui/space_userpref.py72
4 files changed, 69 insertions, 22 deletions
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index 714a3a07f95..a5b86b917b2 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -183,7 +183,7 @@ def module_names(path, recursive=False):
:type path: string
:arg recursive: Also return submodule names for packages.
:type recursive: bool
- :return: a list of strings.
+ :return: a list of string pairs (module_name, module_file).
:rtype: list
"""
@@ -193,13 +193,15 @@ def module_names(path, recursive=False):
for filename in sorted(_os.listdir(path)):
if filename.endswith(".py") and filename != "__init__.py":
- modules.append(filename[0:-3])
+ fullpath = join(path, filename)
+ modules.append((filename[0:-3], fullpath))
elif ("." not in filename):
directory = join(path, filename)
- if isfile(join(directory, "__init__.py")):
- modules.append(filename)
+ fullpath = join(directory, "__init__.py")
+ if isfile(fullpath):
+ modules.append((filename, fullpath))
if recursive:
- for mod_name in module_names(directory, True):
- modules.append("%s.%s" % (filename, mod_name))
+ for mod_name, mod_path in module_names(directory, True):
+ modules.append(("%s.%s" % (filename, mod_name), mod_path))
return modules
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 9b0c758404e..f5144d6cdf5 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -70,7 +70,7 @@ def modules_from_path(path, loaded_modules):
modules = []
- for mod_name in _bpy.path.module_names(path):
+ for mod_name, mod_path in _bpy.path.module_names(path):
mod = _test_import(mod_name, loaded_modules)
if mod:
modules.append(mod)
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 0ef1e490f53..923e9f91c9e 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -586,7 +586,8 @@ def _register_module(module):
bpy_types.register(t)
except:
import traceback
- print("bpy.utils._register_module(): Module '%s' failed to register class '%s.%s'" % (module, t.__module__, t.__name__))
+ 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()
diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py
index 435384708c5..678a66d7e37 100644
--- a/release/scripts/ui/space_userpref.py
+++ b/release/scripts/ui/space_userpref.py
@@ -875,12 +875,12 @@ class USERPREF_PT_addons(bpy.types.Panel):
modules_stale = set(USERPREF_PT_addons._addons_fake_modules.keys())
for path in paths:
- for mod_name in bpy.path.module_names(path):
+ for mod_name, mod_path in bpy.path.module_names(path):
modules_stale -= {mod_name}
mod = USERPREF_PT_addons._addons_fake_modules.get(mod_name)
if mod:
if mod.__time__ != os.path.getmtime(mod_path):
- print("Reloading", mod_name, mod.__time__, os.path.getmtime(mod_path), mod_path)
+ print("reloading addon:", mod_name, mod.__time__, os.path.getmtime(mod_path), mod_path)
del USERPREF_PT_addons._addons_fake_modules[mod_name]
mod = None
@@ -1052,20 +1052,66 @@ class WM_OT_addon_enable(bpy.types.Operator):
module_name = self.properties.module
# note, this still gets added to _bpy_types.TypeMap
+
+ import sys
import bpy_types as _bpy_types
+
+
_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)
+ if mod:
+ mtime_orig = getattr(mod, "__time__", 0)
+ mtime_new = os.path.getmtime(mod.__file__)
+ if mtime_orig != mtime_new:
+ print("module changed on disk:", mod.__file__, "reloading...")
+
+ try:
+ reload(mod)
+ except:
+ handle_error()
+ del sys.modules[module_name]
+ return {'CANCELLED'}
+
+ # Split registering up into 3 steps so we can undo if it fails par way through
+ # 1) try import
try:
mod = __import__(module_name)
+ mod.__time__ = os.path.getmtime(mod.__file__)
+ except:
+ handle_error()
+ return {'CANCELLED'}
+
+ # 2) try register collected modules
+ try:
_bpy_types._register_module(module_name)
+ except:
+ handle_error()
+ del sys.modules[module_name]
+ return {'CANCELLED'}
+
+ # 3) try run the modules register function
+ try:
mod.register()
except:
- import traceback
- traceback.print_exc()
+ handle_error()
+ _bpy_types._unregister_module(module_name)
+ del sys.modules[module_name]
return {'CANCELLED'}
- ext = context.user_preferences.addons.new()
- ext.module = module_name
+ # * OK loaded successfully! *
+ # just incase its enabled alredy
+ ext = context.user_preferences.addons.get(module_name)
+ if not ext:
+ ext = context.user_preferences.addons.new()
+ ext.module = module_name
# check if add-on is written for current blender version, or raise a warning
info = addon_info_get(mod)
@@ -1097,15 +1143,13 @@ class WM_OT_addon_disable(bpy.types.Operator):
import traceback
traceback.print_exc()
+ # could be in more then once, unlikely but better do this just incase.
addons = context.user_preferences.addons
- ok = True
- while ok: # incase its in more then once.
- ok = False
- for ext in addons:
- if ext.module == module_name:
- addons.remove(ext)
- ok = True
- break
+
+ while module_name in addons:
+ addon = addons.get(module_name)
+ if addon:
+ addons.remove(addon)
return {'FINISHED'}