Skip to content

Commit

Permalink
[3.12] gh-105084: Tests: Use setuptools+wheel from sysconfig.get_conf…
Browse files Browse the repository at this point in the history
…ig_var('WHEEL_PKG_DIR') if set (#105056) (#105424)

Includes part of the changes from afa759f,
to make this apply.

Co-Authored-By: Lysandros Nikolaou <lisandrosnik@gmail.com>

(cherry picked from commit bd98b65)
  • Loading branch information
hroncok committed Jun 13, 2023
1 parent 92929fd commit 04b9168
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 33 deletions.
56 changes: 56 additions & 0 deletions Lib/test/support/__init__.py
Expand Up @@ -2270,6 +2270,62 @@ def requires_venv_with_pip():
return unittest.skipUnless(ctypes, 'venv: pip requires ctypes')


@functools.cache
def _findwheel(pkgname):
"""Try to find a wheel with the package specified as pkgname.
If set, the wheels are searched for in WHEEL_PKG_DIR (see ensurepip).
Otherwise, they are searched for in the test directory.
"""
wheel_dir = sysconfig.get_config_var('WHEEL_PKG_DIR') or TEST_HOME_DIR
filenames = os.listdir(wheel_dir)
filenames = sorted(filenames, reverse=True) # approximate "newest" first
for filename in filenames:
# filename is like 'setuptools-67.6.1-py3-none-any.whl'
if not filename.endswith(".whl"):
continue
prefix = pkgname + '-'
if filename.startswith(prefix):
return os.path.join(wheel_dir, filename)
raise FileNotFoundError(f"No wheel for {pkgname} found in {wheel_dir}")


# Context manager that creates a virtual environment, install setuptools and wheel in it
# and returns the path to the venv directory and the path to the python executable
@contextlib.contextmanager
def setup_venv_with_pip_setuptools_wheel(venv_dir):
import subprocess
from .os_helper import temp_cwd

with temp_cwd() as temp_dir:
# Create virtual environment to get setuptools
cmd = [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir]
if verbose:
print()
print('Run:', ' '.join(cmd))
subprocess.run(cmd, check=True)

venv = os.path.join(temp_dir, venv_dir)

# Get the Python executable of the venv
python_exe = os.path.basename(sys.executable)
if sys.platform == 'win32':
python = os.path.join(venv, 'Scripts', python_exe)
else:
python = os.path.join(venv, 'bin', python_exe)

cmd = [python, '-X', 'dev',
'-m', 'pip', 'install',
_findwheel('setuptools'),
_findwheel('wheel')]
if verbose:
print()
print('Run:', ' '.join(cmd))
subprocess.run(cmd, check=True)

yield python


# True if Python is built with the Py_DEBUG macro defined: if
# Python is built in debug mode (./configure --with-pydebug).
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
Expand Down
41 changes: 8 additions & 33 deletions Lib/test/test_cppext.py
Expand Up @@ -35,39 +35,20 @@ def test_build_cpp03(self):
# the test uses venv+pip: skip if it's not available
@support.requires_venv_with_pip()
def check_build(self, std_cpp03, extension_name):
# Build in a temporary directory
with os_helper.temp_cwd():
self._check_build(std_cpp03, extension_name)
venv_dir = 'env'
with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe:
self._check_build(std_cpp03, extension_name, python_exe)

def _check_build(self, std_cpp03, extension_name):
def _check_build(self, std_cpp03, extension_name, python_exe):
pkg_dir = 'pkg'
os.mkdir(pkg_dir)
shutil.copy(SETUP_TESTCPPEXT, os.path.join(pkg_dir, "setup.py"))

venv_dir = 'env'
verbose = support.verbose

# Create virtual environment to get setuptools
cmd = [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir]
if verbose:
print()
print('Run:', ' '.join(cmd))
subprocess.run(cmd, check=True)

# Get the Python executable of the venv
python_exe = 'python'
if sys.executable.endswith('.exe'):
python_exe += '.exe'
if MS_WINDOWS:
python = os.path.join(venv_dir, 'Scripts', python_exe)
else:
python = os.path.join(venv_dir, 'bin', python_exe)

def run_cmd(operation, cmd):
env = os.environ.copy()
env['CPYTHON_TEST_CPP_STD'] = 'c++03' if std_cpp03 else 'c++11'
env['CPYTHON_TEST_EXT_NAME'] = extension_name
if verbose:
if support.verbose:
print('Run:', ' '.join(cmd))
subprocess.run(cmd, check=True, env=env)
else:
Expand All @@ -81,29 +62,23 @@ def run_cmd(operation, cmd):
self.fail(
f"{operation} failed with exit code {proc.returncode}")

cmd = [python, '-X', 'dev',
'-m', 'pip', 'install',
support.findfile('setuptools-67.6.1-py3-none-any.whl'),
support.findfile('wheel-0.40.0-py3-none-any.whl')]
run_cmd('Install build dependencies', cmd)

# Build and install the C++ extension
cmd = [python, '-X', 'dev',
cmd = [python_exe, '-X', 'dev',
'-m', 'pip', 'install', '--no-build-isolation',
os.path.abspath(pkg_dir)]
run_cmd('Install', cmd)

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

# Import the C++ extension
cmd = [python,
cmd = [python_exe,
'-X', 'dev',
'-X', 'showrefcount',
'-c', f"import {extension_name}"]
Expand Down
@@ -0,0 +1,3 @@
When the Python build is configured ``--with-wheel-pkg-dir``, tests
requiring the ``setuptools`` and ``wheel`` wheels will search for the wheels
in ``WHEEL_PKG_DIR``.

0 comments on commit 04b9168

Please sign in to comment.