diff options
author | Christian Tismer <tismer@stackless.com> | 2022-03-13 19:22:02 +0100 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2022-03-15 16:12:58 +0100 |
commit | b702a05c2f2a48be5ef77cdc8e8f4cc4cdb2e9c1 (patch) | |
tree | 81fecf74611015fa7bab113b9368d6457885bb8f | |
parent | 38fe8062b6f03dae438dc4e42537c131a98eceb0 (diff) |
PyPySide: handle signature with the new "builtin method" type
PyPy never had a distinction between normal methods and
builtin methods like Python has by PyCFunction.
Not immediately on our demand, but because the NumPy
extension grew a problem out of exactly the same fact,
a new "builtin method" was created.
Using this new type, three errors concerning signatures
could be resolved:
sample::renaming
QtWidgets::signature_test
QtQml::qqmlnetwork_test
[ChangeLog][PySide6] The new PyPy "builtin method" is
now adopted and handled correctly in the signature module.
Task-number: PYSIDE-1843
Task-number: PYSIDE-535
Change-Id: I462fe67fe63453fc214e332645dba60a1d399f5c
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | build_history/blacklist.txt | 6 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/pep384impl.cpp | 27 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/pep384impl.h | 4 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/signature/signature.cpp | 29 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/signature/signature_extend.cpp | 8 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/signature/signature_helper.cpp | 9 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/signature/signature_p.h | 8 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/voidptr.cpp | 2 |
8 files changed, 85 insertions, 8 deletions
diff --git a/build_history/blacklist.txt b/build_history/blacklist.txt index b5c3b1c61..a40e20aff 100644 --- a/build_history/blacklist.txt +++ b/build_history/blacklist.txt @@ -48,8 +48,6 @@ # PYSIDE-535: These errors are still present. Please try to remove one :) [sample::mixed_mi] pypy -[sample::renaming] - pypy [sample::sample] pypy [sample::str] @@ -72,12 +70,8 @@ pypy [QtWidgets::bug_860] pypy -[QtWidgets::signature_test] - pypy [QtQml::bug_825] pypy -[QtQml::qqmlnetwork_test] - pypy # This is added to the same entry above [QtQml::javascript_exceptions] pypy [QtQml::qqmlincubator_incubateWhile] diff --git a/sources/shiboken6/libshiboken/pep384impl.cpp b/sources/shiboken6/libshiboken/pep384impl.cpp index fd862b7b0..71f7521fa 100644 --- a/sources/shiboken6/libshiboken/pep384impl.cpp +++ b/sources/shiboken6/libshiboken/pep384impl.cpp @@ -46,6 +46,7 @@ #include "sbkenum.h" #include "sbkenum_p.h" #include "sbkconverter.h" +#include "voidptr.h" #include <cstdlib> #include <cstring> @@ -712,6 +713,29 @@ PyStaticMethod_New(PyObject *callable) } #endif // Py_LIMITED_API +#ifdef PYPY_VERSION +PyTypeObject *PepBuiltinMethod_TypePtr = nullptr; + +static PyTypeObject * +getBuiltinMethodType(void) +{ + // PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction. + // + // There is no public declaration for the "builtin method" type. + // We also cannot grep it with a Python script since the import is too early. + // Pick a demo "builtin method" by using the VoidPtr type. + // Create the equivalent of + // "from shiboken6.Shiboken import VoidPtr\n" + // "result = type(VoidPtr(0).toBytes)\n"; + auto *pyVoidP = reinterpret_cast<PyObject *>(SbkVoidPtr_TypeF()); + Shiboken::AutoDecRef arg(Py_BuildValue("i", 0)); + Shiboken::AutoDecRef inst(PyObject_CallFunctionObjArgs(pyVoidP, arg.object(), nullptr)); + Shiboken::AutoDecRef meth(PyObject_GetAttrString(inst, "toBytes")); + auto *result = reinterpret_cast<PyTypeObject *>(PyObject_Type(meth)); + return result; +} +#endif + /***************************************************************************** * * Common newly needed functions @@ -1052,6 +1076,9 @@ Pep384_Init() PepFunction_TypePtr = getFunctionType(); PepStaticMethod_TypePtr = getStaticMethodType(); #endif // Py_LIMITED_API +#ifdef PYPY_VERSION + PepBuiltinMethod_TypePtr = getBuiltinMethodType(); +#endif } } // extern "C" diff --git a/sources/shiboken6/libshiboken/pep384impl.h b/sources/shiboken6/libshiboken/pep384impl.h index 134199788..62a66e37e 100644 --- a/sources/shiboken6/libshiboken/pep384impl.h +++ b/sources/shiboken6/libshiboken/pep384impl.h @@ -532,6 +532,10 @@ LIBSHIBOKEN_API PyObject *PyStaticMethod_New(PyObject *callable); #define PepStaticMethod_TypePtr &PyStaticMethod_Type #endif +#ifdef PYPY_VERSION +extern LIBSHIBOKEN_API PyTypeObject *PepBuiltinMethod_TypePtr; +#endif + // Although not PEP specific, we resolve this similar issue, here: #define PepMethodDescr_TypePtr &PyMethodDescr_Type diff --git a/sources/shiboken6/libshiboken/signature/signature.cpp b/sources/shiboken6/libshiboken/signature/signature.cpp index b7becca26..ab33becac 100644 --- a/sources/shiboken6/libshiboken/signature/signature.cpp +++ b/sources/shiboken6/libshiboken/signature/signature.cpp @@ -86,6 +86,11 @@ PyObject *GetClassOrModOf(PyObject *ob) Py_INCREF(ob); return ob; } +#ifdef PYPY_VERSION + // PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction. + if (Py_TYPE(ob) == PepBuiltinMethod_TypePtr) + return _get_class_of_bm(ob); +#endif if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type)) return _get_class_of_cf(ob); if (Py_TYPE(ob) == PepStaticMethod_TypePtr) @@ -167,6 +172,24 @@ static PyObject *_GetSignature_Cached(PyObject *props, PyObject *func_kind, PyOb return Py_INCREF(value), value; } +#ifdef PYPY_VERSION +PyObject *GetSignature_Method(PyObject *obfunc, PyObject *modifier) +{ + AutoDecRef obtype_mod(GetClassOrModOf(obfunc)); + AutoDecRef type_key(GetTypeKey(obtype_mod)); + if (type_key.isNull()) + Py_RETURN_NONE; + PyObject *dict = TypeKey_to_PropsDict(type_key, obtype_mod); + if (dict == nullptr) + return nullptr; + AutoDecRef func_name(PyObject_GetAttr(obfunc, PyMagicName::name())); + PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr; + if (props == nullptr) + Py_RETURN_NONE; + return _GetSignature_Cached(props, PyName::method(), modifier); +} +#endif + PyObject *GetSignature_Function(PyObject *obfunc, PyObject *modifier) { // make sure that we look into PyCFunction, only... @@ -243,6 +266,12 @@ PyObject *GetSignature_TypeMod(PyObject *ob, PyObject *modifier) PyObject *get_signature_intern(PyObject *ob, PyObject *modifier) { +#ifdef PYPY_VERSION + // PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction. + if (Py_TYPE(ob) == PepBuiltinMethod_TypePtr) { + return pyside_bm_get___signature__(ob, modifier); + } +#endif if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type)) return pyside_cf_get___signature__(ob, modifier); if (Py_TYPE(ob) == PepStaticMethod_TypePtr) diff --git a/sources/shiboken6/libshiboken/signature/signature_extend.cpp b/sources/shiboken6/libshiboken/signature/signature_extend.cpp index a90f82910..d67f40ff9 100644 --- a/sources/shiboken6/libshiboken/signature/signature_extend.cpp +++ b/sources/shiboken6/libshiboken/signature/signature_extend.cpp @@ -91,6 +91,14 @@ static PyObject *_get_written_signature(signaturefunc sf, PyObject *ob, PyObject return ret; } +#ifdef PYPY_VERSION +PyObject *pyside_bm_get___signature__(PyObject *func, PyObject *modifier) +{ + init_module_2(); + return _get_written_signature(GetSignature_Method, func, modifier); +} +#endif + PyObject *pyside_cf_get___signature__(PyObject *func, PyObject *modifier) { init_module_2(); diff --git a/sources/shiboken6/libshiboken/signature/signature_helper.cpp b/sources/shiboken6/libshiboken/signature/signature_helper.cpp index 0f4acd622..129554683 100644 --- a/sources/shiboken6/libshiboken/signature/signature_helper.cpp +++ b/sources/shiboken6/libshiboken/signature/signature_helper.cpp @@ -259,6 +259,15 @@ int insert_snake_case_variants(PyObject *dict) return PyDict_Merge(dict, snake_dict, 0); } +#ifdef PYPY_VERSION +PyObject *_get_class_of_bm(PyObject *ob_bm) +{ + AutoDecRef self(PyObject_GetAttr(ob_bm, PyMagicName::self())); + auto *klass = PyObject_GetAttr(self, PyMagicName::class_()); + return klass; +} +#endif + PyObject *_get_class_of_cf(PyObject *ob_cf) { PyObject *selftype = PyCFunction_GET_SELF(ob_cf); diff --git a/sources/shiboken6/libshiboken/signature/signature_p.h b/sources/shiboken6/libshiboken/signature/signature_p.h index 029cd7cca..898ad9a3b 100644 --- a/sources/shiboken6/libshiboken/signature/signature_p.h +++ b/sources/shiboken6/libshiboken/signature/signature_p.h @@ -81,7 +81,6 @@ PyObject *PySide_BuildSignatureProps(PyObject *class_mod); PyObject *GetClassOrModOf(PyObject *ob); // signature_extend.cpp - PyObject *pyside_cf_get___signature__(PyObject *func, PyObject *modifier); PyObject *pyside_sm_get___signature__(PyObject *sm, PyObject *modifier); PyObject *pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier); @@ -102,6 +101,13 @@ PyObject *_get_class_of_descr(PyObject *ob); PyObject *_address_to_stringlist(PyObject *numkey); int _finish_nested_classes(PyObject *dict); +#ifdef PYPY_VERSION +// PyPy has a special builtin method. +PyObject *GetSignature_Method(PyObject *, PyObject *); +PyObject *pyside_bm_get___signature__(PyObject *func, PyObject *modifier); +PyObject *_get_class_of_bm(PyObject *ob_cf); +#endif + } // extern "C" #endif // SIGNATURE_IMPL_H diff --git a/sources/shiboken6/libshiboken/voidptr.cpp b/sources/shiboken6/libshiboken/voidptr.cpp index e2cd4f4ee..fdbd95efb 100644 --- a/sources/shiboken6/libshiboken/voidptr.cpp +++ b/sources/shiboken6/libshiboken/voidptr.cpp @@ -306,7 +306,7 @@ static PyType_Slot SbkVoidPtrType_slots[] = { {0, nullptr} }; static PyType_Spec SbkVoidPtrType_spec = { - "2:shiboken6.shiboken6.VoidPtr", + "2:shiboken6.Shiboken.VoidPtr", sizeof(SbkVoidPtrObject), 0, Py_TPFLAGS_DEFAULT, |