I have a function, which can return either a tuple of two ints or a tuple of (None, None)
:
(for the purposes of this question, let's assume that this return format is the only way to do this, and it cannot be changed)
from typing import Tuple, Union
def foo(n: int) -> Union[Tuple[int, int], Tuple[None, None]]:
if n < 0:
return None, None
return n, n
Then I want to write a pytest
unittest to test this function. It's always said that one should compare to None
with is
, but this obviously doesn't work:
def test_foo():
assert foo(1) == (1, 1)
assert foo(-1) is (None, None) # fails obviously!
Should I in this situation just use ==
to compare the result?
def test_foo():
assert foo(1) == (1, 1)
assert foo(-1) == (None, None) # best way?
You should use ==
, but indeed it's not "obvious" that using is
would fail.
For example
def foo():
return (1, 2)
print(foo() is foo())
MAY actually return True
(it does in CPython, not sure about other implementations).
Tuples are NOT to be considered entities, but values. Identity on values shouldn't be used as it may match or not (like happens for example for strings or numbers).
If in the code above you use [1, 2]
instead of (1, 2)
then it's guaranteed that is
will return False
because lists are entities, not values, and identity can be used in predictable ways.