[PEP 451] Updates in response to the latest feedback.
This includes removing the remaining ModuleSpec methods and de-emphasizing that find_spec() returns actual ModuleSpec instances.
This commit is contained in:
parent
e9eb066c0d
commit
c9ba4a9756
69
pep-0451.txt
69
pep-0451.txt
|
@ -240,8 +240,8 @@ detail is available in later sections.
|
|||
importlib.machinery.ModuleSpec (new)
|
||||
------------------------------------
|
||||
|
||||
A specification for a module's import-system-related state. See the
|
||||
`ModuleSpec`_ section below for a more detailed description.
|
||||
An encapsulation of a module's import-system-related state during import.
|
||||
See the `ModuleSpec`_ section below for a more detailed description.
|
||||
|
||||
* ModuleSpec(name, loader, \*, origin=None, loader_state=None, is_package=None)
|
||||
|
||||
|
@ -263,13 +263,6 @@ Attributes:
|
|||
* has_location (RO-property) - a flag indicating whether or not the
|
||||
module's "origin" attribute refers to a location.
|
||||
|
||||
Instance Methods:
|
||||
|
||||
* module_repr() - provide a repr string for the spec'ed module;
|
||||
non-locatable modules will use their origin (e.g. "built-in").
|
||||
* init_module_attrs(module) - set any of a module's import-related
|
||||
attributes that aren't already set.
|
||||
|
||||
importlib.util Additions
|
||||
------------------------
|
||||
|
||||
|
@ -289,6 +282,12 @@ Other API Additions
|
|||
importlib.find_loader() (which it replaces), but return a spec instead
|
||||
of a loader.
|
||||
|
||||
For finders:
|
||||
|
||||
* importlib.abc.MetaPathFinder.find_spec(name, path) and
|
||||
importlib.abc.PathEntryFinder.find_spec(name) will return a module
|
||||
spec to use during import.
|
||||
|
||||
For loaders:
|
||||
|
||||
* importlib.abc.Loader.exec_module(module) will execute a module in its
|
||||
|
@ -443,34 +442,30 @@ factory functions nor any the instance methods.
|
|||
How Loading Will Work
|
||||
=====================
|
||||
|
||||
Here is an outline of what ModuleSpec does during loading::
|
||||
|
||||
def load(self):
|
||||
if not hasattr(self.loader, 'exec_module'):
|
||||
module = self.loader.load_module(self.name)
|
||||
self.init_module_attrs(module)
|
||||
return sys.modules[self.name]
|
||||
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(self.loader, 'create_module'):
|
||||
module = self.loader.create_module(self)
|
||||
if hasattr(spec.loader, 'create_module'):
|
||||
module = spec.loader.create_module(spec)
|
||||
if module is None:
|
||||
module = ModuleType(self.name)
|
||||
self.init_module_attrs(module)
|
||||
module = ModuleType(spec.name)
|
||||
# The import-related module attributes get set here:
|
||||
_init_module_attrs(module)
|
||||
|
||||
sys.modules[self.name] = module
|
||||
if not hasattr(spec.loader, 'exec_module'):
|
||||
module = spec.loader.load_module(spec.name)
|
||||
else:
|
||||
sys.modules[spec.name] = module
|
||||
try:
|
||||
self.loader.exec_module(module)
|
||||
spec.loader.exec_module(module)
|
||||
except BaseException:
|
||||
try:
|
||||
del sys.modules[self.name]
|
||||
del sys.modules[spec.name]
|
||||
except KeyError:
|
||||
pass
|
||||
raise
|
||||
return sys.modules[self.name]
|
||||
|
||||
Note: no "load" method is actually implemented as part of the public
|
||||
ModuleSpec API.
|
||||
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
|
||||
|
@ -494,8 +489,8 @@ Each of the following names is an attribute on ModuleSpec objects. A
|
|||
value of None indicates "not set". This contrasts with module
|
||||
objects where the attribute simply doesn't exist. Most of the
|
||||
attributes correspond to the import-related attributes of modules. Here
|
||||
is the mapping. The reverse of this mapping is used by
|
||||
ModuleSpec.init_module_attrs().
|
||||
is the mapping. The reverse of this mapping describes how the import
|
||||
machinery sets the module attributes right before calling exec_module().
|
||||
|
||||
========================== ==============
|
||||
On ModuleSpec On Modules
|
||||
|
@ -523,7 +518,7 @@ involve changing the state of a module's spec.
|
|||
|
||||
"origin" is a string for the name of the place from which the module
|
||||
originates. See `origin`_ above. Aside from the informational value,
|
||||
it is also used in module_repr(). In the case of a spec where
|
||||
it is also used in the module's repr. In the case of a spec where
|
||||
"has_location" is true, ``__file__`` is set to the value of "origin".
|
||||
For built-in modules "origin" would be set to "built-in".
|
||||
|
||||
|
@ -655,7 +650,7 @@ Simply setting loader_state or adding functionality to a custom
|
|||
finder or loader will likely be a better fit and should be tried first.
|
||||
However, as long as a subclass still fulfills the requirements of the
|
||||
import system, objects of that type are completely fine as the return
|
||||
value of Finder.find_spec().
|
||||
value of Finder.find_spec(). The same points apply to duck-typing.
|
||||
|
||||
|
||||
Existing Types
|
||||
|
@ -695,7 +690,7 @@ the cost until later.
|
|||
|
||||
**PathEntryFinder.find_spec(name)**
|
||||
|
||||
Finders will return ModuleSpec objects when find_spec() is
|
||||
Finders must return ModuleSpec objects when find_spec() is
|
||||
called. This new method replaces find_module() and
|
||||
find_loader() (in the PathEntryFinder case). If a loader does
|
||||
not have find_spec(), find_module() and find_loader() are
|
||||
|
@ -715,8 +710,9 @@ Currently a path entry finder may return (None, portions) from
|
|||
find_loader() to indicate it found part of a possible namespace
|
||||
package. To achieve the same effect, find_spec() must return a spec
|
||||
with "loader" set to None (a.k.a. not set) and with
|
||||
submodule_search_locations set to the same portions as were provided by
|
||||
find_loader(). It's up to PathFinder how to handle such specs.
|
||||
submodule_search_locations set to the same portions as would have been
|
||||
provided by find_loader(). It's up to PathFinder how to handle such
|
||||
specs.
|
||||
|
||||
Loaders
|
||||
-------
|
||||
|
@ -777,6 +773,11 @@ Other Changes
|
|||
|
||||
* The various finders and loaders provided by importlib will be
|
||||
updated to comply with this proposal.
|
||||
* Any other implmentations of or dependencies on the import-related APIs
|
||||
(particularly finders and loaders) in the stdlib will be likewise
|
||||
adjusted to this PEP. While they should continue to work, any such
|
||||
changes that get missed should be considered bugs for the Python 3.4.x
|
||||
series.
|
||||
* The spec for the ``__main__`` module will reflect how the interpreter
|
||||
was started. For instance, with ``-m`` the spec's name will be that
|
||||
of the run module, while ``__main__.__name__`` will still be
|
||||
|
|
Loading…
Reference in New Issue