Skip to content

Commit 687ae00

Browse files
committed
Get rid of __defined__ and tp_defined -- there's no need to
distinguish __dict__ and __defined__ any more. In the C structure, tp_cache takes its place -- but this hasn't been implemented yet.
1 parent 6642653 commit 687ae00

File tree

4 files changed

+33
-67
lines changed

4 files changed

+33
-67
lines changed

Include/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ typedef struct _typeobject {
288288
inquiry tp_is_gc; /* For PyObject_IS_GC */
289289
PyObject *tp_bases;
290290
PyObject *tp_mro; /* method resolution order */
291-
PyObject *tp_defined;
291+
PyObject *tp_cache;
292292
PyObject *tp_subclasses;
293293
PyObject *tp_weaklist;
294294

Lib/inspect.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -200,24 +200,9 @@ def classify_class_attrs(cls):
200200
obj = getattr(cls, name)
201201

202202
# Figure out where it was defined.
203-
# A complication: static classes in 2.2 copy dict entries from
204-
# bases into derived classes, so it's not enough just to look for
205-
# "the first" class with the name in its dict. OTOH:
206-
# 1. Some-- but not all --methods in 2.2 come with an __objclass__
207-
# attr that answers the question directly.
208-
# 2. Some-- but not all --classes in 2.2 have a __defined__ dict
209-
# saying which names were defined by the class.
210203
homecls = getattr(obj, "__objclass__", None)
211204
if homecls is None:
212-
# Try __defined__.
213-
for base in mro:
214-
if hasattr(base, "__defined__"):
215-
if name in base.__defined__:
216-
homecls = base
217-
break
218-
if homecls is None:
219-
# Last chance (and first chance for classic classes): search
220-
# the dicts.
205+
# search the dicts.
221206
for base in mro:
222207
if name in base.__dict__:
223208
homecls = base

Misc/NEWS

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ 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.
7+
- New-style classes are now always dynamic (except for built-in and
8+
extension types). There was no longer a performance penalty, and I
9+
no longer see another reason to keep this baggage around. One relic
10+
remains: the __dict__ or a new-style class is a read-only proxy.
11+
You must set the class's attribute to modify. As a consequence, the
12+
__defined__ attribute of new-style types no longer exists, for lack
13+
of need: there is once again only one __dict__ (although in the
14+
future a __cache__ may be resurrected in its place).
1615

1716
- C.__doc__ now works as expected for new-style classes (in 2.2a4 it
1817
always returned None, even when there was a class docstring).

Objects/typeobject.c

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type_module(PyTypeObject *type, void *context)
4444
(int)(s - type->tp_name));
4545
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
4646
return PyString_FromString("__builtin__");
47-
mod = PyDict_GetItemString(type->tp_defined, "__module__");
47+
mod = PyDict_GetItemString(type->tp_dict, "__module__");
4848
if (mod != NULL && PyString_Check(mod)) {
4949
Py_INCREF(mod);
5050
return mod;
@@ -80,21 +80,10 @@ type_dict(PyTypeObject *type, void *context)
8080
return PyDictProxy_New(type->tp_dict);
8181
}
8282

83-
static PyObject *
84-
type_defined(PyTypeObject *type, void *context)
85-
{
86-
if (type->tp_defined == NULL) {
87-
Py_INCREF(Py_None);
88-
return Py_None;
89-
}
90-
return PyDictProxy_New(type->tp_defined);
91-
}
92-
9383
PyGetSetDef type_getsets[] = {
9484
{"__name__", (getter)type_name, NULL, NULL},
9585
{"__module__", (getter)type_module, (setter)type_set_module, NULL},
9686
{"__dict__", (getter)type_dict, NULL, NULL},
97-
{"__defined__", (getter)type_defined, NULL, NULL},
9887
{0}
9988
};
10089

@@ -838,8 +827,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
838827
Py_INCREF(base);
839828
type->tp_base = base;
840829

