PyAPI: bpy.utils.execfile temporarily overrides the __main__ module
This is needed to support Python 3.10's `typing.get_type_hints`, to access the name-space used when creating the class. Also added a docstring for execfile.
This commit is contained in:
parent
4604350eef
commit
eecb90d8d2
@ -82,14 +82,39 @@ _is_factory_startup = _bpy.app.factory_startup
|
|||||||
|
|
||||||
|
|
||||||
def execfile(filepath, mod=None):
|
def execfile(filepath, mod=None):
|
||||||
# module name isn't used or added to 'sys.modules'.
|
"""
|
||||||
# passing in 'mod' allows re-execution without having to reload.
|
Execute a file path as a Python script.
|
||||||
|
|
||||||
|
:arg filepath: Path of the script to execute.
|
||||||
|
:type filepath: string
|
||||||
|
:arg mod: Optional cached module, the result of a previous execution.
|
||||||
|
:type mod: Module or None
|
||||||
|
:return: The module which can be passed back in as ``mod``.
|
||||||
|
:rtype: ModuleType
|
||||||
|
"""
|
||||||
|
|
||||||
import importlib.util
|
import importlib.util
|
||||||
mod_spec = importlib.util.spec_from_file_location("__main__", filepath)
|
mod_name = "__main__"
|
||||||
|
mod_spec = importlib.util.spec_from_file_location(mod_name, filepath)
|
||||||
if mod is None:
|
if mod is None:
|
||||||
mod = importlib.util.module_from_spec(mod_spec)
|
mod = importlib.util.module_from_spec(mod_spec)
|
||||||
|
|
||||||
|
# While the module name is not added to `sys.modules`, it's important to temporarily
|
||||||
|
# include this so statements such as `sys.modules[cls.__module__].__dict__` behave as expected.
|
||||||
|
# See: https://bugs.python.org/issue9499 for details.
|
||||||
|
modules = _sys.modules
|
||||||
|
mod_orig = modules.get(mod_name, None)
|
||||||
|
modules[mod_name] = mod
|
||||||
|
|
||||||
|
# No error supression, just ensure `sys.modules[mod_name]` is properly restored in the case of an error.
|
||||||
|
try:
|
||||||
mod_spec.loader.exec_module(mod)
|
mod_spec.loader.exec_module(mod)
|
||||||
|
finally:
|
||||||
|
if mod_orig is None:
|
||||||
|
modules.pop(mod_name, None)
|
||||||
|
else:
|
||||||
|
modules[mod_name] = mod_orig
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user