diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-12-20 07:56:22 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-12-20 07:56:22 +0400 |
commit | 423994bf396869f9eab2ad252abe5c034ca8181e (patch) | |
tree | 60a5589534a5dd1a03991e2a89479cc3a130b482 /release | |
parent | e4728bf9100f1ea5b701ecdf8b052be3cfab4f2b (diff) |
py api: add restrict state context manager (thats python's context not blenders context),
which restricts bpy.context and bpy.data.
enable this for loading scripts in 'startup' too.
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/modules/addon_utils.py | 61 | ||||
-rw-r--r-- | release/scripts/modules/bpy/utils.py | 23 | ||||
-rw-r--r-- | release/scripts/modules/bpy_restrict_state.py | 57 |
3 files changed, 94 insertions, 47 deletions
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 3d705a0cf79..65ea91cf8ce 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -31,14 +31,6 @@ __all__ = ( import bpy as _bpy _user_preferences = _bpy.context.user_preferences -class _RestrictedContext(): - __slots__ = () - @property - def window_manager(self): - return _bpy.data.window_managers[0] -_ctx_restricted = _RestrictedContext() - - error_duplicates = False error_encoding = False addons_fake_modules = {} @@ -240,6 +232,7 @@ def enable(module_name, default_set=True, persistent=False): import os import sys + from bpy_restrict_state import RestrictBlend def handle_error(): import traceback @@ -267,37 +260,31 @@ def enable(module_name, default_set=True, persistent=False): # Split registering up into 3 steps so we can undo # if it fails par way through. - # first disable the context, using the context at all is + # disable the context, using the context at all is # really bad while loading an addon, don't do it! - ctx = _bpy.context - _bpy.context = _ctx_restricted + with RestrictBlend(): - # 1) try import - try: - mod = __import__(module_name) - mod.__time__ = os.path.getmtime(mod.__file__) - mod.__addon_enabled__ = False - except: - handle_error() - _bpy.context = ctx - return None - - # 2) try register collected modules - # removed, addons need to handle own registration now. - - # 3) try run the modules register function - try: - mod.register() - except: - print("Exception in module register(): %r" % - getattr(mod, "__file__", module_name)) - handle_error() - del sys.modules[module_name] - _bpy.context = ctx - return None - - # finally restore the context - _bpy.context = ctx + # 1) try import + try: + mod = __import__(module_name) + mod.__time__ = os.path.getmtime(mod.__file__) + mod.__addon_enabled__ = False + except: + handle_error() + return None + + # 2) try register collected modules + # removed, addons need to handle own registration now. + + # 3) try run the modules register function + try: + mod.register() + except: + print("Exception in module register(): %r" % + getattr(mod, "__file__", module_name)) + handle_error() + del sys.modules[module_name] + return None # * OK loaded successfully! * if default_set: diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index 58646a708a2..25fe6c1d4e5 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -217,18 +217,21 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): del _global_loaded_modules[:] - for base_path in script_paths(): - for path_subdir in _script_module_dirs: - path = _os.path.join(base_path, path_subdir) - if _os.path.isdir(path): - _sys_path_ensure(path) + from bpy_restrict_state import RestrictBlend + + with RestrictBlend(): + for base_path in script_paths(): + for path_subdir in _script_module_dirs: + path = _os.path.join(base_path, path_subdir) + if _os.path.isdir(path): + _sys_path_ensure(path) - # only add this to sys.modules, don't run - if path_subdir == "modules": - continue + # only add this to sys.modules, don't run + if path_subdir == "modules": + continue - for mod in modules_from_path(path, loaded_modules): - test_register(mod) + for mod in modules_from_path(path, loaded_modules): + test_register(mod) # deal with addons separately _addon_utils.reset_all(reload_scripts) diff --git a/release/scripts/modules/bpy_restrict_state.py b/release/scripts/modules/bpy_restrict_state.py new file mode 100644 index 00000000000..21c69212731 --- /dev/null +++ b/release/scripts/modules/bpy_restrict_state.py @@ -0,0 +1,57 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8-80 compliant> + +""" +This module contains RestrictBlend context manager. +""" + +__all__ = ( + "RestrictBlend", + ) + +import bpy as _bpy + +class _RestrictContext(): + __slots__ = () + _real_data = _bpy.data + @property + def window_manager(self): + return self._real_data.window_managers[0] + + +class _RestrictData(): + __slots__ = () + + +_context_restrict = _RestrictContext() +_data_restrict = _RestrictData() + + +class RestrictBlend(): + __slots__ = ("context", "data") + def __enter__(self): + self.data = _bpy.data + self.context = _bpy.context + _bpy.data = _data_restrict + _bpy.context = _context_restrict + + def __exit__(self, type, value, traceback): + _bpy.data = self.data + _bpy.context = self.context |