diff options
author | Christian Tismer <tismer@stackless.com> | 2018-07-14 15:10:56 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2018-12-22 12:26:10 +0000 |
commit | 73a9168ad56559bb3fba0d93866b05a7fde812de (patch) | |
tree | b57018ee6702eac794867635d549a3b65509ca71 /sources/shiboken2/libshiboken/signature.cpp | |
parent | c013faebdfb248e1ce66fa41aa0a771aaf4e3d80 (diff) |
Complete The Signature Introspection
The signature module has been quite far developed.
In the course of making things fit for the TypeErrors with
the signature module, now also all signatures from all
shiboken modules are queried.
Instead of writing an extra signature existence test for
shiboken, it made more sense to extend the existing
init_platform.py by the shiboken modules.
In fact, by this query a corner case was exploited that
worked on Python 2 but assertion-crashed on Python 3.
The mapping.py modules were also completed to support
all new PySide2 modules.
Special care had to be taken because the "shiboken2" module
exists both as directory and as binary module. The fix was
tricky, and I will add a task that replaces such workarounds
by a better design.
Task-number: PYSIDE-510
Change-Id: Ibf8e322d1905976a0044a702ea178b7f98629fb4
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/shiboken2/libshiboken/signature.cpp')
-rw-r--r-- | sources/shiboken2/libshiboken/signature.cpp | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp index 922f85906..564e5fcef 100644 --- a/sources/shiboken2/libshiboken/signature.cpp +++ b/sources/shiboken2/libshiboken/signature.cpp @@ -129,13 +129,16 @@ static PyObject * _get_class_of_cf(PyObject *ob_cf) { PyObject *selftype = PyCFunction_GET_SELF(ob_cf); - if (selftype == NULL) - selftype = PyDict_GetItem(pyside_globals->map_dict, (PyObject *)ob_cf); - if (selftype == NULL) { - if (!PyErr_Occurred()) - Py_RETURN_NONE; - return NULL; + if (selftype == nullptr) { + selftype = PyDict_GetItem(pyside_globals->map_dict, ob_cf); + if (selftype == nullptr) { + // This must be an overloaded function that we handled special. + Shiboken::AutoDecRef special(Py_BuildValue("(Os)", ob_cf, "overload")); + selftype = PyDict_GetItem(pyside_globals->map_dict, special); + } } + assert(selftype); + PyObject *typemod = (PyType_Check(selftype) || PyModule_Check(selftype)) ? selftype : (PyObject *)Py_TYPE(selftype); // do we support module functions? @@ -175,19 +178,26 @@ GetClassOfFunc(PyObject *ob) } static PyObject * -compute_name_key(PyObject *ob) +get_funcname(PyObject *ob) { - if (PyType_Check(ob)) - return GetClassKey(GetClassOfFunc(ob)); PyObject *func = ob; if (Py_TYPE(ob) == PepStaticMethod_TypePtr) func = PyObject_GetAttrString(ob, "__func__"); else Py_INCREF(func); - Shiboken::AutoDecRef func_name(PyObject_GetAttrString(func, "__name__")); + PyObject *func_name = PyObject_GetAttrString(func, "__name__"); Py_DECREF(func); - if (func_name.isNull()) + if (func_name == nullptr) Py_FatalError("unexpected name problem in compute_name_key"); + return func_name; +} + +static PyObject * +compute_name_key(PyObject *ob) +{ + if (PyType_Check(ob)) + return GetClassKey(ob); + Shiboken::AutoDecRef func_name(get_funcname(ob)); Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob))); return Py_BuildValue("(OO)", type_key.object(), func_name.object()); } @@ -201,9 +211,11 @@ build_name_key_to_func(PyObject *obtype) if (meth == 0) return 0; + Shiboken::AutoDecRef type_key(GetClassKey(obtype)); for (; meth->ml_name != NULL; meth++) { Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, NULL)); - Shiboken::AutoDecRef name_key(compute_name_key(func)); + Shiboken::AutoDecRef func_name(get_funcname(func)); + Shiboken::AutoDecRef name_key(Py_BuildValue("(OO)", type_key.object(), func_name.object())); if (func.isNull() || name_key.isNull() || PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0) return -1; @@ -224,7 +236,7 @@ name_key_to_func(PyObject *ob) Py_RETURN_NONE; PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key); - if (ret == NULL) { + if (ret == nullptr) { // do a lazy initialization Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob))); PyObject *type = PyDict_GetItem(pyside_globals->map_dict, @@ -233,7 +245,7 @@ name_key_to_func(PyObject *ob) Py_RETURN_NONE; assert(PyType_Check(type)); if (build_name_key_to_func(type) < 0) - return NULL; + return nullptr; ret = PyDict_GetItem(pyside_globals->map_dict, name_key); } Py_XINCREF(ret); @@ -901,6 +913,12 @@ _build_func_to_type(PyObject *obtype) strcat(mangled_name, ".overload"); if (PyDict_SetItemString(dict, mangled_name, descr) < 0) return -1; + if (meth->ml_flags & METH_STATIC) { + // This is the special case where a static method is hidden. + Shiboken::AutoDecRef special(Py_BuildValue("(Os)", cfunc.object(), "overload")); + if (PyDict_SetItem(pyside_globals->map_dict, special, obtype) < 0) + return -1; + } if (PyDict_SetItemString(pyside_globals->map_dict, mangled_name, obtype) < 0) return -1; continue; |