This commit is contained in:
Sree Vaddi 2020-06-17 16:53:06 -07:00
commit 92e138cf17
7 changed files with 62 additions and 64 deletions

View File

@ -103,6 +103,11 @@ Improved Modules
Optimizations
=============
* The :mod:`runpy` module now imports fewer modules.
The ``python3 -m module-name`` command startup time is 1.3x faster in
average.
(Contributed by Victor Stinner in :issue:`41006`.)
Deprecated
==========

50
Lib/importlib/_abc.py Normal file
View File

@ -0,0 +1,50 @@
"""Subset of importlib.abc used to reduce importlib.util imports."""
from . import _bootstrap
import abc
class Loader(metaclass=abc.ABCMeta):
"""Abstract base class for import loaders."""
def create_module(self, spec):
"""Return a module to initialize and into which to load.
This method should raise ImportError if anything prevents it
from creating a new module. It may return None to indicate
that the spec should create the new module.
"""
# By default, defer to default semantics for the new module.
return None
# We don't define exec_module() here since that would break
# hasattr checks we do to support backward compatibility.
def load_module(self, fullname):
"""Return the loaded module.
The module must be added to sys.modules and have import-related
attributes set properly. The fullname is a str.
ImportError is raised on failure.
This method is deprecated in favor of loader.exec_module(). If
exec_module() exists then it is used to provide a backwards-compatible
functionality for this method.
"""
if not hasattr(self, 'exec_module'):
raise ImportError
return _bootstrap._load_module_shim(self, fullname)
def module_repr(self, module):
"""Return a module's repr.
Used by the module type when the method does not raise
NotImplementedError.
This method is deprecated.
"""
# The exception will cause ModuleType.__repr__ to ignore this method.
raise NotImplementedError

View File

@ -12,6 +12,7 @@ try:
import _frozen_importlib_external
except ImportError:
_frozen_importlib_external = _bootstrap_external
from ._abc import Loader
import abc
import warnings
from typing import Protocol, runtime_checkable
@ -134,53 +135,6 @@ class PathEntryFinder(Finder):
_register(PathEntryFinder, machinery.FileFinder)
class Loader(metaclass=abc.ABCMeta):
"""Abstract base class for import loaders."""
def create_module(self, spec):
"""Return a module to initialize and into which to load.
This method should raise ImportError if anything prevents it
from creating a new module. It may return None to indicate
that the spec should create the new module.
"""
# By default, defer to default semantics for the new module.
return None
# We don't define exec_module() here since that would break
# hasattr checks we do to support backward compatibility.
def load_module(self, fullname):
"""Return the loaded module.
The module must be added to sys.modules and have import-related
attributes set properly. The fullname is a str.
ImportError is raised on failure.
This method is deprecated in favor of loader.exec_module(). If
exec_module() exists then it is used to provide a backwards-compatible
functionality for this method.
"""
if not hasattr(self, 'exec_module'):
raise ImportError
return _bootstrap._load_module_shim(self, fullname)
def module_repr(self, module):
"""Return a module's repr.
Used by the module type when the method does not raise
NotImplementedError.
This method is deprecated.
"""
# The exception will cause ModuleType.__repr__ to ignore this method.
raise NotImplementedError
class ResourceLoader(Loader):
"""Abstract base class for loaders which can return data from their

View File

@ -1,5 +1,5 @@
"""Utility code for constructing importers, etc."""
from . import abc
from ._abc import Loader
from ._bootstrap import module_from_spec
from ._bootstrap import _resolve_name
from ._bootstrap import spec_from_loader
@ -263,7 +263,7 @@ class _LazyModule(types.ModuleType):
delattr(self, attr)
class LazyLoader(abc.Loader):
class LazyLoader(Loader):
"""A loader that creates a module which defers loading until attribute access."""

View File

@ -650,8 +650,8 @@ class FactoryTests:
# Need to use a circuitous route to get at importlib.machinery to make
# sure the same class object is used in the isinstance() check as
# would have been used to create the loader.
self.assertIsInstance(spec.loader,
self.util.abc.machinery.SourceFileLoader)
SourceFileLoader = self.util.spec_from_file_location.__globals__['SourceFileLoader']
self.assertIsInstance(spec.loader, SourceFileLoader)
self.assertEqual(spec.loader.name, self.name)
self.assertEqual(spec.loader.path, self.path)
self.assertEqual(spec.origin, self.path)

View File

@ -0,0 +1,2 @@
The ``encodings.latin_1`` module is no longer imported at startup. Now it is
only imported when it is the filesystem encoding or the stdio encoding.

View File

@ -1939,7 +1939,6 @@ static PyStatus
init_sys_streams(PyThreadState *tstate)
{
PyObject *iomod = NULL;
PyObject *m;
PyObject *std = NULL;
int fd;
PyObject * encoding_attr;
@ -1959,18 +1958,6 @@ init_sys_streams(PyThreadState *tstate)
}
#endif
/* Hack to avoid a nasty recursion issue when Python is invoked
in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
goto error;
}
Py_DECREF(m);
if (!(m = PyImport_ImportModule("encodings.latin_1"))) {
goto error;
}
Py_DECREF(m);
if (!(iomod = PyImport_ImportModule("io"))) {
goto error;
}