[PEP 451] Changes related to the find_spec() target module.

This commit is contained in:
Eric Snow 2013-11-02 15:08:19 -06:00
parent a1c321efbb
commit f729d23f82
1 changed files with 19 additions and 32 deletions

View File

@ -278,7 +278,7 @@ finders. See the `Factory Functions`_ section below for more detail.
Other API Additions
-------------------
* importlib.find_spec(name, path=None, existing=None) will work exactly
* importlib.find_spec(name, path=None, target=None) will work exactly
the same as importlib.find_loader() (which it replaces), but return a
spec instead of a loader.
@ -493,7 +493,7 @@ Here is the corresponding outline for reload()::
name = module.__spec__.name
except AttributeError:
name = module.__name__
spec = find_spec(name, existing=module)
spec = find_spec(name, target=module)
if sys.modules.get(name) is not module:
raise ImportError
@ -521,7 +521,7 @@ see if the module was already in sys.modules. Now, by the time
exec_module() is called during load (not reload) the import machinery
would already have placed the module in sys.modules. This is part of
the reason why find_spec() has
`the "existing" parameter <The "existing" parameter of find_spec()>`_.
`the "target" parameter <The "target" parameter of find_spec()>`_.
The semantics of reload will remain essentially the same as they exist
already [#reload-semantics-fix]_. The impact of this PEP on some kinds
@ -697,9 +697,9 @@ than returned directly. As is currently the case without the PEP, if a
loader would be costly to create, that loader can be designed to defer
the cost until later.
**MetaPathFinder.find_spec(name, path=None, existing=None)**
**MetaPathFinder.find_spec(name, path=None, target=None)**
**PathEntryFinder.find_spec(name, existing=None)**
**PathEntryFinder.find_spec(name, target=None)**
Finders must return ModuleSpec objects when find_spec() is
called. This new method replaces find_module() and
@ -714,8 +714,8 @@ especially considering PathEntryFinder.find_loader() was just
added in Python 3.3. However, the extra complexity and a less-than-
explicit method name aren't worth it.
The "existing" parameter of find_spec()
---------------------------------------
The "target" parameter of find_spec()
-------------------------------------
A module object with the same name as the "name" argument (or None, the
default) should be passed in to "exising". This argument allows the
@ -727,26 +727,26 @@ Through find_spec() the finder will always identify the loader it
will return in the spec. In the case of reload, at this point the
finder should also decide whether or not the loader supports loading
into the module-to-be-reloaded (which was passed in to find_spec() as
"existing"). This decision may entail consulting with the loader. If
"target"). This decision may entail consulting with the loader. If
the finder determines that the loader does not support reloading that
module, it should either find another loader or return None (indicating
that it could not "find" the module). This reload decision is important
since, as noted in `How Reloading Will Work`_, loaders will no longer be
able to trivially identify a reload situation on their own.
module, it should either find another loader or raise ImportError
(completely stopping import of the module). This reload decision is
important since, as noted in `How Reloading Will Work`_, loaders will
no longer be able to trivially identify a reload situation on their own.
Two alternatives were presented to the "existing" parameter:
Loader.supports_reload() and adding "existing" to Loader.exec_module()
Two alternatives were presented to the "target" parameter:
Loader.supports_reload() and adding "target" to Loader.exec_module()
instead of find_spec(). supports_reload() was the initial approach to
the reload situation. [#supports_reload]_ However, there was some
opposition to the loader-specific, reload-centric approach.
[#supports_reload_considered_harmful]_
As to "existing" on exec_module(), the loader may need other information
from the existing module (or spec) during reload, more than just "does
As to "target" on exec_module(), the loader may need other information
from the target module (or spec) during reload, more than just "does
this loader support reloading this module", that is no longer available
with the move away from load_module(). A proposal on the table was to
add something like "existing" to exec_module(). [#exec_module_existing]_
However, putting "existing" on find_spec() instead is more in line with
add something like "target" to exec_module(). [#exec_module_target]_
However, putting "target" on find_spec() instead is more in line with
the goals of this PEP. Furthermore, it obviates the need for
supports_reload().
@ -835,19 +835,6 @@ Other Changes
* importlib.reload() will now make use of the per-module import lock.
Open Issues
===========
\* In the `Finders`_ section, the PEP specifies returning None (or using
a different loader) when the found loader does not support loading into
an existing module (e.g during reload). An alternative to returning
None would be to raise ImportError with a message like "the loader does
not support reloading the module". This may actually be a better
approach since "could not find a loader" and "the found loader won't
work" are different situations that a single return value (None) may not
sufficiently represent.
Reference Implementation
========================
@ -943,7 +930,7 @@ References
.. [#supports_reload_considered_harmful]
https://mail.python.org/pipermail/python-dev/2013-October/129971.html
.. [#exec_module_existing]
.. [#exec_module_target]
https://mail.python.org/pipermail/python-dev/2013-October/129933.html
Copyright