Voice et bot modif

This commit is contained in:
pi 2026-06-16 17:09:34 +00:00
parent 189d56026b
commit 7333a22bcd
10774 changed files with 634644 additions and 933308 deletions

View file

@ -535,9 +535,14 @@ class TestPyModules:
class TestExtModules:
def make_dist(self, toml_config):
pyproject = Path("pyproject.toml")
pyproject.write_text(cleandoc(toml_config), encoding="utf-8")
with pytest.warns(pyprojecttoml._ExperimentalConfiguration):
return pyprojecttoml.apply_configuration(Distribution({}), pyproject)
def test_pyproject_sets_attribute(self, tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
pyproject = Path("pyproject.toml")
toml_config = """
[project]
name = "test"
@ -547,13 +552,28 @@ class TestExtModules:
{name = "my.ext", sources = ["hello.c", "world.c"]}
]
"""
pyproject.write_text(cleandoc(toml_config), encoding="utf-8")
with pytest.warns(pyprojecttoml._ExperimentalConfiguration):
dist = pyprojecttoml.apply_configuration(Distribution({}), pyproject)
dist = self.make_dist(toml_config)
assert len(dist.ext_modules) == 1
assert dist.ext_modules[0].name == "my.ext"
assert set(dist.ext_modules[0].sources) == {"hello.c", "world.c"}
def test_pyproject_define_macros_as_tuples(self, tmp_path, monkeypatch):
# https://github.com/pypa/setuptools/issues/4810
monkeypatch.chdir(tmp_path)
toml_config = """
[project]
name = "test"
version = "42.0"
[[tool.setuptools.ext-modules]]
name = "my.ext"
sources = ["hello.c", "world.c"]
define-macros = [["FIRST_SINGLE"], ["SECOND_TWO", "1"]]
"""
dist = self.make_dist(toml_config)
assert isinstance(dist.ext_modules[0].define_macros[0], tuple)
assert dist.ext_modules[0].define_macros[0] == ("FIRST_SINGLE",)
assert dist.ext_modules[0].define_macros[1] == ("SECOND_TWO", "1")
class TestDeprecatedFields:
def test_namespace_packages(self, tmp_path):

View file

@ -286,6 +286,29 @@ class TestClassifiers:
assert "classifiers" not in expanded["project"]
class TestImportNames:
EXAMPLES = [
'import-names = ["hello", "world"]',
'import-namespaces = ["hello", "world"]',
'dynamic = ["import-names"]',
'dynamic = ["import-namespaces"]',
]
@pytest.mark.parametrize("example", EXAMPLES)
def test_not_implemented(self, monkeypatch, tmp_path, example):
monkeypatch.chdir(tmp_path)
pyproject = Path("pyproject.toml")
toml_config = f"""
[project]
name = 'proj'
version = '42'
{example}
"""
pyproject.write_text(cleandoc(toml_config), encoding="utf-8")
with pytest.raises(NotImplementedError, match='import-names'):
apply_configuration(Distribution({}), pyproject)
@pytest.mark.parametrize(
"example",
(

View file

@ -1,11 +1,10 @@
from __future__ import annotations
import functools
import importlib
import io
from email import message_from_string
from email.generator import Generator
from email.message import EmailMessage, Message
from email.message import EmailMessage
from email.parser import Parser
from email.policy import EmailPolicy
from inspect import cleandoc
@ -15,11 +14,9 @@ from unittest.mock import Mock
import jaraco.path
import pytest
from packaging.metadata import Metadata
from packaging.requirements import Requirement
from setuptools import _reqs, sic
from setuptools import sic
from setuptools._core_metadata import rfc822_escape, rfc822_unescape
from setuptools.command.egg_info import egg_info, write_requirements
from setuptools.config import expand, setupcfg
from setuptools.dist import Distribution
@ -384,36 +381,32 @@ class TestParityWithMetadataFromPyPaWheel:
yield setupcfg.apply_configuration(Distribution({}), config)
@pytest.mark.uses_network
def test_equivalent_output(self, tmp_path, dist):
"""Ensure output from setuptools is equivalent to the one from `pypa/wheel`"""
# Generate a METADATA file using pypa/wheel for comparison
wheel_metadata = importlib.import_module("wheel.metadata")
pkginfo_to_metadata = getattr(wheel_metadata, "pkginfo_to_metadata", None)
if pkginfo_to_metadata is None: # pragma: nocover
pytest.xfail(
"wheel.metadata.pkginfo_to_metadata is undefined, "
"(this is likely to be caused by API changes in pypa/wheel"
)
# Generate an simplified "egg-info" dir for pypa/wheel to convert
def test_pkg_info_roundtrip(self, tmp_path, dist):
"""Ensure PKG-INFO round trips according to pypa/wheel's methodology"""
# Generate an simplified "egg-info" with PKG-INFO
pkg_info = _get_pkginfo(dist)
egg_info_dir = tmp_path / "pkg.egg-info"
egg_info_dir.mkdir(parents=True)
(egg_info_dir / "PKG-INFO").write_text(pkg_info, encoding="utf-8")
write_requirements(egg_info(dist), egg_info_dir, egg_info_dir / "requires.txt")
# Get pypa/wheel generated METADATA but normalize requirements formatting
metadata_msg = pkginfo_to_metadata(egg_info_dir, egg_info_dir / "PKG-INFO")
metadata_str = _normalize_metadata(metadata_msg)
pkg_info_msg = message_from_string(pkg_info)
pkg_info_str = _normalize_metadata(pkg_info_msg)
# Emulate the way old versions of wheel.bdist_wheel used to parse and regenerate
# the message, then ensures the metadata generated by setuptools is compatible.
with io.StringIO(pkg_info) as buffer:
msg = Parser(EmailMessage).parse(buffer)
# Compare setuptools PKG-INFO x pypa/wheel METADATA
assert metadata_str == pkg_info_str
serialization_policy = EmailPolicy(
utf8=True,
mangle_from_=False,
max_line_length=0,
)
with io.BytesIO() as buffer:
out = io.TextIOWrapper(buffer, encoding="utf-8")
Generator(out, policy=serialization_policy).flatten(msg)
out.flush()
regenerated = buffer.getvalue()
# Make sure it parses/serializes well in pypa/wheel
_assert_roundtrip_message(pkg_info)
raw_metadata = bytes(pkg_info, "utf-8")
# Normalise newlines to avoid test errors on Windows:
raw_metadata = b"\n".join(raw_metadata.splitlines())
regenerated = b"\n".join(regenerated.splitlines())
assert regenerated == raw_metadata
class TestPEP643:
@ -542,71 +535,6 @@ def _makedist(**attrs):
return dist
def _assert_roundtrip_message(metadata: str) -> None:
"""Emulate the way wheel.bdist_wheel parses and regenerates the message,
then ensures the metadata generated by setuptools is compatible.
"""
with io.StringIO(metadata) as buffer:
msg = Parser(EmailMessage).parse(buffer)
serialization_policy = EmailPolicy(
utf8=True,
mangle_from_=False,
max_line_length=0,
)
with io.BytesIO() as buffer:
out = io.TextIOWrapper(buffer, encoding="utf-8")
Generator(out, policy=serialization_policy).flatten(msg)
out.flush()
regenerated = buffer.getvalue()
raw_metadata = bytes(metadata, "utf-8")
# Normalise newlines to avoid test errors on Windows:
raw_metadata = b"\n".join(raw_metadata.splitlines())
regenerated = b"\n".join(regenerated.splitlines())
assert regenerated == raw_metadata
def _normalize_metadata(msg: Message) -> str:
"""Allow equivalent metadata to be compared directly"""
# The main challenge regards the requirements and extras.
# Both setuptools and wheel already apply some level of normalization
# but they differ regarding which character is chosen, according to the
# following spec it should be "-":
# https://packaging.python.org/en/latest/specifications/name-normalization/
# Related issues:
# https://github.com/pypa/packaging/issues/845
# https://github.com/pypa/packaging/issues/644#issuecomment-2429813968
extras = {x.replace("_", "-"): x for x in msg.get_all("Provides-Extra", [])}
reqs = [
_normalize_req(req, extras)
for req in _reqs.parse(msg.get_all("Requires-Dist", []))
]
del msg["Requires-Dist"]
del msg["Provides-Extra"]
# Ensure consistent ord
for req in sorted(reqs):
msg["Requires-Dist"] = req
for extra in sorted(extras):
msg["Provides-Extra"] = extra
# TODO: Handle lack of PEP 643 implementation in pypa/wheel?
del msg["Metadata-Version"]
return msg.as_string()
def _normalize_req(req: Requirement, extras: dict[str, str]) -> str:
"""Allow equivalent requirement objects to be compared directly"""
as_str = str(req).replace(req.name, req.name.replace("_", "-"))
for norm, orig in extras.items():
as_str = as_str.replace(orig, norm)
return as_str
def _get_pkginfo(dist: Distribution):
with io.StringIO() as fp:
dist.metadata.write_pkg_file(fp)

View file

@ -62,6 +62,7 @@ class TestNamespaces:
with paths_on_pythonpath([str(target)]):
subprocess.check_call(develop_cmd)
@pytest.mark.xfail(reason="pkg_resources has been removed")
@pytest.mark.skipif(
bool(os.environ.get("APPVEYOR")),
reason="https://github.com/pypa/setuptools/issues/851",

View file

@ -293,8 +293,6 @@ class TestLegacyNamespaces:
venv.run(["python", "-m", "pip", "install", str(pkg_A), *opts])
venv.run(["python", "-m", "pip", "install", "-e", str(pkg_B), *opts])
venv.run(["python", "-c", f"import {ns}.pkgA; import {ns}.pkgB"])
# additionally ensure that pkg_resources import works
venv.run(["python", "-c", "import pkg_resources"])
class TestPep420Namespaces:

View file

@ -19,9 +19,9 @@ setup(
@pytest.mark.parametrize(
('flag', 'expected_level'), [("--dry-run", "INFO"), ("--verbose", "DEBUG")]
('flags', 'expected_level'), [([], "INFO"), (["--verbose"], "DEBUG")]
)
def test_verbosity_level(tmp_path, monkeypatch, flag, expected_level):
def test_verbosity_level(tmp_path, monkeypatch, flags, expected_level):
"""Make sure the correct verbosity level is set (issue #3038)"""
import setuptools # noqa: F401 # import setuptools to monkeypatch distutils
@ -35,7 +35,7 @@ def test_verbosity_level(tmp_path, monkeypatch, flag, expected_level):
setup_script = tmp_path / "setup.py"
setup_script.write_text(setup_py, encoding="utf-8")
dist = distutils.core.run_setup(setup_script, stop_after="init")
dist.script_args = [flag, "sdist"]
dist.script_args = flags + ["sdist"]
dist.parse_command_line() # <- where the log level is set
log_level = logger.getEffectiveLevel()
log_level_name = logging.getLevelName(log_level)

View file

@ -49,34 +49,6 @@ class TestNamespaces:
with paths_on_pythonpath(map(str, targets)):
subprocess.check_call(try_import)
def test_pkg_resources_import(self, tmpdir):
"""
Ensure that a namespace package doesn't break on import
of pkg_resources.
"""
pkg = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
target = tmpdir / 'packages'
target.mkdir()
install_cmd = [
sys.executable,
'-m',
'pip',
'install',
'-t',
str(target),
str(pkg),
]
with paths_on_pythonpath([str(target)]):
subprocess.check_call(install_cmd)
namespaces.make_site_dir(target)
try_import = [
sys.executable,
'-c',
'import pkg_resources',
]
with paths_on_pythonpath([str(target)]):
subprocess.check_call(try_import)
def test_namespace_package_installed_and_cwd(self, tmpdir):
"""
Installing a namespace packages but also having it in the current
@ -97,42 +69,11 @@ class TestNamespaces:
subprocess.check_call(install_cmd)
namespaces.make_site_dir(target)
# ensure that package imports and pkg_resources imports
# ensure that package imports
pkg_resources_imp = [
sys.executable,
'-c',
'import pkg_resources; import myns.pkgA',
'import myns.pkgA',
]
with paths_on_pythonpath([str(target)]):
subprocess.check_call(pkg_resources_imp, cwd=str(pkg_A))
def test_packages_in_the_same_namespace_installed_and_cwd(self, tmpdir):
"""
Installing one namespace package and also have another in the same
namespace in the current working directory, both of them must be
importable.
"""
pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
target = tmpdir / 'packages'
# use pip to install to the target directory
install_cmd = [
sys.executable,
'-m',
'pip.__main__',
'install',
str(pkg_A),
'-t',
str(target),
]
subprocess.check_call(install_cmd)
namespaces.make_site_dir(target)
# ensure that all packages import and pkg_resources imports
pkg_resources_imp = [
sys.executable,
'-c',
'import pkg_resources; import myns.pkgA; import myns.pkgB',
]
with paths_on_pythonpath([str(target)]):
subprocess.check_call(pkg_resources_imp, cwd=str(pkg_B))

View file

@ -77,30 +77,34 @@ class TestDepends:
f, _p, _i = dep.find_module('setuptools.tests')
f.close()
@needs_bytecode
def testModuleExtract(self):
from json import __version__
@pytest.fixture
def sample_module(self, monkeypatch, tmp_path):
monkeypatch.syspath_prepend(str(tmp_path))
module = "mod_with_version"
version = "2.0.9"
file = tmp_path / f"{module}.py"
file.write_text(f"__version__ = {version!r}", encoding="utf-8")
return (module, version)
assert dep.get_module_constant('json', '__version__') == __version__
@needs_bytecode
def testModuleExtract(self, sample_module):
(module, version) = sample_module
assert dep.get_module_constant(module, '__version__') == version
assert dep.get_module_constant('sys', 'version') == sys.version
assert (
dep.get_module_constant('setuptools.tests.test_setuptools', '__doc__')
== __doc__
)
assert dep.get_module_constant(__name__, '__doc__') == __doc__
@needs_bytecode
def testRequire(self):
req = Require('Json', '1.0.3', 'json')
def testRequire(self, sample_module):
(module, version) = sample_module
req = Require('GivenName', '1.0.3', module)
assert req.name == 'Json'
assert req.module == 'json'
assert req.name == 'GivenName'
assert req.module == module
assert req.requested_version == Version('1.0.3')
assert req.attribute == '__version__'
assert req.full_name() == 'Json-1.0.3'
assert req.full_name() == 'GivenName-1.0.3'
from json import __version__
assert str(req.get_version()) == __version__
assert str(req.get_version()) == version
assert req.version_ok('1.0.9')
assert not req.version_ok('0.9.1')
assert not req.version_ok('unknown')