Skip to content

Commit

Permalink
Hack __text_signature__ back to working with abi3
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Sep 19, 2020
1 parent c07e1aa commit 4e70273
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
13 changes: 13 additions & 0 deletions src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,19 @@ 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.
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;
Expand Down
12 changes: 7 additions & 5 deletions tests/test_text_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -72,7 +70,7 @@ 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)"]
Expand All @@ -92,7 +90,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,
Expand Down

0 comments on commit 4e70273

Please sign in to comment.