python3Packages.pip-requirements-parser: fix build with packaging 26 (#523135)

This commit is contained in:
Fabian Affolter
2026-05-22 23:40:11 +00:00
committed by GitHub
2 changed files with 132 additions and 7 deletions
@@ -5,26 +5,39 @@
packaging,
pyparsing,
pytestCheckHook,
setuptools,
setuptools-scm,
}:
buildPythonPackage rec {
buildPythonPackage (finalAttrs: {
pname = "pip-requirements-parser";
version = "32.0.1";
format = "setuptools";
pyproject = true;
src = fetchFromGitHub {
owner = "nexB";
repo = "pip-requirements-parser";
tag = "v${version}";
tag = "v${finalAttrs.version}";
hash = "sha256-UMrwDXxk+sD3P2jk7s95y4OX6DRBjWWZZ8IhkR6tnZ4=";
};
patches = [
# packaging 26.0 changed the string representation of requirements with
# URLs to contain an extra space before the `@`.
# https://github.com/pypa/packaging/pull/953
# https://github.com/aboutcode-org/pip-requirements-parser/issues/27
# https://github.com/aboutcode-org/pip-requirements-parser/pull/28
./packaging-26.patch
];
dontConfigure = true;
nativeBuildInputs = [ setuptools-scm ];
build-system = [
setuptools
setuptools-scm
];
propagatedBuildInputs = [
dependencies = [
packaging
pyparsing
];
@@ -42,8 +55,8 @@ buildPythonPackage rec {
meta = {
description = "Module to parse pip requirements";
homepage = "https://github.com/nexB/pip-requirements-parser";
changelog = "https://github.com/nexB/pip-requirements-parser/blob/v${version}/CHANGELOG.rst";
changelog = "https://github.com/nexB/pip-requirements-parser/blob/${finalAttrs.src.tag}/CHANGELOG.rst";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ fab ];
};
}
})
@@ -0,0 +1,112 @@
From b50963dfe2b8ecd57dab9627b19d5616c369a044 Mon Sep 17 00:00:00 2001
From: Steve Kowalik <steven@wedontsleep.org>
Date: Mon, 2 Feb 2026 12:56:48 +1100
Subject: [PATCH] Support packaging 26.0 changes
Packaging 26.0 changed the string representation of requirements with
URLs, sprinkle in more spaces.
Closes #27
Signed-off-by: Steve Kowalik <steven@wedontsleep.org>
---
tests/pip_requirements_parser_tests/unit/test_req.py | 4 ++--
.../unit/test_req_file.py | 10 +++++-----
tests/test_pip_api_parse_requirements.py | 8 ++++----
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/tests/pip_requirements_parser_tests/unit/test_req.py b/tests/pip_requirements_parser_tests/unit/test_req.py
index 1348fcab..f811045b 100644
--- a/tests/pip_requirements_parser_tests/unit/test_req.py
+++ b/tests/pip_requirements_parser_tests/unit/test_req.py
@@ -44,13 +44,13 @@ def test_url_with_query(self) -> None:
def test_pep440_wheel_link_requirement(self) -> None:
line = "test @ https://whatever.com/test-0.4-py2.py3-bogus-any.whl"
req = build_install_req(line)
- assert str(req.req) == "test@ https://whatever.com/test-0.4-py2.py3-bogus-any.whl"
+ assert str(req.req) == "test @ https://whatever.com/test-0.4-py2.py3-bogus-any.whl"
assert str(req.link) == "https://whatever.com/test-0.4-py2.py3-bogus-any.whl"
def test_pep440_url_link_requirement(self) -> None:
line = "foo @ git+http://foo.com@ref#egg=foo"
req = build_install_req(line)
- assert str(req.req) == "foo@ git+http://foo.com@ref#egg=foo"
+ assert str(req.req) == "foo @ git+http://foo.com@ref#egg=foo"
assert str(req.link) == "git+http://foo.com@ref#egg=foo"
def test_url_with_authentication_link_requirement(self) -> None:
diff --git a/tests/pip_requirements_parser_tests/unit/test_req_file.py b/tests/pip_requirements_parser_tests/unit/test_req_file.py
index 4ac6375b..d71108d1 100644
--- a/tests/pip_requirements_parser_tests/unit/test_req_file.py
+++ b/tests/pip_requirements_parser_tests/unit/test_req_file.py
@@ -358,7 +358,7 @@ def test_parse_name_at_url_to_wheel_with_packaging(self, parse_requirement_text)
assert r.name == "SomeProject"
assert not r.specifier
assert r.extras == set()
- assert str(r) == "SomeProject@ http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
+ assert str(r) == "SomeProject @ http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
def test_parse_name_at_url__with_packaging(self, parse_requirement_text) -> None:
from packaging.requirements import Requirement
@@ -369,7 +369,7 @@ def test_parse_name_at_url__with_packaging(self, parse_requirement_text) -> None
assert r.name == "SomeProject"
assert not r.specifier
assert r.extras == set()
- assert str(r) == "SomeProject@ http://my.package.repo/SomeProject2.tgz"
+ assert str(r) == "SomeProject @ http://my.package.repo/SomeProject2.tgz"
def test_parse_name_at_vcs_url_to_wheel_with_packaging(self, parse_requirement_text) -> None:
from packaging.requirements import Requirement
@@ -380,7 +380,7 @@ def test_parse_name_at_vcs_url_to_wheel_with_packaging(self, parse_requirement_t
assert r.name == "SomeProject"
assert not r.specifier
assert r.extras == set()
- assert str(r) == "SomeProject@ git+http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
+ assert str(r) == "SomeProject @ git+http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
def test_can_dumps_name_at_url_to_wheel(self, parse_requirement_text) -> None:
text = "SomeProject@http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
@@ -394,7 +394,7 @@ def test_can_dumps_name_at_url_to_wheel(self, parse_requirement_text) -> None:
assert not r.specifier
assert r.link.url == "http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
assert r.extras == set()
- assert str(r.req) == "SomeProject@ http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
+ assert str(r.req) == "SomeProject @ http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
assert r.dumps() == text
def test_can_dumps_name_at_url_to_wheel_with_space(self, parse_requirement_text) -> None:
@@ -409,7 +409,7 @@ def test_can_dumps_name_at_url_to_wheel_with_space(self, parse_requirement_text)
assert not r.specifier
assert r.link.url == "http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
assert r.extras == set()
- assert str(r.req) == "SomeProject@ http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
+ assert str(r.req) == "SomeProject @ http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
assert r.dumps() == "SomeProject@http://my.package.repo/SomeProject2-1.2.3-py33-none-any.whl"
def test_can_dumps_name_at_vcs_url_to_wheel(self, parse_requirement_text) -> None:
diff --git a/tests/test_pip_api_parse_requirements.py b/tests/test_pip_api_parse_requirements.py
index 974f6401..e9afe892 100644
--- a/tests/test_pip_api_parse_requirements.py
+++ b/tests/test_pip_api_parse_requirements.py
@@ -114,8 +114,8 @@ class Pep508Test(NamedTuple):
req_name="pip",
req_url="https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
link_url="https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
- # Note extra space after @
- req_string="pip@ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
+ # Note extra space before and after @
+ req_string="pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
req_spec="",
),
Pep508Test(
@@ -124,8 +124,8 @@ class Pep508Test(NamedTuple):
req_name="pip",
req_url="https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
link_url="https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
- # Note extra space after @
- req_string="pip@ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
+ # Note extra space before and after @
+ req_string="pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4",
req_spec="",
),
Pep508Test(