[Python-checkins] r54379 - in python/branches/release25-maint: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c

ziga.seilnacht python-checkins at python.org
Wed Mar 14 13:34:36 CET 2007


Author: ziga.seilnacht
Date: Wed Mar 14 13:34:30 2007
New Revision: 54379

Modified:
   python/branches/release25-maint/Lib/test/test_descr.py
   python/branches/release25-maint/Misc/NEWS
   python/branches/release25-maint/Objects/typeobject.c
Log:
Patch #1680015: Don't modify __slots__ tuple if it contains an unicode
name. Remove a reference leak that happened if the name could not be
converted to string.
 (backport from rev. 54378)

Modified: python/branches/release25-maint/Lib/test/test_descr.py
==============================================================================
--- python/branches/release25-maint/Lib/test/test_descr.py	(original)
+++ python/branches/release25-maint/Lib/test/test_descr.py	Wed Mar 14 13:34:30 2007
@@ -1210,6 +1210,29 @@
     class C(object):
         __slots__ = ["a", "a_b", "_a", "A0123456789Z"]
 
+    # Test unicode slot names
+    try:
+        unichr
+    except NameError:
+        pass
+    else:
+        # _unicode_to_string used to modify slots in certain circumstances 
+        slots = (unicode("foo"), unicode("bar"))
+        class C(object):
+            __slots__ = slots
+        x = C()
+        x.foo = 5
+        vereq(x.foo, 5)
+        veris(type(slots[0]), unicode)
+        # this used to leak references
+        try:
+            class C(object):
+                __slots__ = [unichr(128)]
+        except (TypeError, UnicodeEncodeError):
+            pass
+        else:
+            raise TestFailed, "[unichr(128)] slots not caught" 
+
     # Test leaks
     class Counted(object):
         counter = 0    # counts the number of instances alive

Modified: python/branches/release25-maint/Misc/NEWS
==============================================================================
--- python/branches/release25-maint/Misc/NEWS	(original)
+++ python/branches/release25-maint/Misc/NEWS	Wed Mar 14 13:34:30 2007
@@ -12,6 +12,9 @@
 Core and builtins
 -----------------
 
+- Patch #1680015: Don't modify __slots__ tuple if it contains an unicode
+  name.
+
 - Patch #922167: Python no longer segfaults when faced with infinitely
   self-recursive reload() calls (as reported by bug #742342).
 

Modified: python/branches/release25-maint/Objects/typeobject.c
==============================================================================
--- python/branches/release25-maint/Objects/typeobject.c	(original)
+++ python/branches/release25-maint/Objects/typeobject.c	Wed Mar 14 13:34:30 2007
@@ -1573,29 +1573,33 @@
 static PyObject *
 _unicode_to_string(PyObject *slots, Py_ssize_t nslots)
 {
-	PyObject *tmp = slots;
-	PyObject *o, *o1;
+	PyObject *tmp = NULL;
+	PyObject *slot_name, *new_name;
 	Py_ssize_t i;
-	ssizessizeargfunc copy = slots->ob_type->tp_as_sequence->sq_slice;
+
 	for (i = 0; i < nslots; i++) {
-		if (PyUnicode_Check(o = PyTuple_GET_ITEM(tmp, i))) {
-			if (tmp == slots) {
-				tmp = copy(slots, 0, PyTuple_GET_SIZE(slots));
+		if (PyUnicode_Check(slot_name = PyTuple_GET_ITEM(slots, i))) {
+			if (tmp == NULL) {
+				tmp = PySequence_List(slots);
 				if (tmp == NULL)
 					return NULL;
 			}
-			o1 = _PyUnicode_AsDefaultEncodedString
-					(o, NULL);
-			if (o1 == NULL) {
+			new_name = _PyUnicode_AsDefaultEncodedString(slot_name,
+								     NULL);
+			if (new_name == NULL) {
 				Py_DECREF(tmp);
-				return 0;
+				return NULL;
 			}
-			Py_INCREF(o1);
-			Py_DECREF(o);
-			PyTuple_SET_ITEM(tmp, i, o1);
+			Py_INCREF(new_name);
+			PyList_SET_ITEM(tmp, i, new_name);
+			Py_DECREF(slot_name);
 		}
 	}
-	return tmp;
+	if (tmp != NULL) {
+		slots = PyList_AsTuple(tmp);
+		Py_DECREF(tmp);
+	}
+	return slots;
 }
 #endif
 
@@ -1742,12 +1746,12 @@
 
 #ifdef Py_USING_UNICODE
 		tmp = _unicode_to_string(slots, nslots);
+		if (tmp == NULL)
+			goto bad_slots;
 		if (tmp != slots) {
 			Py_DECREF(slots);
 			slots = tmp;
 		}
-		if (!tmp)
-			return NULL;
 #endif
 		/* Check for valid slot names and two special cases */
 		for (i = 0; i < nslots; i++) {


More information about the Python-checkins mailing list