Skip to content

Commit e20b656

Browse files
authored
Merge pull request #832 from Randori-Lance/lbarto/lets-try-again
fix: adds support for duplicate constraints, checks for conflicts
2 parents 566dab9 + ca0ee6c commit e20b656

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/fromager/constraints.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ def add_constraint(self, unparsed: str) -> None:
2525
req = Requirement(unparsed)
2626
canon_name = canonicalize_name(req.name)
2727
previous = self._data.get(canon_name)
28+
29+
if not requirements_file.evaluate_marker(req, req):
30+
logger.debug(f"Constraint {req} does not match environment")
31+
return
32+
2833
if previous is not None:
2934
raise KeyError(
3035
f"{canon_name}: new constraint '{req}' conflicts with '{previous}'"

tests/test_constraints.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import pathlib
2+
import typing
23

34
import pytest
5+
from packaging import markers
46
from packaging.requirements import Requirement
57
from packaging.version import Version
68

@@ -37,15 +39,67 @@ def test_add_constraint_conflict():
3739
c = constraints.Constraints()
3840
c.add_constraint("foo<=1.1")
3941
c.add_constraint("flit_core==2.0rc3")
42+
43+
# Exact duplicate should raise error (same package, same marker)
4044
with pytest.raises(KeyError):
4145
c.add_constraint("foo<=1.1")
46+
47+
# Different version, same marker (no marker) should raise error
4248
with pytest.raises(KeyError):
4349
c.add_constraint("foo>1.1")
50+
51+
# Different version for flit_core should raise error
4452
with pytest.raises(KeyError):
4553
c.add_constraint("flit_core>2.0.0")
54+
55+
# Normalized name conflict should raise error
4656
with pytest.raises(KeyError):
4757
c.add_constraint("flit-core>2.0.0")
4858

59+
# Different, but equivalent markers should raise KeyError
60+
with pytest.raises(KeyError):
61+
c.add_constraint(
62+
"bar==1.0; python_version >= '3.11' and platform_machine == 'x86_64'"
63+
)
64+
c.add_constraint(
65+
"bar==1.1; platform_machine == 'x86_64' and python_version >= '3.11'"
66+
)
67+
c.add_constraint(
68+
"bar==1.0; python_version >= '3.11' and platform_machine == 'arm64'"
69+
)
70+
c.add_constraint(
71+
"bar==1.1; platform_machine == 'arm64' and python_version >= '3.11'"
72+
)
73+
74+
# Same package with different markers should NOT raise error
75+
c.add_constraint("baz==1.0; platform_machine != 'ppc64le'")
76+
c.add_constraint("baz==1.1; platform_machine == 'ppc64le'")
77+
78+
# But same package with same marker should raise error
79+
with pytest.raises(KeyError):
80+
c.add_constraint("foo==1.2; platform_machine != 'ppc64le'")
81+
82+
# Verify multiple constraints for same package are stored
83+
assert len(c._data) == 4 # flit_core, foo, bar, and baz
84+
85+
# Make sure correct constraint is added
86+
env = typing.cast(dict[str, str], markers.default_environment())
87+
constraint = c.get_constraint("bar")
88+
89+
if env.get("platform_machine") == "x86_64" and constraint is not None:
90+
assert constraint.name == "bar"
91+
assert constraint.specifier == "==1.0"
92+
assert constraint.marker == markers.Marker(
93+
'python_version >= "3.11" and platform_machine == "x86_64"'
94+
)
95+
96+
if env.get("platform_machine") == "arm64" and constraint is not None:
97+
assert constraint.name == "bar"
98+
assert constraint.specifier == "==1.0"
99+
assert constraint.marker == markers.Marker(
100+
'python_version >= "3.11" and platform_machine == "arm64"'
101+
)
102+
49103

50104
def test_allow_prerelease():
51105
c = constraints.Constraints()

0 commit comments

Comments
 (0)