Commits

Ronald Oussoren committed cf312af

* Add testcases for the OC_PythonNumber class
* Fix issues found by these tests

Stil to do: finish the implementation of -descriptionWithLocale:

  • Participants
  • Parent commits 21e8569
  • Branches pyobjc-ancient

Comments (0)

Files changed (3)

File pyobjc-core/Lib/objc/test/test_number_proxy.py

+"""
+Tests for the proxy of Python numbers
+"""
+import sys
+import objc.test
+from objc.test.fnd import NSNumber, NSNumberFormatter
+from objc.test.pythonnumber import OC_TestNumber
+import objc
+
+OC_PythonNumber = objc.lookUpClass("OC_PythonNumber")
+NSCFNumber = objc.lookUpClass("NSCFNumber")
+
+NSOrderedAscending = -1
+NSOrderedSame = 0
+NSOrderedDescending = 1
+
+class TestNSNumber (objc.test.TestCase):
+    # These testcases check the behaviour of NSNumber, these
+    # are mostly here to verify that NSNumbers behave as
+    # we expect them to.
+
+    def testClass(self):
+        for m in ('numberWithInt_', 'numberWithFloat_', 'numberWithDouble_', 'numberWithShort_'):
+            v = getattr(NSNumber, m)(0)
+            self.assert_(isinstance(v, NSNumber))
+            self.assert_(not isinstance(v, OC_PythonNumber))
+            self.assert_(OC_TestNumber.numberClass_(v) is NSCFNumber)
+
+    def testShortConversions(self):
+        v = NSNumber.numberWithShort_(42)
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), 42.0)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), 42.0)
+
+    def testIntConversions(self):
+        v = NSNumber.numberWithInt_(42)
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), 42.0)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), 42.0)
+
+        # Negative values
+        v = NSNumber.numberWithInt_(-42)
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 214)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 65494)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 4294967254)
+
+        if sys.maxint == (2 ** 31) -1:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 4294967254)
+        else:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 18446744073709551574)
+
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 18446744073709551574)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), -42.0)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), -42.0)
+
+        # Overflow
+        v = NSNumber.numberWithInt_(892455)
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 39)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -25049)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 39)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 40487)
+
+    def testDoubleConversions(self):
+        v = NSNumber.numberWithDouble_(75.5)
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), 75.5)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), 75.5)
+
+        # Negative values
+        v = NSNumber.numberWithDouble_(-127.6)
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 129)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 65409)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 4294967169)
+
+        if sys.maxint == (2 ** 31) -1:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 4294967169)
+        else:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 18446744073709551488)
+
+        # XXX: the next one is actually incorrect (as can be seen by the following C code,
+        # but is what NSNumber returns).
+        #
+        #   double v = -127.6;
+        #   unsigned long long lv = v;
+        #   printf("%llu\n", lv);
+
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 18446744073709551488)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), -127.6)
+
+        # Overflow
+        v = NSNumber.numberWithDouble_(float(2**64 + 99))
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 0)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 0)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 0)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 0)
+
+    def testCompare(self):
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithLong_(1)), NSOrderedAscending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithUnsignedLongLong_(2**63)), NSOrderedAscending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithDouble_(42.0)), NSOrderedAscending)
+
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithLong_(-1)), NSOrderedDescending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithLongLong_(-2**60)), NSOrderedDescending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithDouble_(-42.0)), NSOrderedDescending)
+
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithLong_(0)), NSOrderedSame)
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithDouble_(0.0)), NSOrderedSame)
+        self.assertEquals(OC_TestNumber.compareA_andB_(NSNumber.numberWithLong_(0), NSNumber.numberWithLongLong_(0)), NSOrderedSame)
+
+    def testDescription(self):
+        v = OC_TestNumber.numberDescription_(NSNumber.numberWithInt_(0))
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, u"0")
+
+        v = OC_TestNumber.numberDescription_(NSNumber.numberWithLongLong_(2**60))
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, unicode(str(2**60)))
+
+        v = OC_TestNumber.numberDescription_(NSNumber.numberWithLongLong_(-2**60))
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, unicode(str(-2**60)))
+
+        v = OC_TestNumber.numberDescription_(NSNumber.numberWithDouble_(264.0))
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, u"264")
+
+
+class TestPyNumber (objc.test.TestCase):
+    # Basic tests of the proxy methods
+
+    def testClasses(self):
+        # Ensure that python numbers are proxied using the right proxy type
+        for v in (True, False, 0, 1, 2**32+1, 2**64+1, 42.5):
+            self.assert_(OC_TestNumber.numberClass_(v) is OC_PythonNumber)
+
+    def testPythonIntConversions(self):
+        # Conversions to other values. Note that values are converted
+        # using C casts, without any exceptions when converting a
+        # negative value to an unsigned one and without exceptions for
+        # overflow.
+        v = 42
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), 42.0)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), 42.0)
+
+        # Negative values
+        v = -42
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 214)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 65494)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 4294967254)
+
+        if sys.maxint == (2 ** 31) -1:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 4294967254)
+        else:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 18446744073709551574)
+
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 18446744073709551574)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), -42.0)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), -42.0)
+
+        # Overflow
+        v = 892455
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 39)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -25049)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 39)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 40487)
+
+    def testPythonLongConversions(self):
+        v = long(42)
+        self.assert_(isinstance(v, long))
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 42)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), 42.0)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), 42.0)
+
+        # Negative values
+        v = long(-42)
+        self.assert_(isinstance(v, long))
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), -42)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 214)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 65494)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 4294967254)
+
+        if sys.maxint == (2 ** 31) -1:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 4294967254)
+        else:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 18446744073709551574)
+
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 18446744073709551574)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), -42.0)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), -42.0)
+
+        # Overflow
+        v = long(892455)
+        self.assert_(isinstance(v, long))
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 39)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -25049)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 39)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 40487)
+
+        # Very much overflow
+        v = 2 ** 64 + 1
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 1)
+
+    def testDoubleConversions(self):
+        v = 75.5
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 75)
+        self.assertEquals(OC_TestNumber.numberAsFloat_(v), 75.5)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), 75.5)
+
+        # Negative values
+        v = -127.6
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsInt_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsLong_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsLongLong_(v), -127)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 129)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 65409)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedInt_(v), 4294967169)
+
+        if sys.maxint == (2 ** 31) -1:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 4294967169)
+        else:
+            self.assertEquals(OC_TestNumber.numberAsUnsignedLong_(v), 18446744073709551489)
+
+        self.assertEquals(OC_TestNumber.numberAsUnsignedLongLong_(v), 18446744073709551489)
+        self.assertEquals(OC_TestNumber.numberAsDouble_(v), -127.6)
+
+        # Overflow
+        v = float(2**64 + 99)
+
+        self.assertEquals(OC_TestNumber.numberAsBOOL_(v), 1)
+        self.assertEquals(OC_TestNumber.numberAsChar_(v), 0)
+        self.assertEquals(OC_TestNumber.numberAsShort_(v), 0)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedChar_(v), 0)
+        self.assertEquals(OC_TestNumber.numberAsUnsignedShort_(v), 0)
+
+    def testCompare(self):
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, 1), NSOrderedAscending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, 2**64), NSOrderedAscending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, 42.0), NSOrderedAscending)
+
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, -1), NSOrderedDescending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, -2**64), NSOrderedDescending)
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, -42.0), NSOrderedDescending)
+
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, 0), NSOrderedSame)
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, 0.0), NSOrderedSame)
+        self.assertEquals(OC_TestNumber.compareA_andB_(0, long(0)), NSOrderedSame)
+
+    def testNumberEqual(self):
+        self.assert_(not OC_TestNumber.number_isEqualTo_(0, 1))
+        self.assert_(not OC_TestNumber.number_isEqualTo_(0, 2**64))
+        self.assert_(not OC_TestNumber.number_isEqualTo_(0, 42.0))
+
+        self.assert_(not OC_TestNumber.number_isEqualTo_(0, -1))
+        self.assert_(not OC_TestNumber.number_isEqualTo_(0, -2**64))
+        self.assert_(not OC_TestNumber.number_isEqualTo_(0, -42.0))
+
+        self.assert_(OC_TestNumber.number_isEqualTo_(0, 0))
+        self.assert_(OC_TestNumber.number_isEqualTo_(0, 0.0))
+        self.assert_(OC_TestNumber.number_isEqualTo_(0, long(0)))
+
+    def testDescription(self):
+        v = OC_TestNumber.numberDescription_(0)
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, u"0")
+
+        v = OC_TestNumber.numberDescription_(2**64)
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, unicode(repr(2**64)))
+
+        v = OC_TestNumber.numberDescription_(-2**64)
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, unicode(repr(-2**64)))
+
+        v = OC_TestNumber.numberDescription_(264.0)
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, u"264.0")
+
+        v = OC_TestNumber.numberDescription_(False)
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, u"False")
+
+        v = OC_TestNumber.numberDescription_(True)
+        self.assert_(isinstance(v, unicode))
+        self.assertEquals(v, u"True")
+
+class TestInteractions (objc.test.TestCase):
+    # Test interactions between Python and NSNumber numbers
+    def testMixedCompare(self):
+        # compare for:
+        #   - python number to nsnumber
+        #   - nsnumber to python number
+        # For: (bool, int, long, float) vs (char, short, ...)
+        pass
+
+    def testMixedEquals(self):
+        # isEqualToNumber for:
+        #   - python number to nsnumber
+        #   - nsnumber to python number
+        # For: (bool, int, long, float) vs (char, short, ...)
+        pass
+
+
+class TestNumberFormatter (objc.test.TestCase):
+    # Test behaviour of an NSNumberFormatter, both with 
+    # Python numbers and NSNumbers
+    pass
+
+if __name__ == "__main__":
+    objc.test.main()

