aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/libshiboken/signature/signature_helper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/libshiboken/signature/signature_helper.cpp')
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_helper.cpp112
1 files changed, 32 insertions, 80 deletions
diff --git a/sources/shiboken6/libshiboken/signature/signature_helper.cpp b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
index f38740254..cf84cfa13 100644
--- a/sources/shiboken6/libshiboken/signature/signature_helper.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
////////////////////////////////////////////////////////////////////////////
//
@@ -57,19 +21,6 @@ using namespace Shiboken;
extern "C" {
-// Helper for __qualname__ which might not always exist in Python 2 (type).
-PyObject *_get_qualname(PyObject *ob)
-{
- // We support __qualname__ for types, only.
- assert(PyType_Check(ob));
- PyObject *name = PyObject_GetAttr(ob, PyMagicName::qualname());
- if (name == nullptr) {
- PyErr_Clear();
- name = PyObject_GetAttr(ob, PyMagicName::name());
- }
- return name;
-}
-
static int _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
{
/*
@@ -92,8 +43,6 @@ static int _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_
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;
}
@@ -102,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) {
@@ -120,6 +72,9 @@ int add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr)
AutoDecRef descr(PyDescr_NewGetSet(type, gsp));
if (descr.isNull())
return -1;
+ // PYSIDE-535: We cannot set the attribute. For simplicity, we use
+ // get_signature in PyPy, instead. This can be re-implemented
+ // later by deriving extra heap types.
if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
return -1;
}
@@ -236,7 +191,7 @@ static PyObject *_build_new_entry(PyObject *new_name, PyObject *value)
PyObject *new_value = PyDict_Copy(value);
PyObject *multi = PyDict_GetItem(value, PyName::multi());
if (multi != nullptr && Py_TYPE(multi) == &PyList_Type) {
- ssize_t len = PyList_Size(multi);
+ Py_ssize_t len = PyList_Size(multi);
AutoDecRef list(PyList_New(len));
if (list.isNull())
return nullptr;
@@ -271,6 +226,15 @@ int insert_snake_case_variants(PyObject *dict)
return PyDict_Merge(dict, snake_dict, 0);
}
+#ifdef PYPY_VERSION
+PyObject *_get_class_of_bm(PyObject *ob_bm)
+{
+ AutoDecRef self(PyObject_GetAttr(ob_bm, PyMagicName::self()));
+ auto *klass = PyObject_GetAttr(self, PyMagicName::class_());
+ return klass;
+}
+#endif
+
PyObject *_get_class_of_cf(PyObject *ob_cf)
{
PyObject *selftype = PyCFunction_GET_SELF(ob_cf);
@@ -314,7 +278,7 @@ PyObject *_address_to_stringlist(PyObject *numkey)
* When needed in `PySide_BuildSignatureProps`, the strings are
* finally materialized.
*/
- ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError);
+ Py_ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError);
if (address == -1 && PyErr_Occurred())
return nullptr;
char **sig_strings = reinterpret_cast<char **>(address);
@@ -330,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.
@@ -346,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)
@@ -412,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"