summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2022-01-06 23:30:19 +0100
committerJason R. Coombs <jaraco@jaraco.com>2022-01-08 11:55:35 -0500
commitcf21303f1ef9b143e76d613b253730c61edd97c2 (patch)
tree249e4769b961cdec92c49f32cc137a361945ba39
parenta60fc6a3d5713ea96d2b9a28d9ca0c3d47db0295 (diff)
downloadpython-setuptools-git-cf21303f1ef9b143e76d613b253730c61edd97c2.tar.gz
Speedup startup of Python by importing less
``_distutils_hack`` is imported by a ``.pth`` file at every start of a Python interpreter. The import of costly modules like ``re`` and ``contextlib`` almost doubles the initial startup time of an interpreter. - replace ``contextlib`` with simple context manager and try/except - replace ``re`` with simple string match - move import of ``importlib`` into function body - remove ``warnings.filterwarnings()``, which imports ``re``, too. Fixes: #3006 Signed-off-by: Christian Heimes <christian@python.org>
-rw-r--r--_distutils_hack/__init__.py50
1 files changed, 22 insertions, 28 deletions
diff --git a/_distutils_hack/__init__.py b/_distutils_hack/__init__.py
index 75bc4463..5d2a6b20 100644
--- a/_distutils_hack/__init__.py
+++ b/_distutils_hack/__init__.py
@@ -1,17 +1,14 @@
+# don't import any costly modules
import sys
import os
-import re
-import importlib
-import warnings
-import contextlib
is_pypy = '__pypy__' in sys.builtin_module_names
-warnings.filterwarnings('ignore',
- r'.+ distutils\b.+ deprecated',
- DeprecationWarning)
+# warnings.filterwarnings('ignore',
+# r'.+ distutils\b.+ deprecated',
+# DeprecationWarning)
def warn_distutils_present():
@@ -21,6 +18,7 @@ def warn_distutils_present():
# PyPy for 3.6 unconditionally imports distutils, so bypass the warning
# https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250
return
+ import warnings
warnings.warn(
"Distutils was imported before Setuptools, but importing Setuptools "
"also replaces the `distutils` module in `sys.modules`. This may lead "
@@ -33,8 +31,12 @@ def warn_distutils_present():
def clear_distutils():
if 'distutils' not in sys.modules:
return
+ import warnings
warnings.warn("Setuptools is replacing distutils.")
- mods = [name for name in sys.modules if re.match(r'distutils\b', name)]
+ mods = [
+ name for name in sys.modules
+ if name == "distutils" or name.startswith("distutils.")
+ ]
for name in mods:
del sys.modules[name]
@@ -48,6 +50,7 @@ def enabled():
def ensure_local_distutils():
+ import importlib
clear_distutils()
# With the DistutilsMetaFinder in place,
@@ -73,17 +76,6 @@ def do_override():
ensure_local_distutils()
-class suppress(contextlib.suppress, contextlib.ContextDecorator):
- """
- A version of contextlib.suppress with decorator support.
-
- >>> @suppress(KeyError)
- ... def key_error():
- ... {}['']
- >>> key_error()
- """
-
-
class DistutilsMetaFinder:
def find_spec(self, fullname, path, target=None):
if path is not None:
@@ -94,6 +86,7 @@ class DistutilsMetaFinder:
return method()
def spec_for_distutils(self):
+ import importlib
import importlib.abc
import importlib.util
@@ -144,13 +137,15 @@ class DistutilsMetaFinder:
)
@classmethod
- @suppress(AttributeError)
def is_get_pip(cls):
"""
Detect if get-pip is being invoked. Ref #2993.
"""
- import __main__
- return os.path.basename(__main__.__file__) == 'get-pip.py'
+ try:
+ import __main__
+ return os.path.basename(__main__.__file__) == 'get-pip.py'
+ except AttributeError:
+ pass
@staticmethod
def frame_file_is_setup(frame):
@@ -168,12 +163,11 @@ def add_shim():
DISTUTILS_FINDER in sys.meta_path or insert_shim()
-@contextlib.contextmanager
-def shim():
- insert_shim()
- try:
- yield
- finally:
+class shim:
+ def __enter__(self):
+ insert_shim()
+
+ def __exit__(self, exc, value, tb):
remove_shim()