From 7ef179f53cc6a673f7f9e1398ee0b600afdb89f8 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 24 Sep 2025 15:41:24 +0200 Subject: [PATCH 1/2] [3.11] gh-135374: Adjust test for setuptools' replacement of distutils (GH-138796) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ensurepip installs a bundled copy of distutils, which overrides the stdlib module. This affects several tests. This commit: - skips distutils in test___all__, as we're unlikely to break `__all__` in a security-fix-only branch (and if we do it's not much of a a big deal) - skips importability tests of distutils submodules if the setuptools hack is detected (cherry picked from commit 987af36a717793e97aad57f7da36a0677edfbdbd) Co-authored-by: Petr Viktorin Co-authored-by: Ɓukasz Langa Co-authored-by: Emma Smith --- Lib/test/test___all__.py | 6 ++++++ Lib/test/test_sundry.py | 34 +++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 7e1f80f2512565..756f53444830b6 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -61,6 +61,12 @@ def check_all(self, modname): self.assertEqual(keys, all_set, "in module {}".format(modname)) def walk_modules(self, basedir, modpath): + if modpath == 'distutils.': + # gh-135374: when setuptools is installed, it now replaces + # 'distutils' with its own version. + # In a security-fix only branch of CPython, + # skip the __all__ test rather than deal with the fallout. + return for fn in sorted(os.listdir(basedir)): path = os.path.join(basedir, fn) if os.path.isdir(path): diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index 2accad1aeebd4f..75c486701a98e6 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -4,6 +4,7 @@ import sys from test import support import unittest +import sys class TestUntestedModules(unittest.TestCase): def test_untested_modules_can_be_imported(self): @@ -18,6 +19,32 @@ def test_untested_modules_can_be_imported(self): self.fail('{} has tests even though test_sundry claims ' 'otherwise'.format(name)) + import html.entities + + try: + import tty # Not available on Windows + except ImportError: + if support.verbose: + print("skipping tty") + + def test_distutils_modules(self): + with warnings_helper.check_warnings(quiet=True): + + path_copy = sys.path[:] + import distutils + if '_distutils_hack' in sys.modules: + # gh-135374: when 'setuptools' is installed, it now replaces + # 'distutils' with its own version. + # This imports '_distutils_hack' and modifies sys.path. + # The setuptols version of distutils also does not include some + # of the modules tested here. + + # Undo the path modifications and skip the test. + + sys.path[:] = path_copy + raise unittest.SkipTest( + 'setuptools has replaced distutils with its own version') + import distutils.bcppcompiler import distutils.ccompiler import distutils.cygwinccompiler @@ -44,13 +71,6 @@ def test_untested_modules_can_be_imported(self): import distutils.command.sdist import distutils.command.upload - import html.entities - - try: - import tty # Not available on Windows - except ImportError: - if support.verbose: - print("skipping tty") if __name__ == "__main__": From a6139798cb4417a45fce39e06368fa2cd1f1ef85 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 24 Sep 2025 16:06:58 +0200 Subject: [PATCH 2/2] Use 3.9 test helper --- Lib/test/test_sundry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index 75c486701a98e6..ed0ec6cd1c664a 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -28,7 +28,7 @@ def test_untested_modules_can_be_imported(self): print("skipping tty") def test_distutils_modules(self): - with warnings_helper.check_warnings(quiet=True): + with support.check_warnings(quiet=True): path_copy = sys.path[:] import distutils