[PEP 451] Add namespace package support to example code and explain more about reloading.
This commit is contained in:
parent
1db087f304
commit
88fe8028a0
89
pep-0451.txt
89
pep-0451.txt
|
@ -295,6 +295,8 @@ For loaders:
|
|||
over its module execution functionality.
|
||||
* importlib.abc.Loader.create_module(spec) (optional) will return the
|
||||
module to use for loading.
|
||||
* importlib.abc.Loader.supports_reload(name) (optional) will return True
|
||||
(the default) if the loader supports reloading the module.
|
||||
|
||||
For modules:
|
||||
|
||||
|
@ -445,27 +447,31 @@ How Loading Will Work
|
|||
Here is an outline of what the import machinery does during loading,
|
||||
adjusted to take advantage of the module's spec and the new loader API::
|
||||
|
||||
module = None
|
||||
if hasattr(spec.loader, 'create_module'):
|
||||
module = spec.loader.create_module(spec)
|
||||
if module is None:
|
||||
module = ModuleType(spec.name)
|
||||
# The import-related module attributes get set here:
|
||||
_init_module_attrs(spec, module)
|
||||
|
||||
if not hasattr(spec.loader, 'exec_module'):
|
||||
module = spec.loader.load_module(spec.name)
|
||||
else:
|
||||
sys.modules[spec.name] = module
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
except BaseException:
|
||||
try:
|
||||
del sys.modules[spec.name]
|
||||
except KeyError:
|
||||
pass
|
||||
raise
|
||||
module_to_return = sys.modules[spec.name]
|
||||
module = None
|
||||
if spec.loader is not None and hasattr(spec.loader, 'create_module'):
|
||||
module = spec.loader.create_module(spec)
|
||||
if module is None:
|
||||
module = ModuleType(spec.name)
|
||||
# The import-related module attributes get set here:
|
||||
_init_module_attrs(spec, module)
|
||||
|
||||
if spec.loader is None and spec.submodule_search_locations is not None:
|
||||
# namespace package
|
||||
sys.modules[spec.name] = module
|
||||
elif not hasattr(spec.loader, 'exec_module'):
|
||||
module = spec.loader.load_module(spec.name)
|
||||
else:
|
||||
sys.modules[spec.name] = module
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
except BaseException:
|
||||
try:
|
||||
del sys.modules[spec.name]
|
||||
except KeyError:
|
||||
pass
|
||||
raise
|
||||
module_to_return = sys.modules[spec.name]
|
||||
|
||||
These steps are exactly what Loader.load_module() is already
|
||||
expected to do. Loaders will thus be simplified since they will only
|
||||
|
@ -479,6 +485,42 @@ import-related module attributes on the object. The module writer is on
|
|||
their own if they are doing this.
|
||||
|
||||
|
||||
How Reloading Will Work
|
||||
=======================
|
||||
|
||||
Here is the corresponding outline for reload()::
|
||||
|
||||
_RELOADING = {}
|
||||
|
||||
def reload(module):
|
||||
try:
|
||||
name = module.__spec__.name
|
||||
except AttributeError:
|
||||
name = module.__name__
|
||||
spec = find_spec(name)
|
||||
|
||||
if sys.modules.get(name) is not module:
|
||||
raise ImportError
|
||||
if spec in _RELOADING:
|
||||
return _RELOADING[name]
|
||||
_RELOADING[name] = module
|
||||
try:
|
||||
if spec.loader is None:
|
||||
# namespace loader
|
||||
_init_module_attrs(spec, module)
|
||||
return module
|
||||
if not spec.loader.supports_reload(name):
|
||||
raise ImportError
|
||||
if spec.parent and spec.parent not in sys.modules:
|
||||
raise ImportError
|
||||
|
||||
_init_module_attrs(spec, module)
|
||||
spec.loader.exec_module(module)
|
||||
return sys.modules[name]
|
||||
finally:
|
||||
del _RELOADING[name]
|
||||
|
||||
|
||||
ModuleSpec
|
||||
==========
|
||||
|
||||
|
@ -749,6 +791,13 @@ raising ImportError.
|
|||
module attributes. The fact that load_module() does is a design flaw
|
||||
that this proposal aims to correct.
|
||||
|
||||
**Loader.supports_reload(name)**
|
||||
|
||||
In cases where a module should not be reloaded, Loaders should implement
|
||||
supports_reload() and have it return False. If the method is defined
|
||||
and returns a false value, importlib.reload() will raise an ImportError.
|
||||
Otherwise reloading proceeds as normal.
|
||||
|
||||
Other changes:
|
||||
|
||||
PEP 420 introduced the optional module_repr() loader method to limit
|
||||
|
|
Loading…
Reference in New Issue