Skip to content

Commit 4a36396

Browse files
committed
Read extras first from provides_extra, then requires_dist (closes #57)
1 parent d552ce3 commit 4a36396

File tree

4 files changed

+37
-7
lines changed

4 files changed

+37
-7
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ Invoke with `--compat <compat-version-string>`
77
- Support for pyproject declarative buildsystem, [rpm documentation](https://rpm-software-management.github.io/rpm/manual/buildsystem.html), [pyproject-rpm-macros documentation](https://src.fedoraproject.org/rpms/pyproject-rpm-macros)
88
- section 'Provisional: Declarative Buildsystem (RPM 4.20+)'.
99

10+
### Changed
11+
- Package extras are now primarily read from `provides_extra`, only after that's empty from `requires_dist`
12+
1013

1114
# [0.11.1] - 2024-11-21
1215
### Changed

pyp2spec/pyp2conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def prepare_package_info(data: RawMetadata | dict) -> PackageInfo:
5353
pypi_version=data.get("version", ""),
5454
summary=get_summary_or_placeholder(data.get("summary", "")),
5555
url=resolve_url(project_urls),
56-
extras=get_extras(data.get("requires_dist", [])),
56+
extras=get_extras(data.get("provides_extra", []), data.get("requires_dist", [])),
5757
license_files_present=bool(data.get("license_files")),
5858
license=resolve_license_expression(data)
5959
)

pyp2spec/utils.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,22 @@ def get_summary_or_placeholder(summary: str) -> str:
9999
return summary
100100

101101

102-
def get_extras(requires_dist: list) -> list:
102+
def get_extras(provides_extra: list, requires_dist: list) -> list:
103103
"""Return the sorted list of the found extras names.
104104
105105
Packages define extras explicitly via `Provides-Extra` and
106106
indirectly via `Requires-Dist` metadata.
107-
PyPI metadata doesn't provide the first one, but it is possible to
108-
derive extras names from the `requires_dist` key.
107+
Try to read them from `provides_extra` first.
108+
PyPI metadata doesn't publish `provides_extra` for the older releases,
109+
but it is possible to derive extras names from the `requires_dist` key.
109110
Example value of `requires_dist`:
110111
["sphinxcontrib-websupport ; extra == 'docs'", "flake8>=3.5.0 ; extra == 'lint'"]
111-
If package defines an extra with no requirements, we can't detect that.
112+
If a package defines an extra with no requirements,
113+
we can't detect that from requires_dist.
112114
"""
115+
if provides_extra:
116+
return sorted(provides_extra)
117+
113118
extra_from_req = re.compile(r'''\bextra\s+==\s+["']([^"']+)["']''')
114119
extras = set()
115120
if requires_dist:

tests/test_utils.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def test_python_name(pypi_name, alt_version, expected):
3737
assert prepend_name_with_python(normalize_name(pypi_name), alt_version) == expected
3838

3939

40-
def test_extras_detected_correctly():
40+
def test_extras_detected_correctly_from_requires_dist():
4141
requires_dist = [
4242
"foo ; platform_system == 'Windows'",
4343
"bar ; python_version < '3.8'",
@@ -49,7 +49,29 @@ def test_extras_detected_correctly():
4949
"eggs>=2.12; implementation_name != 'pypy' and extra == 'dev'",
5050
]
5151

52-
assert get_extras(requires_dist) == ["dev", "docs", "lint", "test"]
52+
assert get_extras([], requires_dist) == ["dev", "docs", "lint", "test"]
53+
54+
55+
def test_extras_detected_correctly_from_provides_extra():
56+
provides_extra = ['docs', 'lint', 'dev', 'foo']
57+
requires_dist = [
58+
"foo ; platform_system == 'Windows'",
59+
"bar ; python_version < '3.8'",
60+
"baz",
61+
"foobar ; extra == 'docs'",
62+
"foobaz>=5.3.1",
63+
"spam>=3.5.0 ; extra == 'lint'",
64+
"ham[eggs]>=0.10; extra == 'test'",
65+
"eggs>=2.12; implementation_name != 'pypy' and extra == 'dev'",
66+
]
67+
assert get_extras(provides_extra, requires_dist) == ["dev", "docs", "foo", "lint"]
68+
69+
70+
def test_extras_detected_correctly_from_provides_extra_no_requires():
71+
provides_extra = ['docs', 'lint', 'dev', 'foo']
72+
# this is improbable, but let's be sure we read from the provides_extra without issues
73+
requires_dist = []
74+
assert get_extras(provides_extra, requires_dist) == ["dev", "docs", "foo", "lint"]
5375

5476

5577
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)