841-
/* Initialize tp_defined from passed-in dict */
842-
type->tp_defined = dict = PyDict_Copy(dict);
830+
/* Initialize tp_dict from passed-in dict */
831+
type->tp_dict = dict = PyDict_Copy(dict);
843832
if (dict == NULL) {
844833
Py_DECREF(type);
845834
return NULL;
@@ -973,14 +962,14 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
973962
int i, n;
974963
PyObject *mro, *res, *dict;
975964

976-
/* Look in tp_defined of types in MRO */
965+
/* Look in tp_dict of types in MRO */
977966
mro = type->tp_mro;
978967
assert(PyTuple_Check(mro));
979968
n = PyTuple_GET_SIZE(mro);
980969
for (i = 0; i < n; i++) {
981970
type = (PyTypeObject *) PyTuple_GET_ITEM(mro, i);
982971
assert(PyType_Check(type));
983-
dict = type->tp_defined;
972+
dict = type->tp_dict;
984973
assert(dict && PyDict_Check(dict));
985974
res = PyDict_GetItem(dict, name);
986975
if (res != NULL)
@@ -1014,7 +1003,7 @@ type_getattro(PyTypeObject *type, PyObject *name)
10141003
(PyObject *)type, (PyObject *)metatype);
10151004
}
10161005

1017-
/* Look in tp_defined of this type and its bases */
1006+
/* Look in tp_dict of this type and its bases */
10181007
res = _PyType_Lookup(type, name);
10191008
if (res != NULL) {
10201009
f = res->ob_type->tp_descr_get;
@@ -1070,7 +1059,7 @@ type_dealloc(PyTypeObject *type)
10701059
Py_XDECREF(type->tp_dict);
10711060
Py_XDECREF(type->tp_bases);
10721061
Py_XDECREF(type->tp_mro);
1073-
Py_XDECREF(type->tp_defined);
1062+
Py_XDECREF(type->tp_cache);
10741063
Py_XDECREF(type->tp_subclasses);
10751064
Py_XDECREF(et->name);
10761065
Py_XDECREF(et->slots);
@@ -1136,7 +1125,7 @@ type_traverse(PyTypeObject *type, visitproc visit, void *arg)
11361125
}
11371126

11381127
VISIT(type->tp_dict);
1139-
VISIT(type->tp_defined);
1128+
VISIT(type->tp_cache);
11401129
VISIT(type->tp_mro);
11411130
VISIT(type->tp_bases);
11421131
VISIT(type->tp_base);
@@ -1167,7 +1156,7 @@ type_clear(PyTypeObject *type)
11671156
}
11681157

