Skip to content

Commit 5ed19c7

Browse files
committed
Test parity between setuptools PKG-INFO and wheel METADATA
1 parent e088465 commit 5ed19c7

File tree

1 file changed

+83
-1
lines changed

1 file changed

+83
-1
lines changed

setuptools/tests/test_core_metadata.py

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import functools
22
import io
3+
import importlib
4+
from email import message_from_string
35

46
import pytest
57

6-
from setuptools import sic
8+
from setuptools import sic, _reqs
79
from setuptools.dist import Distribution
810
from setuptools._core_metadata import rfc822_escape, rfc822_unescape
11+
from setuptools.command.egg_info import egg_info, write_requirements
912

1013

1114
EXAMPLE_BASE_INFO = dict(
@@ -296,3 +299,82 @@ def test_maintainer_author(name, attrs, tmpdir):
296299
else:
297300
line = '%s: %s' % (fkey, val)
298301
assert line in pkg_lines_set
302+
303+
304+
def test_parity_with_metadata_from_pypa_wheel(tmp_path):
305+
attrs = dict(
306+
**EXAMPLE_BASE_INFO,
307+
# Example with complex requirement definition
308+
python_requires=">=3.8",
309+
install_requires="""
310+
packaging==23.0
311+
ordered-set==3.1.1
312+
more-itertools==8.8.0; extra == "other"
313+
jaraco.text==3.7.0
314+
importlib-resources==5.10.2; python_version<"3.8"
315+
importlib-metadata==6.0.0 ; python_version<"3.8"
316+
colorama>=0.4.4; sys_platform == "win32"
317+
""",
318+
extras_require={
319+
"testing": """
320+
pytest >= 6
321+
pytest-checkdocs >= 2.4
322+
pytest-flake8 ; \\
323+
# workaround for tholo/pytest-flake8#87
324+
python_version < "3.12"
325+
ini2toml[lite]>=0.9
326+
""",
327+
"other": [],
328+
}
329+
)
330+
# Generate a PKG-INFO file using setuptools
331+
dist = Distribution(attrs)
332+
with io.StringIO() as fp:
333+
dist.metadata.write_pkg_file(fp)
334+
pkg_info = fp.getvalue()
335+
336+
# Ensure Requires-Dist is present
337+
expected = [
338+
'Metadata-Version:',
339+
'Requires-Python: >=3.8',
340+
'Provides-Extra: other',
341+
'Provides-Extra: testing',
342+
'Requires-Dist: pytest-flake8; python_version < "3.12" and extra == "testing"',
343+
'Requires-Dist: more-itertools==8.8.0; extra == "other"',
344+
'Requires-Dist: ini2toml[lite]>=0.9; extra == "testing"',
345+
]
346+
for line in expected:
347+
assert line in pkg_info
348+
349+
# Generate a METADATA file using pypa/wheel for comparisson
350+
wheel_metadata = importlib.import_module("wheel.metadata")
351+
pkginfo_to_metadata = getattr(wheel_metadata, "pkginfo_to_metadata", None)
352+
353+
if pkginfo_to_metadata is None:
354+
pytest.xfail(
355+
"wheel.metadata.pkginfo_to_metadata is undefined, "
356+
"(this is likely to be caused by API changes in pypa/wheel"
357+
)
358+
359+
# Generate an simplified "egg-info" dir for pypa/wheel to convert
360+
egg_info_dir = tmp_path / "pkg.egg-info"
361+
egg_info_dir.mkdir(parents=True)
362+
(egg_info_dir / "PKG-INFO").write_text(pkg_info, encoding="utf-8")
363+
write_requirements(egg_info(dist), egg_info_dir, egg_info_dir / "requires.txt")
364+
365+
# Get pypa/wheel generated METADATA but normalize requirements formatting
366+
metadata_msg = pkginfo_to_metadata(egg_info_dir, egg_info_dir / "PKG-INFO")
367+
metadata_deps = set(_reqs.parse(metadata_msg.get_all("Requires-Dist")))
368+
metadata_extras = set(metadata_msg.get_all("Provides-Extra"))
369+
del metadata_msg["Requires-Dist"]
370+
del metadata_msg["Provides-Extra"]
371+
pkg_info_msg = message_from_string(pkg_info)
372+
pkg_info_deps = set(_reqs.parse(pkg_info_msg.get_all("Requires-Dist")))
373+
pkg_info_extras = set(pkg_info_msg.get_all("Provides-Extra"))
374+
del pkg_info_msg["Requires-Dist"]
375+
del pkg_info_msg["Provides-Extra"]
376+
377+
# Compare setuptools PKG-INFO x pypa/wheel METADATA
378+
assert metadata_msg.as_string() == pkg_info_msg.as_string()
379+
assert metadata_deps == pkg_info_deps
380+
assert metadata_extras == pkg_info_extras

0 commit comments

Comments
 (0)