diff Objects/funcobject.c @ 19244:fbe2074c5fa5 legacy-trunk

func_getattro(), func_setattro(): Implement the new semantics for setting and deleting a function's __dict__ attribute. Deleting it, or setting it to a non-dictionary result in a TypeError. Note that getting it the first time magically initializes it to an empty dict so that func.__dict__ will always appear to be a dictionary (never None). Closes SF bug #446645.
author Barry Warsaw <barry@python.org>
date Tue, 14 Aug 2001 18:23:58 +0000
parents 09df3254b49d
children 0e70df98424e
line wrap: on
line diff
--- a/Objects/funcobject.c	Tue Aug 14 18:22:24 2001 +0000
+++ b/Objects/funcobject.c	Tue Aug 14 18:23:58 2001 +0000
@@ -151,7 +151,18 @@
 		  "function attributes not accessible in restricted mode");
 		return NULL;
 	}
-
+	/* If func_dict is being accessed but no attribute has been set
+	 * yet, then initialize it to the empty dictionary.
+	 */
+	if ((!strcmp(sname, "func_dict") || !strcmp(sname, "__dict__"))
+	     && ((PyFunctionObject*)op)->func_dict == NULL)
+	{
+		PyFunctionObject* funcop = (PyFunctionObject*)op;
+		
+		funcop->func_dict = PyDict_New();
+		if (funcop->func_dict == NULL)
+			return NULL;
+	}
 	return PyObject_GenericGetAttr(op, name);
 }
 
@@ -190,19 +201,22 @@
 		}
 	}
 	else if (!strcmp(sname, "func_dict") || !strcmp(sname, "__dict__")) {
-		/* legal to del f.func_dict.  Can only set func_dict to
-		 * NULL or a dictionary.
+		/* It is illegal to del f.func_dict.  Can only set
+		 * func_dict to a dictionary.
 		 */
-		if (value == Py_None)
-			value = NULL;
-		if (value != NULL && !PyDict_Check(value)) {
+		if (value == NULL) {
 			PyErr_SetString(
 				PyExc_TypeError,
-				"func_dict must be set to a dict object");
+				"function's dictionary may not be deleted");
+			return -1;
+		}
+		if (!PyDict_Check(value)) {
+			PyErr_SetString(
+				PyExc_TypeError,
+				"setting function's dictionary to a non-dict");
 			return -1;
 		}
 	}
-
 	return PyObject_GenericSetAttr(op, name, value);
 }