File pyobjc-core/Modules/objc/OC_PythonNumber.m

 			result =  (long long)PyFloat_AsDouble(value);
 			PyObjC_GIL_RETURN(result);
 		} else if (PyLong_Check(value)) {
-			result =  PyLong_AsLongLong(value);
+			result =  PyLong_AsUnsignedLongLongMask(value);
 			PyObjC_GIL_RETURN(result);
 		}
 	PyObjC_END_WITH_GIL
 			result =  (unsigned long long)PyFloat_AsDouble(value);
 			PyObjC_GIL_RETURN(result);
 		} else if (PyLong_Check(value)) {
-			result =  PyLong_AsUnsignedLongLong(value);
+			result =  PyLong_AsUnsignedLongLongMask(value);
 			PyObjC_GIL_RETURN(result);
 		}
 	PyObjC_END_WITH_GIL
 		if (repr == NULL) {
 			PyObjC_GIL_FORWARD_EXC();
 		}
+
+		PyObject* uniVal = PyUnicode_FromEncodedObject(repr, "ascii", "strict");
+		Py_DECREF(repr);
+		if (PyErr_Occurred()) {
+			PyObjC_GIL_FORWARD_EXC();
+		}
 	
-		result = PyObjC_PythonToId(repr);
+		result = PyObjC_PythonToId(uniVal);
+		Py_DECREF(uniVal);
 		if (PyErr_Occurred()) {
 			PyObjC_GIL_FORWARD_EXC();
 		}
 
