Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita840806

Browse files
gh-105227: Add PyType_GetDict() (GH-105747)
This compensates for static builtin types having `tp_dict` set to `NULL`.Co-authored-by: Petr Viktorin <encukou@gmail.com>
1 parent3e23fa7 commita840806

File tree

6 files changed

+68
-1
lines changed

6 files changed

+68
-1
lines changed

‎Doc/c-api/type.rst‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,23 @@ 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 is meant for specific embedding and language-binding cases,
61+
where direct access to the dict is necessary and indirect access
62+
(e.g. via the proxy or:c:func:`PyObject_GetAttr`) isn't adequate.
63+
64+
Extension modules should continue to use ``tp_dict``,
65+
directly or indirectly, when setting up their own types.
66+
67+
.. versionadded:: 3.12
68+
69+
5370
.. c:function:: void PyType_Modified(PyTypeObject *type)
5471
5572
Invalidate the internal lookup cache for the type and all of its

‎Doc/c-api/typeobj.rst‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1717,7 +1717,19 @@ and :c:type:`PyType_Type` effectively act as defaults.)
17171717
called; it may also be initialized to a dictionary containing initial attributes
17181718
for the type. Once:c:func:`PyType_Ready` has initialized the type, extra
17191719
attributes for the type may be added to this dictionary only if they don't
1720-
correspond to overloaded operations (like:meth:`__add__`).
1720+
correspond to overloaded operations (like:meth:`__add__`). Once
1721+
initialization for the type has finished, this field should be
1722+
treated as read-only.
1723+
1724+
Some types may not store their dictionary in this slot.
1725+
Use:c:func:`PyType_GetDict` to retreive the dictionary for an arbitrary
1726+
type.
1727+
1728+
..versionchanged::3.12
1729+
1730+
Internals detail: For static builtin types, this is always ``NULL``.
1731+
Instead, the dict for such types is stored on ``PyInterpreterState``.
1732+
Use:c:func:`PyType_GetDict` to get the dict for an arbitrary type.
17211733

17221734
**Inheritance:**
17231735

‎Include/cpython/object.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *
284284
PyAPI_FUNC(PyObject*)_PyType_GetDocFromInternalDoc(constchar*,constchar*);
285285
PyAPI_FUNC(PyObject*)_PyType_GetTextSignatureFromInternalDoc(constchar*,constchar*);
286286
PyAPI_FUNC(PyObject*)PyType_GetModuleByDef(PyTypeObject*,PyModuleDef*);
287+
PyAPI_FUNC(PyObject*)PyType_GetDict(PyTypeObject*);
287288

288289
PyAPI_FUNC(int)PyObject_Print(PyObject*,FILE*,int);
289290
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:c:member:`!tp_dict` is now always ``NULL``.:c:func:`!PyType_GetDict()`
5+
provides the correct dict object instead.

‎Modules/_testcapimodule.c‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,30 @@ test_get_type_qualname(PyObject *self, PyObject *Py_UNUSED(ignored))
638638
Py_RETURN_NONE;
639639
}
640640

641+
staticPyObject*
642+
test_get_type_dict(PyObject*self,PyObject*Py_UNUSED(ignored))
643+
{
644+
/* Test for PyType_GetDict */
645+
646+
// Assert ints have a `to_bytes` method
647+
PyObject*long_dict=PyType_GetDict(&PyLong_Type);
648+
assert(long_dict);
649+
assert(PyDict_GetItemString(long_dict,"to_bytes"));// borrowed ref
650+
Py_DECREF(long_dict);
651+
652+
// Make a new type, add an attribute to it and assert it's there
653+
PyObject*HeapTypeNameType=PyType_FromSpec(&HeapTypeNameType_Spec);
654+
assert(HeapTypeNameType);
655+
assert(PyObject_SetAttrString(
656+
HeapTypeNameType,"new_attr",Py_NewRef(Py_None)) >=0);
657+
PyObject*type_dict=PyType_GetDict((PyTypeObject*)HeapTypeNameType);
658+
assert(type_dict);
659+
assert(PyDict_GetItemString(type_dict,"new_attr"));// borrowed ref
660+
Py_DECREF(HeapTypeNameType);
661+
Py_DECREF(type_dict);
662+
Py_RETURN_NONE;
663+
}
664+
641665
staticPyObject*
642666
pyobject_repr_from_null(PyObject*self,PyObject*Py_UNUSED(ignored))
643667
{
@@ -3472,6 +3496,7 @@ static PyMethodDef TestMethods[] = {
34723496
{"test_get_statictype_slots",test_get_statictype_slots,METH_NOARGS},
34733497
{"test_get_type_name",test_get_type_name,METH_NOARGS},
34743498
{"test_get_type_qualname",test_get_type_qualname,METH_NOARGS},
3499+
{"test_get_type_dict",test_get_type_dict,METH_NOARGS},
34753500
{"_test_thread_state",test_thread_state,METH_VARARGS},
34763501
#ifndefMS_WINDOWS
34773502
{"_spawn_pthread_waiter",spawn_pthread_waiter,METH_NOARGS},

‎Objects/typeobject.c‎

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

240+
PyObject*
241+
PyType_GetDict(PyTypeObject*self)
242+
{
243+
PyObject*dict=lookup_tp_dict(self);
244+
return_Py_XNewRef(dict);
245+
}
246+
240247
staticinlinevoid
241248
set_tp_dict(PyTypeObject*self,PyObject*dict)
242249
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp