Skip to content

Commit d596f5a

Browse files
Isolate tp_dict.
1 parent 0effaaa commit d596f5a

File tree

6 files changed

+40
-16
lines changed

6 files changed

+40
-16
lines changed

Include/internal/pycore_object.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,11 @@ extern int _Py_CheckSlotResult(
332332

333333
// PyType_Ready() must be called if _PyType_IsReady() is false.
334334
// See also the Py_TPFLAGS_READY flag.
335-
#define _PyType_IsReady(type) ((type)->tp_dict != NULL)
335+
static inline int
336+
_PyType_IsReady(PyTypeObject *type)
337+
{
338+
return _PyType_GetDict(type) != NULL;
339+
}
336340

337341
// Test if a type supports weak references
338342
static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {

Include/internal/pycore_typeobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ extern void _PyTypes_Fini(PyInterpreterState *);
7878

7979
/* other API */
8080

81+
PyAPI_FUNC(PyObject *) _PyType_GetDict(PyTypeObject *);
8182
extern PyObject * _PyType_GetMRO(PyTypeObject *);
8283

8384
/* Length of array of slotdef pointers used to store slots with the

Modules/_abc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ _abc__abc_init(PyObject *module, PyObject *self)
453453
* their special status w.r.t. pattern matching. */
454454
if (PyType_Check(self)) {
455455
PyTypeObject *cls = (PyTypeObject *)self;
456-
PyObject *flags = PyDict_GetItemWithError(cls->tp_dict,
456+
PyObject *dict = _PyType_GetDict(cls);
457+
PyObject *flags = PyDict_GetItemWithError(dict,
457458
&_Py_ID(__abc_tpflags__));
458459
if (flags == NULL) {
459460
if (PyErr_Occurred()) {
@@ -472,7 +473,7 @@ _abc__abc_init(PyObject *module, PyObject *self)
472473
}
473474
((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS);
474475
}
475-
if (PyDict_DelItem(cls->tp_dict, &_Py_ID(__abc_tpflags__)) < 0) {
476+
if (PyDict_DelItem(dict, &_Py_ID(__abc_tpflags__)) < 0) {
476477
return NULL;
477478
}
478479
}

Objects/structseq.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const char * const PyStructSequence_UnnamedField = "unnamed field";
2626
static Py_ssize_t
2727
get_type_attr_as_size(PyTypeObject *tp, PyObject *name)
2828
{
29-
PyObject *v = PyDict_GetItemWithError(tp->tp_dict, name);
29+
PyObject *v = PyDict_GetItemWithError(_PyType_GetDict(tp), name);
3030
if (v == NULL && !PyErr_Occurred()) {
3131
PyErr_Format(PyExc_TypeError,
3232
"Missed attribute '%U' of type %s",
@@ -496,7 +496,7 @@ initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc,
496496
Py_INCREF(type);
497497

498498
if (initialize_structseq_dict(
499-
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
499+
desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) {
500500
Py_DECREF(type);
501501
return -1;
502502
}
@@ -532,7 +532,7 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
532532
}
533533

534534
if (initialize_structseq_dict(
535-
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
535+
desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) {
536536
PyMem_Free(members);
537537
return -1;
538538
}
@@ -657,7 +657,7 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
657657
}
658658

659659
if (initialize_structseq_dict(
660-
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
660+
desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) {
661661
Py_DECREF(type);
662662
return NULL;
663663
}

Objects/typeobject.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4250,7 +4250,7 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
42504250
Py_ssize_t n = PyTuple_GET_SIZE(mro);
42514251
for (Py_ssize_t i = 0; i < n; i++) {
42524252
PyObject *base = PyTuple_GET_ITEM(mro, i);
4253-
PyObject *dict = _PyType_CAST(base)->tp_dict;
4253+
PyObject *dict = get_dict(_PyType_CAST(base));
42544254
assert(dict && PyDict_Check(dict));
42554255
res = _PyDict_GetItem_KnownHash(dict, name, hash);
42564256
if (res != NULL) {
@@ -4585,7 +4585,7 @@ clear_static_type_interp_data(PyTypeObject *type)
45854585
static_builtin_state *state = _PyStaticType_GetState(type);
45864586
assert(state != NULL);
45874587

4588-
Py_CLEAR(type->tp_dict);
4588+
Py_CLEAR(state->tp_dict);
45894589
Py_CLEAR(state->tp_bases);
45904590
Py_CLEAR(state->tp_mro);
45914591
}
@@ -5481,7 +5481,7 @@ _PyType_GetSlotNames(PyTypeObject *cls)
54815481
assert(PyType_Check(cls));
54825482

54835483
/* Get the slot names from the cache in the class if possible. */
5484-
slotnames = PyDict_GetItemWithError(cls->tp_dict, &_Py_ID(__slotnames__));
5484+
slotnames = PyDict_GetItemWithError(get_dict(cls), &_Py_ID(__slotnames__));
54855485
if (slotnames != NULL) {
54865486
if (slotnames != Py_None && !PyList_Check(slotnames)) {
54875487
PyErr_Format(PyExc_TypeError,
@@ -5982,7 +5982,7 @@ object___reduce_ex___impl(PyObject *self, int protocol)
59825982

59835983
if (objreduce == NULL) {
59845984
objreduce = PyDict_GetItemWithError(
5985-
PyBaseObject_Type.tp_dict, &_Py_ID(__reduce__));
5985+
get_dict(&PyBaseObject_Type), &_Py_ID(__reduce__));
59865986
if (objreduce == NULL && PyErr_Occurred()) {
59875987
return NULL;
59885988
}
@@ -6695,20 +6695,38 @@ type_ready_set_bases(PyTypeObject *type)
66956695
static inline PyObject *
66966696
get_dict(PyTypeObject *type)
66976697
{
6698+
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
6699+
static_builtin_state *state = _PyStaticType_GetState(type);
6700+
assert(state != NULL);
6701+
return state->tp_dict;
6702+
}
66986703
return type->tp_dict;
66996704
}
67006705

6706+
PyObject *
6707+
_PyType_GetDict(PyTypeObject *type)
6708+
{
6709+
return get_dict(type);
6710+
}
6711+
67016712
static inline void
67026713
set_dict(PyTypeObject *type, PyObject *dict)
67036714
{
6715+
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
6716+
static_builtin_state *state = _PyStaticType_GetState(type);
6717+
assert(state != NULL);
6718+
state->tp_dict = dict;
6719+
return;
6720+
}
67046721
type->tp_dict = dict;
67056722
}
67066723

67076724
static inline void
67086725
clear_dict(PyTypeObject *type)
67096726
{
6710-
if (type->tp_dict) {
6711-
PyDict_Clear(type->tp_dict);
6727+
PyObject *dict = get_dict(type);
6728+
if (dict) {
6729+
PyDict_Clear(dict);
67126730
}
67136731
}
67146732

@@ -9379,7 +9397,7 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name,
93799397
}
93809398

93819399
/* Avoid recursing down into unaffected classes */
9382-
PyObject *dict = subclass->tp_dict;
9400+
PyObject *dict = get_dict(subclass);
93839401
if (dict != NULL && PyDict_Check(dict)) {
93849402
int r = PyDict_Contains(dict, attr_name);
93859403
if (r < 0) {
@@ -9547,7 +9565,7 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *
95479565
Py_INCREF(mro);
95489566
do {
95499567
PyObject *obj = PyTuple_GET_ITEM(mro, i);
9550-
PyObject *dict = _PyType_CAST(obj)->tp_dict;
9568+
PyObject *dict = get_dict(_PyType_CAST(obj));
95519569
assert(dict != NULL && PyDict_Check(dict));
95529570

95539571
res = PyDict_GetItemWithError(dict, name);

Python/context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,7 @@ _PyContext_Init(PyInterpreterState *interp)
13091309

13101310
PyObject *missing = get_token_missing();
13111311
if (PyDict_SetItemString(
1312-
PyContextToken_Type.tp_dict, "MISSING", missing))
1312+
_PyType_GetDict(&PyContextToken_Type), "MISSING", missing))
13131313
{
13141314
Py_DECREF(missing);
13151315
return _PyStatus_ERR("can't init context types");

0 commit comments

Comments
 (0)