diff --git a/.gitignore b/.gitignore index 71b8b4c..78062d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /test-sources-2020-04-29.tar.gz +/__pycache__/ /tests/__pycache__/ /tests/data/scripts_pythondistdeps/usr/ +/test-sources-2021-03-11.tar.gz diff --git a/python-rpm-generators.spec b/python-rpm-generators.spec index 7550178..24994bf 100644 --- a/python-rpm-generators.spec +++ b/python-rpm-generators.spec @@ -1,7 +1,7 @@ Name: python-rpm-generators Summary: Dependency generators for Python RPMs Version: 12 -Release: 3%{?dist} +Release: 4%{?dist} # Originally all those files were part of RPM, so license is kept here License: GPLv2+ @@ -47,6 +47,10 @@ install -Dpm0755 -t %{buildroot}%{_rpmconfigdir} *.py %{_rpmconfigdir}/pythonbundles.py %changelog +* Thu Mar 11 2021 Tomas Orsava - 12-4 +- scripts/pythondistdeps: Treat extras names case-insensitively and always + output them in lower case (#1936875) + * Mon Feb 22 2021 Tomas Orsava - 12-3 - scripts/pythondistdeps: Fix for Python 3.10 diff --git a/pythondistdeps.py b/pythondistdeps.py index 9ba0590..f38f726 100755 --- a/pythondistdeps.py +++ b/pythondistdeps.py @@ -21,6 +21,26 @@ from warnings import warn from packaging.requirements import Requirement as Requirement_ from packaging.version import parse +import packaging.markers + +# Monkey patching packaging.markers to handle extras names in a +# case-insensitive manner: +# pip considers dnspython[DNSSEC] and dnspython[dnssec] to be equal, but +# packaging markers treat extras in a case-sensitive manner. To solve this +# issue, we introduce a comparison operator that compares case-insensitively +# if both sides of the comparison are strings. And then we inject this +# operator into packaging.markers to be used when comparing names of extras. +# Fedora BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1936875 +# Upstream issue: https://discuss.python.org/t/what-extras-names-are-treated-as-equal-and-why/7614 +# - After it's established upstream what is the canonical form of an extras +# name, we plan to open an issue with packaging to hopefully solve this +# there without having to resort to monkeypatching. +def str_lower_eq(a, b): + if isinstance(a, str) and isinstance(b, str): + return a.lower() == b.lower() + else: + return a == b +packaging.markers._operators["=="] = str_lower_eq try: from importlib.metadata import PathDistribution @@ -57,7 +77,7 @@ class Distribution(PathDistribution): self.legacy_normalized_name = legacy_normalize_name(self.name) self.requirements = [Requirement(r) for r in self.requires or []] self.extras = [ - v for k, v in self.metadata.items() if k == 'Provides-Extra'] + v.lower() for k, v in self.metadata.items() if k == 'Provides-Extra'] self.py_version = self._parse_py_version(path) # `name` is defined as a property exactly like this in Python 3.10 in the @@ -296,7 +316,7 @@ if __name__ == "__main__": # and pluses in the middle can be easily replaced with dashes. # Python extras names don't contain pluses according to PEP 508. package_name_parts = args.package_name.rpartition('+') - extras_subpackage = package_name_parts[2] or None + extras_subpackage = package_name_parts[2].lower() or None for f in (args.files or stdin.readlines()): f = f.strip() @@ -436,7 +456,7 @@ if __name__ == "__main__": if args.require_extras_subpackages and dep.extras: # A dependency can have more than one extras, # i.e. foo[bar,baz], so let's go through all of them - extras_suffixes += [f"[{e}]" for e in dep.extras] + extras_suffixes += [f"[{e.lower()}]" for e in dep.extras] for extras_suffix in extras_suffixes: if normalized_names_require_pep503: diff --git a/sources b/sources index 1d7f97a..d8fedb8 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (test-sources-2020-04-29.tar.gz) = a5539fbe05a4f7128b4f82e960c3f1392a55ad53086dfd7fbc436d2743feaf64784e08667237baed3a32f149db25bc63e4ab3efc2b0270f969c59550b75102b1 +SHA512 (test-sources-2021-03-11.tar.gz) = 6f34c8151625be489a6a4d56d1fd3d39b7908bd31402c9703cb65918385320dfad35f35a32920c816fb85a829f44aaf04dc1d0654ccf512e26e87e95dbf87430 diff --git a/tests/data/scripts_pythondistdeps/pyreq2rpm.tests-2020.04.07.024dab0-py3.9.egg-info/requires.txt b/tests/data/scripts_pythondistdeps/pyreq2rpm.tests-2020.04.07.024dab0-py3.9.egg-info/requires.txt index 1436266..338afcc 100644 --- a/tests/data/scripts_pythondistdeps/pyreq2rpm.tests-2020.04.07.024dab0-py3.9.egg-info/requires.txt +++ b/tests/data/scripts_pythondistdeps/pyreq2rpm.tests-2020.04.07.024dab0-py3.9.egg-info/requires.txt @@ -100,3 +100,5 @@ hugo5===11.1.0.post3 test___multiple__underscores==1 test_underscores==1 + +dnspython[DNSSEC] diff --git a/tests/data/scripts_pythondistdeps/test-data.yaml b/tests/data/scripts_pythondistdeps/test-data.yaml index 9b97be8..35c72a8 100644 --- a/tests/data/scripts_pythondistdeps/test-data.yaml +++ b/tests/data/scripts_pythondistdeps/test-data.yaml @@ -1,103 +1,5 @@ --requires: --provides: - pyreq2rpm.tests-2020.04.07.024dab0-py3.9.egg-info: - provides: python3.9dist(pyreq2rpm.tests) = 2020.04.07.024dab0 - requires: |- - python(abi) = 3.9 - ((python3.9dist(babel) < 2 or python3.9dist(babel) > 2) with python3.9dist(babel) >= 1.3) - python3.9dist(fedora-python-nb2plots) = 0 - (python3.9dist(foobar0) >= 2.4.8 with python3.9dist(foobar0) < 2.5) - (python3.9dist(foobar1) >= 2.4.8 with python3.9dist(foobar1) < 2.4.9) - (python3.9dist(foobar10) >= 2^post1 with python3.9dist(foobar10) < 3) - python3.9dist(foobar11) = 2.4.8 - python3.9dist(foobar12) = 2.4.8 - python3.9dist(foobar13) = 2.4.8.1 - (python3.9dist(foobar14) >= 2.4.8 with python3.9dist(foobar14) < 2.4.9) - python3.9dist(foobar15) = 2 - python3.9dist(foobar16) = 2 - (python3.9dist(foobar17) >= 2 with python3.9dist(foobar17) < 3) - python3.9dist(foobar18) = 2.4.8~b5 - python3.9dist(foobar19) = 2~b5 - (python3.9dist(foobar2) >= 2.4.8.1 with python3.9dist(foobar2) < 2.4.9) - python3.9dist(foobar20) = 2.4.8^post1 - python3.9dist(foobar21) = 2^post1 - python3.9dist(foobar22) = 2.4.8 - python3.9dist(foobar23) = 2.4.8 - python3.9dist(foobar24) = 2.4.8.1 - python3.9dist(foobar26) = 2 - python3.9dist(foobar27) = 2 - python3.9dist(foobar29) = 2.4.8~b5 - python3.9dist(foobar30) = 2~b5 - python3.9dist(foobar31) = 2.4.8^post1 - python3.9dist(foobar32) = 2^post1 - (python3.9dist(foobar33) < 2.4.8 or python3.9dist(foobar33) > 2.4.8) - (python3.9dist(foobar34) < 2.4.8 or python3.9dist(foobar34) > 2.4.8) - (python3.9dist(foobar35) < 2.4.8.1 or python3.9dist(foobar35) > 2.4.8.1) - (python3.9dist(foobar36) < 2.4.8 or python3.9dist(foobar36) > 2.4.9) - (python3.9dist(foobar37) < 2 or python3.9dist(foobar37) > 2) - (python3.9dist(foobar38) < 2 or python3.9dist(foobar38) > 2) - (python3.9dist(foobar39) < 2 or python3.9dist(foobar39) > 3) - (python3.9dist(foobar4) >= 2 with python3.9dist(foobar4) < 3) - (python3.9dist(foobar40) < 2.4.8~b5 or python3.9dist(foobar40) > 2.4.8~b5) - (python3.9dist(foobar41) < 2~b5 or python3.9dist(foobar41) > 2~b5) - (python3.9dist(foobar42) < 2.4.8^post1 or python3.9dist(foobar42) > 2.4.8^post1) - (python3.9dist(foobar43) < 2^post1 or python3.9dist(foobar43) > 2^post1) - python3.9dist(foobar44) <= 2.4.8 - python3.9dist(foobar45) <= 2.4.8 - python3.9dist(foobar46) <= 2.4.8.1 - python3.9dist(foobar47) < 2.4.8 - python3.9dist(foobar48) <= 2 - python3.9dist(foobar49) <= 2 - python3.9dist(foobar50) < 2 - python3.9dist(foobar51) <= 2.4.8~b5 - python3.9dist(foobar52) <= 2~b5 - python3.9dist(foobar53) <= 2.4.8^post1 - python3.9dist(foobar54) <= 2^post1 - python3.9dist(foobar55) < 2.4.8 - python3.9dist(foobar56) < 2.4.8 - python3.9dist(foobar57) < 2.4.8.1 - python3.9dist(foobar58) < 2.4.8 - python3.9dist(foobar59) < 2 - python3.9dist(foobar60) < 2 - python3.9dist(foobar61) < 2 - python3.9dist(foobar62) < 2.4.8~b5 - python3.9dist(foobar63) < 2~b5 - python3.9dist(foobar64) < 2.4.8^post1 - python3.9dist(foobar65) < 2^post1 - python3.9dist(foobar66) >= 2.4.8 - python3.9dist(foobar67) >= 2.4.8 - python3.9dist(foobar68) >= 2.4.8.1 - python3.9dist(foobar69) >= 2.4.8 - (python3.9dist(foobar7) >= 2.4.8~b5 with python3.9dist(foobar7) < 2.5) - python3.9dist(foobar70) >= 2 - python3.9dist(foobar71) >= 2 - python3.9dist(foobar72) >= 2 - python3.9dist(foobar73) >= 2.4.8~b5 - python3.9dist(foobar74) >= 2~b5 - python3.9dist(foobar75) >= 2.4.8^post1 - python3.9dist(foobar76) >= 2^post1 - python3.9dist(foobar77) > 2.4.8 - python3.9dist(foobar78) > 2.4.8 - python3.9dist(foobar79) > 2.4.8.1 - (python3.9dist(foobar8) >= 2~b5 with python3.9dist(foobar8) < 2.1) - python3.9dist(foobar80) >= 2.4.8 - python3.9dist(foobar81) > 2 - python3.9dist(foobar82) > 2 - python3.9dist(foobar83) >= 2 - python3.9dist(foobar84) > 2.4.8~b5 - python3.9dist(foobar85) > 2~b5 - python3.9dist(foobar86) > 2.4.8^post1 - python3.9dist(foobar87) > 2^post1 - (python3.9dist(foobar9) >= 2.4.8^post1 with python3.9dist(foobar9) < 2.5) - python3.9dist(hugo1) = 1~~dev7 - python3.9dist(hugo2) <= 8~a4 - (python3.9dist(hugo3) < 11.1.1~b14 or python3.9dist(hugo3) > 11.1.1~b14) - python3.9dist(hugo4) > 11~rc0 - python3.9dist(hugo5) = 11.1^post3 - python3.9dist(pyparsing0) - ((python3.9dist(pyparsing1) < 2.0.4 or python3.9dist(pyparsing1) > 2.0.4) with (python3.9dist(pyparsing1) < 2.1.2 or python3.9dist(pyparsing1) > 2.1.2) with (python3.9dist(pyparsing1) < 2.1.6 or python3.9dist(pyparsing1) > 2.1.6) with python3.9dist(pyparsing1) >= 2.0.1) - python3.9dist(test-multiple-underscores) = 1 - python3.9dist(test-underscores) = 1 usr/lib/python3.9/site-packages/taskotron_python_versions-0.1.dev6.dist-info: provides: python3.9dist(taskotron-python-versions) = 0.1~~dev6 requires: |- @@ -1216,6 +1118,40 @@ python3dist(backports-range) = 3.7.2 python3dist(backports.range) = 3.7.2 requires: python(abi) = 3.7 +--requires --normalized-names-format pep503 --package-name python3-dns+DNSSEC: + --provides --majorver-provides --normalized-names-format pep503 --package-name python3-dns+DNSSEC: + usr/lib/python3.9/site-packages/dnspython-2.1.0-py3.9.egg-info: + provides: |- + python3.9dist(dnspython[dnssec]) = 2.1 + python3dist(dnspython[dnssec]) = 2.1 + requires: |- + python(abi) = 3.9 + python3.9dist(cryptography) >= 2.6 +--requires --normalized-names-format pep503 --package-name python3-dns+Dnssec: + --provides --majorver-provides --normalized-names-format pep503 --package-name python3-dns+Dnssec: + usr/lib/python3.9/site-packages/dnspython-2.1.0-py3.9.egg-info: + provides: |- + python3.9dist(dnspython[dnssec]) = 2.1 + python3dist(dnspython[dnssec]) = 2.1 + requires: |- + python(abi) = 3.9 + python3.9dist(cryptography) >= 2.6 +--requires --normalized-names-format pep503 --package-name python3-dns+dnssec: + --provides --majorver-provides --normalized-names-format pep503 --package-name python3-dns+dnssec: + usr/lib/python3.9/site-packages/dnspython-2.1.0-py3.9.egg-info: + provides: |- + python3.9dist(dnspython[dnssec]) = 2.1 + python3dist(dnspython[dnssec]) = 2.1 + requires: |- + python(abi) = 3.9 + python3.9dist(cryptography) >= 2.6 + usr/lib/python3.9/site-packages/dnspython-2.1.0.dist-info: + provides: |- + python3.9dist(dnspython[dnssec]) = 2.1 + python3dist(dnspython[dnssec]) = 2.1 + requires: |- + python(abi) = 3.9 + python3.9dist(cryptography) >= 2.6 --requires --normalized-names-format pep503 --package-name python3-setuptools+certs: --provides --majorver-provides --normalized-names-format pep503 --package-name python3-setuptools+certs: usr/lib/python3.9/site-packages/setuptools-41.6.0.dist-info: @@ -1257,6 +1193,108 @@ python3.9dist(coverage) python3.9dist(nose) python3.9dist(zope-testing) +--requires --normalized-names-format pep503 --require-extras-subpackages: + --provides --normalized-names-format pep503: + pyreq2rpm.tests-2020.04.07.024dab0-py3.9.egg-info: + provides: python3.9dist(pyreq2rpm-tests) = 2020.04.07.024dab0 + requires: |- + python(abi) = 3.9 + ((python3.9dist(babel) < 2 or python3.9dist(babel) > 2) with python3.9dist(babel) >= 1.3) + python3.9dist(dnspython) + python3.9dist(dnspython[dnssec]) + python3.9dist(fedora-python-nb2plots) = 0 + (python3.9dist(foobar0) >= 2.4.8 with python3.9dist(foobar0) < 2.5) + (python3.9dist(foobar1) >= 2.4.8 with python3.9dist(foobar1) < 2.4.9) + (python3.9dist(foobar10) >= 2^post1 with python3.9dist(foobar10) < 3) + python3.9dist(foobar11) = 2.4.8 + python3.9dist(foobar12) = 2.4.8 + python3.9dist(foobar13) = 2.4.8.1 + (python3.9dist(foobar14) >= 2.4.8 with python3.9dist(foobar14) < 2.4.9) + python3.9dist(foobar15) = 2 + python3.9dist(foobar16) = 2 + (python3.9dist(foobar17) >= 2 with python3.9dist(foobar17) < 3) + python3.9dist(foobar18) = 2.4.8~b5 + python3.9dist(foobar19) = 2~b5 + (python3.9dist(foobar2) >= 2.4.8.1 with python3.9dist(foobar2) < 2.4.9) + python3.9dist(foobar20) = 2.4.8^post1 + python3.9dist(foobar21) = 2^post1 + python3.9dist(foobar22) = 2.4.8 + python3.9dist(foobar23) = 2.4.8 + python3.9dist(foobar24) = 2.4.8.1 + python3.9dist(foobar26) = 2 + python3.9dist(foobar27) = 2 + python3.9dist(foobar29) = 2.4.8~b5 + python3.9dist(foobar30) = 2~b5 + python3.9dist(foobar31) = 2.4.8^post1 + python3.9dist(foobar32) = 2^post1 + (python3.9dist(foobar33) < 2.4.8 or python3.9dist(foobar33) > 2.4.8) + (python3.9dist(foobar34) < 2.4.8 or python3.9dist(foobar34) > 2.4.8) + (python3.9dist(foobar35) < 2.4.8.1 or python3.9dist(foobar35) > 2.4.8.1) + (python3.9dist(foobar36) < 2.4.8 or python3.9dist(foobar36) > 2.4.9) + (python3.9dist(foobar37) < 2 or python3.9dist(foobar37) > 2) + (python3.9dist(foobar38) < 2 or python3.9dist(foobar38) > 2) + (python3.9dist(foobar39) < 2 or python3.9dist(foobar39) > 3) + (python3.9dist(foobar4) >= 2 with python3.9dist(foobar4) < 3) + (python3.9dist(foobar40) < 2.4.8~b5 or python3.9dist(foobar40) > 2.4.8~b5) + (python3.9dist(foobar41) < 2~b5 or python3.9dist(foobar41) > 2~b5) + (python3.9dist(foobar42) < 2.4.8^post1 or python3.9dist(foobar42) > 2.4.8^post1) + (python3.9dist(foobar43) < 2^post1 or python3.9dist(foobar43) > 2^post1) + python3.9dist(foobar44) <= 2.4.8 + python3.9dist(foobar45) <= 2.4.8 + python3.9dist(foobar46) <= 2.4.8.1 + python3.9dist(foobar47) < 2.4.8 + python3.9dist(foobar48) <= 2 + python3.9dist(foobar49) <= 2 + python3.9dist(foobar50) < 2 + python3.9dist(foobar51) <= 2.4.8~b5 + python3.9dist(foobar52) <= 2~b5 + python3.9dist(foobar53) <= 2.4.8^post1 + python3.9dist(foobar54) <= 2^post1 + python3.9dist(foobar55) < 2.4.8 + python3.9dist(foobar56) < 2.4.8 + python3.9dist(foobar57) < 2.4.8.1 + python3.9dist(foobar58) < 2.4.8 + python3.9dist(foobar59) < 2 + python3.9dist(foobar60) < 2 + python3.9dist(foobar61) < 2 + python3.9dist(foobar62) < 2.4.8~b5 + python3.9dist(foobar63) < 2~b5 + python3.9dist(foobar64) < 2.4.8^post1 + python3.9dist(foobar65) < 2^post1 + python3.9dist(foobar66) >= 2.4.8 + python3.9dist(foobar67) >= 2.4.8 + python3.9dist(foobar68) >= 2.4.8.1 + python3.9dist(foobar69) >= 2.4.8 + (python3.9dist(foobar7) >= 2.4.8~b5 with python3.9dist(foobar7) < 2.5) + python3.9dist(foobar70) >= 2 + python3.9dist(foobar71) >= 2 + python3.9dist(foobar72) >= 2 + python3.9dist(foobar73) >= 2.4.8~b5 + python3.9dist(foobar74) >= 2~b5 + python3.9dist(foobar75) >= 2.4.8^post1 + python3.9dist(foobar76) >= 2^post1 + python3.9dist(foobar77) > 2.4.8 + python3.9dist(foobar78) > 2.4.8 + python3.9dist(foobar79) > 2.4.8.1 + (python3.9dist(foobar8) >= 2~b5 with python3.9dist(foobar8) < 2.1) + python3.9dist(foobar80) >= 2.4.8 + python3.9dist(foobar81) > 2 + python3.9dist(foobar82) > 2 + python3.9dist(foobar83) >= 2 + python3.9dist(foobar84) > 2.4.8~b5 + python3.9dist(foobar85) > 2~b5 + python3.9dist(foobar86) > 2.4.8^post1 + python3.9dist(foobar87) > 2^post1 + (python3.9dist(foobar9) >= 2.4.8^post1 with python3.9dist(foobar9) < 2.5) + python3.9dist(hugo1) = 1~~dev7 + python3.9dist(hugo2) <= 8~a4 + (python3.9dist(hugo3) < 11.1.1~b14 or python3.9dist(hugo3) > 11.1.1~b14) + python3.9dist(hugo4) > 11~rc0 + python3.9dist(hugo5) = 11.1^post3 + python3.9dist(pyparsing0) + ((python3.9dist(pyparsing1) < 2.0.4 or python3.9dist(pyparsing1) > 2.0.4) with (python3.9dist(pyparsing1) < 2.1.2 or python3.9dist(pyparsing1) > 2.1.2) with (python3.9dist(pyparsing1) < 2.1.6 or python3.9dist(pyparsing1) > 2.1.6) with python3.9dist(pyparsing1) >= 2.0.1) + python3.9dist(test-multiple-underscores) = 1 + python3.9dist(test-underscores) = 1 --requires --normalized-names-format pep503 --require-extras-subpackages --package-name python3-zope-component+missing: --provides --majorver-provides --normalized-names-format pep503 --package-name python3-zope-component+missing: usr/lib/python3.9/site-packages/zope.component-4.3.0-py3.9.egg-info: diff --git a/tests/data/scripts_pythondistdeps/test-requires.yaml b/tests/data/scripts_pythondistdeps/test-requires.yaml index c06d6c0..32d70f2 100644 --- a/tests/data/scripts_pythondistdeps/test-requires.yaml +++ b/tests/data/scripts_pythondistdeps/test-requires.yaml @@ -95,3 +95,8 @@ fsleyes: taskotron-python-versions: wheel: '0.1.dev6': ['3.9'] +dnspython: + sdist: + '2.1.0': ['3.9'] + wheel: + '2.1.0': ['3.9'] diff --git a/update-test-sources.sh b/update-test-sources.sh index b7fa68b..4d7963e 100755 --- a/update-test-sources.sh +++ b/update-test-sources.sh @@ -3,6 +3,7 @@ # # Requirements: # - pip >= 20.0.1 +# - poetry # Due to bug: https://github.com/pypa/pip/issues/9701 # # First prune old test data