Skip to content

Commit afa759f

Browse files
authored
gh-100238: Use setuptools in peg-generator and reenable tests (#104798)
1 parent e399f46 commit afa759f

File tree

6 files changed

+163
-102
lines changed

6 files changed

+163
-102
lines changed

Lib/test/support/__init__.py

+40-3
Original file line numberDiff line numberDiff line change
@@ -1865,15 +1865,16 @@ def missing_compiler_executable(cmd_names=[]):
18651865
missing.
18661866
18671867
"""
1868-
# TODO (PEP 632): alternate check without using distutils
1869-
from distutils import ccompiler, sysconfig, spawn, errors
1868+
from setuptools._distutils import ccompiler, sysconfig, spawn
1869+
from setuptools import errors
1870+
18701871
compiler = ccompiler.new_compiler()
18711872
sysconfig.customize_compiler(compiler)
18721873
if compiler.compiler_type == "msvc":
18731874
# MSVC has no executables, so check whether initialization succeeds
18741875
try:
18751876
compiler.initialize()
1876-
except errors.DistutilsPlatformError:
1877+
except errors.PlatformError:
18771878
return "msvc"
18781879
for name in compiler.executables:
18791880
if cmd_names and name not in cmd_names:
@@ -2270,6 +2271,42 @@ def requires_venv_with_pip():
22702271
return unittest.skipUnless(ctypes, 'venv: pip requires ctypes')
22712272

22722273

2274+
# Context manager that creates a virtual environment, install setuptools and wheel in it
2275+
# and returns the path to the venv directory and the path to the python executable
2276+
@contextlib.contextmanager
2277+
def setup_venv_with_pip_setuptools_wheel(venv_dir):
2278+
import subprocess
2279+
from .os_helper import temp_cwd
2280+
2281+
with temp_cwd() as temp_dir:
2282+
# Create virtual environment to get setuptools
2283+
cmd = [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir]
2284+
if verbose:
2285+
print()
2286+
print('Run:', ' '.join(cmd))
2287+
subprocess.run(cmd, check=True)
2288+
2289+
venv = os.path.join(temp_dir, venv_dir)
2290+
2291+
# Get the Python executable of the venv
2292+
python_exe = os.path.basename(sys.executable)
2293+
if sys.platform == 'win32':
2294+
python = os.path.join(venv, 'Scripts', python_exe)
2295+
else:
2296+
python = os.path.join(venv, 'bin', python_exe)
2297+
2298+
cmd = [python, '-X', 'dev',
2299+
'-m', 'pip', 'install',
2300+
findfile('setuptools-67.6.1-py3-none-any.whl'),
2301+
findfile('wheel-0.40.0-py3-none-any.whl')]
2302+
if verbose:
2303+
print()
2304+
print('Run:', ' '.join(cmd))
2305+
subprocess.run(cmd, check=True)
2306+
2307+
yield python
2308+
2309+
22732310
# True if Python is built with the Py_DEBUG macro defined: if
22742311
# Python is built in debug mode (./configure --with-pydebug).
22752312
Py_DEBUG = hasattr(sys, 'gettotalrefcount')

Lib/test/test_cppext.py

+8-33
Original file line numberDiff line numberDiff line change
@@ -35,39 +35,20 @@ def test_build_cpp03(self):
3535
# the test uses venv+pip: skip if it's not available
3636
@support.requires_venv_with_pip()
3737
def check_build(self, std_cpp03, extension_name):
38-
# Build in a temporary directory
39-
with os_helper.temp_cwd():
40-
self._check_build(std_cpp03, extension_name)
38+
venv_dir = 'env'
39+
with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe:
40+
self._check_build(std_cpp03, extension_name, python_exe)
4141

42-
def _check_build(self, std_cpp03, extension_name):
42+
def _check_build(self, std_cpp03, extension_name, python_exe):
4343
pkg_dir = 'pkg'
4444
os.mkdir(pkg_dir)
4545
shutil.copy(SETUP_TESTCPPEXT, os.path.join(pkg_dir, "setup.py"))
4646

47-
venv_dir = 'env'
48-
verbose = support.verbose
49-
50-
# Create virtual environment to get setuptools
51-
cmd = [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir]
52-
if verbose:
53-
print()
54-
print('Run:', ' '.join(cmd))
55-
subprocess.run(cmd, check=True)
56-
57-
# Get the Python executable of the venv
58-
python_exe = 'python'
59-
if sys.executable.endswith('.exe'):
60-
python_exe += '.exe'
61-
if MS_WINDOWS:
62-
python = os.path.join(venv_dir, 'Scripts', python_exe)
63-
else:
64-
python = os.path.join(venv_dir, 'bin', python_exe)
65-
6647
def run_cmd(operation, cmd):
6748
env = os.environ.copy()
6849
env['CPYTHON_TEST_CPP_STD'] = 'c++03' if std_cpp03 else 'c++11'
6950
env['CPYTHON_TEST_EXT_NAME'] = extension_name
70-
if verbose:
51+
if support.verbose:
7152
print('Run:', ' '.join(cmd))
7253
subprocess.run(cmd, check=True, env=env)
7354
else:
@@ -81,29 +62,23 @@ def run_cmd(operation, cmd):
8162
self.fail(
8263
f"{operation} failed with exit code {proc.returncode}")
8364

84-
cmd = [python, '-X', 'dev',
85-
'-m', 'pip', 'install',
86-
support.findfile('setuptools-67.6.1-py3-none-any.whl'),
87-
support.findfile('wheel-0.40.0-py3-none-any.whl')]
88-
run_cmd('Install build dependencies', cmd)
89-
9065
# Build and install the C++ extension
91-
cmd = [python, '-X', 'dev',
66+
cmd = [python_exe, '-X', 'dev',
9267
'-m', 'pip', 'install', '--no-build-isolation',
9368
os.path.abspath(pkg_dir)]
9469
run_cmd('Install', cmd)
9570

9671
# Do a reference run. Until we test that running python
9772
# doesn't leak references (gh-94755), run it so one can manually check
9873
# -X showrefcount results against this baseline.
99-
cmd = [python,
74+
cmd = [python_exe,
10075
'-X', 'dev',
10176
'-X', 'showrefcount',
10277
'-c', 'pass']
10378
run_cmd('Reference run', cmd)
10479

10580
# Import the C++ extension
106-
cmd = [python,
81+
cmd = [python_exe,
10782
'-X', 'dev',
10883
'-X', 'showrefcount',
10984
'-c', f"import {extension_name}"]

Lib/test/test_peg_generator/__init__.py

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
from test import support
44
from test.support import load_package_tests
55

6-
# TODO: gh-92584: peg_generator uses distutils which was removed in Python 3.12
7-
raise unittest.SkipTest("distutils has been removed in Python 3.12")
8-
96

107
if support.check_sanitizer(address=True, memory=True):
118
# bpo-46633: Skip the test because it is too slow when Python is built

Lib/test/test_peg_generator/test_c_parser.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import contextlib
2+
import subprocess
13
import sysconfig
24
import textwrap
35
import unittest
@@ -8,7 +10,7 @@
810

911
from test import test_tools
1012
from test import support
11-
from test.support import os_helper
13+
from test.support import os_helper, import_helper
1214
from test.support.script_helper import assert_python_ok
1315

1416
_py_cflags_nodist = sysconfig.get_config_var("PY_CFLAGS_NODIST")
@@ -88,6 +90,16 @@ def setUpClass(cls):
8890
cls.library_dir = tempfile.mkdtemp(dir=cls.tmp_base)
8991
cls.addClassCleanup(shutil.rmtree, cls.library_dir)
9092

93+
with contextlib.ExitStack() as stack:
94+
python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools_wheel("venv"))
95+
sitepackages = subprocess.check_output(
96+
[python_exe, "-c", "import sysconfig; print(sysconfig.get_path('platlib'))"],
97+
text=True,
98+
).strip()
99+
stack.enter_context(import_helper.DirsOnSysPath(sitepackages))
100+
cls.addClassCleanup(stack.pop_all().close)
101+
102+
@support.requires_venv_with_pip()
91103
def setUp(self):
92104
self._backup_config_vars = dict(sysconfig._CONFIG_VARS)
93105
cmd = support.missing_compiler_executable()

0 commit comments

Comments
 (0)