[Python-checkins] r60001 - in python/trunk: Lib/ctypes/test/test_arrays.py Misc/NEWS Modules/_ctypes/_ctypes.c

thomas.heller python-checkins at python.org
Wed Jan 16 20:16:28 CET 2008


Author: thomas.heller
Date: Wed Jan 16 20:16:27 2008
New Revision: 60001

Modified:
   python/trunk/Lib/ctypes/test/test_arrays.py
   python/trunk/Misc/NEWS
   python/trunk/Modules/_ctypes/_ctypes.c
Log:
Convert the internal ctypes array type cache to a WeakValueDict so
that array types do not live longer than needed.


Modified: python/trunk/Lib/ctypes/test/test_arrays.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_arrays.py	(original)
+++ python/trunk/Lib/ctypes/test/test_arrays.py	Wed Jan 16 20:16:27 2008
@@ -116,5 +116,19 @@
             self.failUnlessEqual(sz[1:4:2], "o")
             self.failUnlessEqual(sz.value, "foo")
 
+    def test_cache(self):
+        # Array types are cached internally in the _ctypes extension,
+        # in a WeakValueDictionary.  Make sure the array type is
+        # removed from the cache when the itemtype goes away.  This
+        # test will not fail, but will show a leak in the testsuite.
+
+        # Create a new type:
+        class my_int(c_int):
+            pass
+        # Create a new array type based on it:
+        t1 = my_int * 1
+        t2 = my_int * 1
+        self.failUnless(t1 is t2)
+
 if __name__ == '__main__':
     unittest.main()

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Wed Jan 16 20:16:27 2008
@@ -364,6 +364,9 @@
 Library
 -------
 
+- Convert the internal ctypes array type cache to a WeakValueDict so
+  that array types do not live longer than needed.
+
 - Issue #1786: pdb should use its own stdin/stdout around an exec call
   and when creating a recursive instance.
 

Modified: python/trunk/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/trunk/Modules/_ctypes/_ctypes.c	(original)
+++ python/trunk/Modules/_ctypes/_ctypes.c	Wed Jan 16 20:16:27 2008
@@ -127,6 +127,7 @@
 
 PyObject *PyExc_ArgError;
 static PyTypeObject Simple_Type;
+PyObject *array_types_cache;
 
 char *conversion_mode_encoding = NULL;
 char *conversion_mode_errors = NULL;
@@ -4086,16 +4087,10 @@
 PyObject *
 CreateArrayType(PyObject *itemtype, Py_ssize_t length)
 {
-	static PyObject *cache;
 	PyObject *key;
 	PyObject *result;
 	char name[256];
 
-	if (cache == NULL) {
-		cache = PyDict_New();
-		if (cache == NULL)
-			return NULL;
-	}
 #if (PY_VERSION_HEX < 0x02050000)
 	key = Py_BuildValue("(Oi)", itemtype, length);
 #else
@@ -4103,12 +4098,12 @@
 #endif
 	if (!key)
 		return NULL;
-	result = PyDict_GetItem(cache, key);
+	result = PyObject_GetItem(array_types_cache, key);
 	if (result) {
-		Py_INCREF(result);
 		Py_DECREF(key);
 		return result;
-	}
+	} else
+		PyErr_Clear();
 
 	if (!PyType_Check(itemtype)) {
 		PyErr_SetString(PyExc_TypeError,
@@ -4138,7 +4133,11 @@
 		);
 	if (!result)
 		return NULL;
-	PyDict_SetItem(cache, key, result);
+	if (-1 == PyObject_SetItem(array_types_cache, key, result)) {
+		Py_DECREF(key);
+		Py_DECREF(result);
+		return NULL;
+	}
 	Py_DECREF(key);
 	return result;
 }
@@ -4951,6 +4950,7 @@
 init_ctypes(void)
 {
 	PyObject *m;
+	PyObject *weakref;
 
 /* Note:
    ob_type is the metatype (the 'type'), defaults to PyType_Type,
@@ -4963,6 +4963,16 @@
 	if (!m)
 		return;
 
+	weakref = PyImport_ImportModule("weakref");
+	if (weakref == NULL)
+		return;
+	array_types_cache = PyObject_CallMethod(weakref,
+						"WeakValueDictionary",
+						NULL);
+	if (array_types_cache == NULL)
+		return;
+	Py_DECREF(weakref);
+
 	if (PyType_Ready(&PyCArg_Type) < 0)
 		return;
 


More information about the Python-checkins mailing list