Read extras first from provides_extra, then requires_dist (closes #57)

This commit is contained in:
Karolina Surma
2025-02-25 14:56:22 +01:00
committed by Karolina Surma
parent d552ce37c9
commit 4a36396d23
4 changed files with 37 additions and 7 deletions
+3
View File
@@ -7,6 +7,9 @@ Invoke with `--compat <compat-version-string>`
- 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)
- section 'Provisional: Declarative Buildsystem (RPM 4.20+)'.
### Changed
- Package extras are now primarily read from `provides_extra`, only after that's empty from `requires_dist`
# [0.11.1] - 2024-11-21
### Changed
+1 -1
View File
@@ -53,7 +53,7 @@ def prepare_package_info(data: RawMetadata | dict) -> PackageInfo:
pypi_version=data.get("version", ""),
summary=get_summary_or_placeholder(data.get("summary", "")),
url=resolve_url(project_urls),
extras=get_extras(data.get("requires_dist", [])),
extras=get_extras(data.get("provides_extra", []), data.get("requires_dist", [])),
license_files_present=bool(data.get("license_files")),
license=resolve_license_expression(data)
)
+9 -4
View File
@@ -99,17 +99,22 @@ def get_summary_or_placeholder(summary: str) -> str:
return summary
def get_extras(requires_dist: list) -> list:
def get_extras(provides_extra: list, requires_dist: list) -> list:
"""Return the sorted list of the found extras names.
Packages define extras explicitly via `Provides-Extra` and
indirectly via `Requires-Dist` metadata.
PyPI metadata doesn't provide the first one, but it is possible to
derive extras names from the `requires_dist` key.
Try to read them from `provides_extra` first.
PyPI metadata doesn't publish `provides_extra` for the older releases,
but it is possible to derive extras names from the `requires_dist` key.
Example value of `requires_dist`:
["sphinxcontrib-websupport ; extra == 'docs'", "flake8>=3.5.0 ; extra == 'lint'"]
If package defines an extra with no requirements, we can't detect that.
If a package defines an extra with no requirements,
we can't detect that from requires_dist.
"""
if provides_extra:
return sorted(provides_extra)
extra_from_req = re.compile(r'''\bextra\s+==\s+["']([^"']+)["']''')
extras = set()
if requires_dist:
+24 -2
View File
@@ -37,7 +37,7 @@ def test_python_name(pypi_name, alt_version, expected):
assert prepend_name_with_python(normalize_name(pypi_name), alt_version) == expected
def test_extras_detected_correctly():
def test_extras_detected_correctly_from_requires_dist():
requires_dist = [
"foo ; platform_system == 'Windows'",
"bar ; python_version < '3.8'",
@@ -49,7 +49,29 @@ def test_extras_detected_correctly():
"eggs>=2.12; implementation_name != 'pypy' and extra == 'dev'",
]
assert get_extras(requires_dist) == ["dev", "docs", "lint", "test"]
assert get_extras([], requires_dist) == ["dev", "docs", "lint", "test"]
def test_extras_detected_correctly_from_provides_extra():
provides_extra = ['docs', 'lint', 'dev', 'foo']
requires_dist = [
"foo ; platform_system == 'Windows'",
"bar ; python_version < '3.8'",
"baz",
"foobar ; extra == 'docs'",
"foobaz>=5.3.1",
"spam>=3.5.0 ; extra == 'lint'",
"ham[eggs]>=0.10; extra == 'test'",
"eggs>=2.12; implementation_name != 'pypy' and extra == 'dev'",
]
assert get_extras(provides_extra, requires_dist) == ["dev", "docs", "foo", "lint"]
def test_extras_detected_correctly_from_provides_extra_no_requires():
provides_extra = ['docs', 'lint', 'dev', 'foo']
# this is improbable, but let's be sure we read from the provides_extra without issues
requires_dist = []
assert get_extras(provides_extra, requires_dist) == ["dev", "docs", "foo", "lint"]
@pytest.mark.parametrize(