diff options
| author | Christian Heimes <christian@python.org> | 2022-01-06 23:30:19 +0100 |
|---|---|---|
| committer | Jason R. Coombs <jaraco@jaraco.com> | 2022-01-08 11:55:35 -0500 |
| commit | cf21303f1ef9b143e76d613b253730c61edd97c2 (patch) | |
| tree | 249e4769b961cdec92c49f32cc137a361945ba39 | |
| parent | a60fc6a3d5713ea96d2b9a28d9ca0c3d47db0295 (diff) | |
| download | python-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__.py | 50 |
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() |
