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:
Diffstat (limited to 'release/scripts/modules/bpy/utils/__init__.py')
-rw-r--r--release/scripts/modules/bpy/utils/__init__.py171
1 files changed, 148 insertions, 23 deletions
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 31dd836e034..c3175f93f4e 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -32,10 +32,13 @@ __all__ = (
"preset_find",
"preset_paths",
"refresh_script_paths",
+ "app_template_paths",
"register_class",
"register_module",
"register_manual_map",
"unregister_manual_map",
+ "register_classes_factory",
+ "register_submodule_factory",
"make_rna_paths",
"manual_map",
"previews",
@@ -49,18 +52,18 @@ __all__ = (
"unregister_class",
"unregister_module",
"user_resource",
- )
+)
from _bpy import (
- _utils_units as units,
- blend_paths,
- escape_identifier,
- register_class,
- resource_path,
- script_paths as _bpy_script_paths,
- unregister_class,
- user_resource as _user_resource,
- )
+ _utils_units as units,
+ blend_paths,
+ escape_identifier,
+ register_class,
+ resource_path,
+ script_paths as _bpy_script_paths,
+ unregister_class,
+ user_resource as _user_resource,
+)
import bpy as _bpy
import os as _os
@@ -70,6 +73,7 @@ import addon_utils as _addon_utils
_user_preferences = _bpy.context.user_preferences
_script_module_dirs = "startup", "modules"
+_is_factory_startup = _bpy.app.factory_startup
def _test_import(module_name, loaded_modules):
@@ -142,7 +146,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
as modules.
:type refresh_scripts: bool
"""
- use_time = _bpy.app.debug_python
+ use_time = use_class_register_check = _bpy.app.debug_python
+ use_user = not _is_factory_startup
if use_time:
import time
@@ -161,7 +166,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
for module_name in [ext.module for ext in _user_preferences.addons]:
_addon_utils.disable(module_name)
- # *AFTER* unregistering all add-ons, otherwise all calls to unregister_module() will silently fail (do nothing).
+ # *AFTER* unregistering all add-ons, otherwise all calls to
+ # unregister_module() will silently fail (do nothing).
_bpy_types.TypeMap.clear()
def register_module_call(mod):
@@ -232,7 +238,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
from bpy_restrict_state import RestrictBlend
with RestrictBlend():
- for base_path in script_paths():
+ for base_path in script_paths(use_user=use_user):
for path_subdir in _script_module_dirs:
path = _os.path.join(base_path, path_subdir)
if _os.path.isdir(path):
@@ -245,6 +251,12 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
for mod in modules_from_path(path, loaded_modules):
test_register(mod)
+ # load template (if set)
+ if any(_bpy.utils.app_template_paths()):
+ import bl_app_template_utils
+ bl_app_template_utils.reset(reload_scripts=reload_scripts)
+ del bl_app_template_utils
+
# deal with addons separately
_initialize = getattr(_addon_utils, "_initialize", None)
if _initialize is not None:
@@ -269,13 +281,21 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if use_time:
print("Python Script Load Time %.4f" % (time.time() - t_main))
+ if use_class_register_check:
+ for cls in _bpy.types.bpy_struct.__subclasses__():
+ if getattr(cls, "is_registered", False):
+ for subcls in cls.__subclasses__():
+ if not subcls.is_registered:
+ print(
+ "Warning, unregistered class: %s(%s)" %
+ (subcls.__name__, cls.__name__)
+ )
+
# base scripts
-_scripts = _os.path.join(_os.path.dirname(__file__),
- _os.path.pardir,
- _os.path.pardir,
- )
-_scripts = (_os.path.normpath(_scripts), )
+_scripts = (
+ _os.path.dirname(_os.path.dirname(_os.path.dirname(__file__))),
+)
def script_path_user():
@@ -290,7 +310,7 @@ def script_path_pref():
return _os.path.normpath(path) if path else None
-def script_paths(subdir=None, user_pref=True, check_all=False):
+def script_paths(subdir=None, user_pref=True, check_all=False, use_user=True):
"""
Returns a list of valid script paths.
@@ -312,15 +332,30 @@ def script_paths(subdir=None, user_pref=True, check_all=False):
# so the 'BLENDER_SYSTEM_SCRIPTS' environment variable will be used.
base_paths = _bpy_script_paths()
+ # Defined to be (system, user) so we can skip the second if needed.
+ if not use_user:
+ base_paths = base_paths[:1]
+
if check_all:
# All possible paths, no duplicates, keep order.
+ if use_user:
+ test_paths = ('LOCAL', 'USER', 'SYSTEM')
+ else:
+ test_paths = ('LOCAL', 'SYSTEM')
+
base_paths = (
- *(path for path in (_os.path.join(resource_path(res), "scripts")
- for res in ('LOCAL', 'USER', 'SYSTEM')) if path not in base_paths),
+ *(path for path in (
+ _os.path.join(resource_path(res), "scripts")
+ for res in test_paths) if path not in base_paths),
*base_paths,
- )
+ )
+
+ if use_user:
+ test_paths = (*base_paths, script_path_user(), script_path_pref())
+ else:
+ test_paths = (*base_paths, script_path_pref())
- for path in (*base_paths, script_path_user(), script_path_pref()):
+ for path in test_paths:
if path:
path = _os.path.normpath(path)
if path not in scripts and _os.path.isdir(path):
@@ -356,6 +391,37 @@ def refresh_script_paths():
_sys_path_ensure(path)
+def app_template_paths(subdir=None):
+ """
+ Returns valid application template paths.
+
+ :arg subdir: Optional subdir.
+ :type subdir: string
+ :return: app template paths.
+ :rtype: generator
+ """
+ # Note: keep in sync with: Blender's BKE_appdir_app_template_any
+
+ subdir_tuple = (subdir,) if subdir is not None else ()
+
+ # Avoid adding 'bl_app_templates_system' twice.
+ # Either we have a portable build or an installed system build.
+ for resource_type, module_name in (
+ ('USER', "bl_app_templates_user"),
+ ('LOCAL', "bl_app_templates_system"),
+ ('SYSTEM', "bl_app_templates_system"),
+ ):
+ path = resource_path(resource_type)
+ if path:
+ path = _os.path.join(
+ *(path, "scripts", "startup", module_name, *subdir_tuple))
+ if _os.path.isdir(path):
+ yield path
+ # Only load LOCAL or SYSTEM (never both).
+ if resource_type == 'LOCAL':
+ break
+
+
def preset_paths(subdir):
"""
Returns a list of paths for a specific preset.
@@ -636,6 +702,65 @@ def unregister_module(module, verbose=False):
print("done.\n")
+def register_classes_factory(classes):
+ """
+ Utility function to create register and unregister functions
+ which simply registers and unregisters a sequence of classes.
+ """
+ def register():
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
+
+ def unregister():
+ from bpy.utils import unregister_class
+ for cls in reversed(classes):
+ unregister_class(cls)
+
+ return register, unregister
+
+
+def register_submodule_factory(module_name, submodule_names):
+ """
+ Utility function to create register and unregister functions
+ which simply load submodules,
+ calling their register & unregister functions.
+
+ .. note::
+
+ Modules are registered in the order given,
+ unregistered in reverse order.
+
+ :arg module_name: The module name, typically ``__name__``.
+ :type module_name: string
+ :arg submodule_names: List of submodule names to load and unload.
+ :type submodule_names: list of strings
+ :return: register and unregister functions.
+ :rtype: tuple pair of functions
+ """
+
+ module = None
+ submodules = []
+
+ def register():
+ nonlocal module
+ module = __import__(name=module_name, fromlist=submodule_names)
+ submodules[:] = [getattr(module, name) for name in submodule_names]
+ for mod in submodules:
+ mod.register()
+
+ def unregister():
+ from sys import modules
+ for mod in reversed(submodules):
+ mod.unregister()
+ name = mod.__name__
+ delattr(module, name.partition(".")[2])
+ del modules[name]
+ submodules.clear()
+
+ return register, unregister
+
+
# -----------------------------------------------------------------------------
# Manual lookups, each function has to return a basepath and a sequence
# of...