diff options
Diffstat (limited to 'sources/shiboken6/libshiboken/sbkstring.cpp')
-rw-r--r-- | sources/shiboken6/libshiboken/sbkstring.cpp | 156 |
1 files changed, 59 insertions, 97 deletions
diff --git a/sources/shiboken6/libshiboken/sbkstring.cpp b/sources/shiboken6/libshiboken/sbkstring.cpp index 93a630ac8..1471cd7fe 100644 --- a/sources/shiboken6/libshiboken/sbkstring.cpp +++ b/sources/shiboken6/libshiboken/sbkstring.cpp @@ -1,53 +1,11 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2019 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 #include "sbkstring.h" #include "sbkstaticstrings_p.h" #include "autodecref.h" -#include <vector> -#include <unordered_set> - -namespace Shiboken -{ - -namespace String +namespace Shiboken::String { // PYSIDE-795: Redirecting PySequence to Iterable @@ -56,6 +14,30 @@ bool checkIterable(PyObject *obj) return PyObject_HasAttr(obj, Shiboken::PyMagicName::iter()); } +static PyObject *initPathLike() +{ + PyObject *PathLike{}; + auto osmodule = PyImport_ImportModule("os"); + if (osmodule == nullptr + || (PathLike = PyObject_GetAttrString(osmodule, "PathLike")) == nullptr) { + PyErr_Print(); + Py_FatalError("cannot import os.PathLike"); + } + return PathLike; +} + +// PYSIDE-1499: Migrate to pathlib.Path and support __fspath__ in PySide +bool checkPath(PyObject *path) +{ + // Let normal strings through, unchanged. + if (PyUnicode_Check(path) || PyBytes_Check(path)) + return true; + // Without the Limited API, we could look up an `__fspath__` class attribute. + // But we use `isinstance(os.PathLike)`, instead. + static PyObject *PathLike = initPathLike(); + return PyObject_IsInstance(path, PathLike); +} + bool checkType(PyTypeObject *type) { return type == &PyUnicode_Type; @@ -86,23 +68,33 @@ PyObject *fromCString(const char *value, int len) return PyUnicode_FromStringAndSize(value, len); } -const char *toCString(PyObject *str, Py_ssize_t *len) +const char *toCString(PyObject *str) { if (str == Py_None) return nullptr; + if (PyUnicode_Check(str)) + return _PepUnicode_AsString(str); + if (PyBytes_Check(str)) + return PyBytes_AS_STRING(str); + return nullptr; +} + +const char *toCString(PyObject *str, Py_ssize_t *len) +{ + if (str == Py_None) { + *len = 0; + return nullptr; + } if (PyUnicode_Check(str)) { - if (len) { - // We need to encode the unicode string into utf8 to know the size of returned char *. - Shiboken::AutoDecRef uniStr(PyUnicode_AsUTF8String(str)); - *len = PyBytes_GET_SIZE(uniStr.object()); - } + // We need to encode the unicode string into utf8 to know the size of returned char *. + Shiboken::AutoDecRef uniStr(PyUnicode_AsUTF8String(str)); + *len = PyBytes_GET_SIZE(uniStr.object()); // Return unicode from str instead of uniStr, because the lifetime of the returned pointer // depends on the lifetime of str. return _PepUnicode_AsString(str); } if (PyBytes_Check(str)) { - if (len) - *len = PyBytes_GET_SIZE(str); + *len = PyBytes_GET_SIZE(str); return PyBytes_AS_STRING(str); } return nullptr; @@ -184,50 +176,9 @@ Py_ssize_t len(PyObject *str) // PyObject *attr = PyObject_GetAttr(obj, name()); // -using StaticStrings = std::unordered_set<PyObject *>; - -static void finalizeStaticStrings(); // forward - -static StaticStrings &staticStrings() -{ - static StaticStrings result; - return result; -} - -static void finalizeStaticStrings() -{ - auto &set = staticStrings(); - for (PyObject *ob : set) { - Py_REFCNT(ob) = 1; - Py_DECREF(ob); - } - set.clear(); -} - PyObject *createStaticString(const char *str) { - static bool initialized = false; - if (!initialized) { - Py_AtExit(finalizeStaticStrings); - initialized = true; - } - PyObject *result = PyUnicode_InternFromString(str); - if (result == nullptr) { - // This error is never checked, but also very unlikely. Report and exit. - PyErr_Print(); - Py_FatalError("unexpected error in createStaticString()"); - } - auto it = staticStrings().find(result); - if (it == staticStrings().end()) - staticStrings().insert(result); - /* - * Note: We always add one reference even if we have a new string. - * This makes the strings immortal, and we are safe if someone - * uses AutoDecRef, although the set cannot cope with deletions. - * The exit handler cleans that up, anyway. - */ - Py_INCREF(result); - return result; + return PyUnicode_InternFromString(str); } /////////////////////////////////////////////////////////////////////// @@ -282,5 +233,16 @@ PyObject *getSnakeCaseName(PyObject *name, bool lower) return name; } -} // namespace String -} // namespace Shiboken +// Return a generic representation of a PyObject as does PyObject_Repr(). +// Note: PyObject_Repr() may not be called on self from __repr__() as this +// causes a recursion. +PyObject *repr(PyObject *o) +{ + if (o == nullptr) + return PyUnicode_FromString("<NULL>"); + if (o == Py_None) + return PyUnicode_FromString("None"); + return PyUnicode_FromFormat("<%s object at %p>", Py_TYPE(o)->tp_name, o); +} + +} // namespace Shiboken::String |