From 357861d065ca43d98874cda2590eb78bbc88240d Mon Sep 17 00:00:00 2001 From: Pierre Souchay Date: Thu, 19 Aug 2021 15:24:02 +0200 Subject: [PATCH] fix(pep-0508): fix parsing of 'in' and 'not in' constraints This might help fixing https://github.com/python-poetry/poetry/issues/4402 --- poetry/core/packages/constraints/__init__.py | 24 +++++++++++++++- tests/packages/constraints/test_main.py | 30 ++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/poetry/core/packages/constraints/__init__.py b/poetry/core/packages/constraints/__init__.py index c23cdcd23..c992fa66c 100644 --- a/poetry/core/packages/constraints/__init__.py +++ b/poetry/core/packages/constraints/__init__.py @@ -1,6 +1,6 @@ import re -from typing import Union +from typing import Callable, Union from .any_constraint import AnyConstraint from .base_constraint import BaseConstraint @@ -15,6 +15,23 @@ AnyConstraint, Constraint, UnionConstraint, EmptyConstraint, MultiConstraint ] +IN_CONSTRAINT = re.compile(r'in "([^"]+)"') +def parse_in_constraints(constraints: str, constraint_builder: Callable[[str], Constraint]) -> list[str]: + m = IN_CONSTRAINT.match(constraints) + if m: + in_values = m.group(1).strip().split() + return [constraint_builder(c.strip()) for c in in_values] + + raise ValueError(f"Cannot parse in constraint {constraints}") + + +def build_in_constraint(constraints: str) -> BaseConstraint: + return UnionConstraint(*parse_in_constraints(constraints, lambda c: Constraint(c))) + + +def build_not_in_constraint(constraints: str) -> BaseConstraint: + return MultiConstraint(*parse_in_constraints(constraints, lambda c: Constraint(c, operator = "!="))) + def parse_constraint( constraints: str, @@ -22,6 +39,11 @@ def parse_constraint( if constraints == "*": return AnyConstraint() + if constraints.startswith("in "): + return build_in_constraint(constraints) + if constraints.startswith("not in "): + return build_not_in_constraint(constraints[4::]) + or_constraints = re.split(r"\s*\|\|?\s*", constraints.strip()) or_groups = [] for constraints in or_constraints: diff --git a/tests/packages/constraints/test_main.py b/tests/packages/constraints/test_main.py index 0769a47a0..86dacb20b 100644 --- a/tests/packages/constraints/test_main.py +++ b/tests/packages/constraints/test_main.py @@ -37,6 +37,21 @@ def test_parse_constraint(input, constraint): Constraint("linux2", "!="), ), ), + ( + 'not in "x86_64 X86_64 aarch64 AARCH64 ppc64le PPC64LE amd64 AMD64 win32 WIN32"', + MultiConstraint( + Constraint("x86_64", "!="), + Constraint("X86_64", "!="), + Constraint("aarch64", "!="), + Constraint("AARCH64", "!="), + Constraint("ppc64le", "!="), + Constraint("PPC64LE", "!="), + Constraint("amd64", "!="), + Constraint("AMD64", "!="), + Constraint("win32", "!="), + Constraint("WIN32", "!="), + ) + ), ], ) def test_parse_constraint_multi(input, constraint): @@ -51,6 +66,21 @@ def test_parse_constraint_multi(input, constraint): "win32 || !=linux2", UnionConstraint(Constraint("win32"), Constraint("linux2", "!=")), ), + ( + 'in "x86_64 X86_64 aarch64 AARCH64 ppc64le PPC64LE amd64 AMD64 win32 WIN32"', + UnionConstraint( + Constraint("x86_64", "="), + Constraint("X86_64", "="), + Constraint("aarch64", "="), + Constraint("AARCH64", "="), + Constraint("ppc64le", "="), + Constraint("PPC64LE", "="), + Constraint("amd64", "="), + Constraint("AMD64", "="), + Constraint("win32", "="), + Constraint("WIN32", "="), + ) + ), ], ) def test_parse_constraint_union(input, constraint):