Skip to content

Commit fe7a6a0

Browse files
committed
Remove test depending on deprecated wheel.metadata
1 parent 5cf2d08 commit fe7a6a0

File tree

1 file changed

+24
-96
lines changed

1 file changed

+24
-96
lines changed

setuptools/tests/test_core_metadata.py

Lines changed: 24 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from __future__ import annotations
22

33
import functools
4-
import importlib
54
import io
65
from email import message_from_string
76
from email.generator import Generator
8-
from email.message import EmailMessage, Message
7+
from email.message import EmailMessage
98
from email.parser import Parser
109
from email.policy import EmailPolicy
1110
from inspect import cleandoc
@@ -15,11 +14,9 @@
1514
import jaraco.path
1615
import pytest
1716
from packaging.metadata import Metadata
18-
from packaging.requirements import Requirement
1917

20-
from setuptools import _reqs, sic
18+
from setuptools import sic
2119
from setuptools._core_metadata import rfc822_escape, rfc822_unescape
22-
from setuptools.command.egg_info import egg_info, write_requirements
2320
from setuptools.config import expand, setupcfg
2421
from setuptools.dist import Distribution
2522

@@ -384,36 +381,32 @@ def dist(self, request, monkeypatch, tmp_path):
384381
yield setupcfg.apply_configuration(Distribution({}), config)
385382

386383
@pytest.mark.uses_network
387-
def test_equivalent_output(self, tmp_path, dist):
388-
"""Ensure output from setuptools is equivalent to the one from `pypa/wheel`"""
389-
# Generate a METADATA file using pypa/wheel for comparison
390-
wheel_metadata = importlib.import_module("wheel.metadata")
391-
pkginfo_to_metadata = getattr(wheel_metadata, "pkginfo_to_metadata", None)
392-
393-
if pkginfo_to_metadata is None: # pragma: nocover
394-
pytest.xfail(
395-
"wheel.metadata.pkginfo_to_metadata is undefined, "
396-
"(this is likely to be caused by API changes in pypa/wheel"
397-
)
398-
399-
# Generate an simplified "egg-info" dir for pypa/wheel to convert
384+
def test_pkg_info_roundtrip(self, tmp_path, dist):
385+
"""Ensure PKG-INFO round trips according to pypa/wheel's methodology"""
386+
# Generate an simplified "egg-info" with PKG-INFO
400387
pkg_info = _get_pkginfo(dist)
401-
egg_info_dir = tmp_path / "pkg.egg-info"
402-
egg_info_dir.mkdir(parents=True)
403-
(egg_info_dir / "PKG-INFO").write_text(pkg_info, encoding="utf-8")
404-
write_requirements(egg_info(dist), egg_info_dir, egg_info_dir / "requires.txt")
405388

406-
# Get pypa/wheel generated METADATA but normalize requirements formatting
407-
metadata_msg = pkginfo_to_metadata(egg_info_dir, egg_info_dir / "PKG-INFO")
408-
metadata_str = _normalize_metadata(metadata_msg)
409-
pkg_info_msg = message_from_string(pkg_info)
410-
pkg_info_str = _normalize_metadata(pkg_info_msg)
389+
# Emulate the way old versions of wheel.bdist_wheel used to parse and regenerate
390+
# the message, then ensures the metadata generated by setuptools is compatible.
391+
with io.StringIO(pkg_info) as buffer:
392+
msg = Parser(EmailMessage).parse(buffer)
411393

412-
# Compare setuptools PKG-INFO x pypa/wheel METADATA
413-
assert metadata_str == pkg_info_str
394+
serialization_policy = EmailPolicy(
395+
utf8=True,
396+
mangle_from_=False,
397+
max_line_length=0,
398+
)
399+
with io.BytesIO() as buffer:
400+
out = io.TextIOWrapper(buffer, encoding="utf-8")
401+
Generator(out, policy=serialization_policy).flatten(msg)
402+
out.flush()
403+
regenerated = buffer.getvalue()
414404

415-
# Make sure it parses/serializes well in pypa/wheel
416-
_assert_roundtrip_message(pkg_info)
405+
raw_metadata = bytes(pkg_info, "utf-8")
406+
# Normalise newlines to avoid test errors on Windows:
407+
raw_metadata = b"\n".join(raw_metadata.splitlines())
408+
regenerated = b"\n".join(regenerated.splitlines())
409+
assert regenerated == raw_metadata
417410

418411

419412
class TestPEP643:
@@ -542,71 +535,6 @@ def _makedist(**attrs):
542535
return dist
543536

544537

545-
def _assert_roundtrip_message(metadata: str) -> None:
546-
"""Emulate the way wheel.bdist_wheel parses and regenerates the message,
547-
then ensures the metadata generated by setuptools is compatible.
548-
"""
549-
with io.StringIO(metadata) as buffer:
550-
msg = Parser(EmailMessage).parse(buffer)
551-
552-
serialization_policy = EmailPolicy(
553-
utf8=True,
554-
mangle_from_=False,
555-
max_line_length=0,
556-
)
557-
with io.BytesIO() as buffer:
558-
out = io.TextIOWrapper(buffer, encoding="utf-8")
559-
Generator(out, policy=serialization_policy).flatten(msg)
560-
out.flush()
561-
regenerated = buffer.getvalue()
562-
563-
raw_metadata = bytes(metadata, "utf-8")
564-
# Normalise newlines to avoid test errors on Windows:
565-
raw_metadata = b"\n".join(raw_metadata.splitlines())
566-
regenerated = b"\n".join(regenerated.splitlines())
567-
assert regenerated == raw_metadata
568-
569-
570-
def _normalize_metadata(msg: Message) -> str:
571-
"""Allow equivalent metadata to be compared directly"""
572-
# The main challenge regards the requirements and extras.
573-
# Both setuptools and wheel already apply some level of normalization
574-
# but they differ regarding which character is chosen, according to the
575-
# following spec it should be "-":
576-
# https://packaging.python.org/en/latest/specifications/name-normalization/
577-
578-
# Related issues:
579-
# https://github.com/pypa/packaging/issues/845
580-
# https://github.com/pypa/packaging/issues/644#issuecomment-2429813968
581-
582-
extras = {x.replace("_", "-"): x for x in msg.get_all("Provides-Extra", [])}
583-
reqs = [
584-
_normalize_req(req, extras)
585-
for req in _reqs.parse(msg.get_all("Requires-Dist", []))
586-
]
587-
del msg["Requires-Dist"]
588-
del msg["Provides-Extra"]
589-
590-
# Ensure consistent ord
591-
for req in sorted(reqs):
592-
msg["Requires-Dist"] = req
593-
for extra in sorted(extras):
594-
msg["Provides-Extra"] = extra
595-
596-
# TODO: Handle lack of PEP 643 implementation in pypa/wheel?
597-
del msg["Metadata-Version"]
598-
599-
return msg.as_string()
600-
601-
602-
def _normalize_req(req: Requirement, extras: dict[str, str]) -> str:
603-
"""Allow equivalent requirement objects to be compared directly"""
604-
as_str = str(req).replace(req.name, req.name.replace("_", "-"))
605-
for norm, orig in extras.items():
606-
as_str = as_str.replace(orig, norm)
607-
return as_str
608-
609-
610538
def _get_pkginfo(dist: Distribution):
611539
with io.StringIO() as fp:
612540
dist.metadata.write_pkg_file(fp)

0 commit comments

Comments
 (0)