summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-10-04 19:46:06 (GMT)
committerGuido van Rossum <guido@python.org>2001-10-04 19:46:06 (GMT)
commit50fda3ba267fe8c063ce83b832f349857ca7fdc3 (patch)
treec3f6dbc629cdc436c1f7714dacab4227b444c7e0
parentba001a0b676f640b3a11dea48b2a13d9fc0be746 (diff)
downloadcpython-50fda3ba267fe8c063ce83b832f349857ca7fdc3.zip
cpython-50fda3ba267fe8c063ce83b832f349857ca7fdc3.tar.gz
cpython-50fda3ba267fe8c063ce83b832f349857ca7fdc3.tar.bz2
Make new classes dynamic by default.
-rw-r--r--Misc/NEWS10
-rw-r--r--Objects/typeobject.c20
-rw-r--r--PLAN.txt20
3 files changed, 24 insertions, 26 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 1d437d0..726cc05 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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 */
diff --git a/PLAN.txt b/PLAN.txt
index c88511c..9e0fc67 100644
--- a/PLAN.txt
+++ b/PLAN.txt
@@ -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. ***