aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core_common.xml79
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp8
-rw-r--r--sources/pyside6/libpyside/pyside.cpp17
-rw-r--r--sources/pyside6/libpyside/pyside.h5
-rw-r--r--sources/pyside6/tests/QtCore/qfile_test.py22
-rw-r--r--sources/pyside6/tests/QtCore/qfileinfo_test.py9
-rw-r--r--sources/pyside6/tests/registry/init_platform.py3
-rw-r--r--sources/shiboken6/generator/shiboken/pytypenames.h3
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp4
-rw-r--r--sources/shiboken6/libshiboken/CMakeLists.txt2
-rw-r--r--sources/shiboken6/libshiboken/sbkstring.cpp24
-rw-r--r--sources/shiboken6/libshiboken/sbkstring.h1
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py1
13 files changed, 172 insertions, 6 deletions
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
index 0cffffae0..856c01224 100644
--- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
+++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
@@ -47,6 +47,7 @@
<custom-type name="PyByteArray"/>
<custom-type name="PyCallable"/>
<custom-type name="PyObject"/>
+ <custom-type name="PyPathLike"/>
<custom-type name="PySequence"/>
<custom-type name="PyTypeObject"/>
<custom-type name="PyUnicode"/>
@@ -909,9 +910,30 @@
<inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-topython"/>
</add-function>
</value-type>
+
<value-type name="QDir">
<enum-type name="Filter" flags="Filters"/>
<enum-type name="SortFlag" flags="SortFlags"/>
+
+ <!-- PYSIDE-1499: Replace QString by pathlib.Path (qdir.h) -->
+ <modify-function signature="QDir(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="QDir(const QString &amp;,const QString &amp;,SortFlags=SortFlags(Name|IgnoreCase),Filters=AllEntries)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="setPath(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="addSearchPath(const QString &amp;,const QString &amp;)" return-type="PyObject">
+ <modify-argument index="2"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-2"/>
+ </modify-function>
+ <!-- PYSIDE-1499: End of insertion -->
+
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
@@ -1811,6 +1833,22 @@
<include file-name="QDateTime" location="global"/>
<include file-name="QDir" location="global"/>
</extra-includes>
+
+ <!-- PYSIDE-1499: Replace QString by pathlib.Path (qfileinfo.h) -->
+ <modify-function signature="QFileInfo(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="QFileInfo(const QDir &amp;,const QString &amp;)" return-type="PyObject">
+ <modify-argument index="2"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-2"/>
+ </modify-function>
+ <modify-function signature="setFile(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <!-- PYSIDE-1499: End of insertion -->
+
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
@@ -1820,6 +1858,7 @@
</inject-code>
</add-function>
</value-type>
+
<value-type name="QByteArray" hash-function="qHash">
<enum-type name="Base64Option" flags="Base64Options" since="5.2"/>
<enum-type name="Base64DecodingStatus" since="5.15"/>
@@ -2136,7 +2175,47 @@
</modify-function>
<modify-function signature="flush()" allow-thread="yes"/>
</object-type>
+
<object-type name="QFile">
+ <!-- PYSIDE-1499: Replace QString by pathlib.Path (qfile.h) -->
+ <modify-function signature="fromFilesystemPath(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="QFile(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="QFile(const QString &amp;,QObject *)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="setFileName(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="rename(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="link(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="copy(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="permissions(const QString &amp;)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="setPermissions(const QString &amp;,Permissions)" return-type="PyObject">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <!-- PYSIDE-1499: End of insertion -->
+
<modify-function signature="open(QFlags&lt;QIODeviceBase::OpenModeFlag&gt;)" allow-thread="yes"/>
<modify-function signature="open(int,QFlags&lt;QIODeviceBase::OpenModeFlag&gt;,QFlags&lt;QFileDevice::FileHandleFlag&gt;)" allow-thread="yes"/>
<modify-function signature="copy(const QString&amp;)" allow-thread="yes"/>
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp
index a041336da..a105666a1 100644
--- a/sources/pyside6/PySide6/glue/qtcore.cpp
+++ b/sources/pyside6/PySide6/glue/qtcore.cpp
@@ -1662,6 +1662,14 @@ PyMem_Free(temp);
%out = %OUTTYPE();
// @snippet conversion-pynone
+// @snippet qfile-path-1
+auto cppArg0 = PySide::pyPathToQString(%PYARG_1);
+// @snippet qfile-path-1
+
+// @snippet qfile-path-2
+auto cppArg1 = PySide::pyPathToQString(%PYARG_2);
+// @snippet qfile-path-2
+
// @snippet conversion-pystring-char
char c = %CONVERTTOCPP[char](%in);
%out = %OUTTYPE(c);
diff --git a/sources/pyside6/libpyside/pyside.cpp b/sources/pyside6/libpyside/pyside.cpp
index a78e4e9eb..16d77ab57 100644
--- a/sources/pyside6/libpyside/pyside.cpp
+++ b/sources/pyside6/libpyside/pyside.cpp
@@ -478,7 +478,8 @@ void setQuickRegisterItemFunction(QuickRegisterItemFunction function)
#endif // PYSIDE_QML_SUPPORT
// Inspired by Shiboken::String::toCString;
-QString pyStringToQString(PyObject *str) {
+QString pyStringToQString(PyObject *str)
+{
if (str == Py_None)
return QString();
@@ -495,6 +496,20 @@ QString pyStringToQString(PyObject *str) {
return QString();
}
+// PySide-1499: Provide an efficient, correct PathLike interface
+QString pyPathToQString(PyObject *path)
+{
+ // str or bytes pass through
+ if (PyUnicode_Check(path) || PyBytes_Check(path))
+ return pyStringToQString(path);
+
+ // Let PyOS_FSPath do its work and then fix the result for Windows.
+ Shiboken::AutoDecRef strPath(PyOS_FSPath(path));
+ if (strPath.isNull())
+ return QString();
+ return QDir::fromNativeSeparators(pyStringToQString(strPath));
+}
+
static const unsigned char qt_resource_name[] = {
// qt
0x0,0x2,
diff --git a/sources/pyside6/libpyside/pyside.h b/sources/pyside6/libpyside/pyside.h
index 3c4ae92b2..9bb0ab12e 100644
--- a/sources/pyside6/libpyside/pyside.h
+++ b/sources/pyside6/libpyside/pyside.h
@@ -157,6 +157,11 @@ PYSIDE_API void setQuickRegisterItemFunction(QuickRegisterItemFunction function)
PYSIDE_API QString pyStringToQString(PyObject *str);
/**
+ * Provide an efficient, correct PathLike interface.
+ */
+PYSIDE_API QString pyPathToQString(PyObject *path);
+
+/**
* Registers a dynamic "qt.conf" file with the Qt resource system.
*
* This is used in a standalone build, to inform QLibraryInfo of the Qt prefix (where Qt libraries
diff --git a/sources/pyside6/tests/QtCore/qfile_test.py b/sources/pyside6/tests/QtCore/qfile_test.py
index 897b4583c..d480d5e30 100644
--- a/sources/pyside6/tests/QtCore/qfile_test.py
+++ b/sources/pyside6/tests/QtCore/qfile_test.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of Qt for Python.
@@ -86,5 +86,25 @@ class GetCharTest(unittest.TestCase):
self.assertTrue(os.path.exists(QDir.toNativeSeparators(saveFile.fileName())))
+class GetCharTestPath(GetCharTest):
+ # PYSIDE-1499: Do the same with Path objects
+
+ def setUp(self):
+ '''Acquire resources'''
+ handle, filename = tempfile.mkstemp()
+ self.filename = Path(filename)
+ os.write(handle, bytes('a', "UTF-8"))
+ os.close(handle)
+
+
+class DirPath(unittest.TestCase):
+ # PYSIDE-1499: Test QDir with Path objects
+ def testQDirPath(self):
+ test_path = Path("some") / "dir"
+ qdir1 = QDir(os.fspath(test_path))
+ qdir2 = QDir(test_path)
+ self.assertEqual(qdir1, qdir2)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qfileinfo_test.py b/sources/pyside6/tests/QtCore/qfileinfo_test.py
index bbdd4bce9..d28be7c4c 100644
--- a/sources/pyside6/tests/QtCore/qfileinfo_test.py
+++ b/sources/pyside6/tests/QtCore/qfileinfo_test.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of Qt for Python.
@@ -46,6 +46,13 @@ class QFileConstructor(unittest.TestCase):
'''QFileInfo(QFile)'''
obj = QFileInfo(QFile())
+ def testQFileInfoPath(self):
+ # PYSIDE-1499: Test QFileInfo with Path objects
+ test_path = Path("some") / "dir"
+ qinf1 = QFileInfo(os.fspath(test_path))
+ qinf2 = QFileInfo(test_path)
+ self.assertEqual(qinf1, qinf2)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/registry/init_platform.py b/sources/pyside6/tests/registry/init_platform.py
index 41b49dd53..06c488ee3 100644
--- a/sources/pyside6/tests/registry/init_platform.py
+++ b/sources/pyside6/tests/registry/init_platform.py
@@ -136,9 +136,8 @@ if not have_build_dir:
import testbinding
all_modules.append("testbinding")
-# Note: This is not the shiboken dir as usual, but the binary.
from shiboken6 import Shiboken
-all_modules.append("Shiboken")
+all_modules.append("shiboken6.Shiboken")
# 'sample/smart' are needed by 'other', so import them first.
for modname in "minimal sample smart other".split():
diff --git a/sources/shiboken6/generator/shiboken/pytypenames.h b/sources/shiboken6/generator/shiboken/pytypenames.h
index 779f67f2f..cec7054a0 100644
--- a/sources/shiboken6/generator/shiboken/pytypenames.h
+++ b/sources/shiboken6/generator/shiboken/pytypenames.h
@@ -38,6 +38,9 @@ static inline QString pyLongT() { return QStringLiteral("PyLong"); }
static inline QString pyObjectT() { return QStringLiteral("object"); }
static inline QString pyStrT() { return QStringLiteral("str"); }
+// PYSIDE-1499: A custom type determined by existence of an `__fspath__` attribute.
+static inline QString pyPathLikeT() { return QStringLiteral("PyPathLike"); }
+
static inline QString cPyBufferT() { return QStringLiteral("PyBuffer"); }
static inline QString cPyListT() { return QStringLiteral("PyList"); }
static inline QString cPyObjectT() { return QStringLiteral("PyObject"); }
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 40608e566..03efdc7a4 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -1124,6 +1124,10 @@ ShibokenGenerator::CPythonCheckFunctionResult
if (type == cPyArrayObjectT())
return {QLatin1String("PyArray_Check"), {}};
+ // PYSIDE-1499: We replace some strings by path objects.
+ if (type == pyPathLikeT())
+ return {QLatin1String("Shiboken::String::checkPath"), {}};
+
CPythonCheckFunctionResult result;
result.type = buildAbstractMetaTypeFromString(type);
diff --git a/sources/shiboken6/libshiboken/CMakeLists.txt b/sources/shiboken6/libshiboken/CMakeLists.txt
index 241318178..02be441f9 100644
--- a/sources/shiboken6/libshiboken/CMakeLists.txt
+++ b/sources/shiboken6/libshiboken/CMakeLists.txt
@@ -101,7 +101,7 @@ shiboken_compute_python_includes()
shiboken_compute_python_libraries()
if(PYTHON_LIMITED_API)
- target_compile_definitions(libshiboken PUBLIC "-DPy_LIMITED_API=0x03050000")
+ target_compile_definitions(libshiboken PUBLIC "-DPy_LIMITED_API=0x03060000")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
diff --git a/sources/shiboken6/libshiboken/sbkstring.cpp b/sources/shiboken6/libshiboken/sbkstring.cpp
index c234d7307..177b946fa 100644
--- a/sources/shiboken6/libshiboken/sbkstring.cpp
+++ b/sources/shiboken6/libshiboken/sbkstring.cpp
@@ -53,6 +53,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;
diff --git a/sources/shiboken6/libshiboken/sbkstring.h b/sources/shiboken6/libshiboken/sbkstring.h
index 817b8acc2..4b416e16c 100644
--- a/sources/shiboken6/libshiboken/sbkstring.h
+++ b/sources/shiboken6/libshiboken/sbkstring.h
@@ -49,6 +49,7 @@ namespace String
{
LIBSHIBOKEN_API bool check(PyObject *obj);
LIBSHIBOKEN_API bool checkIterable(PyObject *obj);
+ LIBSHIBOKEN_API bool checkPath(PyObject *path);
LIBSHIBOKEN_API bool checkType(PyTypeObject *obj);
LIBSHIBOKEN_API bool checkChar(PyObject *obj);
LIBSHIBOKEN_API bool isConvertible(PyObject *obj);
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index be96a7689..72210fdde 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -237,6 +237,7 @@ type_map.update({
"PyObject": object,
"PyObject*": object,
"PyArrayObject": ArrayLikeVariable, # numpy
+ "PyPathLike": typing.Union[str, bytes, os.PathLike],
"PySequence": typing.Iterable, # important for numpy
"PyTypeObject": type,
"QChar": str,