I’ve just found a weirdness with `InterpreterConst...
# development
a
I’ve just found a weirdness with
InterpreterConstraints
with respect to how it orders inputs. Can someone help me understand what the correct behaviour should be here? (test case will appear in thread)
Copy code
def test_ic_ordering():
    
    inputs = ["CPython==2.7.*", "PyPy", "CPython>=3.6,<4,!=3.7.*"]
    a = InterpreterConstraints(inputs)
    a_str = [str(i) for i in a]
    b = InterpreterConstraints(a_str)

    print(inputs)
    print(a)
    print(a_str)
    print(b) 

    assert a == b
which gives the following output:
Copy code
['CPython==2.7.*', 'PyPy', 'CPython>=3.6,<4,!=3.7.*']
CPython==2.7.* OR CPython!=3.7.*,<4,>=3.6 OR PyPy
['CPython==2.7.*', 'CPython!=3.7.*,<4,>=3.6', 'PyPy']
CPython!=3.7.*,<4,>=3.6 OR CPython==2.7.* OR PyPy
I think the issue arises from the constructor, which I think is a bit too eager to do things without assigning any variables
h
The weird part being how
a != b
, right? Weird. It should be sorting the inputs
a
Copy code
super().__init__(
            v if isinstance(v, Requirement) else self.parse_constraint(v)
            for v in sorted(constraints, key=lambda c: str(c))
        )
I think the correct behaviour is to convert the list into
Requirement
objects, and then do the sort, rather than sorting on the heterogeneous constraints
h
ah yeah that makes sense, good catch. That would be great to fix in a dedicated PR w/ a test like you have above
a
Easy
@hundreds-father-404 My fix breaks a test you wrote recently for poetry constraints. Are you OK with me changing the expected test output here, or would you prefer me to try to make both tests pass?
Copy code
E         '!=3.6.1,>=3.6 || ==2.7.*'  '==2.7.* || !=3.6.1,>=3.6'
(clearly
parse_requirement
has its own internal ordering problem, which is what caused the parent issue)
h
yes you can fix 🙂 ordering doesn't matter for that test, only determinism
a
Figures. Thank you!
I’m guessing the root cause of the bug is that internal sorting that happens inside
Requirement.parse
— so if you input a
list[str]
, you’d sort the list before sorting the requirements inside the list, which would mean that initial list came out slightly unsorted. Wheee