aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken/signature.cpp
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2020-06-13 00:41:37 +0200
committerChristian Tismer <tismer@stackless.com>2020-07-10 11:06:26 +0200
commit3d4d91334dc608a41963d9acb5080139202f33c5 (patch)
treef026ad478a73047e813acfa340ac8e3e7b3b868a /sources/shiboken2/libshiboken/signature.cpp
parent3a0b9ebc9e2980af8dc5fbf4ac8bc6ddfd49c9d9 (diff)
signature: Clean up and improve readability
There were some heavy changes to the signature module when the switchable feature framework was developed. The principle underneath that framework took a number of iterations with many changed ideas. Most of these changes were reverted, but a few improvements should stay, although they have nothing to do with features any longer. Change-Id: I0804082510c3805ba6015925d23afb3ef5d149a4 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/libshiboken/signature.cpp')
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp58
1 files changed, 42 insertions, 16 deletions
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index ba1fc119e..b09b68d47 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -74,7 +74,8 @@ typedef struct safe_globals_struc {
PyObject *helper_module;
PyObject *arg_dict;
PyObject *map_dict;
- PyObject *value_dict; // for writing signatures
+ PyObject *value_dict; // for writing signatures
+ PyObject *feature_dict; // registry for PySide.__feature__
// init part 2: run module
PyObject *pyside_type_init_func;
PyObject *create_signature_func;
@@ -572,6 +573,12 @@ init_phase_1(void)
if (p->value_dict == nullptr)
goto error;
+ // PYSIDE-1019: build a __feature__ dict
+ p->feature_dict = PyDict_New();
+ if (p->feature_dict == nullptr
+ || PyObject_SetAttrString(p->helper_module, "pyside_feature_dict", p->feature_dict) < 0)
+ goto error;
+
// This function will be disabled until phase 2 is done.
p->finish_import_func = nullptr;
@@ -646,17 +653,22 @@ _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
}
}
}
- // staticmethod has just a __doc__ in the class
- assert(strcmp(type->tp_name, "staticmethod") == 0);
+ PyMemberDef *md = type->tp_members;
+ if (md != nullptr)
+ for (; md->name != nullptr; md++)
+ if (strcmp(md->name, name) == 0)
+ return 1;
+ // staticmethod has just a `__doc__` in the class
+ assert(strcmp(type->tp_name, "staticmethod") == 0 && strcmp(name, "__doc__") == 0);
return 0;
}
static int
-add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **old_descr)
+add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr)
{
/*
- * This function is used to assign a new __signature__ attribute,
- * and also to override a __doc__ attribute.
+ * This function is used to assign a new `__signature__` attribute,
+ * and also to override a `__doc__` or `__name__` attribute.
*/
assert(PyType_Check(type));
PyType_Ready(type);
@@ -664,9 +676,11 @@ add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **old_descr)
for (; gsp->name != nullptr; gsp++) {
PyObject *have_descr = PyDict_GetItemString(dict, gsp->name);
if (have_descr != nullptr) {
- assert(strcmp(gsp->name, "__doc__") == 0);
Py_INCREF(have_descr);
- *old_descr = have_descr;
+ if (strcmp(gsp->name, "__doc__") == 0)
+ *doc_descr = have_descr;
+ else
+ assert(false);
if (!_fixup_getset(type, gsp->name, gsp))
continue;
}
@@ -817,7 +831,7 @@ static PyGetSetDef new_PyWrapperDescr_getsets[] = {
//
// Additionally to the interface via __signature__, we also provide
// a general function, which allows for different signature layouts.
-// The "modifier" argument is a string that is passed in from loader.py .
+// The "modifier" argument is a string that is passed in from 'loader.py'.
// Configuration what the modifiers mean is completely in Python.
//
@@ -902,13 +916,25 @@ PySide_PatchTypes(void)
reinterpret_cast<PyObject *>(&PyString_Type), "split"));
Shiboken::AutoDecRef wrap_descr(PyObject_GetAttrString(
reinterpret_cast<PyObject *>(Py_TYPE(Py_True)), "__add__"));
+ // abbreviations for readability
+ auto md_gs = new_PyMethodDescr_getsets;
+ auto md_doc = &old_md_doc_descr;
+ auto cf_gs = new_PyCFunction_getsets;
+ auto cf_doc = &old_cf_doc_descr;
+ auto sm_gs = new_PyStaticMethod_getsets;
+ auto sm_doc = &old_sm_doc_descr;
+ auto tp_gs = new_PyType_getsets;
+ auto tp_doc = &old_tp_doc_descr;
+ auto wd_gs = new_PyWrapperDescr_getsets;
+ auto wd_doc = &old_wd_doc_descr;
+
if (meth_descr.isNull() || wrap_descr.isNull()
|| PyType_Ready(Py_TYPE(meth_descr)) < 0
- || add_more_getsets(PepMethodDescr_TypePtr, new_PyMethodDescr_getsets, &old_md_doc_descr) < 0
- || add_more_getsets(&PyCFunction_Type, new_PyCFunction_getsets, &old_cf_doc_descr) < 0
- || add_more_getsets(PepStaticMethod_TypePtr, new_PyStaticMethod_getsets, &old_sm_doc_descr) < 0
- || add_more_getsets(&PyType_Type, new_PyType_getsets, &old_tp_doc_descr) < 0
- || add_more_getsets(Py_TYPE(wrap_descr), new_PyWrapperDescr_getsets, &old_wd_doc_descr) < 0
+ || add_more_getsets(PepMethodDescr_TypePtr, md_gs, md_doc) < 0
+ || add_more_getsets(&PyCFunction_Type, cf_gs, cf_doc) < 0
+ || add_more_getsets(PepStaticMethod_TypePtr, sm_gs, sm_doc) < 0
+ || add_more_getsets(&PyType_Type, tp_gs, tp_doc) < 0
+ || add_more_getsets(Py_TYPE(wrap_descr), wd_gs, wd_doc) < 0
)
return -1;
#ifndef _WIN32
@@ -1207,8 +1233,8 @@ FinishSignatureInitialization(PyObject *module, const char *signatures[])
* Still, it is not possible to call init phase 2 from here,
* because the import is still running. Do it from Python!
*/
- PySide_PatchTypes();
- if (PySide_FinishSignatures(module, signatures) < 0) {
+ if ( PySide_PatchTypes() < 0
+ || PySide_FinishSignatures(module, signatures) < 0) {
PyErr_Print();
PyErr_SetNone(PyExc_ImportError);
}