Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 50fda3b

Browse files
committed
Make new classes dynamic by default.
1 parent ba001a0 commit 50fda3b

3 files changed

Lines changed: 24 additions & 26 deletions

File tree

Misc/NEWS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ Release date: 28-Sep-2100
44

55
Type/class unification and new-style classes
66

7+
- New-style classes are now dynamic by default. Previous, they were
8+
static (meaning class attributes could not be assigned to) and
9+
dynamic classes had to be requested by adding __dynamic__ = 1 to the
10+
body of the class or to the module. Static classes are faster than
11+
dynamic classes, but dynamic classes are now at most 50% slower than
12+
static classes; previously, they could be up to 10x slower. (This
13+
was accomplished by making dynamic classes faster, not by making
14+
static classes slower. :-) Note that according to one benchmark,
15+
static classes are about the same speed as classic classes.
16+
717
- C.__doc__ now works as expected for new-style classes (in 2.2a4 it
818
always returned None, even when there was a class docstring).
919

Objects/typeobject.c

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -759,9 +759,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
759759
1) in the class dict
760760
2) in the module dict (globals)
761761
The first variable that is an int >= 0 is used.
762-
Otherwise, a default is calculated from the base classes:
763-
if any base class is dynamic, this class is dynamic; otherwise
764-
it is static. */
762+
Otherwise, the default is dynamic. */
765763
dynamic = -1; /* Not yet determined */
766764
/* Look in the class */
767765
tmp = PyDict_GetItemString(dict, "__dynamic__");
@@ -783,19 +781,9 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
783781
}
784782
}
785783
if (dynamic < 0) {
786-
/* Make a new class dynamic if any of its bases is
787-
dynamic. This is not always the same as inheriting
788-
the __dynamic__ class attribute! */
789-
dynamic = 0;
790-
for (i = 0; i < nbases; i++) {
791-
tmptype = (PyTypeObject *)
792-
PyTuple_GET_ITEM(bases, i);
793-
if (tmptype->tp_flags &
794-
Py_TPFLAGS_DYNAMICTYPE) {
795-
dynamic = 1;
796-
break;
797-
}
798-
}
784+
/* Default to dynamic */
785+
dynamic = 1;
786+
799787
}
800788

801789
/* Check for a __slots__ sequence variable in dict, and count it */

PLAN.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,18 @@ Project: core implementation
44
Still to do
55
-----------
66

7-
Make __dynamic__ the default (this requires more performance work --
8-
one particular test, test_descr.inherits(), is about 10x slower when
9-
__dynamic__ is 1. :-( There are two ways to go about the performance
10-
work:
7+
More performance work -- one particular test, test_descr.inherits(),
8+
is still about 50% slower with dynamic classes. :-( The approach of
9+
choice would be:
1110

12-
a) Add shortcuts to the slot_tp_XXX to recognize a PyWrapperDescr
13-
with the correct wrap_tp_XXX function.
14-
15-
b) Add a list or dict of weak refs to derived classes to each dynamic
11+
Add a list of weak refs to derived classes to each dynamic
1612
class, and trap setattr+delattr on the base class so that they
1713
update the tp_XXX slot in each derived class when the base class
1814
__XXX__ gets set or deleted. More work, but more gain (zero waste
19-
in slot_tp_XXX when __XXX__ is not overridden).
15+
in slot_tp_XXX when __XXX__ is not overridden). This is currently
16+
awaiting Fred turning the weak ref API into a standard object API.
2017

21-
Add __del__ handlers.
18+
Add __del__ handlers?
2219

2320
Allow assignment to __bases__ and __dict__?
2421

@@ -39,6 +36,9 @@ implemented.
3936
Done (mostly)
4037
-------------
4138

39+
Make __dynamic__ the default. *** done (but more performance work
40+
needs to be done). ***
41+
4242
Treat all binary operators the same way as I just did for rich
4343
comparison: in a <op> b, if type(a) is not type(b) and isinstance(b,
4444
type(a)), try b.__rop__(a) before trying a.__op__(b). *** Done. ***

0 commit comments

Comments
 (0)