Skip to content

Commit 8c20bb1

Browse files
ericsnowcurrentlyhrnciar
authored andcommitted
00402: Add PyType_GetDict()
This should make pyqt6 build with Python 3.12. For more infor see: python#105747
1 parent 705b245 commit 8c20bb1

File tree

5 files changed

+44
-2
lines changed

5 files changed

+44
-2
lines changed

Doc/c-api/type.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ Type Objects
5050
The return type is now ``unsigned long`` rather than ``long``.
5151
5252
53+
.. c:function:: PyObject* PyType_GetDict(PyTypeObject* type)
54+
55+
Return the type object's internal namespace, which is otherwise only
56+
exposed via a read-only proxy (``cls.__dict__``). This is a
57+
replacement for accessing :c:member:`~PyTypeObject.tp_dict` directly.
58+
The returned dictionary must be treated as read-only.
59+
60+
This function isn't intended for general use. It's meant for
61+
specific embedding and language-binding cases, where direct access
62+
to the dict is necessary and indirect access (e.g. via the proxy)
63+
isn't adequate. Extension modules may continue to use ``tp_dict``,
64+
directly or indirectly, when setting up their own types.
65+
66+
.. versionadded:: 3.12
67+
68+
5369
.. c:function:: void PyType_Modified(PyTypeObject *type)
5470
5571
Invalidate the internal lookup cache for the type and all of its

Doc/c-api/typeobj.rst

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Quick Reference
110110
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
111111
| :c:member:`~PyTypeObject.tp_base` | :c:type:`PyTypeObject` * | __base__ | | | X | |
112112
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
113-
| :c:member:`~PyTypeObject.tp_dict` | :c:type:`PyObject` * | __dict__ | | | ? | |
113+
| <<:c:member:`~PyTypeObject.tp_dict`>> | :c:type:`PyObject` * | __dict__ | | | ? | |
114114
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
115115
| :c:member:`~PyTypeObject.tp_descr_get` | :c:type:`descrgetfunc` | __get__ | | | | X |
116116
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
@@ -157,6 +157,9 @@ Quick Reference
157157
**<>**: Names in angle brackets should be initially set to ``NULL`` and
158158
treated as read-only.
159159
160+
**<<>>**: Names in double angle brackets should be initially set to
161+
``NULL`` and treated as read-only after initialization.
162+
160163
**[]**: Names in square brackets are for internal use only.
161164
162165
**<R>** (as a prefix) means the field is required (must be non-``NULL``).
@@ -1717,7 +1720,17 @@ and :c:type:`PyType_Type` effectively act as defaults.)
17171720
called; it may also be initialized to a dictionary containing initial attributes
17181721
for the type. Once :c:func:`PyType_Ready` has initialized the type, extra
17191722
attributes for the type may be added to this dictionary only if they don't
1720-
correspond to overloaded operations (like :meth:`__add__`).
1723+
correspond to overloaded operations (like :meth:`__add__`). Once
1724+
initialization for the type has finished, this field should be
1725+
treated as read-only.
1726+
1727+
.. versionchanged:: 3.12
1728+
1729+
Internals detail: For the static builtin types this is always ``NULL``.
1730+
Instead, the dict for each is stored on ``PyInterpreterState``.
1731+
If needed, use :c:func:`PyType_GetDict` to get the corresponding
1732+
dict for those types. This is not normally necessary,
1733+
and certainly not for user-defined type objects.
17211734

17221735
**Inheritance:**
17231736

Include/cpython/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *
283283
PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *);
284284
PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
285285
PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *);
286+
PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
286287

287288
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
288289
PyAPI_FUNC(void) _Py_BreakPoint(void);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The new :c:func:`PyType_GetDict` provides the dictionary for the given type
2+
object that is normally exposed by ``cls.__dict__``. Normally it's
3+
sufficient to use :c:member:`~PyTypeObject.tp_dict`, but for the static
4+
builtin types ``tp_dict`` is now always ``NULL``. ``PyType_GetDict()``
5+
provides the correct dict object instead.

Objects/typeobject.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,13 @@ _PyType_GetDict(PyTypeObject *self)
238238
return lookup_tp_dict(self);
239239
}
240240

241+
PyObject *
242+
PyType_GetDict(PyTypeObject *self)
243+
{
244+
PyObject *dict = lookup_tp_dict(self);
245+
return _Py_XNewRef(dict);
246+
}
247+
241248
static inline void
242249
set_tp_dict(PyTypeObject *self, PyObject *dict)
243250
{

0 commit comments

Comments
 (0)