summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2001-08-14 18:23:58 (GMT)
committerBarry Warsaw <barry@python.org>2001-08-14 18:23:58 (GMT)
commit142865cae1d68d1a597624af115abb60bd2bf11c (patch)
treea3443cd47a8b8132bd150aaecb7fcff6e0365bd3
parent5ef99a0bc56a3abfa6fdbbd47c10aef523833352 (diff)
downloadcpython-142865cae1d68d1a597624af115abb60bd2bf11c.zip
cpython-142865cae1d68d1a597624af115abb60bd2bf11c.tar.gz
cpython-142865cae1d68d1a597624af115abb60bd2bf11c.tar.bz2
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.
-rw-r--r--Objects/funcobject.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 311bcde..6532e58 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -151,7 +151,18 @@ func_getattro(PyObject *op, PyObject *name)
"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 @@ func_setattro(PyObject *op, PyObject *name, PyObject *value)
}
}
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);
}