[PyObjC-svn] r2001 - in trunk/pyobjc/pyobjc-core: . Lib/objc Lib/objc/test Modules/objc

[email protected]
Newsgroups gmane.comp.python.pyobjc.cvs
Message-ID <[email protected]>
Author: ronaldoussoren
Date: Mon May  5 11:53:33 2008
New Revision: 2001

Log:
- copy.deepcopy support is not possible after all, implementation probably needs
pickle support first.

- add custom implementations of -copyWithZone: and -mutableCopyWithZone: for
  OC_PythonArray and OC_PythonDictionary (with tests)



Added:
   trunk/pyobjc/pyobjc-core/Lib/objc/test/test_dict_proxy.py   (contents, props changed)
   trunk/pyobjc/pyobjc-core/Lib/objc/test/test_list_proxy.py   (contents, props changed)
Modified:
   trunk/pyobjc/pyobjc-core/Lib/objc/_convenience.py
   trunk/pyobjc/pyobjc-core/Lib/objc/test/test_copying.py
   trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonArray.m
   trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonDictionary.m
   trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonObject.m
   trunk/pyobjc/pyobjc-core/NEWS.txt

Modified: trunk/pyobjc/pyobjc-core/Lib/objc/_convenience.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/Lib/objc/_convenience.py	(original)
+++ trunk/pyobjc/pyobjc-core/Lib/objc/_convenience.py	Mon May  5 11:53:33 2008
@@ -561,16 +561,17 @@
     ('__copy__', lambda self: self.copyWithZone_(None)),
 )
 
-NSKeyedArchiver = lookUpClass('NSKeyedArchiver')
-NSKeyedUnarchiver = lookUpClass('NSKeyedUnarchiver')
-def coder_deepcopy(self):
-    buf = NSKeyedArchiver.archivedDataWithRootObject_(self)
-    result = NSKeyedUnarchiver.unarchiveObjectWithData_(buf)
-    return result
-
-CONVENIENCE_METHODS['encodeWithCoder:'] = (
-    ('__deepcopy__', coder_deepcopy ),
-)
+# This won't work:
+#NSKeyedArchiver = lookUpClass('NSKeyedArchiver')
+#NSKeyedUnarchiver = lookUpClass('NSKeyedUnarchiver')
+#def coder_deepcopy(self, memo):
+#   buf = NSKeyedArchiver.archivedDataWithRootObject_(self)
+#   result = NSKeyedUnarchiver.unarchiveObjectWithData_(buf)
+#   return result
+#
+#CONVENIENCE_METHODS['encodeWithCoder:'] = (
+#   ('__deepcopy__', coder_deepcopy ),
+#)
 
 CLASS_METHODS['NSNull'] = (
     ('__nonzero__',  lambda self: False ),

Modified: trunk/pyobjc/pyobjc-core/Lib/objc/test/test_copying.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/Lib/objc/test/test_copying.py	(original)
+++ trunk/pyobjc/pyobjc-core/Lib/objc/test/test_copying.py	Mon May  5 11:53:33 2008
@@ -221,5 +221,22 @@
         self.assertEquals(o.x, 42)
         self.assertEquals(o.intVal(), 40)
 
+
+NSMutableArray = objc.lookUpClass("NSMutableArray")
+import copy
+
+class TestPyCopyObjC (objc.test.TestCase):
+    # Testcases that ensure that copy.copy works
+    # with Objective-C objects as well.
+
+    def testCopyArray(self):
+        a = NSMutableArray.arrayWithArray_(['a', 'b', 'c'])
+        self.assert_(isinstance(a, NSMutableArray))
+
+        b = copy.copy(a)
+        self.assert_(isinstance(b, NSMutableArray))
+        self.assert_(list(a) == list(b))
+
+
 if __name__ == "__main__":
     objc.test.main()

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonArray.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonArray.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonArray.m	Mon May  5 11:53:33 2008
@@ -449,50 +449,56 @@
 }
 
 
-#if 1
--(NSObject*)replacementObjectForArchiver:(NSArchiver*)archiver 
+-(id)copyWithZone:(NSZone*)zone
 {
-	(void)(archiver);
-	return self;
-}
+	if (PyObjC_CopyFunc) {
+		PyObjC_BEGIN_WITH_GIL
+			PyObject* copy = PyObject_CallFunctionObjArgs(PyObjC_CopyFunc,
+					value, NULL);
 
--(NSObject*)replacementObjectForKeyedArchiver:(NSKeyedArchiver*)archiver
-{
-	(void)(archiver);
-	return self;
-}
+			if (copy == NULL) {
+				PyObjC_GIL_FORWARD_EXC();
+			} 
 
--(NSObject*)replacementObjectForCoder:(NSKeyedArchiver*)archiver
-{
-	(void)(archiver);
-	return self;
-}
+			NSObject* result = PyObjC_PythonToId(copy);
+			Py_DECREF(copy);
 
--(NSObject*)replacementObjectForPortCoder:(NSKeyedArchiver*)archiver
-{
-	(void)(archiver);
-	return self;
-}
+			if (PyErr_Occurred()) {
+				PyObjC_GIL_FORWARD_EXC();
+			}
 
--(Class)classForArchiver
-{
-	return [OC_PythonArray class];
-}
+			[result retain];
 
--(Class)classForKeyedArchiver
-{
-	return [OC_PythonArray class];
-}
+			PyObjC_GIL_RETURN(result);
 
--(Class)classForCoder
-{
-	return [OC_PythonArray class];
+		PyObjC_END_WITH_GIL
+	} else {
+		return [super copyWithZone:zone];
+	}
 }
 
