diff options
author | Christian Tismer <tismer@stackless.com> | 2018-11-25 15:55:45 +0100 |
---|---|---|
committer | Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> | 2018-12-03 20:31:58 +0000 |
commit | 14af709e10fa8a2e3c84094c13ebdda9833be124 (patch) | |
tree | f6be857ed5d6502e4073a395b21e22cce278da75 /sources/shiboken2/libshiboken | |
parent | 5778103f5c86dc7f95bd79eabc24de4021eb2734 (diff) |
Generate Hinting Stubs Automatically
The script is now automatically called in the cmake build,
as part of the create_pyside_module macro.
The script runs after every module build and tries to
generate .pyi files. This does not need to succeed, but
will generate all files in the end. The script has been prepared
to allow partial runs without overhead.
After integration of the .pyi generation into cmake, these files
are also installed into the install directory by cmake.
For wheel building, setup.py has entries, too.
Building a full project with all modules revealed a bug in the
signature module that allowed unsupported function objects.
Module enum_sig had to be changed to suppress types
which have no ancestry in shiboken.
PYTHONPATH was avoided because it was not Windows
compatible. Instead, the script was changed to accept
"--sys-path" and "--lib-path" parameters. The latter evaluates
either to PATH or LD_LIBRARY_PATH.
The necessity to create .pyi files while the project is in the
build process showed a hard to track down error condition
in PySide_BuildSignatureProps.
Simple logging was added as a start of introducing logging
everywhere.
Task-number: PYSIDE-735
Change-Id: I6b3eec4b823d026583e902023badedeb06fe0961
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/libshiboken')
-rw-r--r-- | sources/shiboken2/libshiboken/pep384impl.h | 7 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/signature.cpp | 95 |
2 files changed, 53 insertions, 49 deletions
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h index 78b9defb5..bfa8f38a7 100644 --- a/sources/shiboken2/libshiboken/pep384impl.h +++ b/sources/shiboken2/libshiboken/pep384impl.h @@ -333,10 +333,11 @@ LIBSHIBOKEN_API PyObject *PepFunction_Get(PyObject *, const char *); #define PyFunction_Check(op) (Py_TYPE(op) == PepFunction_TypePtr) #define PyFunction_GET_CODE(func) PyFunction_GetCode(func) -#define PyFunction_GetCode(func) PepFunction_Get((PyObject *)func, "__code__") -#define PepFunction_GetName(func) PepFunction_Get((PyObject *)func, "__name__") +#define PyFunction_GetCode(func) PepFunction_Get((PyObject *)func, "__code__") +#define PepFunction_GetName(func) PepFunction_Get((PyObject *)func, "__name__") #else -#define PepFunction_GetName(func) (((PyFunctionObject *)func)->func_name) +#define PepFunction_TypePtr (&PyFunction_Type) +#define PepFunction_GetName(func) (((PyFunctionObject *)func)->func_name) #endif /***************************************************************************** diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp index 92ce3e50a..922f85906 100644 --- a/sources/shiboken2/libshiboken/signature.cpp +++ b/sources/shiboken2/libshiboken/signature.cpp @@ -120,6 +120,8 @@ pyside_sm_get___signature__(PyObject *sm, const char *modifier) { init_module_2(); Shiboken::AutoDecRef func(PyObject_GetAttrString(sm, "__func__")); + if (Py_TYPE(func) == PepFunction_TypePtr) + Py_RETURN_NONE; return GetSignature_Function(func, modifier); } @@ -299,28 +301,38 @@ GetClassKey(PyObject *ob) return Py_BuildValue("O", class_name.object()); } +static PyObject *empty_dict = nullptr; + +static PyObject * +TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype) +{ + PyObject *dict = PyDict_GetItem(pyside_globals->arg_dict, type_key); + if (dict == nullptr) { + if (empty_dict == nullptr) + empty_dict = PyDict_New(); + dict = empty_dict; + } + if (PyTuple_Check(dict)) + dict = PySide_BuildSignatureProps(obtype); + return dict; +} + static PyObject * GetSignature_Function(PyObject *ob_func, const char *modifier) { + // make sure that we look into PyCFunction, only... + if (Py_TYPE(ob_func) == PepFunction_TypePtr) + Py_RETURN_NONE; Shiboken::AutoDecRef typemod(GetClassOfFunc(ob_func)); Shiboken::AutoDecRef type_key(GetClassKey(typemod)); if (type_key.isNull()) Py_RETURN_NONE; - PyObject *dict = PyDict_GetItem(pyside_globals->arg_dict, type_key); - if (dict == NULL) - Py_RETURN_NONE; - if (PyTuple_Check(dict)) { - /* - * We do the initialization lazily. - * This has also the advantage that we can freely import PySide. - */ - dict = PySide_BuildSignatureProps(typemod); - if (dict == NULL) - Py_RETURN_NONE; - } + PyObject *dict = TypeKey_to_PropsDict(type_key, typemod); + if (dict == nullptr) + return nullptr; Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob_func, "__name__")); PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr; - if (props == NULL) + if (props == nullptr) Py_RETURN_NONE; int flags = PyCFunction_GET_FLAGS(ob_func); @@ -333,8 +345,7 @@ GetSignature_Function(PyObject *ob_func, const char *modifier) sig_kind = "staticmethod"; else sig_kind = "method"; - PyObject *ret = GetSignature_Cached(props, sig_kind, modifier); - return ret; + return GetSignature_Cached(props, sig_kind, modifier); } static PyObject * @@ -346,20 +357,11 @@ GetSignature_Wrapper(PyObject *ob, const char *modifier) if (func_name.isNull() || objclass.isNull() || class_key.isNull()) return nullptr; - PyObject *dict = PyDict_GetItem(pyside_globals->arg_dict, class_key); - if (dict == NULL) - Py_RETURN_NONE; - if (PyTuple_Check(dict)) { - /* - * We do the initialization lazily. - * This has also the advantage that we can freely import PySide. - */ - dict = PySide_BuildSignatureProps(objclass); - if (dict == NULL) - Py_RETURN_NONE; - } + PyObject *dict = TypeKey_to_PropsDict(class_key, objclass); + if (dict == nullptr) + return nullptr; PyObject *props = PyDict_GetItem(dict, func_name); - if (props == NULL) + if (props == nullptr) Py_RETURN_NONE; return GetSignature_Cached(props, "method", modifier); } @@ -370,18 +372,11 @@ GetSignature_TypeMod(PyObject *ob, const char *modifier) Shiboken::AutoDecRef ob_name(PyObject_GetAttrString(ob, "__name__")); Shiboken::AutoDecRef ob_key(GetClassKey(ob)); - PyObject *dict = PyDict_GetItem(pyside_globals->arg_dict, ob_key); - if (dict == NULL) - Py_RETURN_NONE; - - if (PyTuple_Check(dict)) { - dict = PySide_BuildSignatureProps(ob); - if (dict == NULL) { - Py_RETURN_NONE; - } - } + PyObject *dict = TypeKey_to_PropsDict(ob_key, ob); + if (dict == nullptr) + return nullptr; PyObject *props = PyDict_GetItem(dict, ob_name); - if (props == NULL) + if (props == nullptr) Py_RETURN_NONE; return GetSignature_Cached(props, "method", modifier); } @@ -587,6 +582,9 @@ get_signature(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier)) return NULL; + if (Py_TYPE(ob) == PepFunction_TypePtr) + Py_RETURN_NONE; + if (Py_TYPE(ob) == &PyCFunction_Type) return pyside_cf_get___signature__(ob, modifier); if (Py_TYPE(ob) == PepStaticMethod_TypePtr) @@ -723,14 +721,13 @@ static PyMethodDef signature_methods[] = { static void init_module_2(void) { - static int init_done = 0, initializing = 0; + static int init_done = 0; if (!init_done) { - if (initializing) - Py_FatalError("Init 2 called recursively!"); - init_phase_2(pyside_globals, signature_methods); + // Phase 2 will call __init__.py which touches a signature, itself. + // Therefore we set init_done prior to init_phase_2(). init_done = 1; - initializing = 0; + init_phase_2(pyside_globals, signature_methods); } } @@ -751,8 +748,14 @@ PySide_BuildSignatureProps(PyObject *classmod) if (arg_tup == nullptr) return nullptr; PyObject *dict = PyObject_CallObject(pyside_globals->sigparse_func, arg_tup); - if (dict == nullptr) - return nullptr; + if (dict == nullptr) { + if (PyErr_Occurred()) + return nullptr; + // No error: return an empty dict. + if (empty_dict == nullptr) + empty_dict = PyDict_New(); + return empty_dict; + } // We replace the arguments by the result dict. if (PyDict_SetItem(pyside_globals->arg_dict, type_key, dict) < 0) |