aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/libshiboken/signature
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/libshiboken/signature')
-rw-r--r--sources/shiboken6/libshiboken/signature/signature.cpp33
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_extend.cpp40
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_globals.cpp20
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_helper.cpp41
4 files changed, 53 insertions, 81 deletions
diff --git a/sources/shiboken6/libshiboken/signature/signature.cpp b/sources/shiboken6/libshiboken/signature/signature.cpp
index f83618779..3255cb56d 100644
--- a/sources/shiboken6/libshiboken/signature/signature.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature.cpp
@@ -197,7 +197,7 @@ PyObject *GetSignature_Wrapper(PyObject *ob, PyObject *modifier)
PyObject *props = PyDict_GetItem(dict, func_name);
if (props == nullptr) {
// handle `__init__` like the class itself
- if (strcmp(String::toCString(func_name), "__init__") == 0)
+ if (PyUnicode_CompareWithASCIIString(func_name, "__init__") == 0)
return GetSignature_TypeMod(objclass, modifier);
Py_RETURN_NONE;
}
@@ -227,6 +227,8 @@ PyObject *GetSignature_TypeMod(PyObject *ob, PyObject *modifier)
// The `modifier` argument is a string that is passed in from `loader.py`.
// Configuration what the modifiers mean is completely in Python.
//
+// PYSIDE-2101: The __signature__ attribute is gone due to rlcompleter.
+//
PyObject *get_signature_intern(PyObject *ob, PyObject *modifier)
{
@@ -246,6 +248,9 @@ PyObject *get_signature_intern(PyObject *ob, PyObject *modifier)
return pyside_tp_get___signature__(ob, modifier);
if (Py_TYPE(ob) == &PyWrapperDescr_Type)
return pyside_wd_get___signature__(ob, modifier);
+ // For classmethods we use the simple wrapper description implementation.
+ if (Py_TYPE(ob) == &PyClassMethodDescr_Type)
+ return pyside_wd_get___signature__(ob, modifier);
return nullptr;
}
@@ -302,7 +307,7 @@ static PyObject *feature_import(PyObject * /* self */, PyObject *args, PyObject
PyMethodDef signature_methods[] = {
{"__feature_import__", (PyCFunction)feature_import, METH_VARARGS | METH_KEYWORDS, nullptr},
{"get_signature", (PyCFunction)get_signature, METH_VARARGS,
- "get the __signature__, but pass an optional string parameter"},
+ "get the signature, passing an optional string parameter"},
{nullptr, nullptr, 0, nullptr}
};
@@ -385,9 +390,7 @@ PyObject *PySide_BuildSignatureProps(PyObject *type_key)
#ifdef PYPY_VERSION
static bool get_lldebug_flag()
{
- PyObject *sysmodule = PyImport_AddModule("sys");
- auto *dic = PyModule_GetDict(sysmodule);
- dic = PyDict_GetItemString(dic, "pypy_translation_info");
+ auto *dic = PySys_GetObject("pypy_translation_info");
int lldebug = PyObject_IsTrue(PyDict_GetItemString(dic, "translation.lldebug"));
int lldebug0 = PyObject_IsTrue(PyDict_GetItemString(dic, "translation.lldebug0"));
return lldebug || lldebug0;
@@ -428,8 +431,6 @@ static int PySide_FinishSignatures(PyObject *module, const char *signatures[])
if (PyCFunction_Check(func))
if (PyDict_SetItem(pyside_globals->map_dict, func, module) < 0)
return -1;
- if (_finish_nested_classes(obdict) < 0)
- return -1;
// The finish_import function will not work the first time since phase 2
// was not yet run. But that is ok, because the first import is always for
// the shiboken module (or a test module).
@@ -451,10 +452,12 @@ static int PySide_FinishSignatures(PyObject *module, const char *signatures[])
int InitSignatureStrings(PyTypeObject *type, const char *signatures[])
{
+ // PYSIDE-2404: This function now also builds the mapping for static methods.
+ // It was one missing spot to let Lazy import work.
init_shibokensupport_module();
auto *ob_type = reinterpret_cast<PyObject *>(type);
int ret = PySide_BuildSignatureArgs(ob_type, signatures);
- if (ret < 0) {
+ if (ret < 0 || _build_func_to_type(ob_type) < 0) {
PyErr_Print();
PyErr_SetNone(PyExc_ImportError);
}
@@ -471,6 +474,8 @@ void 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!
*/
+ init_shibokensupport_module();
+
#ifndef PYPY_VERSION
static const bool patch_types = true;
#else
@@ -534,7 +539,7 @@ static PyObject *adjustFuncName(const char *func_name)
// Find the feature flags
auto type = reinterpret_cast<PyTypeObject *>(obtype.object());
- auto dict = type->tp_dict;
+ AutoDecRef dict(PepType_GetDict(type));
int id = currentSelectId(type);
id = id < 0 ? 0 : id; // if undefined, set to zero
auto lower = id & 0x01;
@@ -583,7 +588,9 @@ void SetError_Argument(PyObject *args, const char *func_name, PyObject *info)
PyObject *e, *v, *t;
// Note: These references are all borrowed.
PyErr_Fetch(&e, &v, &t);
+ Py_DECREF(e);
info = v;
+ Py_XDECREF(t);
}
// PYSIDE-1019: Modify the function name expression according to feature.
AutoDecRef new_func_name(adjustFuncName(func_name));
@@ -614,14 +621,10 @@ void SetError_Argument(PyObject *args, const char *func_name, PyObject *info)
* But the __doc__ attribute existed already by inheritance, and calling
* PyType_Modified() is not supported. So we added the getsets explicitly
* to the metatype.
+ *
+ * PYSIDE-2101: The __signature__ attribute is gone due to rlcompleter.
*/
-PyObject *Sbk_TypeGet___signature__(PyObject *ob, PyObject *modifier)
-{
- init_shibokensupport_module();
- return pyside_tp_get___signature__(ob, modifier);
-}
-
PyObject *Sbk_TypeGet___doc__(PyObject *ob)
{
init_shibokensupport_module();
diff --git a/sources/shiboken6/libshiboken/signature/signature_extend.cpp b/sources/shiboken6/libshiboken/signature/signature_extend.cpp
index d571f90f3..7292f8216 100644
--- a/sources/shiboken6/libshiboken/signature/signature_extend.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_extend.cpp
@@ -70,8 +70,6 @@ PyObject *pyside_cf_get___signature__(PyObject *func, PyObject *modifier)
PyObject *pyside_sm_get___signature__(PyObject *sm, PyObject *modifier)
{
AutoDecRef func(PyObject_GetAttr(sm, PyMagicName::func()));
- if (Py_TYPE(func) == PepFunction_TypePtr)
- return PyObject_GetAttr(func, PyMagicName::signature());
return _get_written_signature(GetSignature_Function, func, modifier);
}
@@ -79,7 +77,7 @@ PyObject *pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier)
{
AutoDecRef func(name_key_to_func(ob_md));
if (func.object() == Py_None)
- return Py_None;
+ Py_RETURN_NONE;
if (func.isNull())
Py_FatalError("missing mapping in MethodDescriptor");
return pyside_cf_get___signature__(func, modifier);
@@ -123,13 +121,15 @@ static PyObject *handle_doc(PyObject *ob, PyObject *old_descr)
{
AutoDecRef ob_type_mod(GetClassOrModOf(ob));
const char *name;
- if (PyModule_Check(ob_type_mod.object()))
+ bool isModule = PyModule_Check(ob_type_mod.object());
+ if (isModule)
name = PyModule_GetName(ob_type_mod.object());
else
name = reinterpret_cast<PyTypeObject *>(ob_type_mod.object())->tp_name;
PyObject *res{};
- if (handle_doc_in_progress || name == nullptr || strncmp(name, "PySide6.", 8) != 0) {
+ if (handle_doc_in_progress || name == nullptr
+ || (isModule && strncmp(name, "PySide6.", 8) != 0)) {
res = PyObject_CallMethodObjArgs(old_descr, PyMagicName::get(), ob, nullptr);
} else {
handle_doc_in_progress++;
@@ -169,59 +169,29 @@ static PyObject *pyside_wd_get___doc__(PyObject *wd)
return handle_doc(wd, old_wd_doc_descr);
}
-// the default setter for all objects
-static int pyside_set___signature__(PyObject *op, PyObject *value)
-{
- // By this additional check, this function refuses write access.
- // We consider both nullptr and Py_None as not been written.
- 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);
- return -1;
- }
- int ret = value == nullptr ? PyDict_DelItem(pyside_globals->value_dict, op)
- : PyDict_SetItem(pyside_globals->value_dict, op, value);
- Py_XINCREF(value);
- return ret;
-}
-
// PYSIDE-535: We cannot patch types easily in PyPy.
// Let's use the `get_signature` function, instead.
static PyGetSetDef new_PyCFunction_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_cf_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_cf_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
static PyGetSetDef new_PyStaticMethod_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_sm_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_sm_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
static PyGetSetDef new_PyMethodDescr_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_md_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_md_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
static PyGetSetDef new_PyWrapperDescr_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_wd_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_wd_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
diff --git a/sources/shiboken6/libshiboken/signature/signature_globals.cpp b/sources/shiboken6/libshiboken/signature/signature_globals.cpp
index d0ea86fc6..3a79a12d5 100644
--- a/sources/shiboken6/libshiboken/signature/signature_globals.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_globals.cpp
@@ -88,11 +88,9 @@ static safe_globals_struc *init_phase_1()
* Due to MSVC's limitation to 64k strings, we needed to assemble pieces.
*/
auto **block_ptr = reinterpret_cast<const char **>(PySide_CompressedSignaturePackage);
- int npieces = 0;
PyObject *piece{};
AutoDecRef zipped_string_sequence(PyList_New(0));
for (; **block_ptr != 0; ++block_ptr) {
- npieces++;
// we avoid the string/unicode dilemma by not using PyString_XXX:
piece = Py_BuildValue("s", *block_ptr);
if (piece == nullptr || PyList_Append(zipped_string_sequence, piece) < 0)
@@ -189,6 +187,16 @@ static int init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
p->feature_imported_func = PyObject_GetAttrString(loader, "feature_imported");
if (p->feature_imported_func == nullptr)
break;
+
+ // We call stuff like the feature initialization late,
+ // after all the function pointers are in place.
+ PyObject *post_init_func = PyObject_GetAttrString(loader, "post_init");
+ if (post_init_func == nullptr)
+ break;
+ PyObject *ret = PyObject_CallFunctionObjArgs(post_init_func, nullptr);
+ if (ret == nullptr)
+ break;
+
return 0;
} while (0);
@@ -201,12 +209,12 @@ static int init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
#ifndef _WIN32
////////////////////////////////////////////////////////////////////////////
// a stack trace for linux-like platforms
-#include <stdio.h>
+#include <cstdio>
#if defined(__GLIBC__)
# include <execinfo.h>
#endif
#include <signal.h>
-#include <stdlib.h>
+#include <cstdlib>
#include <unistd.h>
static void handler(int sig) {
@@ -219,7 +227,7 @@ static void handler(int sig) {
// print out all the frames to stderr
#endif
- fprintf(stderr, "Error: signal %d:\n", sig);
+ std::fprintf(stderr, "Error: signal %d:\n", sig);
#if defined(__GLIBC__)
backtrace_symbols_fd(array, size, STDERR_FILENO);
#endif
@@ -229,7 +237,7 @@ static void handler(int sig) {
////////////////////////////////////////////////////////////////////////////
#endif // _WIN32
-safe_globals pyside_globals = nullptr;
+safe_globals_struc *pyside_globals = nullptr;
void init_shibokensupport_module(void)
{
diff --git a/sources/shiboken6/libshiboken/signature/signature_helper.cpp b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
index ef0c021d5..cf84cfa13 100644
--- a/sources/shiboken6/libshiboken/signature/signature_helper.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
@@ -51,10 +51,13 @@ int 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__` or `__name__` attribute.
+ *
+ * PYSIDE-2101: The __signature__ attribute is gone due to rlcompleter.
*/
assert(PyType_Check(type));
PyType_Ready(type);
- PyObject *dict = type->tp_dict;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *dict = tpDict.object();
for (; gsp->name != nullptr; gsp++) {
PyObject *have_descr = PyDict_GetItemString(dict, gsp->name);
if (have_descr != nullptr) {
@@ -291,7 +294,7 @@ PyObject *_address_to_stringlist(PyObject *numkey)
return res_list;
}
-static int _build_func_to_type(PyObject *obtype)
+int _build_func_to_type(PyObject *obtype)
{
/*
* There is no general way to directly get the type of a static method.
@@ -307,7 +310,17 @@ static int _build_func_to_type(PyObject *obtype)
* We also check for hidden methods, see below.
*/
auto *type = reinterpret_cast<PyTypeObject *>(obtype);
- PyObject *dict = type->tp_dict;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *dict = tpDict.object();
+
+ // PYSIDE-2404: Get the original dict for late initialization.
+ // The dict might have been switched before signature init.
+ static const auto *pyTypeType_tp_dict = PepType_GetDict(&PyType_Type);
+ if (Py_TYPE(dict) != Py_TYPE(pyTypeType_tp_dict)) {
+ tpDict.reset(PyObject_GetAttr(dict, PyName::orig_dict()));
+ dict = tpDict.object();
+ }
+
PyMethodDef *meth = type->tp_methods;
if (meth == nullptr)
@@ -373,26 +386,4 @@ static int _build_func_to_type(PyObject *obtype)
return 0;
}
-int _finish_nested_classes(PyObject *obdict)
-{
- PyObject *key, *value, *obtype;
- PyTypeObject *subtype;
- Py_ssize_t pos = 0;
-
- if (obdict == nullptr)
- return -1;
- while (PyDict_Next(obdict, &pos, &key, &value)) {
- if (PyType_Check(value)) {
- obtype = value;
- if (_build_func_to_type(obtype) < 0)
- return -1;
- // now continue with nested cases
- subtype = reinterpret_cast<PyTypeObject *>(obtype);
- if (_finish_nested_classes(subtype->tp_dict) < 0)
- return -1;
- }
- }
- return 0;
-}
-
} // extern "C"