diff options
Diffstat (limited to 'sources/shiboken6/libshiboken/signature/signature_helper.cpp')
-rw-r--r-- | sources/shiboken6/libshiboken/signature/signature_helper.cpp | 104 |
1 files changed, 31 insertions, 73 deletions
diff --git a/sources/shiboken6/libshiboken/signature/signature_helper.cpp b/sources/shiboken6/libshiboken/signature/signature_helper.cpp index 129554683..9aab7a6a9 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 //////////////////////////////////////////////////////////////////////////// // @@ -53,6 +17,8 @@ #include "signature_p.h" +#include <cstring> + using namespace Shiboken; extern "C" { @@ -87,10 +53,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) { @@ -148,11 +117,11 @@ static PyObject *_func_with_new_name(PyTypeObject *type, * but does not create a descriptor. * XXX Maybe we can get rid of this, completely? */ - auto obtype = reinterpret_cast<PyObject *>(type); - int len = strlen(new_name); - auto name = new char[len + 1]; - strcpy(name, new_name); - auto new_meth = new PyMethodDef; + auto *obtype = reinterpret_cast<PyObject *>(type); + const size_t len = std::strlen(new_name); + auto *name = new char[len + 1]; + std::strcpy(name, new_name); + auto *new_meth = new PyMethodDef; new_meth->ml_name = name; new_meth->ml_meth = meth->ml_meth; new_meth->ml_flags = meth->ml_flags; @@ -229,8 +198,8 @@ static PyObject *_build_new_entry(PyObject *new_name, PyObject *value) if (list.isNull()) return nullptr; for (int idx = 0; idx < len; ++idx) { - auto multi_entry = PyList_GetItem(multi, idx); - auto dup = PyDict_Copy(multi_entry); + auto *multi_entry = PyList_GetItem(multi, idx); + auto *dup = PyDict_Copy(multi_entry); if (PyDict_SetItem(dup, PyName::name(), new_name) < 0) return nullptr; if (PyList_SetItem(list, idx, dup) < 0) @@ -248,7 +217,8 @@ static PyObject *_build_new_entry(PyObject *new_name, PyObject *value) int insert_snake_case_variants(PyObject *dict) { AutoDecRef snake_dict(PyDict_New()); - PyObject *key, *value; + PyObject *key{}; + PyObject *value{}; Py_ssize_t pos = 0; while (PyDict_Next(dict, &pos, &key, &value)) { AutoDecRef name(String::getSnakeCaseName(key, true)); @@ -327,7 +297,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. @@ -343,7 +313,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) @@ -386,8 +366,8 @@ static int _build_func_to_type(PyObject *obtype) if (descr == nullptr) return -1; char mangled_name[200]; - strcpy(mangled_name, meth->ml_name); - strcat(mangled_name, ".overload"); + std::strcpy(mangled_name, meth->ml_name); + std::strcat(mangled_name, ".overload"); if (PyDict_SetItemString(dict, mangled_name, descr) < 0) return -1; if (meth->ml_flags & METH_STATIC) { @@ -409,26 +389,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" |