You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Regression with __hash__ definition and rich comparison operators #45890
A new behavior was introduced in r59106 in python trunk, which look
suspicious to me. Basically, every time a class defines a comparison
operator, it's __hash__ method is defined to None. The simple following
example shows it:
>>> classA(object):
... def__init__(self, b):
... self.b = b
... def__cmp__(self, other):
... ifnotisinstance(other, A):
... return-1
... returncmp(self.b, other.b)
...
>>> hash(A(2))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Also, to be more clear, that happens when you define any of the
functions in the name_op array (lt, __le___, __gt__, __ge__, ...).
It's not just a problem about the object being non hashable.
This was done intentionally -- if you define a comparison without
defining a hash, the default hash will not match your comparison, and
your objects will misbehave when used as dictionary keys.
Can you give more details about the Zope issue? I agree that needs to
be resolved before we release 2.6.
exarkun commented on Dec 3, 2007
exarkunmannequin
Mannequin
More actions
zope.interface.interface.InterfaceClass implements __lt__ and __gt__.
It doesn't override any of the other comparison methods, and it relies
on inheriting an identity-based __hash__ from its parent.
Disabling __hash__ when __cmp__ or __eq__ is defined makes sense, but it
does not seem like it needs to be disabled if only __lt__ or __gt__ is
defined.
You have a point. Can you suggest a patch that fixes this?
Question though -- what semantics are used for __lt__ and __gt__ that
they don't require overriding __eq__?
exarkun commented on Dec 3, 2007
exarkunmannequin
Mannequin
More actions
It implements ordering based on the interface's fully-qualified Python
name (ie, (module, __name__)). This is compatible with the default
__eq__ implementation.
Still, this would go much faster if someone other than myself could be
coerced into researching how to fix this (at least the Zope use -- I
haven't heard back from the OP).
therve commented on Dec 3, 2007
thervemannequin
MannequinAuthor
More actions
There are different ways to fix this. Reverting r59016 is one of them,
but I guess it's not an acceptable solution :).
From what I understand of the changes, removing the operations (lt,
__gt__, __le__, __ge__) from the name_op array would fix this. But I
have to understand why they have been put in there in the first place.
I'll try tomorrow, you assign this to me if you want.
Well, the name_op array is used for other purposes. Perhaps the main
issue is that the presence of any of these causes the "rich comparison"
functionality to be overridden. But please do look into this if you can!
therve commented on Dec 4, 2007
thervemannequin
MannequinAuthor
More actions
I gave it a try. The following patch corrects 2 problems:
classes with only __lt__ and __gt__ defined are hashable
classes defining __eq__ get a meaningful exception.
I've restricted the hash_name_op to the bare minimum, but no tests
failed, so I supposed it was enough :).
Please review.
therve commented on Dec 19, 2007
thervemannequin
MannequinAuthor
More actions
This is probably not the best moment (holidays etc), but please take
this issue seriously. This problem completely block the community
builders at pybots.org, and make any tests on current python trunk
impossible. This also means that if in the meantime another regression
appear, it will be even more difficult to solve it afterwards.
Also, zope is not the only one affected, storm seems to suffer from the
problem too (not exacly the same, though). As twisted is also unusable
without zope.interface, that makes several project that can't follow
python developpement at all (zope.interface error happens at import
time, for the record).
If this problem isn't solved in a reasonable time, it really questions
the future of the community builders and their purpose.
To be honest, I have no idea what pybots is, and how it's affected.
Maybe you can get someone else interested in reviewing the code? I'm
focusing mostly on Py3k.
Activity
therve commentedon Dec 3, 2007
A new behavior was introduced in r59106 in python trunk, which look
suspicious to me. Basically, every time a class defines a comparison
operator, it's __hash__ method is defined to None. The simple following
example shows it:
The problematic change is here:
http://svn.python.org/view/python/trunk/Objects/typeobject.c?rev=59106&r1=58032&r2=59106
And mainly the overrides_hash call in inherit_slots.
FWIW, I've encounter the problem because zope.interface is now usable on
trunk.
therve commentedon Dec 3, 2007
Of course, I meant unusable.
therve commentedon Dec 3, 2007
Also, to be more clear, that happens when you define any of the
functions in the name_op array (lt, __le___, __gt__, __ge__, ...).
It's not just a problem about the object being non hashable.
gvanrossum commentedon Dec 3, 2007
This was done intentionally -- if you define a comparison without
defining a hash, the default hash will not match your comparison, and
your objects will misbehave when used as dictionary keys.
Can you give more details about the Zope issue? I agree that needs to
be resolved before we release 2.6.
exarkun commentedon Dec 3, 2007
zope.interface.interface.InterfaceClass implements __lt__ and __gt__.
It doesn't override any of the other comparison methods, and it relies
on inheriting an identity-based __hash__ from its parent.
Disabling __hash__ when __cmp__ or __eq__ is defined makes sense, but it
does not seem like it needs to be disabled if only __lt__ or __gt__ is
defined.
gvanrossum commentedon Dec 3, 2007
You have a point. Can you suggest a patch that fixes this?
Question though -- what semantics are used for __lt__ and __gt__ that
they don't require overriding __eq__?
exarkun commentedon Dec 3, 2007
It implements ordering based on the interface's fully-qualified Python
name (ie, (module, __name__)). This is compatible with the default
__eq__ implementation.
gvanrossum commentedon Dec 3, 2007
Fair enough.
Still, this would go much faster if someone other than myself could be
coerced into researching how to fix this (at least the Zope use -- I
haven't heard back from the OP).
therve commentedon Dec 3, 2007
There are different ways to fix this. Reverting r59016 is one of them,
but I guess it's not an acceptable solution :).
From what I understand of the changes, removing the operations (lt,
__gt__, __le__, __ge__) from the name_op array would fix this. But I
have to understand why they have been put in there in the first place.
I'll try tomorrow, you assign this to me if you want.
gvanrossum commentedon Dec 3, 2007
Well, the name_op array is used for other purposes. Perhaps the main
issue is that the presence of any of these causes the "rich comparison"
functionality to be overridden. But please do look into this if you can!
therve commentedon Dec 4, 2007
I gave it a try. The following patch corrects 2 problems:
I've restricted the hash_name_op to the bare minimum, but no tests
failed, so I supposed it was enough :).
Please review.
therve commentedon Dec 19, 2007
This is probably not the best moment (holidays etc), but please take
this issue seriously. This problem completely block the community
builders at pybots.org, and make any tests on current python trunk
impossible. This also means that if in the meantime another regression
appear, it will be even more difficult to solve it afterwards.
Also, zope is not the only one affected, storm seems to suffer from the
problem too (not exacly the same, though). As twisted is also unusable
without zope.interface, that makes several project that can't follow
python developpement at all (zope.interface error happens at import
time, for the record).
If this problem isn't solved in a reasonable time, it really questions
the future of the community builders and their purpose.
Thanks.
gvanrossum commentedon Dec 19, 2007
To be honest, I have no idea what pybots is, and how it's affected.
Maybe you can get someone else interested in reviewing the code? I'm
focusing mostly on Py3k.
gvanrossum commentedon Dec 19, 2007
Committed revision 59576.
I found some time.
Happy pybotting!
therve commentedon Dec 20, 2007
Thanks a lot!