mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
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.
This commit is contained in:
parent
5ef99a0bc5
commit
142865cae1
1 changed files with 22 additions and 8 deletions
|
@ -151,7 +151,18 @@ func_getattro(PyObject *op, PyObject *name)
|
||||||
"function attributes not accessible in restricted mode");
|
"function attributes not accessible in restricted mode");
|
||||||
return NULL;
|
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);
|
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__")) {
|
else if (!strcmp(sname, "func_dict") || !strcmp(sname, "__dict__")) {
|
||||||
/* legal to del f.func_dict. Can only set func_dict to
|
/* It is illegal to del f.func_dict. Can only set
|
||||||
* NULL or a dictionary.
|
* func_dict to a dictionary.
|
||||||
*/
|
*/
|
||||||
if (value == Py_None)
|
if (value == NULL) {
|
||||||
value = NULL;
|
|
||||||
if (value != NULL && !PyDict_Check(value)) {
|
|
||||||
PyErr_SetString(
|
PyErr_SetString(
|
||||||
PyExc_TypeError,
|
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 -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyObject_GenericSetAttr(op, name, value);
|
return PyObject_GenericSetAttr(op, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue