Hello, I ran tests in some zope modules with python3.2, and got an exception:
$ cd zope.proxy $ python3.2 setup.py test ... File "/home/menesis/src/zope.proxy/build/lib.linux-i686-3.2/zope/proxy/__init__.py", line 16, in <module> from zope.interface import moduleProvides File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/__init__.py", line 53, in <module> from zope.interface.interface import Interface, _wire File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/interface.py", line 710, in <module> Interface = InterfaceClass("Interface", __module__ = 'zope.interface') File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/interface.py", line 479, in __init__ Specification.__init__(self, bases) File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/interface.py", line 266, in __init__ self.__bases__ = tuple(bases) File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/interface.py", line 290, in __setBases self.changed(self) File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/interface.py", line 309, in changed ancestors = ro(self) File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/ro.py", line 22, in ro return mergeOrderings([_flatten(object)]) File "/home/menesis/src/zope.proxy/zope.interface-3.6.3-py3.2-linux-i686.egg/zope/interface/ro.py", line 51, in mergeOrderings if o not in seen: TypeError: unhashable type: 'InterfaceClass' I found the following to explain what happens: http://stackoverflow.com/questions/1608842/types-that-define-eq-are-unhashable-in-python-3-x And a commit which does exactly that: define an __eq__ but not __hash__. Adding a simple def __hash__(self): return id(self) fixes the problem. This change was released as zope.interface 3.6.3. Earlier version does not have this problem. On Thu, 2011-05-26 12:10-0400, Tres Seaver wrote: > Log message for revision 121819: > Correct comparison of interfaces from different modules but with the same > name. > > Fixes LP #570942. > > > Changed: > U zope.interface/trunk/CHANGES.txt > U zope.interface/trunk/src/zope/interface/interface.py > U zope.interface/trunk/src/zope/interface/tests/test_interface.py > U zope.interface/trunk/src/zope/interface/tests/test_sorting.py > > -=- > Modified: zope.interface/trunk/CHANGES.txt > =================================================================== > --- zope.interface/trunk/CHANGES.txt 2011-05-26 11:27:21 UTC (rev 121818) > +++ zope.interface/trunk/CHANGES.txt 2011-05-26 16:10:57 UTC (rev 121819) > @@ -1,7 +1,12 @@ > ``zope.interface Changelog`` > ============================ > > +3.6.3 (unreleased) > +------------------ > > +- LP #570942: Now correctly compare interfaces from different modules but > + with the same names. > + > 3.6.2 (2011-05-17) > ------------------ > > > Modified: zope.interface/trunk/src/zope/interface/interface.py > =================================================================== > --- zope.interface/trunk/src/zope/interface/interface.py 2011-05-26 > 11:27:21 UTC (rev 121818) > +++ zope.interface/trunk/src/zope/interface/interface.py 2011-05-26 > 16:10:57 UTC (rev 121819) > @@ -670,32 +670,42 @@ > sort before None. > > """ > - if o1 == o2: > - return 0 > - > if o1 is None: > return 1 > if o2 is None: > return -1 > > - n1 = (getattr(o1, '__name__', ''), > - getattr(getattr(o1, '__module__', None), '__name__', '')) > - n2 = (getattr(o2, '__name__', ''), > - getattr(getattr(o2, '__module__', None), '__name__', '')) > + n1 = (getattr(o1, '__name__', ''), getattr(o1, '__module__', '')) > + n2 = (getattr(o2, '__name__', ''), getattr(o2, '__module__', '')) > > + # This spelling works under Python3, which doesn't have cmp(). > return (n1 > n2) - (n1 < n2) > > + def __eq__(self, other): > + c = self.__cmp(self, other) > + return c == 0 > + > + def __ne__(self, other): > + c = self.__cmp(self, other) > + return c != 0 > + > def __lt__(self, other): > c = self.__cmp(self, other) > - #print '<', self, other, c < 0, c > return c < 0 > > + def __le__(self, other): > + c = self.__cmp(self, other) > + return c <= 0 > + > def __gt__(self, other): > c = self.__cmp(self, other) > - #print '>', self, other, c > 0, c > return c > 0 > > + def __ge__(self, other): > + c = self.__cmp(self, other) > + return c >= 0 > > + > Interface = InterfaceClass("Interface", __module__ = 'zope.interface') > > class Attribute(Element): > > Modified: zope.interface/trunk/src/zope/interface/tests/test_interface.py > =================================================================== > --- zope.interface/trunk/src/zope/interface/tests/test_interface.py > 2011-05-26 11:27:21 UTC (rev 121818) > +++ zope.interface/trunk/src/zope/interface/tests/test_interface.py > 2011-05-26 16:10:57 UTC (rev 121819) > @@ -348,8 +348,40 @@ > # Old style classes don't have a '__class__' attribute > self.failUnlessRaises(AttributeError, I.providedBy, Bad) > > + def test_comparison_with_None(self): > + from zope.interface import Interface > > + class IEmpty(Interface): > + pass > > + self.failUnless(IEmpty < None) > + self.failUnless(IEmpty <= None) > + self.failIf(IEmpty == None) > + self.failUnless(IEmpty != None) > + self.failIf(IEmpty >= None) > + self.failIf(IEmpty > None) > + > + self.failIf(None < IEmpty) > + self.failIf(None <= IEmpty) > + self.failIf(None == IEmpty) > + self.failUnless(None != IEmpty) > + self.failUnless(None >= IEmpty) > + self.failUnless(None > IEmpty) > + > + def test_comparison_with_same_instance(self): > + from zope.interface import Interface > + > + class IEmpty(Interface): > + pass > + > + self.failIf(IEmpty < IEmpty) > + self.failUnless(IEmpty <= IEmpty) > + self.failUnless(IEmpty == IEmpty) > + self.failIf(IEmpty != IEmpty) > + self.failUnless(IEmpty >= IEmpty) > + self.failIf(IEmpty > IEmpty) > + > + > if sys.version_info >= (2, 4): > > def test_invariant_as_decorator(): > > Modified: zope.interface/trunk/src/zope/interface/tests/test_sorting.py > =================================================================== > --- zope.interface/trunk/src/zope/interface/tests/test_sorting.py > 2011-05-26 11:27:21 UTC (rev 121818) > +++ zope.interface/trunk/src/zope/interface/tests/test_sorting.py > 2011-05-26 16:10:57 UTC (rev 121819) > @@ -37,6 +37,14 @@ > l = [I1, None, I3, I5, I6, I4, I2] > l.sort() > self.assertEqual(l, [I1, I2, I3, I4, I5, I6, None]) > + > + def test_w_equal_names(self): > + # interfaces with equal names but different modules should sort by > + # module name > + from zope.interface.tests.m1 import I1 as m1_I1 > + l = [I1, m1_I1] > + l.sort() > + self.assertEqual(l, [m1_I1, I1]) > > def test_suite(): > return TestSuite(( _______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )