From 55e2134a4ac896210d93ba7079cb70ace43f4f3b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 23 Dec 2021 13:50:36 -0500 Subject: [PATCH] In distutils_hack, only add the metadata finder once. In ensure_local_distutils, rely on a context manager for reliable manipulation. Fixes #2958. --- _distutils_hack/__init__.py | 19 ++++++++++++++++--- changelog.d/2958.change.rst | 1 + setup.py | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 changelog.d/2958.change.rst diff --git a/_distutils_hack/__init__.py b/_distutils_hack/__init__.py index 22bc9ed6e8..85a51370b6 100644 --- a/_distutils_hack/__init__.py +++ b/_distutils_hack/__init__.py @@ -3,6 +3,7 @@ import re import importlib import warnings +import contextlib is_pypy = '__pypy__' in sys.builtin_module_names @@ -52,9 +53,8 @@ def ensure_local_distutils(): # With the DistutilsMetaFinder in place, # perform an import to cause distutils to be # loaded from setuptools._distutils. Ref #2906. - add_shim() - importlib.import_module('distutils') - remove_shim() + with shim(): + importlib.import_module('distutils') # check that submodules load as expected core = importlib.import_module('distutils.core') @@ -129,6 +129,19 @@ def frame_file_is_setup(frame): DISTUTILS_FINDER = DistutilsMetaFinder() +def ensure_shim(): + DISTUTILS_FINDER in sys.meta_path or add_shim() + + +@contextlib.contextmanager +def shim(): + add_shim() + try: + yield + finally: + remove_shim() + + def add_shim(): sys.meta_path.insert(0, DISTUTILS_FINDER) diff --git a/changelog.d/2958.change.rst b/changelog.d/2958.change.rst new file mode 100644 index 0000000000..9a3910e157 --- /dev/null +++ b/changelog.d/2958.change.rst @@ -0,0 +1 @@ +In distutils_hack, only add the metadata finder once. In ensure_local_distutils, rely on a context manager for reliable manipulation. diff --git a/setup.py b/setup.py index 4cda3d3890..d15189db0f 100755 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ class install_with_pth(install): import os var = 'SETUPTOOLS_USE_DISTUTILS' enabled = os.environ.get(var, 'local') == 'local' - enabled and __import__('_distutils_hack').add_shim() + enabled and __import__('_distutils_hack').ensure_shim() """).lstrip().replace('\n', '; ') def initialize_options(self):