Sync dependency conversion with upstream pyreq2rpm.

Improve handling of > operator, preventing post-release from satisfying most rpm requirements.
Improve handling of < operator, preventing pre-release from satisfying rpm requirement.
Improve handling of != operator with prefix matching, preventing pre-release from satisfying rpm requirements.

Related: rhbz#1950291
This commit is contained in:
Gordon Messmer 2021-10-22 16:30:53 -07:00 committed by Karolina Surma
parent d427052f40
commit f8c2fede5b
3 changed files with 41 additions and 18 deletions

View File

@ -12,7 +12,7 @@ License: MIT
# In other cases, such as backports, increment the point
# release.
Version: 0
Release: 49%{?dist}
Release: 50%{?dist}
# Macro files
Source001: macros.pyproject
@ -119,6 +119,11 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856
%license LICENSE
%changelog
* Mon Nov 1 2021 Gordon Messmer <gordon.messmer@gmail.com> - 0-50
- Improve handling of > operator, preventing post-release from satisfying most rpm requirements
- Improve handling of < operator, preventing pre-release from satisfying rpm requirement
- Improve handling of != operator with prefix matching, preventing pre-release from satisfying rpm requirements
* Tue Oct 19 2021 Karolina Surma <ksurma@redhat.com> - 0-49
- %%pyproject_save_files: Save %%_pyproject_modules file with importable module names
- Introduce %%pyproject_check_import which passes %%_pyproject_modules to %%py3_check_import

View File

@ -159,13 +159,13 @@ Build system dependencies in pyproject.toml with extras:
build-backend = "foo.build"
expected: |
python3dist(foo)
python3dist(bar) > 5
python3dist(bar[baz]) > 5
python3dist(bar) > 5.0
python3dist(bar[baz]) > 5.0
(python3dist(ne) < 1 or python3dist(ne) > 1)
python3dist(ge) >= 1.2
python3dist(le) <= 1.2.3
python3dist(lt) < 1.2.3.4
python3dist(gt) > 1.2.3.4.5
python3dist(lt) < 1.2.3.4~~
python3dist(gt) > 1.2.3.4.5.0
(python3dist(compatible) >= 0.4 with python3dist(compatible) < 0.5)
python3dist(equal) = 0.5
python3dist(arbitrary-equal) = 0.6
@ -174,7 +174,7 @@ Build system dependencies in pyproject.toml with extras:
python3dist(multi) = 6
python3dist(multi[extras1]) = 6
python3dist(multi[extras2]) = 6
((python3dist(combo) < 3 or python3dist(combo) > 3) with python3dist(combo) < 5 with python3dist(combo) > 2)
((python3dist(combo) < 3 or python3dist(combo) > 3) with python3dist(combo) < 5~~ with python3dist(combo) > 2.0)
python3dist(py3)
stderr_contains: "WARNING: Simplifying 'appdirs@https://github.com/ActiveState/appdirs/archive/8eacfa312d77aba28d483fbfb6f6fc54099622be.zip' to 'appdirs'."
result: 0
@ -193,7 +193,7 @@ Build system dependencies in pyproject.toml without extras:
]
build-backend = "foo.build"
expected: |
python3dist(bar) > 5
python3dist(bar) > 5.0
python3dist(multi) = 6
result: 0
@ -237,8 +237,8 @@ Default build system, run dependencies in setup.py:
python3dist(wheel)
python3dist(wheel)
python3dist(pyyaml)
python3dist(inst) > 1
python3dist(inst2) < 3
python3dist(inst) > 1.0
python3dist(inst2) < 3~~
result: 0
Run dependencies with extras (not selected):
@ -430,7 +430,7 @@ Tox extras:
python3dist(tox-current-env) >= 0.0.6
python3dist(toxdep)
python3dist(inst)
python3dist(dep11) > 11
python3dist(dep11) > 11.0
python3dist(dep12)
python3dist(dep21)
python3dist(dep22)
@ -470,8 +470,8 @@ Tox provision unsatisfied:
python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6
python3dist(tox) >= 3.999
python3dist(setuptools) > 40
python3dist(wheel) > 2
python3dist(setuptools) > 40.0
python3dist(wheel) > 2.0
result: 0
Tox provision satisfied:
@ -504,7 +504,7 @@ Tox provision satisfied:
python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6
python3dist(tox) >= 3.5
python3dist(setuptools) > 40
python3dist(setuptools) > 40.0
python3dist(toxdep1)
python3dist(toxdep2)
python3dist(inst)
@ -564,7 +564,7 @@ Default build system, met deps in requirements file:
python3dist(ncclient)
(python3dist(cryptography) < 1.5.2 or python3dist(cryptography) > 1.5.2)
python3dist(paramiko)
(python3dist(sqlalchemy) < 1.1 with python3dist(sqlalchemy) >= 1.0.10)
(python3dist(sqlalchemy) < 1.1~~ with python3dist(sqlalchemy) >= 1.0.10)
python3dist(setuptools) >= 40.8
python3dist(wheel)
python3dist(wheel)

View File

@ -36,6 +36,9 @@ class RpmVersion():
self.pre = version._version.pre
self.dev = version._version.dev
self.post = version._version.post
# version.local is ignored as it is not expected to appear
# in public releases
# https://www.python.org/dev/peps/pep-0440/#local-version-identifiers
def increment(self):
self.version[-1] += 1
@ -93,17 +96,26 @@ def convert_not_equal(name, operator, version_id):
if version_id.endswith('.*'):
version_id = version_id[:-2]
version = RpmVersion(version_id)
lower_version = RpmVersion(version_id).increment()
version_gt = RpmVersion(version_id).increment()
version_gt_operator = '>='
# Prevent dev and pre-releases from satisfying a < requirement
version = '{}~~'.format(version)
else:
version = RpmVersion(version_id)
lower_version = version
return '({} < {} or {} > {})'.format(
name, version, name, lower_version)
version_gt = version
version_gt_operator = '>'
return '({} < {} or {} {} {})'.format(
name, version, name, version_gt_operator, version_gt)
def convert_ordered(name, operator, version_id):
if version_id.endswith('.*'):
# PEP 440 does not define semantics for prefix matching
# with ordered comparisons
# see: https://github.com/pypa/packaging/issues/320
# and: https://github.com/pypa/packaging/issues/321
# This style of specifier is officially "unsupported",
# even though it is processed. Support may be removed
# in version 21.0.
version_id = version_id[:-2]
version = RpmVersion(version_id)
if operator == '>':
@ -114,6 +126,12 @@ def convert_ordered(name, operator, version_id):
operator = '<'
else:
version = RpmVersion(version_id)
# Prevent dev and pre-releases from satisfying a < requirement
if operator == '<' and not version.pre and not version.dev and not version.post:
version = '{}~~'.format(version)
# Prevent post-releases from satisfying a > requirement
if operator == '>' and not version.pre and not version.dev and not version.post:
version = '{}.0'.format(version)
return '{} {} {}'.format(name, operator, version)
OPERATORS = {'~=': convert_compatible,