From 7602b9a77a0bb984e4d6c8bc93af60ff37c79b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 13 Jul 2021 10:23:35 +0000 Subject: [PATCH] %pyproject_buildrequires: Support x.* versions Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1981558 Related: rhbz#1950291 --- pyproject-rpm-macros.spec | 1 + pyproject_buildrequires.py | 13 +++++++++---- pyproject_buildrequires_testcases.yaml | 20 ++++++++++++++++++++ test_pyproject_buildrequires.py | 12 ++++++++++-- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/pyproject-rpm-macros.spec b/pyproject-rpm-macros.spec index 53a8b6b..512292e 100644 --- a/pyproject-rpm-macros.spec +++ b/pyproject-rpm-macros.spec @@ -112,6 +112,7 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856 %changelog * Fri Jul 09 2021 Miro HronĨok - 0-44 - Escape weird paths generated by %%pyproject_save_files +- Support x.* versions in %%pyproject_buildrequires - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags Related: rhbz#1991688 diff --git a/pyproject_buildrequires.py b/pyproject_buildrequires.py index 0232126..42fd77a 100644 --- a/pyproject_buildrequires.py +++ b/pyproject_buildrequires.py @@ -2,7 +2,6 @@ import os import sys import importlib.metadata import argparse -import functools import traceback import contextlib from io import StringIO @@ -13,17 +12,23 @@ import tempfile import email.parser import pathlib -print_err = functools.partial(print, file=sys.stderr) # Some valid Python version specifiers are not supported. -# Whitelist characters we can handle. -VERSION_RE = re.compile('[a-zA-Z0-9.-]+') +# Allow only the forms we know we can handle. +VERSION_RE = re.compile(r'[a-zA-Z0-9.-]+(\.\*)?') class EndPass(Exception): """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: from packaging.requirements import Requirement, InvalidRequirement from packaging.utils import canonicalize_name diff --git a/pyproject_buildrequires_testcases.yaml b/pyproject_buildrequires_testcases.yaml index cf2c4d9..0053537 100644 --- a/pyproject_buildrequires_testcases.yaml +++ b/pyproject_buildrequires_testcases.yaml @@ -69,6 +69,24 @@ Bad character in version: requires = ["pkg == 0.$.^.*"] 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: generate_extras: true installed: @@ -88,6 +106,7 @@ Build system dependencies in pyproject.toml with extras: "compatible ~= 0.4.0", "equal == 0.5.0", "arbitrary_equal === 0.6.0", + "asterisk_equal == 0.6.*", "multi[Extras1,Extras2] == 6.0", "combo >2, <5, != 3.0.0", "invalid!!ignored", @@ -106,6 +125,7 @@ Build system dependencies in pyproject.toml with extras: (python3dist(compatible) >= 0.4 with python3dist(compatible) < 0.5) python3dist(equal) = 0.5 python3dist(arbitrary-equal) = 0.6 + (python3dist(asterisk-equal) >= 0.6 with python3dist(asterisk-equal) < 0.7) python3dist(multi) = 6 python3dist(multi[extras1]) = 6 python3dist(multi[extras2]) = 6 diff --git a/test_pyproject_buildrequires.py b/test_pyproject_buildrequires.py index 5170c29..4a7ebb2 100644 --- a/test_pyproject_buildrequires.py +++ b/test_pyproject_buildrequires.py @@ -57,8 +57,16 @@ def test_data(case_name, capsys, tmp_path, monkeypatch): else: assert 0 == case['result'] - captured = capsys.readouterr() - assert captured.out == case['expected'] + # this prevents us from accidentally writing "empty" tests + # 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: for req in requirement_files: req.close()