Merge pull request #1201 from alex/abi3-text-signature

Hack __text_signature__ back to working with abi3
This commit is contained in:
Yuji Kanagawa 2020-09-20 16:46:04 +09:00 committed by GitHub
commit e33e58fc72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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 // Just patch the type objects for the things there's no
// PyType_FromSpec API for... there's no reason this should work, // PyType_FromSpec API for... there's no reason this should work,
// except for that it does and we have tests. // 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() { if let Some(buffer) = T::buffer_methods() {
unsafe { unsafe {
(*(*type_object).tp_as_buffer).bf_getbuffer = buffer.as_ref().bf_getbuffer; (*(*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"); 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] #[test]
#[ignore] #[cfg_attr(Py_LIMITED_API, ignore)]
fn class_with_docs_and_signature() { fn class_with_docs_and_signature() {
/// docs line1 /// docs line1
#[pyclass] #[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] #[test]
#[ignore] #[cfg_attr(Py_LIMITED_API, ignore)]
fn class_with_signature() { fn class_with_signature() {
#[pyclass] #[pyclass]
#[text_signature = "(a, b=None, *, c=42)"] #[text_signature = "(a, b=None, *, c=42)"]
@ -92,7 +88,11 @@ fn class_with_signature() {
let py = gil.python(); let py = gil.python();
let typeobj = py.get_type::<MyClass>(); 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_assert!(
py, py,
typeobj, typeobj,