Ronald Oussoren avatar Ronald Oussoren committed d0eda05

Workaround for a buglet in pickle. This also ensures that only the relevant
state gets placed into a pickle.

Comments (0)

Files changed (2)

Lib/objc/_pythonify.py

     def __getattr__(self, attr):
         return getattr(self.__pyobjc_object__, attr)
 
+    def __reduce__(self):
+        return (float, (float(self),))
+
 class OC_PythonLong(long):
 
     def __new__(cls, obj, value):
             raise AttributeError, "'%s' object has no attribute '%s')"%(self.__class__.__name__, attr)
         self.__dict__['__pyobjc_object__'] = value
 
+    def __reduce__(self):
+        return (long, (long(self),))
+
 class OC_PythonInt(int):
     __slots__=('__pyobjc_object__',)
 
     def __getattr__(self, attr):
         return getattr(self.__pyobjc_object__, attr)
 
+    def __reduce__(self):
+        return (int, (int(self),))
+
 NSNumber = _objc.lookUpClass('NSNumber')
 NSDecimalNumber = _objc.lookUpClass('NSDecimalNumber')
 Foundation = None

Lib/objc/test/test_pickle.py

+from Foundation import NSNumber
+import unittest
+from objc._pythonify import OC_PythonInt, OC_PythonFloat, OC_PythonLong
+import pickle
+import cPickle
+import sys
+
+class TestPickleNumber (unittest.TestCase):
+
+    def testPickleInt(self):
+        v = NSNumber.numberWithInt_(42)
+        self.assert_(isinstance(v, OC_PythonInt))
+
+        # First python pickle
+        s = pickle.dumps(v)
+        v2 = pickle.loads(s)
+        self.assertEquals(v2, v)
+        self.assert_(not isinstance(v2, OC_PythonInt))
+        self.assert_(isinstance(v2, int))
+
+        # Then C pickle
+        s = cPickle.dumps(v)
+        v2 = cPickle.loads(s)
+        self.assertEquals(v2, v)
+        self.assert_(not isinstance(v2, OC_PythonInt))
+        self.assert_(isinstance(v2, int))
+
+    def testPickleFloat(self):
+        v = NSNumber.numberWithFloat_(42)
+        self.assert_(isinstance(v, OC_PythonFloat))
+
+        # First python pickle
+        s = pickle.dumps(v)
+        v2 = pickle.loads(s)
+        self.assertEquals(v2, v)
+        self.assert_(not isinstance(v2, OC_PythonFloat))
+        self.assert_(isinstance(v2, float))
+
+        # Then C pickle
+        s = cPickle.dumps(v)
+        v2 = cPickle.loads(s)
+        self.assertEquals(v2, v)
+        self.assert_(not isinstance(v2, OC_PythonFloat))
+        self.assert_(isinstance(v2, float))
+
+    def testPickleLongLong(self):
+        v = NSNumber.numberWithLongLong_(sys.maxint + 3)
+        self.assert_(isinstance(v, OC_PythonLong))
+
+        # First python pickle
+        s = pickle.dumps(v)
+        v2 = pickle.loads(s)
+        self.assertEquals(v2, v)
+        self.assert_(not isinstance(v2, OC_PythonLong))
+        self.assert_(isinstance(v2, long))
+
+        # Then C pickle
+        s = cPickle.dumps(v)
+        v2 = cPickle.loads(s)
+        self.assertEquals(v2, v)
+        self.assert_(not isinstance(v2, OC_PythonLong))
+        self.assert_(isinstance(v2, long))
+
+
+
+
+if __name__ == "__main__":
+    unittest.main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.