diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 892cc74ec39158..db62b47100ad3a 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -401,6 +401,10 @@ def __del__(self): del L self.assertEqual(PyList.num, 0) + def test_heap_ctype_doc_and_text_signature(self): + self.assertEqual(_testcapi.HeapDocCType.__doc__, "somedoc") + self.assertEqual(_testcapi.HeapDocCType.__text_signature__, "(arg1, arg2)") + def test_subclass_of_heap_gc_ctype_with_tpdealloc_decrefs_once(self): class HeapGcCTypeSubclass(_testcapi.HeapGcCType): def __init__(self): diff --git a/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst b/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst new file mode 100644 index 00000000000000..44cf58a4b06388 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst @@ -0,0 +1,2 @@ +Types created with :c:func:`PyType_FromSpec` now make any signature in their +``tp_doc`` slot accessible from ``__text_signature__``. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 593034ef65e2ca..7536d29535038c 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6462,6 +6462,30 @@ static PyTypeObject MethodDescriptor2_Type = { .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, }; +PyDoc_STRVAR(heapdocctype__doc__, +"HeapDocCType(arg1, arg2)\n" +"--\n" +"\n" +"somedoc"); + +typedef struct { + PyObject_HEAD +} HeapDocCTypeObject; + +static PyType_Slot HeapDocCType_slots[] = { + {Py_tp_doc, (char*)heapdocctype__doc__}, + {0}, +}; + +static PyType_Spec HeapDocCType_spec = { + "_testcapi.HeapDocCType", + sizeof(HeapDocCTypeObject), + 0, + Py_TPFLAGS_DEFAULT, + HeapDocCType_slots +}; + + PyDoc_STRVAR(heapgctype__doc__, "A heap type with GC, and with overridden dealloc.\n\n" "The 'value' attribute is set to 10 in __init__."); @@ -7130,6 +7154,12 @@ PyInit__testcapi(void) Py_INCREF(TestError); PyModule_AddObject(m, "error", TestError); + PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); + if (HeapDocCType == NULL) { + return NULL; + } + PyModule_AddObject(m, "HeapDocCType", HeapDocCType); + PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); if (HeapGcCType == NULL) { return NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c66f8fcec8ed51..74040757a07021 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3018,15 +3018,14 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) else if (slot->slot == Py_tp_doc) { /* For the docstring slot, which usually points to a static string literal, we need to make a copy */ - const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); - size_t len = strlen(old_doc)+1; + size_t len = strlen(slot->pfunc)+1; char *tp_doc = PyObject_MALLOC(len); if (tp_doc == NULL) { type->tp_doc = NULL; PyErr_NoMemory(); goto fail; } - memcpy(tp_doc, old_doc, len); + memcpy(tp_doc, slot->pfunc, len); type->tp_doc = tp_doc; } else if (slot->slot == Py_tp_members) { @@ -3058,6 +3057,16 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) res->ht_cached_keys = _PyDict_NewKeysForClass(); } + if (type->tp_doc) { + PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); + if (!__doc__) + goto fail; + int ret = _PyDict_SetItemId(type->tp_dict, &PyId___doc__, __doc__); + Py_DECREF(__doc__); + if (ret < 0) + goto fail; + } + if (weaklistoffset) { type->tp_weaklistoffset = weaklistoffset; if (PyDict_DelItemString((PyObject *)type->tp_dict, "__weaklistoffset__") < 0) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy