aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/libshiboken')
-rw-r--r--sources/shiboken2/libshiboken/CMakeLists.txt10
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp94
-rw-r--r--sources/shiboken2/libshiboken/embed/embedding_generator.py4
-rw-r--r--sources/shiboken2/libshiboken/helper.cpp3
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.cpp42
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h2
-rw-r--r--sources/shiboken2/libshiboken/qapp_macro.cpp9
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.cpp92
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.h65
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings_p.h73
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.cpp71
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.h10
-rw-r--r--sources/shiboken2/libshiboken/shiboken.h1
-rw-r--r--sources/shiboken2/libshiboken/shibokenbuffer.cpp4
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp132
-rw-r--r--sources/shiboken2/libshiboken/signature.h2
-rw-r--r--sources/shiboken2/libshiboken/typespec.cpp3
17 files changed, 477 insertions, 140 deletions
diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt
index 7cbb22978..a38da8d89 100644
--- a/sources/shiboken2/libshiboken/CMakeLists.txt
+++ b/sources/shiboken2/libshiboken/CMakeLists.txt
@@ -30,8 +30,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
"${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.py" @ONLY)
add_custom_command(
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.inc"
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature.inc"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap_inc.h"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_inc.h"
COMMAND ${PYTHON_EXECUTABLE} -E
"${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
--cmake-dir "${CMAKE_CURRENT_BINARY_DIR}/embed"
@@ -53,6 +53,7 @@ sbkconverter.cpp
sbkenum.cpp
sbkmodule.cpp
sbkstring.cpp
+sbkstaticstrings.cpp
bindingmanager.cpp
threadstatesaver.cpp
shibokenbuffer.cpp
@@ -62,8 +63,8 @@ pep384impl.cpp
voidptr.cpp
typespec.cpp
bufferprocs_py37.cpp
-embed/signature_bootstrap.inc
-embed/signature.inc
+embed/signature_bootstrap_inc.h
+embed/signature_inc.h
)
get_numpy_location()
@@ -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 b9f6735d8..000035627 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>
@@ -92,6 +93,7 @@ static PyType_Slot SbkObjectType_Type_slots[] = {
{Py_tp_alloc, reinterpret_cast<void *>(PyType_GenericAlloc)},
{Py_tp_new, reinterpret_cast<void *>(SbkObjectTypeTpNew)},
{Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
+ {Py_tp_getset, reinterpret_cast<void *>(SbkObjectType_Type_getsetlist)},
{0, nullptr}
};
static PyType_Spec SbkObjectType_Type_spec = {
@@ -106,7 +108,7 @@ static PyType_Spec SbkObjectType_Type_spec = {
#if PY_VERSION_HEX < 0x03000000
/*****************************************************************************
*
- * PYSIDE-816: Workaround for Python 2.7
+ * PYSIDE-816: Workaround for Python 2.7 for SbkObjectType_TypeF().
*
* This is an add-on for function typeobject.c:tp_new_wrapper from Python 2.7 .
* Problem:
@@ -121,9 +123,16 @@ static PyType_Spec SbkObjectType_Type_spec = {
* The problem is that heap types have this unwanted dependency.
* But we cannot get at static slot_tp_new, and so we have to use
* the original function and patch Py_TPFLAGS_HEAPTYPE away during the call.
+ *
+ * PYSIDE-1051: The same problem holds for all dynamic metatypes generated by
+ * SbkObjectTypeTpNew() and all types generated by
+ * introduceWrapperType() .
+ *
+ * This led to a drastic overhaul of patch_tp_new_wrapper() which now adds
+ * the new wrapper to exactly those types which have the old wrapper.
*/
-static PyCFunction old_tp_new_wrapper = nullptr;
+ternaryfunc old_tp_new_wrapper = nullptr;
static PyObject *
tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
@@ -136,9 +145,9 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
return ret;
}
-// This is intentionally the new docstring of Python 3.7 .
+// This is intentionally the __new__ docstring of Python 3.7 .
static struct PyMethodDef tp_new_methoddef[] = {
- {"__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS|METH_KEYWORDS,
+ {"__new__", reinterpret_cast<PyCFunction>(tp_new_wrapper), METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("__new__($type, *args, **kwargs)\n--\n\n"
"Create and return a new object. "
"See help(type) for accurate signature.")},
@@ -146,43 +155,38 @@ static struct PyMethodDef tp_new_methoddef[] = {
};
static int
-get_old_tp_new_wrapper(void)
-{
- // We get the old tp_new_wrapper from any initialized type.
- PyTypeObject *type = &PyType_Type;
- PyObject *dict = type->tp_dict;
- PyObject *key, *func = nullptr;
- Py_ssize_t pos = 0;
- while (PyDict_Next(dict, &pos, &key, &func)) {
- char *name = PyString_AsString(key);
- if (strcmp(name, "__new__") == 0) {
- break;
+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.
+ */
+ auto newMethod = Shiboken::PyMagicName::new_();
+ if (old_tp_new_wrapper == nullptr) {
+ PyObject *func = PyDict_GetItem(PyType_Type.tp_dict, newMethod);
+ assert(func);
+ PyCFunctionObject *pycf_ob = reinterpret_cast<PyCFunctionObject *>(func);
+ old_tp_new_wrapper = reinterpret_cast<ternaryfunc>(pycf_ob->m_ml->ml_meth);
+ }
+ PyObject *mro = type->tp_mro;
+ 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, newMethod);
+ if (existing && PyCFunction_Check(existing)
+ && type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ auto *pycf_ob = reinterpret_cast<PyCFunctionObject *>(existing);
+ auto existing_wrapper = reinterpret_cast<ternaryfunc>(pycf_ob->m_ml->ml_meth);
+ if (existing_wrapper == tp_new_wrapper)
+ break;
+ 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, newMethod, func))
+ return -1;
+ }
}
}
- if (func == nullptr)
- return -1;
- PyCFunctionObject *pycf_ob = reinterpret_cast<PyCFunctionObject *>(func);
- old_tp_new_wrapper = pycf_ob->m_ml->ml_meth;
- return 0;
-}
-
-static int
-add_tp_new_wrapper(PyTypeObject *type)
-{
- // get the original tp_new_wrapper
- if (old_tp_new_wrapper == nullptr && get_old_tp_new_wrapper() < 0)
- return -1;
- // initialize tp_dict
- if (type->tp_dict == nullptr)
- type->tp_dict = PyDict_New();
- if (type->tp_dict == nullptr)
- return -1;
- PyObject *ob_type = reinterpret_cast<PyObject *>(type);
- Shiboken::AutoDecRef func(PyCFunction_New(tp_new_methoddef, ob_type));
- if (func.isNull())
- return -1;
- if (PyDict_SetItemString(type->tp_dict, "__new__", func))
- return -1;
return 0;
}
/*****************************************************************************/
@@ -197,7 +201,7 @@ PyTypeObject *SbkObjectType_TypeF(void)
PepHeapType_SIZE + sizeof(SbkObjectTypePrivate);
type = reinterpret_cast<PyTypeObject *>(PyType_FromSpec(&SbkObjectType_Type_spec));
#if PY_VERSION_HEX < 0x03000000
- if (add_tp_new_wrapper(type) < 0)
+ if (patch_tp_new_wrapper(type) < 0)
return nullptr;
#endif
}
@@ -452,6 +456,11 @@ PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *k
auto *newType = reinterpret_cast<SbkObjectType *>(type_new(metatype, args, kwds));
if (!newType)
return nullptr;
+#if PY_VERSION_HEX < 0x03000000
+ // PYSIDE-1051: The newly created metatype needs the PYSIDE-816 wrapper, too.
+ if (patch_tp_new_wrapper(&newType->type) < 0)
+ return nullptr;
+#endif
Shiboken::ObjectType::initPrivateData(newType);
SbkObjectTypePrivate *sotp = PepType_SOTP(newType);
@@ -842,6 +851,11 @@ introduceWrapperType(PyObject *enclosingObject,
Py_TYPE(heaptype) = SbkObjectType_TypeF();
Py_INCREF(Py_TYPE(heaptype));
auto *type = reinterpret_cast<SbkObjectType *>(heaptype);
+#if PY_VERSION_HEX < 0x03000000
+ // PYSIDE-1051: The newly created type needs the PYSIDE-816 wrapper, too.
+ if (patch_tp_new_wrapper(&type->type) < 0)
+ return nullptr;
+#endif
if (baseType) {
if (baseTypes) {
for (int i = 0; i < PySequence_Fast_GET_SIZE(baseTypes); ++i)
diff --git a/sources/shiboken2/libshiboken/embed/embedding_generator.py b/sources/shiboken2/libshiboken/embed/embedding_generator.py
index 77aa5c329..15f63649b 100644
--- a/sources/shiboken2/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken2/libshiboken/embed/embedding_generator.py
@@ -88,7 +88,7 @@ def create_zipfile(limited_api):
and make a chunked base64 encoded file from it.
"""
zip_name = "signature.zip"
- inc_name = "signature.inc"
+ inc_name = "signature_inc.h"
flag = '-b' if sys.version_info >= (3,) else ''
os.chdir(work_dir)
@@ -131,7 +131,7 @@ def create_zipfile(limited_api):
tmp.close()
# also generate a simple embeddable .pyc file for signature_bootstrap.pyc
boot_name = "signature_bootstrap.py" if limited_api else "signature_bootstrap.pyc"
- with open(boot_name, "rb") as ldr, open("signature_bootstrap.inc", "w") as inc:
+ with open(boot_name, "rb") as ldr, open("signature_bootstrap_inc.h", "w") as inc:
_embed_bytefile(ldr, inc, limited_api)
os.chdir(cur_dir)
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..5729100bf 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"
{
@@ -85,14 +87,15 @@ static PyGetSetDef probe_getseters[] = {
#define probe_tp_str make_dummy(2)
#define probe_tp_traverse make_dummy(3)
#define probe_tp_clear make_dummy(4)
+#define probe_tp_iternext make_dummy(5)
#define probe_tp_methods probe_methoddef
#define probe_tp_getset probe_getseters
-#define probe_tp_descr_get make_dummy(7)
-#define probe_tp_init make_dummy(8)
-#define probe_tp_alloc make_dummy(9)
-#define probe_tp_new make_dummy(10)
-#define probe_tp_free make_dummy(11)
-#define probe_tp_is_gc make_dummy(12)
+#define probe_tp_descr_get make_dummy(8)
+#define probe_tp_init make_dummy(9)
+#define probe_tp_alloc make_dummy(10)
+#define probe_tp_new make_dummy(11)
+#define probe_tp_free make_dummy(12)
+#define probe_tp_is_gc make_dummy(13)
#define probe_tp_name "type.probe"
#define probe_tp_basicsize make_dummy_int(42)
@@ -102,6 +105,7 @@ static PyType_Slot typeprobe_slots[] = {
{Py_tp_str, probe_tp_str},
{Py_tp_traverse, probe_tp_traverse},
{Py_tp_clear, probe_tp_clear},
+ {Py_tp_iternext, probe_tp_iternext},
{Py_tp_methods, probe_tp_methods},
{Py_tp_getset, probe_tp_getset},
{Py_tp_descr_get, probe_tp_descr_get},
@@ -125,16 +129,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
@@ -143,6 +147,7 @@ check_PyTypeObject_valid()
|| probe_tp_traverse != check->tp_traverse
|| probe_tp_clear != check->tp_clear
|| probe_tp_weakrefoffset != typetype->tp_weaklistoffset
+ || probe_tp_iternext != check->tp_iternext
|| probe_tp_methods != check->tp_methods
|| probe_tp_getset != check->tp_getset
|| probe_tp_base != typetype->tp_base
@@ -416,9 +421,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 +463,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 +473,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 +626,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/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index 93f718988..1aa7e6fc0 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -110,7 +110,7 @@ typedef struct _typeobject {
void *X23; // richcmpfunc tp_richcompare;
Py_ssize_t tp_weaklistoffset;
void *X25; // getiterfunc tp_iter;
- void *X26; // iternextfunc tp_iternext;
+ iternextfunc tp_iternext;
struct PyMethodDef *tp_methods;
void *X28; // struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
diff --git a/sources/shiboken2/libshiboken/qapp_macro.cpp b/sources/shiboken2/libshiboken/qapp_macro.cpp
index 12af9613c..306f53b74 100644
--- a/sources/shiboken2/libshiboken/qapp_macro.cpp
+++ b/sources/shiboken2/libshiboken/qapp_macro.cpp
@@ -120,6 +120,7 @@ reset_qApp_var(void)
PyObject *
MakeSingletonQAppWrapper(PyTypeObject *type)
{
+ static bool app_created = false;
if (type == nullptr)
type = Py_NONE_TYPE;
if (!(type == Py_NONE_TYPE || Py_TYPE(qApp_content) == Py_NONE_TYPE)) {
@@ -145,6 +146,9 @@ MakeSingletonQAppWrapper(PyTypeObject *type)
Py_REFCNT(qApp_var) = 1; // fuse is armed...
}
if (type == Py_NONE_TYPE) {
+ // PYSIDE-1093: Ignore None when no instance has ever been created.
+ if (!app_created)
+ Py_RETURN_NONE;
// Debug mode showed that we need to do more than just remove the
// reference. To keep everything in the right order, it is easiest
// to do a full shutdown, using QtCore.__moduleShutdown().
@@ -158,9 +162,10 @@ MakeSingletonQAppWrapper(PyTypeObject *type)
Py_REFCNT(qApp_content) = Py_REFCNT(Py_None);
if (__moduleShutdown != nullptr)
Py_XDECREF(PyObject_CallFunction(__moduleShutdown, const_cast<char *>("()")));
+ } else {
+ PyObject_INIT(qApp_content, type);
+ app_created = true;
}
- else
- (void)PyObject_INIT(qApp_content, type);
Py_INCREF(qApp_content);
return qApp_content;
}
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
new file mode 100644
index 000000000..3727eb494
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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(iter, "__iter__")
+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..42c5585fa
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 *iter();
+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..4a441222f 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.
@@ -38,14 +38,23 @@
****************************************************************************/
#include "sbkstring.h"
+#include "sbkstaticstrings_p.h"
#include "autodecref.h"
+#include <vector>
+
namespace Shiboken
{
namespace String
{
+// PYSIDE-795: Redirecting PySequence to Iterable
+bool checkIterable(PyObject *obj)
+{
+ return PyObject_HasAttr(obj, Shiboken::PyMagicName::iter());
+}
+
bool checkType(PyTypeObject *type)
{
return type == &PyUnicode_Type
@@ -200,6 +209,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 7f434e1b9..84d7768c5 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.
@@ -43,17 +43,12 @@
#include "sbkpython.h"
#include "shibokenmacros.h"
-#if PY_MAJOR_VERSION >= 3
- #define SBK_BYTES_NAME "bytes"
-#else
- #define SBK_BYTES_NAME "str"
-#endif
-
namespace Shiboken
{
namespace String
{
LIBSHIBOKEN_API bool check(PyObject *obj);
+ LIBSHIBOKEN_API bool checkIterable(PyObject *obj);
LIBSHIBOKEN_API bool checkType(PyTypeObject *obj);
LIBSHIBOKEN_API bool checkChar(PyObject *obj);
LIBSHIBOKEN_API bool isConvertible(PyObject *obj);
@@ -65,6 +60,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/shibokenbuffer.cpp b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
index 330470183..dd6e46320 100644
--- a/sources/shiboken2/libshiboken/shibokenbuffer.cpp
+++ b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
@@ -43,7 +43,11 @@
bool Shiboken::Buffer::checkType(PyObject *pyObj)
{
+#ifdef IS_PY3K
+ return PyObject_CheckBuffer(pyObj) != 0;
+#else
return PyObject_CheckReadBuffer(pyObj) != 0;
+#endif
}
void *Shiboken::Buffer::getPointer(PyObject *pyObj, Py_ssize_t *size)
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 07ef366ba..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);
@@ -100,7 +102,7 @@ CreateSignature(PyObject *props, PyObject *key)
{
/*
* Here is the new function to create all signatures. It simply calls
- * into Python and creates a signature object for a dummy-function.
+ * into Python and creates a signature object directly.
* This is so much simpler than using all the attributes explicitly
* to support '_signature_is_functionlike()'.
*/
@@ -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 *sig_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 *sig_kind;
+ PyObject *func_kind;
if (PyModule_Check(obtype_mod))
- sig_kind = "function";
+ func_kind = Shiboken::PyName::function();
else if (flags & METH_CLASS)
- sig_kind = "classmethod";
+ func_kind = Shiboken::PyName::classmethod();
else if (flags & METH_STATIC)
- sig_kind = "staticmethod";
+ func_kind = Shiboken::PyName::staticmethod();
else
- sig_kind = "method";
- return GetSignature_Cached(props, sig_kind, modifier);
+ 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,15 +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 *sig_kind, const char *modifier)
+GetSignature_Cached(PyObject *props, PyObject *func_kind, PyObject *modifier)
{
+ // Special case: We want to know the 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", sig_kind)
- : Py_BuildValue("(ss)", sig_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
@@ -451,11 +464,11 @@ GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier)
}
static const char *PySide_CompressedSignaturePackage[] = {
-#include "embed/signature.inc"
+#include "embed/signature_inc.h"
};
static const unsigned char PySide_SignatureLoader[] = {
-#include "embed/signature_bootstrap.inc"
+#include "embed/signature_bootstrap_inc.h"
};
static safe_globals_struc *
@@ -474,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
@@ -492,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",
@@ -509,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.
@@ -555,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;
}
@@ -597,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;
}
@@ -799,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);
@@ -818,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;
@@ -1106,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)) {
@@ -1219,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;