diff options
Diffstat (limited to 'sources/shiboken6/libshiboken/signature/signature_helper.cpp')
-rw-r--r-- | sources/shiboken6/libshiboken/signature/signature_helper.cpp | 112 |
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" |