Skip to content

[3.12] gh-100238: Use setuptools in peg-generator and reenable tests (GH-104798) #105135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1868,15 +1868,16 @@ def missing_compiler_executable(cmd_names=[]):
missing.

"""
# TODO (PEP 632): alternate check without using distutils
from distutils import ccompiler, sysconfig, spawn, errors
from setuptools._distutils import ccompiler, sysconfig, spawn
from setuptools import errors

compiler = ccompiler.new_compiler()
sysconfig.customize_compiler(compiler)
if compiler.compiler_type == "msvc":
# MSVC has no executables, so check whether initialization succeeds
try:
compiler.initialize()
except errors.DistutilsPlatformError:
except errors.PlatformError:
return "msvc"
for name in compiler.executables:
if cmd_names and name not in cmd_names:
Expand Down
3 changes: 0 additions & 3 deletions Lib/test/test_peg_generator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
from test import support
from test.support import load_package_tests

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


if support.check_sanitizer(address=True, memory=True):
# bpo-46633: Skip the test because it is too slow when Python is built
Expand Down
14 changes: 13 additions & 1 deletion Lib/test/test_peg_generator/test_c_parser.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import contextlib
import subprocess
import sysconfig
import textwrap
import unittest
Expand All @@ -8,7 +10,7 @@

from test import test_tools
from test import support
from test.support import os_helper
from test.support import os_helper, import_helper
from test.support.script_helper import assert_python_ok

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

with contextlib.ExitStack() as stack:
python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools_wheel("venv"))
sitepackages = subprocess.check_output(
[python_exe, "-c", "import sysconfig; print(sysconfig.get_path('platlib'))"],
text=True,
).strip()
stack.enter_context(import_helper.DirsOnSysPath(sitepackages))
cls.addClassCleanup(stack.pop_all().close)

@support.requires_venv_with_pip()
def setUp(self):
self._backup_config_vars = dict(sysconfig._CONFIG_VARS)
cmd = support.missing_compiler_executable()
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_peg_generator/test_pegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ def test_soft_keyword(self) -> None:
start:
| "number" n=NUMBER { eval(n.string) }
| "string" n=STRING { n.string }
| SOFT_KEYWORD l=NAME n=(NUMBER | NAME | STRING) { f"{l.string} = {n.string}"}
| SOFT_KEYWORD l=NAME n=(NUMBER | NAME | STRING) { l.string + " = " + n.string }
"""
parser_class = make_parser(grammar)
self.assertEqual(parse_string("number 1", parser_class), 1)
Expand Down
54 changes: 47 additions & 7 deletions Tools/peg_generator/pegen/build.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import itertools
import os
import pathlib
import sys
import sysconfig
Expand Down Expand Up @@ -27,6 +28,46 @@ def get_extra_flags(compiler_flags: str, compiler_py_flags_nodist: str) -> List[
return f"{flags} {py_flags_nodist}".split()


def fixup_build_ext(cmd):
"""Function needed to make build_ext tests pass.

When Python was built with --enable-shared on Unix, -L. is not enough to
find libpython<blah>.so, because regrtest runs in a tempdir, not in the
source directory where the .so lives.

When Python was built with in debug mode on Windows, build_ext commands
need their debug attribute set, and it is not done automatically for
some reason.

This function handles both of these things. Example use:

cmd = build_ext(dist)
support.fixup_build_ext(cmd)
cmd.ensure_finalized()

Unlike most other Unix platforms, Mac OS X embeds absolute paths
to shared libraries into executables, so the fixup is not needed there.

Taken from distutils (was part of the CPython stdlib until Python 3.11)
"""
if os.name == 'nt':
cmd.debug = sys.executable.endswith('_d.exe')
elif sysconfig.get_config_var('Py_ENABLE_SHARED'):
# To further add to the shared builds fun on Unix, we can't just add
# library_dirs to the Extension() instance because that doesn't get
# plumbed through to the final compiler command.
runshared = sysconfig.get_config_var('RUNSHARED')
if runshared is None:
cmd.library_dirs = ['.']
else:
if sys.platform == 'darwin':
cmd.library_dirs = []
else:
name, equals, value = runshared.partition('=')
cmd.library_dirs = [d for d in value.split(os.pathsep) if d]



def compile_c_extension(
generated_source_path: str,
build_dir: Optional[str] = None,
Expand All @@ -49,16 +90,15 @@ def compile_c_extension(
static library of the common parser sources (this is useful in case you are
creating multiple extensions).
"""
import distutils.log
from distutils.core import Distribution, Extension
from distutils.tests.support import fixup_build_ext # type: ignore
import setuptools.logging

from distutils.ccompiler import new_compiler
from distutils.dep_util import newer_group
from distutils.sysconfig import customize_compiler
from setuptools import Extension, Distribution
from setuptools._distutils.dep_util import newer_group
from setuptools._distutils.ccompiler import new_compiler
from setuptools._distutils.sysconfig import customize_compiler

if verbose:
distutils.log.set_threshold(distutils.log.DEBUG)
setuptools.logging.set_threshold(setuptools.logging.logging.DEBUG)

source_file_path = pathlib.Path(generated_source_path)
extension_name = source_file_path.stem
Expand Down