diff options
author | Barry Warsaw <barry@python.org> | 2001-08-14 18:23:58 (GMT) |
---|---|---|
committer | Barry Warsaw <barry@python.org> | 2001-08-14 18:23:58 (GMT) |
commit | 142865cae1d68d1a597624af115abb60bd2bf11c (patch) | |
tree | a3443cd47a8b8132bd150aaecb7fcff6e0365bd3 /Objects | |
parent | 5ef99a0bc56a3abfa6fdbbd47c10aef523833352 (diff) | |
download | cpython-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.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/funcobject.c | 30 |
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); } |