--(Class)classForPortCoder
+-(id)mutableCopyWithZone:(NSZone*)zone
 {
-	return [OC_PythonArray class];
-}
-#endif
+	if (PyObjC_CopyFunc) {
+		PyObjC_BEGIN_WITH_GIL
+			PyObject* copy = PySequence_List(value);
+			if (copy == NULL) {
+				PyObjC_GIL_FORWARD_EXC();
+			} 
 
+			NSObject* result = PyObjC_PythonToId(copy);
+			Py_DECREF(copy);
+
+			if (PyErr_Occurred()) {
+				PyObjC_GIL_FORWARD_EXC();
+			}
+
+			[result retain];
+			PyObjC_GIL_RETURN(result);
+
+		PyObjC_END_WITH_GIL
+	} else {
+		return [super mutableCopyWithZone:zone];
+	}
+}
 @end /* implementation OC_PythonArray */

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonDictionary.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonDictionary.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonDictionary.m	Mon May  5 11:53:33 2008
@@ -523,42 +523,63 @@
 	}
 }
 
-
-#if 1
-
--(NSObject*)replacementObjectForArchiver:(NSArchiver*)archiver
-{
-	(void)archiver;
-	return self;
-}
-
--(NSObject*)replacementObjectForKeyedArchiver:(NSKeyedArchiver*)archiver
-{
-	(void)archiver;
-	return self;
-}
-
-
--(Class)classForArchiver
+-(id)copyWithZone:(NSZone*)zone
 {
-	return [OC_PythonDictionary class];
-}
-
--(Class)classForKeyedArchiver
-{
-	return [OC_PythonDictionary class];
-}
-
--(Class)classForCoder
-{
-	return [OC_PythonDictionary class];
+	if (PyObjC_CopyFunc) {
+		PyObjC_BEGIN_WITH_GIL
+			PyObject* copy = PyObject_CallFunctionObjArgs(PyObjC_CopyFunc,
+					value, NULL);
+			if (copy == NULL) {
+				PyObjC_GIL_FORWARD_EXC();
+			} 
+
+			NSObject* result = PyObjC_PythonToId(copy);
+			Py_DECREF(copy);
+
+			if (PyErr_Occurred()) {
+				PyObjC_GIL_FORWARD_EXC();
+			}
+
+			[result retain];
+
+			PyObjC_GIL_RETURN(result);
+
+		PyObjC_END_WITH_GIL
+	} else {
+		return [super copyWithZone:zone];
+	}
 }
 
--(Class)classForPortCoder
+-(id)mutableCopyWithZone:(NSZone*)zone
 {
-	return [OC_PythonDictionary class];
+	if (PyObjC_CopyFunc) {
+		PyObjC_BEGIN_WITH_GIL
+			PyObject* copy = PyDict_New();
+			if (copy == NULL) {
+				PyObjC_GIL_FORWARD_EXC();
+			} 
+
+			int r = PyDict_Update(copy, value);
+			if (r == -1) {
+				PyObjC_GIL_FORWARD_EXC();
+			} 
+
+			NSObject* result = PyObjC_PythonToId(copy);
+			Py_DECREF(copy);
+
+			if (PyErr_Occurred()) {
+				PyObjC_GIL_FORWARD_EXC();
+			}
+
+			[result retain];
+
+			PyObjC_GIL_RETURN(result);
+
+		PyObjC_END_WITH_GIL
+	} else {
+		return [super mutableCopyWithZone:zone];
+	}
 }
 
-#endif
 
 @end  // interface OC_PythonDictionary

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonObject.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonObject.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonObject.m	Mon May  5 11:53:33 2008
@@ -399,7 +399,7 @@
 
 	} else {
 		PyObjC_BEGIN_WITH_GIL
-			copy = PyObject_CallFunction(PyObjC_CopyFunc, "O", pyObject);
+			copy = PyObject_CallFunctionObjArgs(PyObjC_CopyFunc, pyObject, NULL);
 			if (copy == NULL) {
 				PyObjC_GIL_FORWARD_EXC();
 			}

Modified: trunk/pyobjc/pyobjc-core/NEWS.txt
==============================================================================
--- trunk/pyobjc/pyobjc-core/NEWS.txt	(original)
+++ trunk/pyobjc/pyobjc-core/NEWS.txt	Mon May  5 11:53:33 2008
@@ -35,8 +35,14 @@
 - Objective-C classes that support the ``NSCopying`` protocol can now be
   copied using ``copy.copy`` as well.
 
-- Objective-C classes that support the ``NSCoding`` protocol can now be
-  copied using ``copy.deepcopy``.
+.. 
+   it would be nice to have the following, but that's not easy to achieve::
+	- Objective-C classes that support the ``NSCoding`` protocol can now be
+	  copied using ``copy.deepcopy``.
+
+- ``OC_PythonArray`` and ``OC_PythonDictionary`` now explicitly implement
+  ``copyWithZone:`` and ``mutableCopyWithZone:``, copies will now be 
+  Python objects instead of regular ``NSDictionary`` instances.
 
 - Pure Python objects now support the ``NSCopying`` protocol.
 

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.