]> granicus.if.org Git - python/commitdiff
Make function objects somewhat mutable -- the members func_code,
authorGuido van Rossum <guido@python.org>
Fri, 22 May 1998 00:55:34 +0000 (00:55 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 22 May 1998 00:55:34 +0000 (00:55 +0000)
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.

Objects/funcobject.c

index d62dd08c190b14d1cbff2f79fc28277883c989e2..c9dd1398a2bae88fe4c93e913baf1a6197143461 100644 (file)
@@ -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*/