Author ncoghlan
Recipients amaury.forgeotdarc, barry, eikeon, glyph, gvanrossum, jek, ncoghlan, rhettinger, schmir
Date 2008-08-11.15:48:29
SpamBayes Score 1.5421e-13
Marked as misclassified No
Message-id <>
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
for the warnings - for classes with a metaclass implemented in Python,
the warning message will point to the __new__ method of the metaclass
instead of to the first line of the offending class definition. I don't
see a way around this problem, but it definitely caused me grief in
tracking down some of the misbehaving classes in the standard library
that use ABCMeta as their metaclass in 2.6 (I actually cheated and
recompiled with the stack level on the warnings set to 2 instead of 1).

The update also eliminates the spurious and not-so-spurious Py3k
warnings that this update triggered in the test suite under the -3 flag.
Most were just test suite classes that happen to become unhashable in
Py3k, but a few were classes in the standard lib itself that defined
__eq__ or __cmp__ methods that were incompatible with the default
__hash__ implementation (collections.Mapping, collections.Set,
unittest.TestSuite, xml.dom.minidom.NamedNodeMap, numbers.Number,
UserList.UserList). Instances of all of the affected classes are now
explicitly unhashable in 2.x as well as 3.x (note that any code which
relied on any of them being hashable was already broken due to the fact
that these classes didn't provide the correct hash and equality invariants).

The numbers.Number change deserves special mention - the actual warning
occurs further down in the number stack (when numbers.Complex defines a
new __eq__ method), but it seemed appropriate to block the inheritance
of object.__hash__ in Number since an id() based hash isn't appropriate
for any numeric type. This particular aspect of the change should
probably be forward ported to Py3k.

In implementing the warnings, I'm also pretty happy with the current
Py3k approach that overriding __cmp__ or __eq__ means that __hash__
isn't inherited *at all*, rather than restricting the block solely to
object.__hash__. The current behaviour is simple to explain, and more
importantly, I think it is more correct - any time you change the
definition of equality for the class, you really do need to think
carefully about what it means for mutability and hashability.

P.S. I should never have said this part of the change was going to be
easy, because that was just begging old Murphy to come slap me upside
the head...
Date User Action Args
2008-08-11 15:48:47ncoghlansetrecipients: + ncoghlan, gvanrossum, barry, rhettinger, amaury.forgeotdarc, schmir, jek, eikeon, glyph
2008-08-11 15:48:47ncoghlansetmessageid: <>
2008-08-11 15:48:31ncoghlanlinkissue2235 messages
2008-08-11 15:48:29ncoghlancreate