Touch-up for PEP 451

This commit is contained in:
Brett Cannon 2013-11-08 10:19:24 -05:00
parent 3ba7d9323f
commit b4fb332c27
1 changed files with 23 additions and 18 deletions

View File

@ -3,6 +3,7 @@ Title: A ModuleSpec Type for the Import System
Version: $Revision$ Version: $Revision$
Last-Modified: $Date$ Last-Modified: $Date$
Author: Eric Snow <ericsnowcurrently@gmail.com> Author: Eric Snow <ericsnowcurrently@gmail.com>
BDFL-Delegate: Brett Cannon <brett@python.org>, Nick Coghlan <ncoghlan@gmail.com>
Discussions-To: import-sig@python.org Discussions-To: import-sig@python.org
Status: Draft Status: Draft
Type: Standards Track Type: Standards Track
@ -67,12 +68,12 @@ module.
Right now loaders (via load_module()) are responsible for certain Right now loaders (via load_module()) are responsible for certain
boilerplate, import-related operations. These are: boilerplate, import-related operations. These are:
1. perform some (module-related) validation; 1. Perform some (module-related) validation
2. create the module object; 2. Create the module object
3. set import-related attributes on the module; 3. Set import-related attributes on the module
4. "register" the module to sys.modules; 4. "Register" the module to sys.modules
5. exec the module; 5. Exec the module
6. clean up in the event of failure while loading the module. 6. Clean up in the event of failure while loading the module
This all takes place during the import system's call to This all takes place during the import system's call to
Loader.load_module(). Loader.load_module().
@ -170,7 +171,7 @@ challenge.
As more developers come to understand and customize the import system, As more developers come to understand and customize the import system,
any weaknesses in the finder and loader APIs will be more impactful. So any weaknesses in the finder and loader APIs will be more impactful. So
the sooner we can address any such weaknesses the import system, the the sooner we can address any such weaknesses the import system, the
better...and there are a couple we can take care of with this proposal. better...and there are a couple we hope to take care of with this proposal.
Firstly, any time the import system needs to save information about a Firstly, any time the import system needs to save information about a
module we end up with more attributes on module objects that are module we end up with more attributes on module objects that are
@ -184,7 +185,7 @@ during recent efforts on a separate proposal. [#ref_files_pep]_
The `finder`_ and `loader`_ sections above detail current responsibility The `finder`_ and `loader`_ sections above detail current responsibility
of both. Notably, loaders are not required to provide any of the of both. Notably, loaders are not required to provide any of the
functionality of their load_module() through other methods. Thus, functionality of their load_module() method through other methods. Thus,
though the import-related information about a module is likely available though the import-related information about a module is likely available
without loading the module, it is not otherwise exposed. without loading the module, it is not otherwise exposed.
@ -284,9 +285,9 @@ Other API Additions
For finders: For finders:
* importlib.abc.MetaPathFinder.find_spec(name, path) and * importlib.abc.MetaPathFinder.find_spec(name, path, target) and
importlib.abc.PathEntryFinder.find_spec(name) will return a module importlib.abc.PathEntryFinder.find_spec(name, target) will return a
spec to use during import. module spec to use during import.
For loaders: For loaders:
@ -453,10 +454,12 @@ adjusted to take advantage of the module's spec and the new loader API::
_init_module_attrs(spec, module) _init_module_attrs(spec, module)
if spec.loader is None and spec.submodule_search_locations is not None: if spec.loader is None and spec.submodule_search_locations is not None:
# namespace package # Namespace package
sys.modules[spec.name] = module sys.modules[spec.name] = module
elif not hasattr(spec.loader, 'exec_module'): elif not hasattr(spec.loader, 'exec_module'):
module = spec.loader.load_module(spec.name) spec.loader.load_module(spec.name)
# __loader__ and __package__ would be explicitly set here for
# backwards-compatibility.
else: else:
sys.modules[spec.name] = module sys.modules[spec.name] = module
try: try:
@ -502,13 +505,15 @@ Here is the corresponding outline for reload()::
_RELOADING[name] = module _RELOADING[name] = module
try: try:
if spec.loader is None: if spec.loader is None:
# namespace loader # Namespace loader
_init_module_attrs(spec, module) _init_module_attrs(spec, module)
return module return module
if spec.parent and spec.parent not in sys.modules: if spec.parent and spec.parent not in sys.modules:
raise ImportError raise ImportError
_init_module_attrs(spec, module) _init_module_attrs(spec, module)
# Ignoring backwards-compatibility call to load_module()
# for simplicity.
spec.loader.exec_module(module) spec.loader.exec_module(module)
return sys.modules[name] return sys.modules[name]
finally: finally:
@ -690,7 +695,7 @@ equivalent object, though at least the latter is likely.
Finders Finders
------- -------
Finders are still responsible for identifying, an typically creating, Finders are still responsible for identifying, and typically creating,
the loader that should be used to load a module. That loader will the loader that should be used to load a module. That loader will
now be stored in the module spec returned by find_spec() rather now be stored in the module spec returned by find_spec() rather
than returned directly. As is currently the case without the PEP, if a than returned directly. As is currently the case without the PEP, if a
@ -809,7 +814,7 @@ this method is part of ModuleSpec, it will be deprecated on loaders.
However, if it exists on a loader it will be used exclusively. However, if it exists on a loader it will be used exclusively.
Loader.init_module_attr() method, added prior to Python 3.4's Loader.init_module_attr() method, added prior to Python 3.4's
release , will be removed in favor of the same method on ModuleSpec. release, will be removed in favor of the same method on ModuleSpec.
However, InspectLoader.is_package() will not be deprecated even However, InspectLoader.is_package() will not be deprecated even
though the same information is found on ModuleSpec. ModuleSpec though the same information is found on ModuleSpec. ModuleSpec
@ -832,11 +837,11 @@ Other Changes
series. series.
* The spec for the ``__main__`` module will reflect how the interpreter * The spec for the ``__main__`` module will reflect how the interpreter
was started. For instance, with ``-m`` the spec's name will be that was started. For instance, with ``-m`` the spec's name will be that
of the run module, while ``__main__.__name__`` will still be of the module used, while ``__main__.__name__`` will still be
"__main__". "__main__".
* We will add importlib.find_spec() to mirror importlib.find_loader() * We will add importlib.find_spec() to mirror importlib.find_loader()
(which becomes deprecated). (which becomes deprecated).
* importlib.reload() is changed to use ModuleSpec.load(). * importlib.reload() is changed to use ModuleSpec.
* importlib.reload() will now make use of the per-module import lock. * importlib.reload() will now make use of the per-module import lock.