Make Python hashing / identity traits for Formula
, Variable
, Expression
more strict
#8491
Labels
Formula
, Variable
, Expression
more strict
#8491
Relates #8315
At present, we overload
__hash__
and__eq__
- returningFormula
, a non-bool value - forVariable
andExpression
. With the implicit behavior of__nonzero__
forFormula
, a non-null Formula will always return true, meaning that some of Python's identity mechanisms will produce unexpected results.The main issue is that comparison in some unittests may not be fully checked, as
unittest
'sassertEqual
for two objects may be comparing by__eq__
and not__hash__
, since it will checka == b
, and then return(a == b).__nonzero__()
, which is not the check that the author would intend.We could throw on
__nonzero__
forFormula
; however, that will preventVariable
,Expression
, etc. from being used in containers likedict
, because, in CPython (Python 2.7.12) it does a comparison with__eq__
after finding the item according to its hash (which I guess is to avoid hash collisions):https://github.com/python/cpython/blob/1fae982b9b6fff5a987a69856b91339e5d023838/Objects/dictobject.c#L342
Potential solutions:
Formula.__nonzero__
, and require users use a wrapping dictionary that has keys which define__eq__
to compare based on the object's hash.sympy
s style: ensure that==
and!=
return boolean value comparison, and have other operators (< <= > >=
) return Formulas(I had tried to see if defining
__cmp__
could buy us something, but then re-read the docs which states that rich comparison (__eq__
,__lt
__, etc.) will take precedence over__cmp__
if they are defined.)My vote is for (1), as it is relatively simple, and we can massage the interface to
pybind11
to make it relatively seamless. Aside from this caveat indict
, I'm not sure of any other situations where this will affect us.(2) doesn't buy us much of anything w.r.t. #8315, as we still need other logical operators to play well in this framework.
(3) would not catch future errors.
@soonho-tri Can I ask what your opinion is on this, and if there are other solutions that you can think of?
The text was updated successfully, but these errors were encountered: