Commits

Bob Ippolito committed 3c380c5

correct -hash to __hash__ mapping

  • Participants
  • Parent commits b247d78
  • Branches pyobjc-ancient

Comments (0)

Files changed (2)

Lib/objc/_convenience.py

 """
 from _objc import setClassExtender, selector, lookUpClass, currentBundle, repythonify, splitSignature
 from itertools import imap
+import sys
 
 __all__ = ['CONVENIENCE_METHODS', 'CLASS_METHODS']
 
     ('__contains__', lambda self, elem: bool(self.containsObject_(container_wrap(elem)))),
 )
 
+
+
+def objc_hash(self, _max=sys.maxint, _const=((sys.maxint + 1L) * 2L)):
+    rval = self.hash()
+    if rval > _max:
+        rval -= _const
+        # -1 is not a valid hash in Python and hash(x) will
+        # translate a hash of -1 to -2, so we might as well
+        # do it here so that it's not too surprising..
+        if rval == -1:
+            rval = -2
+    return int(rval)
 CONVENIENCE_METHODS['hash'] = (
-    ('__hash__', lambda self: self.hash()),
+    ('__hash__', objc_hash),
 )
 
 CONVENIENCE_METHODS['isEqualTo:'] = (

Lib/objc/test/test_convenience.py

+import sys
+import unittest
+
+import objc
+import struct
+
+NSObject = objc.lookUpClass('NSObject')
+
+class OC_TestConveniences(NSObject):
+    def initWithHashValue_(self, hashValue):
+        self = super(OC_TestConveniences, self).init()
+        self.hashValue = hashValue
+        return self
+
+    def hash(self):
+        return self.hashValue
+
+class TestConveniences(unittest.TestCase):
+
+    def testHash(self):
+        for hashValue in (0, sys.maxint, sys.maxint + 1L, 0xFFFFFFFFL):
+            expect = struct.unpack('i', struct.pack('I', hashValue))[0]
+            # Python can't hash to -1.  Surprise! :)
+            if expect == -1:
+                expect = -2
+            o = OC_TestConveniences.alloc().initWithHashValue_(hashValue)
+            self.assertEquals(o.hash(), hashValue)
+            self.assertEquals(hash(o), expect, 'o.hash() == 0x%X | %r != %r' % (o.hash(), hash(o), expect))
+
+if __name__ == '__main__':
+    unittest.main()