Subset operator behaving inconsistently

Viewed 36

Working on a project that stores and fetches data in sqlalchemy, I encounter a confusing error in testing a custom filter function. The filter function returns a list of "Move Orders" from the database, and in testing I assert that this list is a subset of the list of all orders:

assert filtered_orders <= all_orders

I have three "Stockpoints" (other sqlalchemy table class) that may have MoveOrders associated with them, and running this test in a loop over each, it passes for all except the last "Stockpoint":

assert filtered_orders <= all_orders 
TypeError: '<=' not supported between instances of 'MoveOrder' and 'MoveOrder'

As seen in the error message, on the last pass (last stockpoint), it evaluates the lists to be of type MoveOrder; the type of the lists' elements. Some further inspection:

print(f"types: {type(filtered_orders)} and {type(all_orders)}")
>types: <class 'list'> and <class 'list'>

assert isinstance(filtered_orders, list)
assert isinstance(all_orders, list)
assert filtered_orders <= all_orders
TypeError: '<=' not supported between instances of 'MoveOrder' and 'MoveOrder'

As you can see in the last code block, inspecting the variables filtered_orders and all_orders individually shows that they are of type list and pass individual isinstance() asserts... until the line where they are evaluated with the <= operator! Any idea how this sudden "change of mind" could be occurring?

1 Answers

There's enough details flying around in this question that I thought it would be worth putting up an answer.

The reason why you're having trouble is that <= and other comparison operators mean different things between sets and lists. For sets,

{1,2} <= {1,2,3}

is testing whether set1 is a subset of set2 (in this case, the result is True).

However:

[1,2] <= [1,2,3]

is not testing subsets - <= isn't defined that way for lists. In the case of lists, what you're actually testing is this:

list1[0] <= list2[0] and list1[1] <= list2[1] and ......

that is, each element is compared against each other element at the same position. That's why this:

[1,2] <= [1,2,3]

is True but this:

[2,1] <= [1,2,3]

is False.

This explains the error; when you do this:

filtered_orders <= all_orders 

it's comparing a MoveOrder object in filtered_orders to a MoveOrder object in all_orders, but class MoveOrder does not have the <= comparison defined, so the operation fails. As you've tried, checking for subset using sets fixes the issue.

Related