aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2021-02-12 19:13:43 +0100
committerChristian Tismer <tismer@stackless.com>2021-06-12 19:15:33 +0200
commit5276f9bf787eadd5a336f5f6eb6bcf19865de198 (patch)
tree0fa765d7acd45623fc83892026fd98fba6ff9da4 /sources/pyside6
parentf8205c58207fd6c35ce743fc931392bac49ccc2f (diff)
build support for pathlib.Path, baseline
[ChangeLog][PySide6] pathlib.Path gets additionally accepted for all function arguments which have a std::filesystem::path type. This is a first part that implements those modifications which have a std::filesystem::path entry. In a later patch, all the possible other Path insertions will be made. Task-number: PYSIDE-1499 Change-Id: I2dec04dbdb2aaff6ca56c39b28f60281262fe078 Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/pyside6')
-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
7 files changed, 138 insertions, 5 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():