-		Py_DECREF(repr);
 
 	PyObjC_END_WITH_GIL
 	return (NSString*)result;
 	}
 }
 
+- (NSComparisonResult)compare:(NSNumber *)aNumber
+{
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* other = PyObjC_IdToPython(aNumber);
+		if (other == NULL) {
+			PyObjC_GIL_FORWARD_EXC();
+		}
+
+		int r = PyObject_Compare(value, other);
+		Py_DECREF(other);
+		if (PyErr_Occurred()) {
+			PyObjC_GIL_FORWARD_EXC();
+		}
+
+		if (r < 0) {
+			PyObjC_GIL_RETURN(NSOrderedAscending);
+		} else if (r > 0) {
+			PyObjC_GIL_RETURN(NSOrderedDescending);
+		} else {
+			PyObjC_GIL_RETURN(NSOrderedSame);
+		}
+
+
+	PyObjC_END_WITH_GIL
+}
+
+-(BOOL)isEqualToNumber:(NSNumber*)aNumber
+{
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* other = PyObjC_IdToPython(aNumber);
+		if (other == NULL) {
+			PyObjC_GIL_FORWARD_EXC();
+		}
+
+		int r = PyObject_RichCompareBool(value, other, Py_EQ);
+		Py_DECREF(other);
+		if (r == -1) {
+			PyObjC_GIL_FORWARD_EXC();
+		}
+
+		if (r) {
+			PyObjC_GIL_RETURN(YES);
+		} else {
+			PyObjC_GIL_RETURN(NO);
+		}
+
+	PyObjC_END_WITH_GIL
+}
+
 #if 1
 
 -(NSObject*)replacementObjectForArchiver:(NSObject*)archiver
 	return [OC_PythonNumber class];
 }
 
+-(id)copy
+{
+	return [self copyWithZone:0];
+}
+
+-(id)copyWithZone:(NSZone*)zone
+{
+	(void)zone;
+	[self retain];
+	return self;
+}
+
+
 #endif
 @end

File pyobjc-core/Modules/objc/test/pythonnumber.m