11691158
CLEAR(type->tp_dict);
1170-
CLEAR(type->tp_defined);
1159+
CLEAR(type->tp_cache);
11711160
CLEAR(type->tp_mro);
11721161
CLEAR(type->tp_bases);
11731162
CLEAR(type->tp_base);
@@ -1455,7 +1444,7 @@ PyTypeObject PyBaseObject_Type = {
14551444
static int
14561445
add_methods(PyTypeObject *type, PyMethodDef *meth)
14571446
{
1458-
PyObject *dict = type->tp_defined;
1447+
PyObject *dict = type->tp_dict;
14591448

14601449
for (; meth->ml_name != NULL; meth++) {
14611450
PyObject *descr;
@@ -1474,7 +1463,7 @@ add_methods(PyTypeObject *type, PyMethodDef *meth)
14741463
static int
14751464
add_members(PyTypeObject *type, PyMemberDef *memb)
14761465
{
1477-
PyObject *dict = type->tp_defined;
1466+
PyObject *dict = type->tp_dict;
14781467

14791468
for (; memb->name != NULL; memb++) {
14801469
PyObject *descr;
@@ -1493,7 +1482,7 @@ add_members(PyTypeObject *type, PyMemberDef *memb)
14931482
static int
14941483
add_getset(PyTypeObject *type, PyGetSetDef *gsp)
14951484
{
1496-
PyObject *dict = type->tp_defined;
1485+
PyObject *dict = type->tp_dict;
14971486

14981487
for (; gsp->name != NULL; gsp++) {
14991488
PyObject *descr;
@@ -1746,7 +1735,6 @@ PyType_Ready(PyTypeObject *type)
17461735
return 0;
17471736
}
17481737
assert((type->tp_flags & Py_TPFLAGS_READYING) == 0);
1749-
assert(type->tp_dict == NULL);
17501738

17511739
type->tp_flags |= Py_TPFLAGS_READYING;
17521740

@@ -1773,16 +1761,16 @@ PyType_Ready(PyTypeObject *type)
17731761
goto error;
17741762
}
17751763

1776-
/* Initialize tp_defined */
1777-
dict = type->tp_defined;
1764+
/* Initialize tp_dict */
1765+
dict = type->tp_dict;
17781766
if (dict == NULL) {
17791767
dict = PyDict_New();
17801768
if (dict == NULL)
17811769
goto error;
1782-
type->tp_defined = dict;
1770+
type->tp_dict = dict;
17831771
}
17841772

1785-
/* Add type-specific descriptors to tp_defined */
1773+
/* Add type-specific descriptors to tp_dict */
17861774
if (add_operators(type) < 0)
17871775
goto error;
17881776
if (type->tp_methods != NULL) {
@@ -1798,12 +1786,6 @@ PyType_Ready(PyTypeObject *type)
17981786
goto error;
17991787
}
18001788

1801-
/* Temporarily make tp_dict the same object as tp_defined.
1802-
(This is needed to call mro(), and can stay this way for
1803-
dynamic types). */
1804-
Py_INCREF(type->tp_defined);
1805-
type->tp_dict = type->tp_defined;
1806-
18071789
/* Calculate method resolution order */
18081790
if (mro_internal(type) < 0) {
18091791
goto error;
@@ -2676,18 +2658,18 @@ add_tp_new_wrapper(PyTypeObject *type)
26762658
{
26772659
PyObject *func;
26782660

2679-
if (PyDict_GetItemString(type->tp_defined, "__new__") != NULL)
2661+
if (PyDict_GetItemString(type->tp_dict, "__new__") != NULL)
26802662
return 0;
26812663
func = PyCFunction_New(tp_new_methoddef, (PyObject *)type);
26822664
if (func == NULL)
26832665
return -1;
2684-
return PyDict_SetItemString(type->tp_defined, "__new__", func);
2666+
return PyDict_SetItemString(type->tp_dict, "__new__", func);
26852667
}
26862668

26872669
static int
26882670
add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped)
26892671
{
2690-
PyObject *dict = type->tp_defined;
2672+
PyObject *dict = type->tp_dict;
26912673

26922674
for (; wraps->name != NULL; wraps++) {
26932675
PyObject *descr;
@@ -2706,14 +2688,14 @@ add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped)
27062688
/* This function is called by PyType_Ready() to populate the type's
27072689
dictionary with method descriptors for function slots. For each
27082690
function slot (like tp_repr) that's defined in the type, one or
2709-
more corresponding descriptors are added in the type's tp_defined
2691+
more corresponding descriptors are added in the type's tp_dict
27102692
dictionary under the appropriate name (like __repr__). Some
27112693
function slots cause more than one descriptor to be added (for
27122694
example, the nb_add slot adds both __add__ and __radd__
27132695
descriptors) and some function slots compete for the same
27142696
descriptor (for example both sq_item and mp_subscript generate a
27152697
__getitem__ descriptor). This only adds new descriptors and
2716-
doesn't overwrite entries in tp_defined that were previously
2698+
doesn't overwrite entries in tp_dict that were previously
27172699
defined. The descriptors contain a reference to the C function
27182700
they must call, so that it's safe if they are copied into a
27192701
subtype's __dict__ and the subtype has a different C function in
@@ -3942,7 +3924,7 @@ fixup_slot_dispatchers(PyTypeObject *type)
39423924
base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
39433925
assert(PyType_Check(base));
39443926
descr = PyDict_GetItem(
3945-
base->tp_defined, p->name_strobj);
3927+
base->tp_dict, p->name_strobj);
39463928
if (descr != NULL)
39473929
break;
39483930
}
@@ -4055,7 +4037,7 @@ super_getattro(PyObject *self, PyObject *name)
40554037
tmp = PyTuple_GET_ITEM(mro, i);
40564038
assert(PyType_Check(tmp));
40574039
res = PyDict_GetItem(
4058-
((PyTypeObject *)tmp)->tp_defined, name);
4040+
((PyTypeObject *)tmp)->tp_dict, name);
40594041
if (res != NULL) {
40604042
Py_INCREF(res);
40614043
f = res->ob_type->tp_descr_get;

0 commit comments

Comments
 (0)