While working on a difference engine to identify differences in very large data structures, I noticed that a type
comparison between identical-but-redeclared namedtuples
misbehaves. Redeclaring the namedtuples
is unavoidable*. Here is a minimal example:
def test_named_tuples_same_type():
from collections import namedtuple
X = namedtuple("X", "x")
a = X(1)
# We are unable to avoid redeclaring X
X = namedtuple("X", "x")
b = X(1)
print(repr(a))
print(repr(b))
# X(x=1)
# X(x=1)
assert isinstance(type(a), type(b)) # fail
assert type(a) == type(b) # fail
The asserts return:
> assert isinstance(type(a), type(b)) # fail
E AssertionError: assert False
E + where False = isinstance(<class 'tests.test_deep_diff.X'>, <class 'tests.test_deep_diff.X'>)
E + where <class 'tests.test_deep_diff.X'> = type(X(x=1))
E + and <class 'tests.test_deep_diff.X'> = type(X(x=1))
and
> assert type(a) == type(b) # fail
E AssertionError: assert <class 'tests.test_deep_diff.X'> == <class 'tests.test_deep_diff.X'>
How to assert the type of both are equal or semantically equal (without str(type())
)?
*Redeclaring the namedtuple
is unavoidable because it takes place in unmodifiable exec
'd code to generate the data structures being diffed.