%pyproject_buildrequires: Support x.* versions

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1981558
This commit is contained in:
Miro Hrončok 2021-07-12 23:24:58 +02:00
parent d204ac14cd
commit ddaf2e9fb2
4 changed files with 41 additions and 6 deletions

View File

@ -107,6 +107,8 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856
* Fri Jul 09 2021 Miro Hrončok <miro@hroncok.cz> - 0-44 * Fri Jul 09 2021 Miro Hrončok <miro@hroncok.cz> - 0-44
- Escape weird paths generated by %%pyproject_save_files - Escape weird paths generated by %%pyproject_save_files
- Fixes rhbz#1976363 - Fixes rhbz#1976363
- Support x.* versions in %%pyproject_buildrequires
- Fixes rhbz#1981558
* Thu Jul 01 2021 Tomas Hrnciar <thrnciar@redhat.com> - 0-43 * Thu Jul 01 2021 Tomas Hrnciar <thrnciar@redhat.com> - 0-43
- Generate BuildRequires from file - Generate BuildRequires from file

View File

@ -2,7 +2,6 @@ import os
import sys import sys
import importlib.metadata import importlib.metadata
import argparse import argparse
import functools
import traceback import traceback
import contextlib import contextlib
from io import StringIO from io import StringIO
@ -13,17 +12,23 @@ import tempfile
import email.parser import email.parser
import pathlib import pathlib
print_err = functools.partial(print, file=sys.stderr)
# Some valid Python version specifiers are not supported. # Some valid Python version specifiers are not supported.
# Whitelist characters we can handle. # Allow only the forms we know we can handle.
VERSION_RE = re.compile('[a-zA-Z0-9.-]+') VERSION_RE = re.compile(r'[a-zA-Z0-9.-]+(\.\*)?')
class EndPass(Exception): class EndPass(Exception):
"""End current pass of generating requirements""" """End current pass of generating requirements"""
# nb: we don't use functools.partial to be able to use pytest's capsys
# see https://github.com/pytest-dev/pytest/issues/8900
def print_err(*args, **kwargs):
kwargs.setdefault('file', sys.stderr)
print(*args, **kwargs)
try: try:
from packaging.requirements import Requirement, InvalidRequirement from packaging.requirements import Requirement, InvalidRequirement
from packaging.utils import canonicalize_name from packaging.utils import canonicalize_name

View File

@ -69,6 +69,24 @@ Bad character in version:
requires = ["pkg == 0.$.^.*"] requires = ["pkg == 0.$.^.*"]
except: ValueError except: ValueError
Single value version with unsupported compatible operator:
installed:
toml: 1
pyproject.toml: |
[build-system]
requires = ["pkg ~= 42"]
stderr_contains: "WARNING: Skipping invalid requirement: pkg ~= 42"
result: 0
Asterisk in version with unsupported compatible operator:
installed:
toml: 1
pyproject.toml: |
[build-system]
requires = ["pkg ~= 0.1.*"]
stderr_contains: "WARNING: Skipping invalid requirement: pkg ~= 0.1.*"
result: 0
Build system dependencies in pyproject.toml with extras: Build system dependencies in pyproject.toml with extras:
generate_extras: true generate_extras: true
installed: installed:
@ -88,6 +106,7 @@ Build system dependencies in pyproject.toml with extras:
"compatible ~= 0.4.0", "compatible ~= 0.4.0",
"equal == 0.5.0", "equal == 0.5.0",
"arbitrary_equal === 0.6.0", "arbitrary_equal === 0.6.0",
"asterisk_equal == 0.6.*",
"multi[Extras1,Extras2] == 6.0", "multi[Extras1,Extras2] == 6.0",
"combo >2, <5, != 3.0.0", "combo >2, <5, != 3.0.0",
"invalid!!ignored", "invalid!!ignored",
@ -106,6 +125,7 @@ Build system dependencies in pyproject.toml with extras:
(python3dist(compatible) >= 0.4 with python3dist(compatible) < 0.5) (python3dist(compatible) >= 0.4 with python3dist(compatible) < 0.5)
python3dist(equal) = 0.5 python3dist(equal) = 0.5
python3dist(arbitrary-equal) = 0.6 python3dist(arbitrary-equal) = 0.6
(python3dist(asterisk-equal) >= 0.6 with python3dist(asterisk-equal) < 0.7)
python3dist(multi) = 6 python3dist(multi) = 6
python3dist(multi[extras1]) = 6 python3dist(multi[extras1]) = 6
python3dist(multi[extras2]) = 6 python3dist(multi[extras2]) = 6

View File

@ -57,8 +57,16 @@ def test_data(case_name, capsys, tmp_path, monkeypatch):
else: else:
assert 0 == case['result'] assert 0 == case['result']
captured = capsys.readouterr() # this prevents us from accidentally writing "empty" tests
assert captured.out == case['expected'] # if we ever need to do that, we can remove the check or change it:
assert 'expected' in case or 'stderr_contains' in case
out, err = capsys.readouterr()
if 'expected' in case:
assert out == case['expected']
if 'stderr_contains' in case:
assert case['stderr_contains'] in err
finally: finally:
for req in requirement_files: for req in requirement_files:
req.close() req.close()