aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp6
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp6
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp2
-rw-r--r--sources/shiboken2/libshiboken/CMakeLists.txt2
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp11
-rw-r--r--sources/shiboken2/libshiboken/helper.cpp3
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.cpp27
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.cpp91
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.h65
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings_p.h72
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.cpp64
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.h3
-rw-r--r--sources/shiboken2/libshiboken/shiboken.h1
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp124
-rw-r--r--sources/shiboken2/libshiboken/signature.h2
-rw-r--r--sources/shiboken2/libshiboken/typespec.cpp3
16 files changed, 392 insertions, 90 deletions
diff --git a/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp b/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp
index 4f55fb8f3..552191955 100644
--- a/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp
+++ b/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp
@@ -121,7 +121,7 @@ PySideEasingCurveFunctor::~PySideEasingCurveFunctor()
{
CustomFunctionsData::m_list[m_index].m_obj = 0;
- PyObject_SetAttrString(m_parent, "__ecf__", Py_None);
+ PyObject_SetAttr(m_parent, Shiboken::PyMagicName::ecf(), Py_None);
}
qreal PySideEasingCurveFunctor::operator()(qreal progress)
@@ -146,13 +146,13 @@ PyObject *PySideEasingCurveFunctor::callable()
PyObject *PySideEasingCurveFunctor::callable(PyObject *parent)
{
- return PyObject_GetAttrString(parent, "__ecf__");
+ return PyObject_GetAttr(parent, Shiboken::PyMagicName::ecf());
}
PySideEasingCurveFunctor::PySideEasingCurveFunctor(int index, PyObject *parent, PyObject *pyFunc)
: m_parent(parent), m_func(pyFunc), m_index(index)
{
- PyObject_SetAttrString(m_parent, "__ecf__", m_func);
+ PyObject_SetAttr(m_parent, Shiboken::PyMagicName::ecf(), m_func);
PySide::WeakRef::create(m_parent, deleteData, this);
}
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 93f7321aa..4c798aef9 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -308,7 +308,7 @@ PyModule_AddStringConstant(module, "__version__", qVersion());
// @snippet qobject-connect
static bool isDecorator(PyObject *method, PyObject *self)
{
- Shiboken::AutoDecRef methodName(PyObject_GetAttrString(method, "__name__"));
+ Shiboken::AutoDecRef methodName(PyObject_GetAttr(method, Shiboken::PyMagicName::name()));
if (!PyObject_HasAttr(self, methodName))
return true;
Shiboken::AutoDecRef otherMethod(PyObject_GetAttr(self, methodName));
@@ -811,8 +811,8 @@ _findChildrenHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %P
// @snippet qobject-tr
QString result;
if (QCoreApplication::instance()) {
- PyObject *klass = PyObject_GetAttrString(%PYSELF, "__class__");
- PyObject *cname = PyObject_GetAttrString(klass, "__name__");
+ PyObject *klass = PyObject_GetAttr(%PYSELF, Shiboken::PyMagicName::class_());
+ PyObject *cname = PyObject_GetAttr(klass, Shiboken::PyMagicName::name());
result = QString(QCoreApplication::instance()->translate(Shiboken::String::toCString(cname),
/* %1, %2, QCoreApplication::CodecForTr, %3)); */
%1, %2, %3));
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 85ce8f954..5e9d9378e 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -6018,7 +6018,7 @@ QString CppGenerator::writeReprFunction(QTextStream &s, GeneratorContext &contex
Indentation indent(INDENT);
s << INDENT << "str.replace(0, idx, Py_TYPE(self)->tp_name);" << endl;
}
- s << INDENT << "PyObject *mod = PyDict_GetItemString(Py_TYPE(self)->tp_dict, \"__module__\");" << endl;
+ s << INDENT << "PyObject *mod = PyDict_GetItem(Py_TYPE(self)->tp_dict, Shiboken::PyMagicName::module());" << endl;
// PYSIDE-595: The introduction of heap types has the side effect that the module name
// is always prepended to the type name. Therefore the strchr check:
s << INDENT << "if (mod && !strchr(str, '.'))" << endl;
diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt
index 0c2c67fe8..a38da8d89 100644
--- a/sources/shiboken2/libshiboken/CMakeLists.txt
+++ b/sources/shiboken2/libshiboken/CMakeLists.txt
@@ -53,6 +53,7 @@ sbkconverter.cpp
sbkenum.cpp
sbkmodule.cpp
sbkstring.cpp
+sbkstaticstrings.cpp
bindingmanager.cpp
threadstatesaver.cpp
shibokenbuffer.cpp
@@ -129,6 +130,7 @@ install(FILES
python25compat.h
sbkdbg.h
sbkstring.h
+ sbkstaticstrings.h
shiboken.h
shibokenmacros.h
threadstatesaver.h
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index 9d233b847..15993aff0 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -44,6 +44,7 @@
#include "sbkconverter.h"
#include "sbkenum.h"
#include "sbkstring.h"
+#include "sbkstaticstrings_p.h"
#include "autodecref.h"
#include "gilstate.h"
#include <string>
@@ -160,11 +161,9 @@ patch_tp_new_wrapper(PyTypeObject *type)
* The old tp_new_wrapper is added to all types that have tp_new.
* We patch that with a version that ignores the heaptype flag.
*/
- static PyObject *__new__ = nullptr;
+ auto newMethod = Shiboken::PyMagicName::new_();
if (old_tp_new_wrapper == nullptr) {
- if ((__new__ = Py_BuildValue("s", "__new__")) == nullptr)
- return -1;
- PyObject *func = PyDict_GetItem(PyType_Type.tp_dict, __new__);
+ PyObject *func = PyDict_GetItem(PyType_Type.tp_dict, newMethod);
PyCFunctionObject *pycf_ob = reinterpret_cast<PyCFunctionObject *>(func);
old_tp_new_wrapper = reinterpret_cast<ternaryfunc>(pycf_ob->m_ml->ml_meth);
}
@@ -172,7 +171,7 @@ patch_tp_new_wrapper(PyTypeObject *type)
Py_ssize_t i, n = PyTuple_GET_SIZE(mro);
for (i = 0; i < n; i++) {
type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
- PyObject *existing = PyDict_GetItem(type->tp_dict, __new__);
+ PyObject *existing = PyDict_GetItem(type->tp_dict, newMethod);
if (existing && PyCFunction_Check(existing)
&& type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
auto *pycf_ob = reinterpret_cast<PyCFunctionObject *>(existing);
@@ -182,7 +181,7 @@ patch_tp_new_wrapper(PyTypeObject *type)
if (existing_wrapper == old_tp_new_wrapper) {
PyObject *ob_type = reinterpret_cast<PyObject *>(type);
Shiboken::AutoDecRef func(PyCFunction_New(tp_new_methoddef, ob_type));
- if (func.isNull() || PyDict_SetItem(type->tp_dict, __new__, func))
+ if (func.isNull() || PyDict_SetItem(type->tp_dict, newMethod, func))
return -1;
}
}
diff --git a/sources/shiboken2/libshiboken/helper.cpp b/sources/shiboken2/libshiboken/helper.cpp
index fac72d56f..013080b6e 100644
--- a/sources/shiboken2/libshiboken/helper.cpp
+++ b/sources/shiboken2/libshiboken/helper.cpp
@@ -39,6 +39,7 @@
#include "helper.h"
#include "sbkstring.h"
+#include "sbkstaticstrings.h"
#include <stdarg.h>
#ifdef _WIN32
@@ -78,7 +79,7 @@ bool listToArgcArgv(PyObject *argList, int *argc, char ***argv, const char *defa
if (hasEmptyArgList) {
// Try to get the script name
PyObject *globals = PyEval_GetGlobals();
- PyObject *appName = PyDict_GetItemString(globals, "__file__");
+ PyObject *appName = PyDict_GetItem(globals, Shiboken::PyMagicName::file());
(*argv)[0] = strdup(appName ? Shiboken::String::toCString(appName) : defaultAppName);
} else {
for (int i = 0; i < numArgs; ++i) {
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index fe7157d24..f4e404bed 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -39,6 +39,8 @@
#include "pep384impl.h"
#include "autodecref.h"
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
extern "C"
{
@@ -125,16 +127,16 @@ check_PyTypeObject_valid()
{
auto *obtype = reinterpret_cast<PyObject *>(&PyType_Type);
auto *probe_tp_base = reinterpret_cast<PyTypeObject *>(
- PyObject_GetAttrString(obtype, "__base__"));
- PyObject *probe_tp_bases = PyObject_GetAttrString(obtype, "__bases__");
+ PyObject_GetAttr(obtype, Shiboken::PyMagicName::base()));
+ auto *probe_tp_bases = PyObject_GetAttr(obtype, Shiboken::PyMagicName::bases());
auto *check = reinterpret_cast<PyTypeObject *>(
PyType_FromSpecWithBases(&typeprobe_spec, probe_tp_bases));
auto *typetype = reinterpret_cast<PyTypeObject *>(obtype);
- PyObject *w = PyObject_GetAttrString(obtype, "__weakrefoffset__");
+ PyObject *w = PyObject_GetAttr(obtype, Shiboken::PyMagicName::weakrefoffset());
long probe_tp_weakrefoffset = PyLong_AsLong(w);
- PyObject *d = PyObject_GetAttrString(obtype, "__dictoffset__");
+ PyObject *d = PyObject_GetAttr(obtype, Shiboken::PyMagicName::dictoffset());
long probe_tp_dictoffset = PyLong_AsLong(d);
- PyObject *probe_tp_mro = PyObject_GetAttrString(obtype, "__mro__");
+ PyObject *probe_tp_mro = PyObject_GetAttr(obtype, Shiboken::PyMagicName::mro());
if (false
|| strcmp(probe_tp_name, check->tp_name) != 0
|| probe_tp_basicsize != check->tp_basicsize
@@ -416,9 +418,10 @@ PepRun_GetResult(const char *command, const char *resvar)
PyObject *d, *v, *res;
d = PyDict_New();
- if (d == NULL || PyDict_SetItemString(d, "__builtins__",
- PyEval_GetBuiltins()) < 0)
- return NULL;
+ if (d == nullptr
+ || PyDict_SetItem(d, Shiboken::PyMagicName::builtins(), PyEval_GetBuiltins()) < 0) {
+ return nullptr;
+ }
v = PyRun_String(command, Py_file_input, d, d);
res = v ? PyDict_GetItemString(d, resvar) : NULL;
Py_XDECREF(v);
@@ -457,7 +460,7 @@ PyMethod_New(PyObject *func, PyObject *self)
PyObject *
PyMethod_Function(PyObject *im)
{
- PyObject *ret = PyObject_GetAttrString(im, "__func__");
+ PyObject *ret = PyObject_GetAttr(im, Shiboken::PyMagicName::func());
// We have to return a borrowed reference.
Py_DECREF(ret);
@@ -467,7 +470,7 @@ PyMethod_Function(PyObject *im)
PyObject *
PyMethod_Self(PyObject *im)
{
- PyObject *ret = PyObject_GetAttrString(im, "__self__");
+ PyObject *ret = PyObject_GetAttr(im, Shiboken::PyMagicName::self());
// We have to return a borrowed reference.
// If we don't obey that here, then we get a test error!
@@ -620,8 +623,8 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
return name;
}
#endif
- Shiboken::AutoDecRef privateobj(PyObject_GetAttrString(
- reinterpret_cast<PyObject *>(Py_TYPE(self)), "__name__"));
+ Shiboken::AutoDecRef privateobj(PyObject_GetAttr(
+ reinterpret_cast<PyObject *>(Py_TYPE(self)), Shiboken::PyMagicName::name()));
#ifndef Py_LIMITED_API
return _Py_Mangle(privateobj, name);
#else
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
new file mode 100644
index 000000000..dcd25da16
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
+#include "sbkstring.h"
+
+#define STATIC_STRING_IMPL(funcName, value) \
+PyObject *funcName() \
+{ \
+ static PyObject *const s = Shiboken::String::createStaticString(value); \
+ return s; \
+}
+
+namespace Shiboken
+{
+namespace PyName {
+// exported:
+STATIC_STRING_IMPL(dumps, "dumps")
+STATIC_STRING_IMPL(loads, "loads")
+
+// Internal:
+STATIC_STRING_IMPL(classmethod, "classmethod")
+STATIC_STRING_IMPL(compile, "compile");
+STATIC_STRING_IMPL(function, "function")
+STATIC_STRING_IMPL(marshal, "marshal")
+STATIC_STRING_IMPL(method, "method")
+STATIC_STRING_IMPL(overload, "overload")
+STATIC_STRING_IMPL(staticmethod, "staticmethod")
+} // namespace PyName
+
+namespace PyMagicName {
+// exported:
+STATIC_STRING_IMPL(class_, "__class__")
+STATIC_STRING_IMPL(ecf, "__ecf__")
+STATIC_STRING_IMPL(file, "__file__")
+STATIC_STRING_IMPL(module, "__module__")
+STATIC_STRING_IMPL(name, "__name__")
+
+// Internal:
+STATIC_STRING_IMPL(base, "__base__")
+STATIC_STRING_IMPL(bases, "__bases__")
+STATIC_STRING_IMPL(builtins, "__builtins__")
+STATIC_STRING_IMPL(code, "__code__")
+STATIC_STRING_IMPL(dictoffset, "__dictoffset__")
+STATIC_STRING_IMPL(func, "__func__")
+STATIC_STRING_IMPL(func_kind, "__func_kind__")
+STATIC_STRING_IMPL(mro, "__mro__")
+STATIC_STRING_IMPL(new_, "__new__")
+STATIC_STRING_IMPL(objclass, "__objclass__")
+STATIC_STRING_IMPL(self, "__self__")
+STATIC_STRING_IMPL(signature, "__signature__")
+STATIC_STRING_IMPL(weakrefoffset, "__weakrefoffset__")
+} // namespace PyMagicName
+} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.h b/sources/shiboken2/libshiboken/sbkstaticstrings.h
new file mode 100644
index 000000000..fa21a8e2c
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#ifndef SBKSTATICSTRINGS_H
+#define SBKSTATICSTRINGS_H
+
+#include "sbkpython.h"
+#include "shibokenmacros.h"
+
+namespace Shiboken
+{
+// Some often-used strings
+namespace PyName
+{
+LIBSHIBOKEN_API PyObject *dumps();
+LIBSHIBOKEN_API PyObject *loads();
+} // namespace PyName
+
+namespace PyMagicName
+{
+LIBSHIBOKEN_API PyObject *class_();
+LIBSHIBOKEN_API PyObject *ecf();
+LIBSHIBOKEN_API PyObject *file();
+LIBSHIBOKEN_API PyObject *module();
+LIBSHIBOKEN_API PyObject *name();
+} // namespace PyMagicName
+} // namespace Shiboken
+
+#endif // SBKSTATICSTRINGS_H
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings_p.h b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
new file mode 100644
index 000000000..bb4cb13c3
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include "sbkpython.h"
+#include "shibokenmacros.h"
+
+namespace Shiboken
+{
+namespace PyName
+{
+PyObject *classmethod();
+PyObject *compile();
+PyObject *function();
+PyObject *marshal();
+PyObject *method();
+PyObject *overload();
+PyObject *staticmethod();
+} // namespace PyName
+namespace PyMagicName
+{
+PyObject *base();
+PyObject *bases();
+PyObject *builtins();
+PyObject *code();
+PyObject *dictoffset();
+PyObject *func();
+PyObject *func_kind();
+PyObject *module();
+PyObject *mro();
+PyObject *new_();
+PyObject *objclass();
+PyObject *self();
+PyObject *signature();
+PyObject *weakrefoffset();
+} // namespace PyMagicName
+} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstring.cpp b/sources/shiboken2/libshiboken/sbkstring.cpp
index 9ba5be281..2e638a413 100644
--- a/sources/shiboken2/libshiboken/sbkstring.cpp
+++ b/sources/shiboken2/libshiboken/sbkstring.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -40,6 +40,8 @@
#include "sbkstring.h"
#include "autodecref.h"
+#include <vector>
+
namespace Shiboken
{
@@ -200,6 +202,64 @@ Py_ssize_t len(PyObject *str)
return 0;
}
-} // namespace String
+///////////////////////////////////////////////////////////////////////
+//
+// Implementation of efficient Python strings
+// ------------------------------------------
+//
+// Instead of repetitively executing
+//
+// PyObject *attr = PyObject_GetAttrString(obj, "__name__");
+//
+// a helper of the form
+//
+// PyObject *name()
+// {
+// static PyObject *const s = Shiboken::String::createStaticString("__name__");
+// return result;
+// }
+//
+// can now be implemented, which registers the string into a static set avoiding
+// repetitive string creation. The resulting code looks like:
+//
+// PyObject *attr = PyObject_GetAttr(obj, name());
+//
+// Missing:
+// There is no finalization for the string structures, yet.
+// But this is a global fault in shiboken. We are missing a true
+// finalization like in all other modules.
+
+using StaticStrings = std::vector<PyObject *>;
+
+static StaticStrings &staticStrings()
+{
+ static StaticStrings result;
+ return result;
+}
+
+PyObject *createStaticString(const char *str)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ PyObject *result = PyUnicode_InternFromString(str);
+#else
+ PyObject *result = PyString_InternFromString(str);
+#endif
+ if (result == nullptr) {
+ // This error is never checked, but also very unlikely. Report and exit.
+ PyErr_Print();
+ Py_FatalError("unexpected error in createStaticString()");
+ }
+ staticStrings().push_back(result);
+ return result;
+}
+void finalizeStaticStrings() // Currently unused
+{
+ auto &list = staticStrings();
+ for (auto s : list)
+ Py_DECREF(s);
+ list.clear();
+}
+
+} // namespace String
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstring.h b/sources/shiboken2/libshiboken/sbkstring.h
index 0ead25269..c82ed5a22 100644
--- a/sources/shiboken2/libshiboken/sbkstring.h
+++ b/sources/shiboken2/libshiboken/sbkstring.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -59,6 +59,7 @@ namespace String
LIBSHIBOKEN_API PyObject *fromStringAndSize(const char *str, Py_ssize_t size);
LIBSHIBOKEN_API int compare(PyObject *val1, const char *val2);
LIBSHIBOKEN_API Py_ssize_t len(PyObject *str);
+ LIBSHIBOKEN_API PyObject *createStaticString(const char *str);
} // namespace String
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/shiboken.h b/sources/shiboken2/libshiboken/shiboken.h
index 1356670aa..0d2d6b0a6 100644
--- a/sources/shiboken2/libshiboken/shiboken.h
+++ b/sources/shiboken2/libshiboken/shiboken.h
@@ -52,6 +52,7 @@
#include "sbkenum.h"
#include "sbkmodule.h"
#include "sbkstring.h"
+#include "sbkstaticstrings.h"
#include "shibokenmacros.h"
#include "shibokenbuffer.h"
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 746b026c4..5430ab064 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -39,6 +39,8 @@
#include "basewrapper.h"
#include "autodecref.h"
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
extern "C"
{
@@ -51,11 +53,11 @@ extern "C"
// These constants were needed in former versions of the module:
#define PYTHON_HAS_QUALNAME (PY_VERSION_HEX >= 0x03030000)
-#define PYTHON_HAS_UNICODE (PY_VERSION_HEX >= 0x03000000)
#define PYTHON_HAS_WEAKREF_PYCFUNCTION (PY_VERSION_HEX >= 0x030500A0)
#define PYTHON_IS_PYTHON3 (PY_VERSION_HEX >= 0x03000000)
#define PYTHON_HAS_KEYWORDONLY (PYTHON_IS_PYTHON3)
#define PYTHON_USES_PERCENT_V_FORMAT (PYTHON_IS_PYTHON3)
+#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
#define PYTHON_HAS_DESCR_REDUCE (PY_VERSION_HEX >= 0x03040000)
#define PYTHON_HAS_METH_REDUCE (PYTHON_HAS_DESCR_REDUCE)
#define PYTHON_NEEDS_ITERATOR_FLAG (!PYTHON_IS_PYTHON3)
@@ -64,7 +66,7 @@ extern "C"
#define PYTHON_HAS_INT_AND_LONG (!PYTHON_IS_PYTHON3)
// These constants are still in use:
-#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
+#define PYTHON_USES_UNICODE (PY_VERSION_HEX >= 0x03000000)
typedef struct safe_globals_struc {
// init part 1: get arg_dict
@@ -84,11 +86,11 @@ static safe_globals pyside_globals = nullptr;
static PyObject *GetTypeKey(PyObject *ob);
-static PyObject *GetSignature_Function(PyObject *, const char *);
-static PyObject *GetSignature_TypeMod(PyObject *, const char *);
-static PyObject *GetSignature_Wrapper(PyObject *, const char *);
+static PyObject *GetSignature_Function(PyObject *, PyObject *);
+static PyObject *GetSignature_TypeMod(PyObject *, PyObject *);
+static PyObject *GetSignature_Wrapper(PyObject *, PyObject *);
static PyObject *get_signature(PyObject *self, PyObject *args);
-static PyObject *get_signature_intern(PyObject *ob, const char *modifier);
+static PyObject *get_signature_intern(PyObject *ob, PyObject *modifier);
static PyObject *PySide_BuildSignatureProps(PyObject *class_mod);
@@ -108,10 +110,10 @@ CreateSignature(PyObject *props, PyObject *key)
const_cast<char *>("(OO)"), props, key);
}
-typedef PyObject *(*signaturefunc)(PyObject *, const char *);
+typedef PyObject *(*signaturefunc)(PyObject *, PyObject *);
static PyObject *
-_get_written_signature(signaturefunc sf, PyObject *ob, const char *modifier)
+_get_written_signature(signaturefunc sf, PyObject *ob, PyObject *modifier)
{
/*
* Be a writable Attribute, but have a computed value.
@@ -134,19 +136,19 @@ _get_written_signature(signaturefunc sf, PyObject *ob, const char *modifier)
}
static PyObject *
-pyside_cf_get___signature__(PyObject *func, const char *modifier)
+pyside_cf_get___signature__(PyObject *func, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_Function, func, modifier);
}
static PyObject *
-pyside_sm_get___signature__(PyObject *sm, const char *modifier)
+pyside_sm_get___signature__(PyObject *sm, PyObject *modifier)
{
init_module_2();
- Shiboken::AutoDecRef func(PyObject_GetAttrString(sm, "__func__"));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(sm, Shiboken::PyMagicName::func()));
if (Py_TYPE(func) == PepFunction_TypePtr)
- return PyObject_GetAttrString(func, "__signature__");
+ return PyObject_GetAttr(func, Shiboken::PyMagicName::signature());
return _get_written_signature(GetSignature_Function, func, modifier);
}
@@ -158,7 +160,7 @@ _get_class_of_cf(PyObject *ob_cf)
selftype = PyDict_GetItem(pyside_globals->map_dict, ob_cf);
if (selftype == nullptr) {
// This must be an overloaded function that we handled special.
- Shiboken::AutoDecRef special(Py_BuildValue("(Os)", ob_cf, "overload"));
+ Shiboken::AutoDecRef special(Py_BuildValue("(OO)", ob_cf, Shiboken::PyName::overload()));
selftype = PyDict_GetItem(pyside_globals->map_dict, special);
if (selftype == nullptr) {
// This is probably a module function. We will return type(None).
@@ -176,15 +178,15 @@ _get_class_of_cf(PyObject *ob_cf)
static PyObject *
_get_class_of_sm(PyObject *ob_sm)
{
- Shiboken::AutoDecRef func(PyObject_GetAttrString(ob_sm, "__func__"));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(ob_sm, Shiboken::PyMagicName::func()));
return _get_class_of_cf(func);
}
static PyObject *
_get_class_of_descr(PyObject *ob)
{
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
- return PyObject_GetAttrString(ob, "__objclass__");
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ return PyObject_GetAttr(ob, Shiboken::PyMagicName::objclass());
}
static PyObject *
@@ -216,10 +218,10 @@ get_funcname(PyObject *ob)
{
PyObject *func = ob;
if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
- func = PyObject_GetAttrString(ob, "__func__");
+ func = PyObject_GetAttr(ob, Shiboken::PyMagicName::func());
else
Py_INCREF(func);
- PyObject *func_name = PyObject_GetAttrString(func, "__name__");
+ PyObject *func_name = PyObject_GetAttr(func, Shiboken::PyMagicName::name());
Py_DECREF(func);
if (func_name == nullptr)
Py_FatalError("unexpected name problem in compute_name_key");
@@ -287,7 +289,7 @@ name_key_to_func(PyObject *ob)
}
static PyObject *
-pyside_md_get___signature__(PyObject *ob_md, const char *modifier)
+pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier)
{
init_module_2();
Shiboken::AutoDecRef func(name_key_to_func(ob_md));
@@ -299,14 +301,14 @@ pyside_md_get___signature__(PyObject *ob_md, const char *modifier)
}
static PyObject *
-pyside_wd_get___signature__(PyObject *ob, const char *modifier)
+pyside_wd_get___signature__(PyObject *ob, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_Wrapper, ob, modifier);
}
static PyObject *
-pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
+pyside_tp_get___signature__(PyObject *obtype_mod, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_TypeMod, obtype_mod, modifier);
@@ -314,7 +316,7 @@ pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
// forward
static PyObject *
-GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier);
+GetSignature_Cached(PyObject *props, PyObject *func_kind, PyObject *modifier);
static PyObject *
GetTypeKey(PyObject *ob)
@@ -332,8 +334,8 @@ GetTypeKey(PyObject *ob)
*
* This is the PyCFunction behavior, as opposed to Python functions.
*/
- Shiboken::AutoDecRef class_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef module_name(PyObject_GetAttrString(ob, "__module__"));
+ Shiboken::AutoDecRef class_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ Shiboken::AutoDecRef module_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::module()));
if (module_name.isNull())
PyErr_Clear();
@@ -364,7 +366,7 @@ TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype)
}
static PyObject *
-GetSignature_Function(PyObject *obfunc, const char *modifier)
+GetSignature_Function(PyObject *obfunc, PyObject *modifier)
{
// make sure that we look into PyCFunction, only...
if (Py_TYPE(obfunc) == PepFunction_TypePtr)
@@ -376,29 +378,29 @@ GetSignature_Function(PyObject *obfunc, const char *modifier)
PyObject *dict = TypeKey_to_PropsDict(type_key, obtype_mod);
if (dict == nullptr)
return nullptr;
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(obfunc, "__name__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(obfunc, Shiboken::PyMagicName::name()));
PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr;
if (props == nullptr)
Py_RETURN_NONE;
int flags = PyCFunction_GET_FLAGS(obfunc);
- const char *func_kind;
+ PyObject *func_kind;
if (PyModule_Check(obtype_mod))
- func_kind = "function";
+ func_kind = Shiboken::PyName::function();
else if (flags & METH_CLASS)
- func_kind = "classmethod";
+ func_kind = Shiboken::PyName::classmethod();
else if (flags & METH_STATIC)
- func_kind = "staticmethod";
+ func_kind = Shiboken::PyName::staticmethod();
else
- func_kind = "method";
+ func_kind = Shiboken::PyName::method();
return GetSignature_Cached(props, func_kind, modifier);
}
static PyObject *
-GetSignature_Wrapper(PyObject *ob, const char *modifier)
+GetSignature_Wrapper(PyObject *ob, PyObject *modifier)
{
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef objclass(PyObject_GetAttrString(ob, "__objclass__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ Shiboken::AutoDecRef objclass(PyObject_GetAttr(ob, Shiboken::PyMagicName::objclass()));
Shiboken::AutoDecRef class_key(GetTypeKey(objclass));
if (func_name.isNull() || objclass.isNull() || class_key.isNull())
@@ -409,13 +411,13 @@ GetSignature_Wrapper(PyObject *ob, const char *modifier)
PyObject *props = PyDict_GetItem(dict, func_name);
if (props == nullptr)
Py_RETURN_NONE;
- return GetSignature_Cached(props, "method", modifier);
+ return GetSignature_Cached(props, Shiboken::PyName::method(), modifier);
}
static PyObject *
-GetSignature_TypeMod(PyObject *ob, const char *modifier)
+GetSignature_TypeMod(PyObject *ob, PyObject *modifier)
{
- Shiboken::AutoDecRef ob_name(PyObject_GetAttrString(ob, "__name__"));
+ Shiboken::AutoDecRef ob_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
Shiboken::AutoDecRef ob_key(GetTypeKey(ob));
PyObject *dict = TypeKey_to_PropsDict(ob_key, ob);
@@ -424,19 +426,26 @@ GetSignature_TypeMod(PyObject *ob, const char *modifier)
PyObject *props = PyDict_GetItem(dict, ob_name);
if (props == nullptr)
Py_RETURN_NONE;
- return GetSignature_Cached(props, "method", modifier);
+ return GetSignature_Cached(props, Shiboken::PyName::method(), modifier);
}
static PyObject *
-GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier)
+GetSignature_Cached(PyObject *props, PyObject *func_kind, PyObject *modifier)
{
// Special case: We want to know the func_kind.
- if (modifier && strcmp(modifier, "__func_kind__") == 0)
- return Py_BuildValue("s", func_kind);
+ if (modifier) {
+#if PYTHON_USES_UNICODE
+ PyUnicode_InternInPlace(&modifier);
+#else
+ PyString_InternInPlace(&modifier);
+#endif
+ if (modifier == Shiboken::PyMagicName::func_kind())
+ return Py_BuildValue("O", func_kind);
+ }
Shiboken::AutoDecRef key(modifier == nullptr
- ? Py_BuildValue("s", func_kind)
- : Py_BuildValue("(ss)", func_kind, modifier));
+ ? Py_BuildValue("O", func_kind)
+ : Py_BuildValue("(OO)", func_kind, modifier));
PyObject *value = PyDict_GetItem(props, key);
if (value == nullptr) {
// we need to compute a signature object
@@ -478,13 +487,10 @@ init_phase_1(void)
#ifdef Py_LIMITED_API
// We must work for multiple versions, so use source code.
#else
- Shiboken::AutoDecRef marshal_str(Py_BuildValue("s", "marshal"));
- if (marshal_str.isNull())
- goto error;
- Shiboken::AutoDecRef marshal_module(PyImport_Import(marshal_str));
+ Shiboken::AutoDecRef marshal_module(PyImport_Import(Shiboken::PyName::marshal()));
if (marshal_module.isNull())
goto error;
- Shiboken::AutoDecRef loads(PyObject_GetAttrString(marshal_module, "loads"));
+ Shiboken::AutoDecRef loads(PyObject_GetAttr(marshal_module, Shiboken::PyName::loads()));
if (loads.isNull())
goto error;
#endif
@@ -496,7 +502,7 @@ init_phase_1(void)
goto error;
#ifdef Py_LIMITED_API
PyObject *builtins = PyEval_GetBuiltins();
- PyObject *compile = PyDict_GetItemString(builtins, "compile");
+ PyObject *compile = PyDict_GetItem(builtins, Shiboken::PyName::compile());
if (compile == nullptr)
goto error;
Shiboken::AutoDecRef code_obj(PyObject_CallFunction(compile, "Oss",
@@ -513,7 +519,7 @@ init_phase_1(void)
goto error;
// Initialize the module
PyObject *mdict = PyModule_GetDict(p->helper_module);
- if (PyDict_SetItemString(mdict, "__builtins__", PyEval_GetBuiltins()) < 0)
+ if (PyDict_SetItem(mdict, Shiboken::PyMagicName::builtins(), PyEval_GetBuiltins()) < 0)
goto error;
/*
* Unpack an embedded ZIP file with more signature modules.
@@ -559,7 +565,7 @@ init_phase_1(void)
}
error:
PyErr_Print();
- PyErr_SetString(PyExc_SystemError, "could not initialize part 1");
+ Py_FatalError("could not initialize part 1");
return nullptr;
}
@@ -601,11 +607,10 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
if (p->finish_import_func == nullptr)
goto error;
return 0;
- return 0;
}
error:
PyErr_Print();
- PyErr_SetString(PyExc_SystemError, "could not initialize part 2");
+ Py_FatalError("could not initialize part 2");
return -1;
}
@@ -803,7 +808,7 @@ static PyGetSetDef new_PyWrapperDescr_getsets[] = {
//
static PyObject *
-get_signature_intern(PyObject *ob, const char *modifier)
+get_signature_intern(PyObject *ob, PyObject *modifier)
{
if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type))
return pyside_cf_get___signature__(ob, modifier);
@@ -822,11 +827,11 @@ static PyObject *
get_signature(PyObject * /* self */, PyObject *args)
{
PyObject *ob;
- const char *modifier = nullptr;
+ PyObject *modifier = nullptr;
init_module_1();
- if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier))
+ if (!PyArg_ParseTuple(args, "O|O", &ob, &modifier))
return nullptr;
if (Py_TYPE(ob) == PepFunction_TypePtr)
Py_RETURN_NONE;
@@ -1110,13 +1115,14 @@ _build_func_to_type(PyObject *obtype)
* "{name}.overload".
*/
PyObject *descr = PyDict_GetItemString(dict, meth->ml_name);
- const char *look_attr = meth->ml_flags & METH_STATIC ? "__func__" : "__name__";
+ PyObject *look_attr = meth->ml_flags & METH_STATIC
+ ? Shiboken::PyMagicName::func() : Shiboken::PyMagicName::name();
int check_name = meth->ml_flags & METH_STATIC ? 0 : 1;
if (descr == nullptr)
return -1;
// We first check all methods if one is hidden by something else.
- Shiboken::AutoDecRef look(PyObject_GetAttrString(descr, look_attr));
+ Shiboken::AutoDecRef look(PyObject_GetAttr(descr, look_attr));
Shiboken::AutoDecRef given(Py_BuildValue("s", meth->ml_name));
if (look.isNull()
|| (check_name && PyObject_RichCompareBool(look, given, Py_EQ) != 1)) {
@@ -1223,7 +1229,7 @@ SetError_Argument(PyObject *args, const char *func_name)
*/
PyObject *
-Sbk_TypeGet___signature__(PyObject *ob, const char *modifier)
+Sbk_TypeGet___signature__(PyObject *ob, PyObject *modifier)
{
return pyside_tp_get___signature__(ob, modifier);
}
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index 57fd4047a..b22a78497 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -48,7 +48,7 @@ extern "C"
LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *[]);
LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]);
LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *);
-LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, const char *);
+LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, PyObject *);
LIBSHIBOKEN_API PyObject *Sbk_TypeGet___doc__(PyObject *);
} // extern "C"
diff --git a/sources/shiboken2/libshiboken/typespec.cpp b/sources/shiboken2/libshiboken/typespec.cpp
index 6dc5b00bc..510ed51e6 100644
--- a/sources/shiboken2/libshiboken/typespec.cpp
+++ b/sources/shiboken2/libshiboken/typespec.cpp
@@ -39,6 +39,7 @@
#include "sbkpython.h"
#include "typespec.h"
+#include "sbkstaticstrings.h"
#include <structmember.h>
#if PY_MAJOR_VERSION < 3
@@ -730,7 +731,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
}
// no PyId_ things in Python 2
// err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname);
- err = PyDict_SetItemString(type->tp_dict, "__module__", modname);
+ err = PyDict_SetItem(type->tp_dict, Shiboken::PyMagicName::module(), modname);
Py_DECREF(modname);
if (err != 0)
goto fail;