]> granicus.if.org Git - python/commitdiff
func_getattro(), func_setattro(): Implement the new semantics for
authorBarry Warsaw <barry@python.org>
Tue, 14 Aug 2001 18:23:58 +0000 (18:23 +0000)
committerBarry Warsaw <barry@python.org>
Tue, 14 Aug 2001 18:23:58 +0000 (18:23 +0000)
    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.

Objects/funcobject.c

index 311bcdeff995a5a164ef3d405e39b1f1539295c8..6532e58c43e2fc2e5879ac1f1dccdc26275a9974 100644 (file)
@@ -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);
 }