diff options
author | Christian Tismer <tismer@stackless.com> | 2021-02-12 19:13:43 +0100 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2021-06-12 19:15:33 +0200 |
commit | 5276f9bf787eadd5a336f5f6eb6bcf19865de198 (patch) | |
tree | 0fa765d7acd45623fc83892026fd98fba6ff9da4 /sources/pyside6 | |
parent | f8205c58207fd6c35ce743fc931392bac49ccc2f (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.xml | 79 | ||||
-rw-r--r-- | sources/pyside6/PySide6/glue/qtcore.cpp | 8 | ||||
-rw-r--r-- | sources/pyside6/libpyside/pyside.cpp | 17 | ||||
-rw-r--r-- | sources/pyside6/libpyside/pyside.h | 5 | ||||
-rw-r--r-- | sources/pyside6/tests/QtCore/qfile_test.py | 22 | ||||
-rw-r--r-- | sources/pyside6/tests/QtCore/qfileinfo_test.py | 9 | ||||
-rw-r--r-- | sources/pyside6/tests/registry/init_platform.py | 3 |
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 &)" 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 &,const QString &,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 &)" 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 &,const QString &)" 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 &)" 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 &,const QString &)" 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 &)" 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 &)" 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 &)" 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 &,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 &)" 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 &)" 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 &)" 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 &)" 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 &)" 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 &,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<QIODeviceBase::OpenModeFlag>)" allow-thread="yes"/> <modify-function signature="open(int,QFlags<QIODeviceBase::OpenModeFlag>,QFlags<QFileDevice::FileHandleFlag>)" allow-thread="yes"/> <modify-function signature="copy(const QString&)" 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(): |