Skip to content

Commit 8e9c330

Browse files
committed
Test parity between setuptools PKG-INFO and wheel METADATA
1 parent f930f71 commit 8e9c330

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(
@@ -243,3 +246,82 @@ def test_maintainer_author(name, attrs, tmpdir):
243246
else:
244247
line = '%s: %s' % (fkey, val)
245248
assert line in pkg_lines_set
249+
250+
251+
def test_parity_with_metadata_from_pypa_wheel(tmp_path):
252+
attrs = dict(
253+
**EXAMPLE_BASE_INFO,
254+
# Example with complex requirement definition
255+
python_requires=">=3.8",
256+
install_requires="""
257+
packaging==23.0
258+
ordered-set==3.1.1
259+
more-itertools==8.8.0; extra == "other"
260+
jaraco.text==3.7.0
261+
importlib-resources==5.10.2; python_version<"3.8"
262+
importlib-metadata==6.0.0 ; python_version<"3.8"
263+
colorama>=0.4.4; sys_platform == "win32"
264+
""",
265+
extras_require={
266+
"testing": """
267+
pytest >= 6
268+
pytest-checkdocs >= 2.4
269+
pytest-flake8 ; \\
270+
# workaround for tholo/pytest-flake8#87
271+
python_version < "3.12"
272+
ini2toml[lite]>=0.9
273+
""",
274+
"other": [],
275+
}
276+
)
277+
# Generate a PKG-INFO file using setuptools
278+
dist = Distribution(attrs)
279+
with io.StringIO() as fp:
280+
dist.metadata.write_pkg_file(fp)
281+
pkg_info = fp.getvalue()
282+
283+
# Ensure Requires-Dist is present
284+
expected = [
285+
'Metadata-Version:',
286+
'Requires-Python: >=3.8',
287+
'Provides-Extra: other',
288+
'Provides-Extra: testing',
289+
'Requires-Dist: pytest-flake8; python_version < "3.12" and extra == "testing"',
290+
'Requires-Dist: more-itertools==8.8.0; extra == "other"',
291+
'Requires-Dist: ini2toml[lite]>=0.9; extra == "testing"',
292+
]
293+
for line in expected:
294+
assert line in pkg_info
295+
296+
# Generate a METADATA file using pypa/wheel for comparisson
297+
wheel_metadata = importlib.import_module("wheel.metadata")
298+
pkginfo_to_metadata = getattr(wheel_metadata, "pkginfo_to_metadata", None)
299+
300+
if pkginfo_to_metadata is None:
301+
pytest.xfail(
302+
"wheel.metadata.pkginfo_to_metadata is undefined, "
303+
"(this is likely to be caused by API changes in pypa/wheel"
304+
)
305+
306+
# Generate an simplified "egg-info" dir for pypa/wheel to convert
307+
egg_info_dir = tmp_path / "pkg.egg-info"
308+
egg_info_dir.mkdir(parents=True)
309+
(egg_info_dir / "PKG-INFO").write_text(pkg_info, encoding="utf-8")
310+
write_requirements(egg_info(dist), egg_info_dir, egg_info_dir / "requires.txt")
311+
312+
# Get pypa/wheel generated METADATA but normalize requirements formatting
313+
metadata_msg = pkginfo_to_metadata(egg_info_dir, egg_info_dir / "PKG-INFO")
314+
metadata_deps = set(_reqs.parse(metadata_msg.get_all("Requires-Dist")))
315+
metadata_extras = set(metadata_msg.get_all("Provides-Extra"))
316+
del metadata_msg["Requires-Dist"]
317+
del metadata_msg["Provides-Extra"]
318+
pkg_info_msg = message_from_string(pkg_info)
319+
pkg_info_deps = set(_reqs.parse(pkg_info_msg.get_all("Requires-Dist")))
320+
pkg_info_extras = set(pkg_info_msg.get_all("Provides-Extra"))
321+
del pkg_info_msg["Requires-Dist"]
322+
del pkg_info_msg["Provides-Extra"]
323+
324+
# Compare setuptools PKG-INFO x pypa/wheel METADATA
325+
assert metadata_msg.as_string() == pkg_info_msg.as_string()
326+
assert metadata_deps == pkg_info_deps
327+
assert metadata_extras == pkg_info_extras

0 commit comments

Comments
 (0)