-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
__eq__ / __hash__ check doesn't take inheritance into account #46488
Comments
In 2.6a, seems like the __hash__ implementation and __eq__ must be >>> class Base(object):
... def __init__(self, name):
... self.name = name
... def __eq__(self, other):
... return self.name == other.name
... def __hash__(self):
... return hash(self.name)
...
>>> class Extended(Base):
... def __eq__(self, other):
... print "trace: __eq__ called"
... return Base.__eq__(self, other)
...
>>> hash(Base('b1'))
603887253
>>> hash(Extended('e1'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'Extended' |
This issue is similar to bpo-1549. Note that only new-style classes are I think the change was intentional. Guido, do you confirm? However there should be some documentation about it, a NEWS entry or an The initial modification appeared in the py3k branch (r51454): |
Wouldn't you expect this sort of thing to break code? Does it meet the |
The py3k feature was intentional. I'm not sure who did the backport (could've been me, long ago). I think |
The attached patch reverts r59576 and the part of r59106 about the It also adds the py3k warning:: |
I noticed that my patch uses Py_TYPE(self)->tp_hash, whereas normal I am almost sure that both expressions return the same value. |
HERE BE DRAGONS There are cases where Py_TYPE(self)->tp_hash is the function currently |
Ah, I remember that it took me some time to understand the boundaries Here is another version of the patch, which does not test tp_hash while |
Hi Amaury, thanks for your work on this. I applied your patch and looked (1) I don't think you need to add a warning to classic classes that (2) I can't seen to trigger the warning for new classes (and yes, I >>> class C(object):
... def __eq__(self, other): return False
...
>>> hash(C())
-134976284 (3) test_Hashable in test_collections.py fails. This is because the >>> list.__hash__([])
-135100116 but >>> hash([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list' Note that in 2.5, both raise TypeError. |
Let's try to have this resolved before the next release. Also let's try not to accidentally merge the 2.6 changes related to this |
Note: some more tests also fail: test_descr, test_quopri, test_set |
Here is a new patch, all tests pass.
I had to add two TPSLOT entries to the slodefs list; can you please |
Guido, can you comment on Amaury's latest patch? I'm going to bump this |
As barry said, this should have been a release blocker for the first |
I'm going to have to ask someone else to look at this code. I am too |
Amaury's patch doesn't currently remove the new-in-2.6 code that turns P.S. you'd think I would have learnt by now not to try to make sense of |
Thanks for giving this some time. I think that backwards compatibility So, concluding, insofar as the proposal is to revert 2.6 to the 2.5 |
The _new__/init stuff showed up on my diff as well (obviously) - I'll dig into this further today and tomorrow - I'll probably start by |
Attached patch allows classes to explicitly block inheritance of This is similar to the approach used in Py3k, but allows __hash__ to be |
Unassigning for the moment - I'll take a look at adding the Py3k warning It would be nice to avoid the explicit check for Py_None in (Also, glyph, I'd love to know if my patch helps to clear up Django's |
Suggestion from GvR (one I like): instead of re-using Py_None, add a new (I'll keep the None at the Python level though, since that matches the |
I don't like the changes in listobject.c and dictobject.c: they seem to |
Unhashable types that implement an "I'm not hashable" __hash__ method |
Isn't that a serious compatibility issue? 2.5 code should work on 2.6 For deque objects, I don't get your point: Python 2.6b1+ (trunk, Jul 1 2008, 22:35:48) [MSC v.1500 32 bit Intel)]
on win32
>>> from collections import deque
>>> hash(deque())
TypeError: deque objects are unhashable |
As far as deque goes, the following behaviour on the trunk is the Python 2.6b1+ (trunk:64655, Jul 2 2008, 22:48:24)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import deque, Hashable
>>> isinstance(deque(), Hashable)
True All of the container types that my patch touches were already unhashable Since collections.Hashable is new in 2.6, I can live with it returning |
Attached updated patch which implements Guido's suggestion from above All tests which don't depend on a -u resource flag still pass (currently |
Two failures in the -uall run (test_codecmaps_hk, test_linuxaudiodev). |
Fixed for 2.6 in r64962 and the underlying PyObject_HashNotImplemented Still need to update the C API documentation and the library reference, |
How's this going? |
The documentation and Py3k warning will be ready for the third beta next |
Py3k warnings for this have been checked in on the trunk as r65642. There's an unfortunate problem with having to define a fixed stack level The update also eliminates the spurious and not-so-spurious Py3k The numbers.Number change deserves special mention - the actual warning In implementing the warnings, I'm also pretty happy with the current P.S. I should never have said this part of the change was going to be |
I still intend to do the necessary documentation updates for this, but |
Let's lower the priority a little then. |
numbers.Number change forward ported to Py3k in r65808 Docs updated for 2.6 and 3.0 in r65810 and r65811 respectively. Which means I can finally close this one :) |
Reopening - still need to fix the Python level docs for hash() and |
__hash__() documentation fixed for 2.6 in r66085 and for 3.0 in r66086. |
…_hash__" method not being inherited because of python/cpython#46488.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: