diff options
author | Guido van Rossum <guido@python.org> | 2001-10-04 19:46:06 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-10-04 19:46:06 (GMT) |
commit | 50fda3ba267fe8c063ce83b832f349857ca7fdc3 (patch) | |
tree | c3f6dbc629cdc436c1f7714dacab4227b444c7e0 | |
parent | ba001a0b676f640b3a11dea48b2a13d9fc0be746 (diff) | |
download | cpython-50fda3ba267fe8c063ce83b832f349857ca7fdc3.zip cpython-50fda3ba267fe8c063ce83b832f349857ca7fdc3.tar.gz cpython-50fda3ba267fe8c063ce83b832f349857ca7fdc3.tar.bz2 |
Make new classes dynamic by default.
-rw-r--r-- | Misc/NEWS | 10 | ||||
-rw-r--r-- | Objects/typeobject.c | 20 | ||||
-rw-r--r-- | PLAN.txt | 20 |
3 files changed, 24 insertions, 26 deletions
@@ -4,6 +4,16 @@ Release date: 28-Sep-2100 Type/class unification and new-style classes +- New-style classes are now dynamic by default. Previous, they were + static (meaning class attributes could not be assigned to) and + dynamic classes had to be requested by adding __dynamic__ = 1 to the + body of the class or to the module. Static classes are faster than + dynamic classes, but dynamic classes are now at most 50% slower than + static classes; previously, they could be up to 10x slower. (This + was accomplished by making dynamic classes faster, not by making + static classes slower. :-) Note that according to one benchmark, + static classes are about the same speed as classic classes. + - C.__doc__ now works as expected for new-style classes (in 2.2a4 it always returned None, even when there was a class docstring). diff --git a/Objects/typeobject.c b/Objects/typeobject.c index fae159c..e4f07e5 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -759,9 +759,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) 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. */ + Otherwise, the default is dynamic. */ dynamic = -1; /* Not yet determined */ /* Look in the class */ tmp = PyDict_GetItemString(dict, "__dynamic__"); @@ -783,19 +781,9 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) } } 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) { - dynamic = 1; - break; - } - } + /* Default to dynamic */ + dynamic = 1; + } /* Check for a __slots__ sequence variable in dict, and count it */ @@ -4,21 +4,18 @@ Project: core implementation Still to do ----------- -Make __dynamic__ the default (this requires more performance work -- -one particular test, test_descr.inherits(), is about 10x slower when -__dynamic__ is 1. :-( There are two ways to go about the performance -work: +More performance work -- one particular test, test_descr.inherits(), +is still about 50% slower with dynamic classes. :-( The approach of +choice would be: - a) Add shortcuts to the slot_tp_XXX to recognize a PyWrapperDescr - with the correct wrap_tp_XXX function. - - b) Add a list or dict of weak refs to derived classes to each dynamic + Add a list of weak refs to derived classes to each dynamic class, and trap setattr+delattr on the base class so that they update the tp_XXX slot in each derived class when the base class __XXX__ gets set or deleted. More work, but more gain (zero waste - in slot_tp_XXX when __XXX__ is not overridden). + in slot_tp_XXX when __XXX__ is not overridden). This is currently + awaiting Fred turning the weak ref API into a standard object API. -Add __del__ handlers. +Add __del__ handlers? Allow assignment to __bases__ and __dict__? @@ -39,6 +36,9 @@ implemented. Done (mostly) ------------- +Make __dynamic__ the default. *** done (but more performance work +needs to be done). *** + Treat all binary operators the same way as I just did for rich comparison: in a <op> b, if type(a) is not type(b) and isinstance(b, type(a)), try b.__rop__(a) before trying a.__op__(b). *** Done. *** |