diff options
author | Guido van Rossum <guido@python.org> | 1998-05-22 00:55:34 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1998-05-22 00:55:34 (GMT) |
commit | 0dabacee160cbb9d848b4e2b292e9e70aefd96f8 (patch) | |
tree | 6e04feaa1108db1c742fb391f3dd1ab0ab524ee0 | |
parent | b1ed9c529579ebeba7bafabeaa9254f8df3c33f9 (diff) | |
download | cpython-0dabacee160cbb9d848b4e2b292e9e70aefd96f8.zip cpython-0dabacee160cbb9d848b4e2b292e9e70aefd96f8.tar.gz cpython-0dabacee160cbb9d848b4e2b292e9e70aefd96f8.tar.bz2 |
Make function objects somewhat mutable -- the members func_code,
func_defaults and func_doc (alias __doc__) may be assigned to. For
the first two, there's a type restriction to code object and tuple,
respectively.
-rw-r--r-- | Objects/funcobject.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c index d62dd08..c9dd139 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -127,11 +127,11 @@ PyFunction_SetDefaults(op, defaults) #define OFF(x) offsetof(PyFunctionObject, x) static struct memberlist func_memberlist[] = { - {"func_code", T_OBJECT, OFF(func_code), READONLY}, + {"func_code", T_OBJECT, OFF(func_code)}, {"func_globals",T_OBJECT, OFF(func_globals), READONLY}, {"func_name", T_OBJECT, OFF(func_name), READONLY}, {"__name__", T_OBJECT, OFF(func_name), READONLY}, - {"func_defaults",T_OBJECT, OFF(func_defaults), READONLY}, + {"func_defaults",T_OBJECT, OFF(func_defaults)}, {"func_doc", T_OBJECT, OFF(func_doc)}, {"__doc__", T_OBJECT, OFF(func_doc)}, {NULL} /* Sentinel */ @@ -150,6 +150,38 @@ func_getattr(op, name) return PyMember_Get((char *)op, func_memberlist, name); } +static int +func_setattr(op, name, value) + PyFunctionObject *op; + char *name; + PyObject *value; +{ + if (PyEval_GetRestricted()) { + PyErr_SetString(PyExc_RuntimeError, + "function attributes not settable in restricted mode"); + return -1; + } + if (strcmp(name, "func_code") == 0) { + if (value == NULL || !PyCode_Check(value)) { + PyErr_SetString( + PyExc_TypeError, + "func_code must be set to a code object"); + return -1; + } + } + else if (strcmp(name, "func_defaults") == 0) { + if (value != Py_None && !PyTuple_Check(value)) { + PyErr_SetString( + PyExc_TypeError, + "func_defaults must be set to a tuple object"); + return -1; + } + if (value == Py_None) + value = NULL; + } + return PyMember_Set((char *)op, func_memberlist, name, value); +} + static void func_dealloc(op) PyFunctionObject *op; @@ -216,7 +248,7 @@ PyTypeObject PyFunction_Type = { (destructor)func_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)func_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ + (setattrfunc)func_setattr, /*tp_setattr*/ (cmpfunc)func_compare, /*tp_compare*/ (reprfunc)func_repr, /*tp_repr*/ 0, /*tp_as_number*/ |