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.
This commit is contained in:
@@ -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
|
||||
# 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.
|
||||
# 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
|
||||
# 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:
|
||||
|
||||
@@ -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
|
||||
|
||||
# only add this to sys.modules, don't run
|
||||
if path_subdir == "modules":
|
||||
continue
|
||||
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)
|
||||
|
||||
for mod in modules_from_path(path, loaded_modules):
|
||||
test_register(mod)
|
||||
# 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)
|
||||
|
||||
# deal with addons separately
|
||||
_addon_utils.reset_all(reload_scripts)
|
||||
|
||||
57
release/scripts/modules/bpy_restrict_state.py
Normal file
57
release/scripts/modules/bpy_restrict_state.py
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user