Expr's __eq__ method is inherited from dataclass, which checks only fields/annotations declared in the instance's class, not fields/annotations inherited from superclasses. This means that type_ (declared in Expr) is not checked for any of the concrete subclasses. Hence, for example:
Const(3) == Const(3.0)
returns True.
We should require type to be equal for the Expr to be equal. (Since type may be "None" to indicate the type has not yet been computed by type propagation, we should probably add a method equals_modulo_none_type or similar.)
Note that this would happen as a side-effect of replacing KRecord with dataclass, which will automatically check inherited fields like type_. However it seems likely that most of the work here will be in fixing tests/etc. to work with this stricter definition of equality.
Expr's
__eq__
method is inherited from dataclass, which checks only fields/annotations declared in the instance's class, not fields/annotations inherited from superclasses. This means thattype_
(declared in Expr) is not checked for any of the concrete subclasses. Hence, for example:returns True.
We should require type to be equal for the Expr to be equal. (Since type may be "None" to indicate the type has not yet been computed by type propagation, we should probably add a method
equals_modulo_none_type
or similar.)Note that this would happen as a side-effect of replacing KRecord with dataclass, which will automatically check inherited fields like type_. However it seems likely that most of the work here will be in fixing tests/etc. to work with this stricter definition of equality.