list vs tuples
Closed this issue · 8 comments
Hi,
I recently played around with my own order ignoring pytest assert helper: https://gist.github.com/soxofaan/8e6512f765f0f0df697311c2561be57e . I then polled the pytest devs in pytest-dev/pytest#7899 if it would be interesting to create a PR about this. This turned out to be a duplicate of pytest-dev/pytest#5548 which led to pytest-unordered :)
pytest-unordered seems to do more than what I did in my prototype, except checking the type of the sequence container.
Through the design of unordered(*args)
, you can not express that you expect for example a list and it should fail on a tuple (or vice versa).
A sequence is not necessarily either a list or a tuple. You are missing strings and generators. Do you want exact type checking for them?
unordered(*'abc') == 'bca'
Out[6]: True
unordered(0, 1, 2, 3) == range(4)
Out[7]: True
Although unordered string comparison seems pretty useless, I want to support generators.
If you want exact type checking you can do it explicitly:
actual = (1, 2)
assert unordered(*actual) == (2, 1) and isinstance(actual, tuple)
I played with IgnoreOrder
a bit. It seems it can only compare sequences that can be sorted. This leads to a TypeError
:
[3, 2, {1: ['b', 'a']}] == IgnoreOrder([{1: unordered('a', 'b')}, 2, 3])
You are missing strings and generators
good point, I didn't think of generators
Do you want exact type checking for them?
I would expect the type checking to be the default with unordered
because it is the default with regular asserts.
For example, when working with standard pytest, one expects this assert
assert actual == {"foo": [1,2,3]}
to pass on {"foo": [1,2,3]}
and fail on {"foo": (1,2,3)}
When adding unordered
one probably wants to ignore the order, but keep the type checking.
If you want exact type checking you can do it explicitly
yes, but that does not scale well if you are using unordered
in a nested way, e.g.
actual = {"foo": [2, 1], "bar": (4, 3)}
assert actual == {"foo": unordered(1,2), "bar": unordered(4,3)} and isinstance(actual["foo"], list) and isinstance(actual["bar"], tuple)
It seems it can only compare sequences that can be sorted.
indeed that is a problem in my prototype that I quickfixed somewhat dirty with the key
argument of sorted
.
for example, by using repr
as key
function to make the items sortable:
def test_ignore_order_key():
assert [{"f": "b"}, {"x": "y:"}] == IgnoreOrder([{"x": "y:"}, {"f": "b"}], key=repr)
apparently you added some special case handling for generators recently:
pytest-unordered/pytest_unordered.py
Lines 28 to 31 in e8f7915
why not generalize it to:
- if you use it
*args
-style likeunordered(1,2,3)
you don't care about type checking - if you use it single arg-style like
unordered([1,2,3])
orunordered((1,2,3))
or ... you do care a bout type checking
why not generalize it to:
* if you use it `*args`-style like `unordered(1,2,3)` you don't care about type checking * if you use it single arg-style like `unordered([1,2,3])` or `unordered((1,2,3))` or ... you do care a bout type checking
Good point. Can you create a pull request?
Thank you. It looks easier than I initially thought.