diff options
author | Guido van Rossum <guido@python.org> | 2001-08-17 16:47:50 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-08-17 16:47:50 (GMT) |
commit | 1a49350e8d7fdf7c847cc41bc1d3511dd203320d (patch) | |
tree | 20b5eb20413550d1f150fadbe7526568a0b8529c | |
parent | 7cb32ae7bf1a9c3b9ce1ee0d93894a7a528a2a6f (diff) | |
download | cpython-1a49350e8d7fdf7c847cc41bc1d3511dd203320d.zip cpython-1a49350e8d7fdf7c847cc41bc1d3511dd203320d.tar.gz cpython-1a49350e8d7fdf7c847cc41bc1d3511dd203320d.tar.bz2 |
type_new(): look for __dynamic__ at the module level (after looking in
the class dict). Anything but a nonnegative int in either place is
*ignored* (before, a non-Boolean was an error). The default is still
static -- in a comparative test, Jeremy's Tools/compiler package ran
twice as slow (compiling itself) using dynamic as the default. (The
static version, which requires a few tweaks to avoid modifying class
variables, runs at about the same speed as the classic version.)
slot_tp_descr_get(): this also needed fallback behavior.
slot_tp_getattro(): remove a debug fprintf() call.
-rw-r--r-- | Objects/typeobject.c | 68 |
1 files changed, 54 insertions, 14 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 474ff3e..29cb203 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -566,23 +566,44 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) return NULL; } - /* Should this be a dynamic class (i.e. modifiable __dict__)? */ + /* Should this be a dynamic class (i.e. modifiable __dict__)? + Look in two places for a variable named __dynamic__: + 1) in the class dict + 2) in the module dict (globals) + The first variable that is an int >= 0 is used. + Otherwise, a default is calculated from the base classes: + if any base class is dynamic, this class is dynamic; otherwise + it is static. */ + dynamic = -1; /* Not yet determined */ + /* Look in the class */ tmp = PyDict_GetItemString(dict, "__dynamic__"); if (tmp != NULL) { - /* The class author has a preference */ - dynamic = PyObject_IsTrue(tmp); - Py_DECREF(tmp); + dynamic = PyInt_AsLong(tmp); if (dynamic < 0) - return NULL; + PyErr_Clear(); } - else { - /* Make a new class dynamic if any of its bases is dynamic. - This is not always the same as inheriting the __dynamic__ - class attribute! */ + if (dynamic < 0) { + /* Look in the module globals */ + tmp = PyEval_GetGlobals(); + if (tmp != NULL) { + tmp = PyDict_GetItemString(tmp, "__dynamic__"); + if (tmp != NULL) { + dynamic = PyInt_AsLong(tmp); + if (dynamic < 0) + PyErr_Clear(); + } + } + } + if (dynamic < 0) { + /* Make a new class dynamic if any of its bases is + dynamic. This is not always the same as inheriting + the __dynamic__ class attribute! */ dynamic = 0; for (i = 0; i < nbases; i++) { - tmptype = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); - if (tmptype->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { + tmptype = (PyTypeObject *) + PyTuple_GET_ITEM(bases, i); + if (tmptype->tp_flags & + Py_TPFLAGS_DYNAMICTYPE) { dynamic = 1; break; } @@ -2565,8 +2586,6 @@ slot_tp_getattro(PyObject *self, PyObject *name) /* Avoid further slowdowns */ if (tp->tp_getattro == slot_tp_getattro) tp->tp_getattro = PyObject_GenericGetAttr; - else - fprintf(stderr, "huh?\n"); return PyObject_GenericGetAttr(self, name); } return PyObject_CallFunction(getattr, "OO", self, name); @@ -2672,7 +2691,28 @@ slot_tp_iternext(PyObject *self) return PyObject_CallMethod(self, "next", ""); } -SLOT2(slot_tp_descr_get, "__get__", PyObject *, PyObject *, "OO") +static PyObject * +slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + PyTypeObject *tp = self->ob_type; + PyObject *get; + static PyObject *get_str = NULL; + + if (get_str == NULL) { + get_str = PyString_InternFromString("__get__"); + if (get_str == NULL) + return NULL; + } + get = _PyType_Lookup(tp, get_str); + if (get == NULL) { + /* Avoid further slowdowns */ + if (tp->tp_descr_get == slot_tp_descr_get) + tp->tp_descr_get = NULL; + Py_INCREF(self); + return self; + } + return PyObject_CallFunction(get, "OOO", self, obj, type); +} static int slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) |