+#include <Python.h>
+#include "pyobjc-api.h"
+
+#import <Foundation/Foundation.h>
+
+@interface OC_TestNumber : NSObject {}
++(Class)numberClass:(NSNumber*)number;
++(BOOL)numberAsBOOL:(NSNumber*)number;
++(char)numberAsChar:(NSNumber*)number;
++(short)numberAsShort:(NSNumber*)number;
++(int)numberAsInt:(NSNumber*)number;
++(long)numberAsLong:(NSNumber*)number;
++(long long)numberAsLongLong:(NSNumber*)number;
++(unsigned char)numberAsUnsignedChar:(NSNumber*)number;
++(unsigned short)numberAsUnsignedShort:(NSNumber*)number;
++(unsigned int)numberAsUnsignedInt:(NSNumber*)number;
++(unsigned long)numberAsUnsignedLong:(NSNumber*)number;
++(unsigned long long)numberAsUnsignedLongLong:(NSNumber*)number;
++(NSDecimal)numberAsDecimal:(NSNumber*)number;
++(float)numberAsFloat:(NSNumber*)number;
++(double)numberAsDouble:(NSNumber*)number;
+
++(const char*)objCTypeOf:(NSNumber*)number;
++(int)compareA:(NSNumber*)a andB:(NSNumber*)b;
++(BOOL)number:(NSNumber*)a isEqualTo:(NSNumber*)b;
++(NSString*)numberDescription:(NSNumber*)number;
++(NSString*)numberDescription:(NSNumber*)number withLocale:(id)aLocale;
+@end
+
+@implementation OC_TestNumber
+
++(Class)numberClass:(NSNumber*)number
+{
+	return [number class];
+}
+
++(const char*)objCTypeOf:(NSNumber*)number
+{
+	return [number objCType];
+}
+
++(int)compareA:(NSNumber*)a andB:(NSNumber*)b
+{
+	return [a compare:b];
+}
+
++(BOOL)number:(NSNumber*)a isEqualTo:(NSNumber*)b
+{
+	return [a isEqualToNumber:b];
+}
+
++(NSString*)numberDescription:(NSNumber*)number
+{
+	return [number description];
+}
+
++(NSString*)numberAsString:(NSNumber*)number
+{
+	return [number stringValue];
+}
+
++(NSString*)numberDescription:(NSNumber*)number withLocale:(id)aLocale
+{
+	return [number descriptionWithLocale:aLocale];
+}
+
++(BOOL)numberAsBOOL:(NSNumber*)number
+{
+	return [number boolValue];
+}
+
++(char)numberAsChar:(NSNumber*)number
+{
+	return [number charValue];
+}
+
++(short)numberAsShort:(NSNumber*)number
+{
+	return [number shortValue];
+}
+
++(int)numberAsInt:(NSNumber*)number
+{
+	return [number intValue];
+}
+
++(long)numberAsLong:(NSNumber*)number
+{
+	return [number longValue];
+}
+
++(long long)numberAsLongLong:(NSNumber*)number
+{
+	return [number longLongValue];
+}
+
++(unsigned char)numberAsUnsignedChar:(NSNumber*)number
+{
+	return [number unsignedCharValue];
+}
+
++(unsigned short)numberAsUnsignedShort:(NSNumber*)number
+{
+	return [number unsignedShortValue];
+}
+
++(unsigned int)numberAsUnsignedInt:(NSNumber*)number
+{
+	return [number unsignedIntValue];
+}
+
++(unsigned long)numberAsUnsignedLong:(NSNumber*)number
+{
+	return [number unsignedLongValue];
+}
+
++(unsigned long long)numberAsUnsignedLongLong:(NSNumber*)number
+{
+	return [number unsignedLongLongValue];
+}
+
++(NSDecimal)numberAsDecimal:(NSNumber*)number
+{
+	return [number decimalValue];
+}
+
++(float)numberAsFloat:(NSNumber*)number
+{
+	return [number floatValue];
+}
+
++(double)numberAsDouble:(NSNumber*)number
+{
+	return [number doubleValue];
+}
+
+
+@end
+
+
+static PyMethodDef NULL_methods[] = {
+	        { 0, 0, 0, 0 }
+};
+
+void initpythonnumber(void);
+void initpythonnumber(void)
+{
+	PyObject* m;
+
+	m = Py_InitModule4("pythonnumber", NULL_methods,
+		NULL, NULL, PYTHON_API_VERSION);
+
+	if (PyObjC_ImportAPI(m) < 0) return;
+
+	PyModule_AddObject(m, "OC_TestNumber",
+	    PyObjCClass_New([OC_TestNumber class]));
+}