diff Python/structmember.c @ 58018:46f4b7b5b4dd 3.1

Merged revisions 77161 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ................ r77161 | benjamin.peterson | 2009-12-30 13:44:54 -0600 (Wed, 30 Dec 2009) | 12 lines Merged revisions 77157 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77157 | benjamin.peterson | 2009-12-30 13:34:10 -0600 (Wed, 30 Dec 2009) | 5 lines check if the attribute is set before deleting it with T_OBJECT_EX (fixes #7604) Also, add a note to the docs about the better behavior of T_OBJECT_EX as compared to T_OBJECT. ........ ................
author Benjamin Peterson <benjamin@python.org>
date Wed, 30 Dec 2009 19:47:05 +0000
parents 85b67fb5672b
children a88e0f6ab945 a7b58f1e8af0
line wrap: on
line diff
--- a/Python/structmember.c	Wed Dec 30 16:25:13 2009 +0000
+++ b/Python/structmember.c	Wed Dec 30 19:47:05 2009 +0000
@@ -104,17 +104,27 @@
 {
 	PyObject *oldv;
 
+	addr += l->offset;
+
 	if ((l->flags & READONLY) || l->type == T_STRING)
 	{
 		PyErr_SetString(PyExc_AttributeError, "readonly attribute");
 		return -1;
 	}
-	if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) {
-		PyErr_SetString(PyExc_TypeError,
-				"can't delete numeric/char attribute");
-		return -1;
+	if (v == NULL) {
+		if (l->type == T_OBJECT_EX) {
+			/* Check if the attribute is set. */
+			if (*(PyObject **)addr == NULL) {
+				PyErr_SetString(PyExc_AttributeError, l->name);
+				return -1;
+			}
+		}
+		else if (l->type != T_OBJECT) {
+			PyErr_SetString(PyExc_TypeError,
+					"can't delete numeric/char attribute");
+			return -1;
+		}
 	}
-	addr += l->offset;
 	switch (l->type) {
 	case T_BOOL:{
 		if (!PyBool_Check(v)) {