Hack __text_signature__ back to working with abi3

This commit is contained in:
Alex Gaynor 2020-09-19 11:23:00 -04:00
parent c07e1aa40a
commit 9d8559158b
2 changed files with 23 additions and 7 deletions

View File

@ -256,6 +256,22 @@ fn tp_init_additional<T: PyClass>(type_object: *mut ffi::PyTypeObject) {
// Just patch the type objects for the things there's no
// PyType_FromSpec API for... there's no reason this should work,
// except for that it does and we have tests.
// Running this causes PyPy to segfault.
#[cfg(not(PyPy))]
if T::DESCRIPTION != "\0" {
unsafe {
// Until CPython 3.10, tp_doc was treated specially for heap-types,
// and it removed the text_signature value from it. We go in after
// the fact and replace tp_doc with something that _does_ include
// the text_signature value!
ffi::PyObject_Free((*type_object).tp_doc as _);
let data = ffi::PyObject_Malloc(T::DESCRIPTION.len());
data.copy_from(T::DESCRIPTION.as_ptr() as _, T::DESCRIPTION.len());
(*type_object).tp_doc = data as _;
}
}
if let Some(buffer) = T::buffer_methods() {
unsafe {
(*(*type_object).tp_as_buffer).bf_getbuffer = buffer.as_ref().bf_getbuffer;

View File

@ -31,10 +31,8 @@ fn class_with_docs() {
py_assert!(py, typeobj, "typeobj.__text_signature__ is None");
}
// Ignored because heap types don't have working __text_signature__:
// https://github.com/python/cpython/blob/master/Objects/typeobject.c#L864-L870
#[test]
#[ignore]
#[cfg_attr(Py_LIMITED_API, ignore)]
fn class_with_docs_and_signature() {
/// docs line1
#[pyclass]
@ -69,10 +67,8 @@ fn class_with_docs_and_signature() {
);
}
// Ignored because heap types don't have working __text_signature__:
// https://github.com/python/cpython/blob/master/Objects/typeobject.c#L864-L870
#[test]
#[ignore]
#[cfg_attr(Py_LIMITED_API, ignore)]
fn class_with_signature() {
#[pyclass]
#[text_signature = "(a, b=None, *, c=42)"]
@ -92,7 +88,11 @@ fn class_with_signature() {
let py = gil.python();
let typeobj = py.get_type::<MyClass>();
py_assert!(py, typeobj, "typeobj.__doc__ is None");
py_assert!(
py,
typeobj,
"typeobj.__doc__ is None or typeobj.__doc__ == ''"
);
py_assert!(
py,
typeobj,