Skip to content

Commit

Permalink
Merge pull request #3009 from tiran/issue3006_startup_speedup
Browse files Browse the repository at this point in the history
Speedup startup of Python by importing less
  • Loading branch information
jaraco committed Jan 8, 2022
2 parents a60fc6a + 7619852 commit fd966a3
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 27 deletions.
62 changes: 35 additions & 27 deletions _distutils_hack/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
# 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)


def warn_distutils_present():
if 'distutils' not in sys.modules:
return
if is_pypy and sys.version_info < (3, 7):
# 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 "
Expand All @@ -33,8 +26,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]

Expand All @@ -48,6 +45,7 @@ def enabled():


def ensure_local_distutils():
import importlib
clear_distutils()

# With the DistutilsMetaFinder in place,
Expand All @@ -73,15 +71,12 @@ def do_override():
ensure_local_distutils()


class suppress(contextlib.suppress, contextlib.ContextDecorator):
"""
A version of contextlib.suppress with decorator support.
class _TrivialRe:
def __init__(self, *patterns):
self._patterns = patterns

>>> @suppress(KeyError)
... def key_error():
... {}['']
>>> key_error()
"""
def match(self, string):
return all(pat in string for pat in self._patterns)


class DistutilsMetaFinder:
Expand All @@ -94,8 +89,20 @@ def find_spec(self, fullname, path, target=None):
return method()

def spec_for_distutils(self):
import importlib
import importlib.abc
import importlib.util
import warnings

# warnings.filterwarnings() imports the re module
warnings._add_filter(
'ignore',
_TrivialRe("distutils", "deprecated"),
DeprecationWarning,
None,
0,
append=True
)

try:
mod = importlib.import_module('setuptools._distutils')
Expand Down Expand Up @@ -144,13 +151,15 @@ def pip_imported_during_build(cls):
)

@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):
Expand All @@ -168,12 +177,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()


Expand Down
2 changes: 2 additions & 0 deletions changelog.d/3006.change.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed startup performance issue of Python interpreter due to imports of
costly modules in ``_distutils_hack`` -- by :user:`tiran`
1 change: 1 addition & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ filterwarnings=
# SETUPTOOLS_USE_DISTUTILS=stdlib but for
# https://github.com/pytest-dev/pytest/discussions/9296
ignore:The distutils.sysconfig module is deprecated, use sysconfig instead
ignore:The distutils package is deprecated.*

# Workaround for pypa/setuptools#2868
# ideally would apply to PyPy only but for
Expand Down

0 comments on commit fd966a3

Please sign in to comment.