aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken/signature.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/libshiboken/signature.cpp')
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp58
1 files changed, 37 insertions, 21 deletions
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index e62f861a2..0afdbcdc9 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -99,7 +99,7 @@ CreateSignature(PyObject *props, PyObject *key)
{
/*
* Here is the new function to create all signatures. It simply calls
- * into Python and creates a signature object for a dummy-function.
+ * into Python and creates a signature object directly.
* This is so much simpler than using all the attributes explicitly
* to support '_signature_is_functionlike()'.
*/
@@ -187,8 +187,12 @@ _get_class_of_descr(PyObject *ob)
}
static PyObject *
-GetClassOfFunc(PyObject *ob)
+GetClassOrModOf(PyObject *ob)
{
+ /*
+ * Return the type or module of a function or type.
+ * The purpose is finally to use the name of the object.
+ */
if (PyType_Check(ob)) {
// PySide-928: The type case must do refcounting like the others as well.
Py_INCREF(ob);
@@ -202,7 +206,7 @@ GetClassOfFunc(PyObject *ob)
return _get_class_of_descr(ob);
if (Py_TYPE(ob) == &PyWrapperDescr_Type)
return _get_class_of_descr(ob);
- Py_FatalError("unexpected type in GetClassOfFunc");
+ Py_FatalError("unexpected type in GetClassOrModOf");
return nullptr;
}
@@ -227,7 +231,7 @@ compute_name_key(PyObject *ob)
if (PyType_Check(ob))
return GetTypeKey(ob);
Shiboken::AutoDecRef func_name(get_funcname(ob));
- Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOrModOf(ob)));
return Py_BuildValue("(OO)", type_key.object(), func_name.object());
}
@@ -267,7 +271,7 @@ name_key_to_func(PyObject *ob)
PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
if (ret == nullptr) {
// do a lazy initialization
- Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOrModOf(ob)));
PyObject *type = PyDict_GetItem(pyside_globals->map_dict,
type_key);
if (type == nullptr)
@@ -309,7 +313,7 @@ pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
// forward
static PyObject *
-GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier);
+GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier);
static PyObject *
GetTypeKey(PyObject *ob)
@@ -364,7 +368,7 @@ GetSignature_Function(PyObject *obfunc, const char *modifier)
// make sure that we look into PyCFunction, only...
if (Py_TYPE(obfunc) == PepFunction_TypePtr)
Py_RETURN_NONE;
- Shiboken::AutoDecRef obtype_mod(GetClassOfFunc(obfunc));
+ Shiboken::AutoDecRef obtype_mod(GetClassOrModOf(obfunc));
Shiboken::AutoDecRef type_key(GetTypeKey(obtype_mod));
if (type_key.isNull())
Py_RETURN_NONE;
@@ -377,16 +381,16 @@ GetSignature_Function(PyObject *obfunc, const char *modifier)
Py_RETURN_NONE;
int flags = PyCFunction_GET_FLAGS(obfunc);
- const char *sig_kind;
+ const char *func_kind;
if (PyModule_Check(obtype_mod))
- sig_kind = "function";
+ func_kind = "function";
else if (flags & METH_CLASS)
- sig_kind = "classmethod";
+ func_kind = "classmethod";
else if (flags & METH_STATIC)
- sig_kind = "staticmethod";
+ func_kind = "staticmethod";
else
- sig_kind = "method";
- return GetSignature_Cached(props, sig_kind, modifier);
+ func_kind = "method";
+ return GetSignature_Cached(props, func_kind, modifier);
}
static PyObject *
@@ -423,11 +427,15 @@ GetSignature_TypeMod(PyObject *ob, const char *modifier)
}
static PyObject *
-GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier)
+GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier)
{
+ // Special case: We want to know the func_kind.
+ if (modifier && strcmp(modifier, "__func_kind__") == 0)
+ return Py_BuildValue("s", func_kind);
+
Shiboken::AutoDecRef key(modifier == nullptr
- ? Py_BuildValue("s", sig_kind)
- : Py_BuildValue("(ss)", sig_kind, modifier));
+ ? Py_BuildValue("s", func_kind)
+ : Py_BuildValue("(ss)", func_kind, modifier));
PyObject *value = PyDict_GetItem(props, key);
if (value == nullptr) {
// we need to compute a signature object
@@ -674,10 +682,16 @@ handle_doc(PyObject *ob, PyObject *old_descr)
{
init_module_1();
init_module_2();
- Shiboken::AutoDecRef ob_type(GetClassOfFunc(ob));
- auto *type = reinterpret_cast<PyTypeObject *>(ob_type.object());
- if (handle_doc_in_progress || strncmp(type->tp_name, "PySide2.", 8) != 0)
- return PyObject_CallMethod(old_descr, const_cast<char *>("__get__"), const_cast<char *>("(O)"), ob);
+ Shiboken::AutoDecRef ob_type_mod(GetClassOrModOf(ob));
+ const char *name;
+ if (PyModule_Check(ob_type_mod))
+ name = PyModule_GetName(ob_type_mod);
+ else
+ name = reinterpret_cast<PyTypeObject *>(ob_type_mod.object())->tp_name;
+ if (handle_doc_in_progress || name == nullptr
+ || strncmp(name, "PySide2.", 8) != 0)
+ return PyObject_CallMethod(old_descr, const_cast<char *>("__get__"),
+ const_cast<char *>("(O)"), ob);
handle_doc_in_progress++;
PyObject *res = PyObject_CallFunction(
pyside_globals->make_helptext_func,
@@ -720,7 +734,9 @@ static int
pyside_set___signature__(PyObject *op, PyObject *value)
{
// By this additional check, this function refuses write access.
- if (get_signature_intern(op, nullptr)) {
+ // We consider both nullptr and Py_None as not been written.
+ Shiboken::AutoDecRef has_val(get_signature_intern(op, nullptr));
+ if (!(has_val.isNull() || has_val == Py_None)) {
PyErr_Format(PyExc_AttributeError,
"Attribute '__signature__' of '%.50s' object is not writable",
Py_TYPE(op)->tp_name);