Commit 1a49350e authored by Guido van Rossum's avatar Guido van Rossum

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.
parent 7cb32ae7
...@@ -566,23 +566,44 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) ...@@ -566,23 +566,44 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
return NULL; 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__"); tmp = PyDict_GetItemString(dict, "__dynamic__");
if (tmp != NULL) { if (tmp != NULL) {
/* The class author has a preference */ dynamic = PyInt_AsLong(tmp);
dynamic = PyObject_IsTrue(tmp);
Py_DECREF(tmp);
if (dynamic < 0) if (dynamic < 0)
return NULL; PyErr_Clear();
} }
else { if (dynamic < 0) {
/* Make a new class dynamic if any of its bases is dynamic. /* Look in the module globals */
This is not always the same as inheriting the __dynamic__ tmp = PyEval_GetGlobals();
class attribute! */ 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; dynamic = 0;
for (i = 0; i < nbases; i++) { for (i = 0; i < nbases; i++) {
tmptype = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); tmptype = (PyTypeObject *)
if (tmptype->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { PyTuple_GET_ITEM(bases, i);
if (tmptype->tp_flags &
Py_TPFLAGS_DYNAMICTYPE) {
dynamic = 1; dynamic = 1;
break; break;
} }
...@@ -2565,8 +2586,6 @@ slot_tp_getattro(PyObject *self, PyObject *name) ...@@ -2565,8 +2586,6 @@ slot_tp_getattro(PyObject *self, PyObject *name)
/* Avoid further slowdowns */ /* Avoid further slowdowns */
if (tp->tp_getattro == slot_tp_getattro) if (tp->tp_getattro == slot_tp_getattro)
tp->tp_getattro = PyObject_GenericGetAttr; tp->tp_getattro = PyObject_GenericGetAttr;
else
fprintf(stderr, "huh?\n");
return PyObject_GenericGetAttr(self, name); return PyObject_GenericGetAttr(self, name);
} }
return PyObject_CallFunction(getattr, "OO", self, name); return PyObject_CallFunction(getattr, "OO", self, name);
...@@ -2672,7 +2691,28 @@ slot_tp_iternext(PyObject *self) ...@@ -2672,7 +2691,28 @@ slot_tp_iternext(PyObject *self)
return PyObject_CallMethod(self, "next", ""); 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 static int
slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment