From 3e2c643ae0b21f9e596bfd9c8ec99ca546ea8d0f Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 17 Aug 2021 21:39:34 +0800 Subject: [PATCH] bpo-42035: Add PyType_GetQualName() to get a type's qualified name. (GH-27551) --- Doc/c-api/type.rst | 7 ++++ Doc/data/refcounts.dat | 3 ++ Doc/data/stable_abi.dat | 1 + Doc/whatsnew/3.11.rst | 3 ++ Include/object.h | 1 + .../2021-08-02-20-49-36.bpo-42035.HTBcZt.rst | 2 + Misc/stable_abi.txt | 2 + Modules/_testcapimodule.c | 41 +++++++++++++++++++ Objects/typeobject.c | 6 +++ PC/python3dll.c | 1 + 10 files changed, 67 insertions(+) create mode 100644 Misc/NEWS.d/next/C API/2021-08-02-20-49-36.bpo-42035.HTBcZt.rst diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 630c7db437c..413294dde77 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -112,6 +112,13 @@ Type Objects .. versionadded:: 3.11 +.. c:function:: PyObject* PyType_GetQualName(PyTypeObject *type) + + Return the type's qualified name. Equivalent to getting the + type's ``__qualname__`` attribute. + + .. versionadded:: 3.11 + .. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot) Return the function pointer stored in the given slot. If the diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 9b5c00599f1..3ef1b280e11 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -2310,6 +2310,9 @@ PyType_GetFlags:PyTypeObject*:type:0: PyType_GetName:PyObject*::+1: PyType_GetName:PyTypeObject*:type:0: +PyType_GetQualName:PyObject*::+1: +PyType_GetQualName:PyTypeObject*:type:0: + PyType_GetSlot:void*::: PyType_GetSlot:PyTypeObject*:type:0: PyType_GetSlot:int:slot:: diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 4938459d317..ea57cc83f7a 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -644,6 +644,7 @@ function,PyType_GetFlags,3.2, function,PyType_GetModule,3.10, function,PyType_GetModuleState,3.10, function,PyType_GetName,3.11, +function,PyType_GetQualName,3.11, function,PyType_GetSlot,3.4, function,PyType_IsSubtype,3.2, function,PyType_Modified,3.2, diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 88b6f8fa731..c546ec0fc6d 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -298,6 +298,9 @@ C API Changes * Add a new :c:func:`PyType_GetName` function to get type's short name. (Contributed by Hai Shi in :issue:`42035`.) +* Add a new :c:func:`PyType_GetQualName` function to get type's qualified name. + (Contributed by Hai Shi in :issue:`42035`.) + New Features ------------ diff --git a/Include/object.h b/Include/object.h index 23ebad84ab4..fb8a63fc7db 100644 --- a/Include/object.h +++ b/Include/object.h @@ -241,6 +241,7 @@ PyAPI_FUNC(void *) PyType_GetModuleState(struct _typeobject *); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030B0000 PyAPI_FUNC(PyObject *) PyType_GetName(PyTypeObject *); +PyAPI_FUNC(PyObject *) PyType_GetQualName(PyTypeObject *); #endif /* Generic type check */ diff --git a/Misc/NEWS.d/next/C API/2021-08-02-20-49-36.bpo-42035.HTBcZt.rst b/Misc/NEWS.d/next/C API/2021-08-02-20-49-36.bpo-42035.HTBcZt.rst new file mode 100644 index 00000000000..4631c43fdd5 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2021-08-02-20-49-36.bpo-42035.HTBcZt.rst @@ -0,0 +1,2 @@ +Add a new :c:func:`PyType_GetQualName` function to get type's qualified +name. diff --git a/Misc/stable_abi.txt b/Misc/stable_abi.txt index ba16669bd29..a3ee0f01bec 100644 --- a/Misc/stable_abi.txt +++ b/Misc/stable_abi.txt @@ -2147,6 +2147,8 @@ function PyGC_IsEnabled function PyType_GetName added 3.11 +function PyType_GetQualName + added 3.11 # (Detailed comments aren't really needed for further entries: from here on # we can use version control logs.) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c35eac78ebe..0a3c6e0b9b2 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1159,6 +1159,46 @@ test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) } +static PyObject * +test_get_type_qualname(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *tp_qualname = PyType_GetQualName(&PyLong_Type); + assert(strcmp(PyUnicode_AsUTF8(tp_qualname), "int") == 0); + Py_DECREF(tp_qualname); + + tp_qualname = PyType_GetQualName(&_PyNamespace_Type); + assert(strcmp(PyUnicode_AsUTF8(tp_qualname), "SimpleNamespace") == 0); + Py_DECREF(tp_qualname); + + PyObject *HeapTypeNameType = PyType_FromSpec(&HeapTypeNameType_Spec); + if (HeapTypeNameType == NULL) { + Py_RETURN_NONE; + } + tp_qualname = PyType_GetQualName((PyTypeObject *)HeapTypeNameType); + assert(strcmp(PyUnicode_AsUTF8(tp_qualname), "HeapTypeNameType") == 0); + Py_DECREF(tp_qualname); + + PyObject *spec_name = PyUnicode_FromString(HeapTypeNameType_Spec.name); + if (spec_name == NULL) { + goto done; + } + if (PyObject_SetAttrString(HeapTypeNameType, + "__qualname__", spec_name) < 0) { + Py_DECREF(spec_name); + goto done; + } + tp_qualname = PyType_GetQualName((PyTypeObject *)HeapTypeNameType); + assert(strcmp(PyUnicode_AsUTF8(tp_qualname), + "_testcapi.HeapTypeNameType") == 0); + Py_DECREF(spec_name); + Py_DECREF(tp_qualname); + + done: + Py_DECREF(HeapTypeNameType); + Py_RETURN_NONE; +} + + static PyObject * get_args(PyObject *self, PyObject *args) { @@ -5667,6 +5707,7 @@ static PyMethodDef TestMethods[] = { {"get_args", get_args, METH_VARARGS}, {"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS}, {"test_get_type_name", test_get_type_name, METH_NOARGS}, + {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, {"get_kwargs", (PyCFunction)(void(*)(void))get_kwargs, METH_VARARGS|METH_KEYWORDS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1efb9fc5944..a38690aed5c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3620,6 +3620,12 @@ PyType_GetName(PyTypeObject *type) return type_name(type, NULL); } +PyObject * +PyType_GetQualName(PyTypeObject *type) +{ + return type_qualname(type, NULL); +} + void * PyType_GetSlot(PyTypeObject *type, int slot) { diff --git a/PC/python3dll.c b/PC/python3dll.c index e0a78294a65..2420e53e705 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -593,6 +593,7 @@ EXPORT_FUNC(PyType_GetFlags) EXPORT_FUNC(PyType_GetModule) EXPORT_FUNC(PyType_GetModuleState) EXPORT_FUNC(PyType_GetName) +EXPORT_FUNC(PyType_GetQualName) EXPORT_FUNC(PyType_GetSlot) EXPORT_FUNC(PyType_IsSubtype) EXPORT_FUNC(PyType_Modified)