Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-PyQt6 for openSUSE:Factory 
checked in at 2023-07-25 11:50:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-PyQt6 (Old)
 and      /work/SRC/openSUSE:Factory/.python-PyQt6.new.1467 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-PyQt6"

Tue Jul 25 11:50:19 2023 rev:16 rq:1099759 version:6.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-PyQt6/python-PyQt6.changes        
2023-06-12 15:26:55.195218298 +0200
+++ /work/SRC/openSUSE:Factory/.python-PyQt6.new.1467/python-PyQt6.changes      
2023-07-25 11:51:32.229604917 +0200
@@ -1,0 +2,12 @@
+Thu Jul 20 10:57:34 UTC 2023 - Markéta Machová <mmach...@suse.com>
+
+- Update to 6.5.1
+  * Added support for QPermission and related classes and methods.
+  * Added the max_workers argument to uic.compileUiDir() to specify 
+    the maximum number of worker processes to use when compiling 
+    the .ui files in a directory.
+  * pyuic6 will now compile all the .ui files in a directory if the 
+    name of the directory is passed instead of a .ui file.
+  * Added the --max-workers command line option to pyuic6.
+
+-------------------------------------------------------------------

Old:
----
  PyQt6-6.5.0.tar.gz

New:
----
  PyQt6-6.5.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-PyQt6.spec ++++++
--- /var/tmp/diff_new_pack.bpJJFa/_old  2023-07-25 11:51:34.753619695 +0200
+++ /var/tmp/diff_new_pack.bpJJFa/_new  2023-07-25 11:51:34.757619719 +0200
@@ -21,7 +21,7 @@
 %define pyqt_build_for_qt6 1
 %{?sle15_python_module_pythons}
 Name:           python-%{mname}
-Version:        6.5.0
+Version:        6.5.1
 Release:        0
 Summary:        Python bindings for Qt 6
 License:        GPL-3.0-only OR SUSE-GPL-2.0-with-FLOSS-exception OR NonFree

++++++ PyQt6-6.5.0.tar.gz -> PyQt6-6.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/ChangeLog new/PyQt6-6.5.1/ChangeLog
--- old/PyQt6-6.5.0/ChangeLog   2023-04-05 14:16:47.435856000 +0200
+++ new/PyQt6-6.5.1/ChangeLog   2023-06-02 12:40:57.300344000 +0200
@@ -1,5 +1,50 @@
+2023-05-26  Phil Thompson  <p...@riverbankcomputing.com>
+
+       * NEWS, qpy/QtCore/qpycore_pyqtboundsignal.cpp:
+       Fixed a regression that broke pyqtSlot arguments that where
+       typedefs.
+       [443f350df939] [6.5.1] <6.5-maint>
+
+2023-05-25  Phil Thompson  <p...@riverbankcomputing.com>
+
+       * NEWS, project.py:
+       Ensure the permission plugins are built in.
+       [dea56beea30d] <6.5-maint>
+
+2023-05-23  Phil Thompson  <p...@riverbankcomputing.com>
+
+       * PyQt6.msp:
+       Fixed the conversion of QPermission.
+       [ba763ef07730] <6.5-maint>
+
+2023-05-22  Phil Thompson  <p...@riverbankcomputing.com>
+
+       * PyQt6.msp, config-tests/cfgtest_QtCore.cpp:
+       Fixed build issues with the permissions support.
+       [04c3b8f59a6c] <6.5-maint>
+
+       * NEWS, PyQt6.msp, config-tests/cfgtest_QtCore.cpp:
+       Added support for QPermission et al.
+       [f673353b1366] <6.5-maint>
+
+2023-04-24  Phil Thompson  <p...@riverbankcomputing.com>
+
+       * extras/uic/pyuic.py:
+       pyuic6 doesn't, for consistency reasons, recurse when compiling a
+       directory.
+       [7f0f1196edd6] <6.5-maint>
+
+       * NEWS, extras/uic/compile_ui.py, extras/uic/pyuic.py:
+       compileUiDir() can now compile muliple .ui files in parallel. pyuic6
+       can now compile a directory contents.
+       [09ca845e4626] <6.5-maint>
+
 2023-04-05  Phil Thompson  <p...@riverbankcomputing.com>
 
+       * .hgtags:
+       Added tag 6.5.0 for changeset db2b0386d4f1
+       [a2256de71810]
+
        * NEWS, qpy/QtCore/qpycore_chimera.cpp:
        Fixed a regression in the handling of QFlags as signal arguments.
        [db2b0386d4f1] [6.5.0]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/NEWS new/PyQt6-6.5.1/NEWS
--- old/PyQt6-6.5.0/NEWS        2023-04-05 14:16:47.437537000 +0200
+++ new/PyQt6-6.5.1/NEWS        2023-06-02 12:40:57.301942800 +0200
@@ -1,3 +1,13 @@
+v6.5.1 26th May 2023
+  - Added support for QPermission and related classes and methods.
+  - Added the max_workers argument to uic.compileUiDir() to specifiy the
+    maximum number of worker processes to use when compiling the .ui files in a
+    directory.
+  - pyuic6 will now compile all the .ui files in a directory if the name of the
+    directory is passed instead of a .ui file.
+  - Added the --max-workers command line option to pyuic6.
+  - Bug fixes.
+
 v6.5.0 5th April 2023
   - Added support for Qt v6.5 including the QtSpatialAudio module.
   - Bug fixes.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/PKG-INFO new/PyQt6-6.5.1/PKG-INFO
--- old/PyQt6-6.5.0/PKG-INFO    2023-04-05 14:16:56.788123400 +0200
+++ new/PyQt6-6.5.1/PKG-INFO    2023-06-02 12:41:06.071410200 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: PyQt6
-Version: 6.5.0
+Version: 6.5.1
 Requires-Python: >=3.6.1
 Summary: Python bindings for the Qt cross platform application toolkit
 Home-Page: https://www.riverbankcomputing.com/software/pyqt/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/config-tests/cfgtest_QtCore.cpp 
new/PyQt6-6.5.1/config-tests/cfgtest_QtCore.cpp
--- old/PyQt6-6.5.0/config-tests/cfgtest_QtCore.cpp     2023-04-05 
14:16:47.446821000 +0200
+++ new/PyQt6-6.5.1/config-tests/cfgtest_QtCore.cpp     2023-06-02 
12:40:57.311180600 +0200
@@ -31,5 +31,9 @@
     if (sizeof (qreal) != sizeof (double))
         out << "PyQt_qreal_double\n";
 
+#if !QT_CONFIG(permissions)
+    out << "PyQt_Permissions";
+#endif
+
     return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/project.py new/PyQt6-6.5.1/project.py
--- old/PyQt6-6.5.0/project.py  2023-04-05 14:16:47.685877000 +0200
+++ new/PyQt6-6.5.1/project.py  2023-06-02 12:40:57.553051200 +0200
@@ -517,8 +517,43 @@
         if not project.qt_shared and test_output[0] == 'shared':
             project.qt_shared = True
 
+            # If permissions are available make sure the static plugins get
+            # compiled in.
+            if 'PyQt_Permissions' not in test_output:
+                self.builder_settings.append('CONFIG += permssions')
+                self.builder_settings.append(
+                        'QMAKE_INFO_PLIST = ' + self._info_plist())
+
         return super().handle_test_output(test_output[1:])
 
+    def _info_plist(self):
+        """ Create an Info.plist that contains entries for all supported
+        permissions and return the absolute name of the file.
+        """
+
+        keys = ('NSBluetoothAlwaysUsageDescription',
+                'NSCalendarsUsageDescription', 'NSCameraUsageDescription',
+                'NSContactsUsageDescription', 'NSLocationUsageDescription',
+                'NSMicrophoneUsageDescription')
+
+        content = '\n'.join(
+                ['<key>{}</key><string>Dummy</string>'.format(k) for k in 
keys])
+
+        info_plist = os.path.join(self.project.build_dir, 'Info.plist')
+
+        with open(info_plist, 'w') as f:
+            f.write(
+'''<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 
"http://www.apple.com/DTDs/PropertyList-1.0.dtd";>
+<plist version="1.0">
+<dict>
+{}
+</dict>
+</plist>
+'''.format(content))
+
+        return info_plist
+
 
 class QtDBus(PyQtBindings):
     """ The QtDBus bindings. """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/pyproject.toml 
new/PyQt6-6.5.1/pyproject.toml
--- old/PyQt6-6.5.0/pyproject.toml      2023-04-05 14:16:47.686265200 +0200
+++ new/PyQt6-6.5.1/pyproject.toml      2023-06-02 12:40:57.553341000 +0200
@@ -6,7 +6,7 @@
 # Specify the PEP 566 metadata for the project.
 [tool.sip.metadata]
 name = "PyQt6"
-version = "6.5.0"
+version = "6.5.1"
 summary = "Python bindings for the Qt cross platform application toolkit"
 home-page = "https://www.riverbankcomputing.com/software/pyqt/";
 author = "Riverbank Computing Limited"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/qpy/QtCore/qpycore_pyqtboundsignal.cpp 
new/PyQt6-6.5.1/qpy/QtCore/qpycore_pyqtboundsignal.cpp
--- old/PyQt6-6.5.0/qpy/QtCore/qpycore_pyqtboundsignal.cpp      2023-04-05 
14:16:47.518521800 +0200
+++ new/PyQt6-6.5.1/qpy/QtCore/qpycore_pyqtboundsignal.cpp      2023-06-02 
12:40:57.387069200 +0200
@@ -953,11 +953,13 @@
             const Chimera *sig_arg = signal->parsed_arguments.at(a);
             const Chimera *slot_arg = slot->parsed_arguments.at(a);
 
-            // We simply compare the C++ names. We used to compare meta-types
-            // but this is unreliable as the signal's type may have been
-            // registered by Qt internally (and so given a new meta-type) after
-            // the slot was defined (and has the meta-type of PyQt_PyObject).
-            if (sig_arg->name() != slot_arg->name())
+            // In the first instance we compare meta-types (which deals with
+            // typedefed types).  However this can be unreliable as the
+            // signal's type may have been registered by Qt internally (and so
+            // given a new meta-type) after the slot was defined (and has the
+            // meta-type of PyQt_PyObject) so we also compare the C++ names.
+            if (sig_arg->metatype != slot_arg->metatype &&
+                sig_arg->name() != slot_arg->name())
             {
                 slot = 0;
                 break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/sip/QtCore/QtCoremod.sip 
new/PyQt6-6.5.1/sip/QtCore/QtCoremod.sip
--- old/PyQt6-6.5.0/sip/QtCore/QtCoremod.sip    2023-04-05 14:16:55.531872500 
+0200
+++ new/PyQt6-6.5.1/sip/QtCore/QtCoremod.sip    2023-06-02 12:41:05.022572000 
+0200
@@ -40,6 +40,7 @@
 %Feature PyQt_Process
 %Feature PyQt_WebChannel
 %Feature PyQt_DTLS
+%Feature PyQt_Permissions
 
 %Copying
 Copyright (c) 2023 Riverbank Computing Limited <i...@riverbankcomputing.com>
@@ -74,8 +75,8 @@
 const char *PYQT_VERSION_STR;
 
 %ModuleCode
-static int PYQT_VERSION = 0x060500;
-static const char *PYQT_VERSION_STR = "6.5.0";
+static int PYQT_VERSION = 0x060501;
+static const char *PYQT_VERSION_STR = "6.5.1";
 %End
 
 %Include qglobal.sip
@@ -146,6 +147,7 @@
 %Include qoperatingsystemversion.sip
 %Include qparallelanimationgroup.sip
 %Include qpauseanimation.sip
+%Include qpermissions.sip
 %Include qpropertyanimation.sip
 %Include qpluginloader.sip
 %Include qpoint.sip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/sip/QtCore/qcoreapplication.sip 
new/PyQt6-6.5.1/sip/QtCore/qcoreapplication.sip
--- old/PyQt6-6.5.0/sip/QtCore/qcoreapplication.sip     2023-04-05 
14:16:55.515679600 +0200
+++ new/PyQt6-6.5.1/sip/QtCore/qcoreapplication.sip     2023-06-02 
12:41:05.008861800 +0200
@@ -132,6 +132,43 @@
         // Make sure the QCoreApplication is destroyed.
         delete sipCpp;
 %End
+
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+    Qt::PermissionStatus checkPermission(const QPermission &permission);
+%End
+%End
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+    void requestPermission(const QPermission &permission, SIP_PYCALLABLE 
handler /TypeHint="Callable[[QPermission], None]"/) /ReleaseGIL/;
+%MethodCode
+        // Make sure the callable doesn't get garbage collected until it is 
invoked.
+        Py_INCREF(a1);
+        
+        Py_BEGIN_ALLOW_THREADS
+        
+        sipCpp->requestPermission(*a0, [a1](const QPermission &arg0) {
+            SIP_BLOCK_THREADS
+        
+            PyObject *res;
+        
+            res = sipCallMethod(NULL, a1, "N", new QPermission(arg0), 
sipType_QPermission, NULL);
+        
+            Py_DECREF(a1);
+        
+            if (!res)
+                pyqt6_err_print();
+            else
+                Py_DECREF(res);
+        
+            SIP_UNBLOCK_THREADS
+        });
+        
+        Py_END_ALLOW_THREADS
+%End
+
+%End
+%End
 };
 
 void qAddPostRoutine(SIP_PYCALLABLE);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/sip/QtCore/qnamespace.sip 
new/PyQt6-6.5.1/sip/QtCore/qnamespace.sip
--- old/PyQt6-6.5.0/sip/QtCore/qnamespace.sip   2023-04-05 14:16:55.559121800 
+0200
+++ new/PyQt6-6.5.1/sip/QtCore/qnamespace.sip   2023-06-02 12:41:05.033792000 
+0200
@@ -1552,6 +1552,16 @@
     };
 
 %End
+%If (Qt_6_5_0 -)
+
+    enum class PermissionStatus
+    {
+        Undetermined,
+        Granted,
+        Denied,
+    };
+
+%End
 };
 
 class QKeyCombination
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/sip/QtCore/qpermissions.sip 
new/PyQt6-6.5.1/sip/QtCore/qpermissions.sip
--- old/PyQt6-6.5.0/sip/QtCore/qpermissions.sip 1970-01-01 01:00:00.000000000 
+0100
+++ new/PyQt6-6.5.1/sip/QtCore/qpermissions.sip 2023-06-02 12:41:04.983158300 
+0200
@@ -0,0 +1,292 @@
+// qpermissions.sip generated by MetaSIP
+//
+// This file is part of the QtCore Python extension module.
+//
+// Copyright (c) 2023 Riverbank Computing Limited <i...@riverbankcomputing.com>
+// 
+// This file is part of PyQt6.
+// 
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file.  Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+// 
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license.  For more information contact
+// i...@riverbankcomputing.com.
+// 
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+
+class QPermission /TypeHintIn="Union[QBluetoothPermission, 
QCalendarPermission, QCameraPermission, QContactsPermission, 
QLocationPermission, QMicrophonePermission]"/
+{
+%TypeHeaderCode
+#include <qpermissions.h>
+%End
+
+%ConvertToTypeCode
+// Note that we don't allow sub-classes of the typed permissions.
+const sipTypeDef *td = sipTypeFromPyTypeObject(Py_TYPE(sipPy));
+
+if (!sipIsErr)
+    return (td == sipType_QBluetoothPermission ||
+            td == sipType_QCalendarPermission ||
+            td == sipType_QCameraPermission ||
+            td == sipType_QContactsPermission ||
+            td == sipType_QLocationPermission ||
+            td == sipType_QMicrophonePermission);
+
+void *cpp = sipConvertToType(sipPy, td, sipTransferObj, SIP_NOT_NONE, NULL, 
sipIsErr);
+
+if (*sipIsErr)
+    return 0;
+
+if (td == sipType_QBluetoothPermission)
+    *sipCppPtr = new QPermission(*reinterpret_cast<QBluetoothPermission 
*>(cpp));
+
+else if (td == sipType_QCalendarPermission)
+    *sipCppPtr = new QPermission(*reinterpret_cast<QCalendarPermission 
*>(cpp));
+
+else if (td == sipType_QCameraPermission)
+    *sipCppPtr = new QPermission(*reinterpret_cast<QCameraPermission *>(cpp));
+
+else if (td == sipType_QContactsPermission)
+    *sipCppPtr = new QPermission(*reinterpret_cast<QContactsPermission 
*>(cpp));
+
+else if (td == sipType_QLocationPermission)
+    *sipCppPtr = new QPermission(*reinterpret_cast<QLocationPermission 
*>(cpp));
+
+else if (td == sipType_QMicrophonePermission)
+    *sipCppPtr = new QPermission(*reinterpret_cast<QMicrophonePermission 
*>(cpp));
+
+return sipGetState(sipTransferObj);
+%End
+
+public:
+    QPermission();
+    Qt::PermissionStatus status() const;
+    QMetaType type() const;
+    SIP_PYOBJECT value() const;
+%MethodCode
+        const sipTypeDef *td = SIP_NULLPTR;
+        void *perm = SIP_NULLPTR;
+        QMetaType mt = sipCpp->type();
+        
+        if (mt == QMetaType::fromType<QBluetoothPermission>())
+        {
+            std::optional<QBluetoothPermission> opt_perm = 
sipCpp->value<QBluetoothPermission>();
+            
+            if (opt_perm)
+            {
+                perm = new QBluetoothPermission(opt_perm.value());
+                td = sipType_QBluetoothPermission;
+            }
+        }
+        else if (mt == QMetaType::fromType<QCalendarPermission>())
+        {
+            std::optional<QCalendarPermission> opt_perm = 
sipCpp->value<QCalendarPermission>();
+            
+            if (opt_perm)
+            {
+                perm = new QCalendarPermission(opt_perm.value());
+                td = sipType_QCalendarPermission;
+            }
+        }
+        else if (mt == QMetaType::fromType<QCameraPermission>())
+        {
+            std::optional<QCameraPermission> opt_perm = 
sipCpp->value<QCameraPermission>();
+            
+            if (opt_perm)
+            {
+                perm = new QCameraPermission(opt_perm.value());
+                td = sipType_QCameraPermission;
+            }
+        }
+        else if (mt == QMetaType::fromType<QContactsPermission>())
+        {
+            std::optional<QContactsPermission> opt_perm = 
sipCpp->value<QContactsPermission>();
+            
+            if (opt_perm)
+            {
+                perm = new QContactsPermission(opt_perm.value());
+                td = sipType_QContactsPermission;
+            }
+        }
+        else if (mt == QMetaType::fromType<QLocationPermission>())
+        {
+            std::optional<QLocationPermission> opt_perm = 
sipCpp->value<QLocationPermission>();
+            
+            if (opt_perm)
+            {
+                perm = new QLocationPermission(opt_perm.value());
+                td = sipType_QLocationPermission;
+            }
+        }
+        else if (mt == QMetaType::fromType<QMicrophonePermission>())
+        {
+            std::optional<QMicrophonePermission> opt_perm = 
sipCpp->value<QMicrophonePermission>();
+            
+            if (opt_perm)
+            {
+                perm = new QMicrophonePermission(opt_perm.value());
+                td = sipType_QMicrophonePermission;
+            }
+        }
+        
+        if (perm)
+        {
+            sipRes = sipConvertFromNewType(perm, td, SIP_NULLPTR);
+        }
+        else
+        {
+            sipRes = Py_None;
+            Py_INCREF(sipRes);
+        }
+%End
+};
+
+%End
+%End
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+
+class QLocationPermission
+{
+%TypeHeaderCode
+#include <qpermissions.h>
+%End
+
+public:
+    QLocationPermission();
+    QLocationPermission(const QLocationPermission &other);
+    ~QLocationPermission();
+
+    enum Accuracy
+    {
+        Approximate,
+        Precise,
+    };
+
+    void setAccuracy(QLocationPermission::Accuracy accuracy);
+    QLocationPermission::Accuracy accuracy() const;
+
+    enum Availability
+    {
+        WhenInUse,
+        Always,
+    };
+
+    void setAvailability(QLocationPermission::Availability availability);
+    QLocationPermission::Availability availability() const;
+};
+
+%End
+%End
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+
+class QCalendarPermission
+{
+%TypeHeaderCode
+#include <qpermissions.h>
+%End
+
+public:
+    QCalendarPermission();
+    QCalendarPermission(const QCalendarPermission &other);
+    ~QCalendarPermission();
+
+    enum AccessMode
+    {
+        ReadOnly,
+        ReadWrite,
+    };
+
+    void setAccessMode(QCalendarPermission::AccessMode mode);
+    QCalendarPermission::AccessMode accessMode() const;
+};
+
+%End
+%End
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+
+class QContactsPermission
+{
+%TypeHeaderCode
+#include <qpermissions.h>
+%End
+
+public:
+    QContactsPermission();
+    QContactsPermission(const QContactsPermission &other);
+    ~QContactsPermission();
+
+    enum AccessMode
+    {
+        ReadOnly,
+        ReadWrite,
+    };
+
+    void setAccessMode(QContactsPermission::AccessMode mode);
+    QContactsPermission::AccessMode accessMode() const;
+};
+
+%End
+%End
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+
+class QCameraPermission
+{
+%TypeHeaderCode
+#include <qpermissions.h>
+%End
+
+public:
+    QCameraPermission();
+    QCameraPermission(const QCameraPermission &other);
+    ~QCameraPermission();
+};
+
+%End
+%End
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+
+class QMicrophonePermission
+{
+%TypeHeaderCode
+#include <qpermissions.h>
+%End
+
+public:
+    QMicrophonePermission();
+    QMicrophonePermission(const QMicrophonePermission &other);
+    ~QMicrophonePermission();
+};
+
+%End
+%End
+%If (Qt_6_5_0 -)
+%If (PyQt_Permissions)
+
+class QBluetoothPermission
+{
+%TypeHeaderCode
+#include <qpermissions.h>
+%End
+
+public:
+    QBluetoothPermission();
+    QBluetoothPermission(const QBluetoothPermission &other);
+    ~QBluetoothPermission();
+};
+
+%End
+%End
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/uic/compile_ui.py 
new/PyQt6-6.5.1/uic/compile_ui.py
--- old/PyQt6-6.5.0/uic/compile_ui.py   2023-04-05 14:16:47.672638700 +0200
+++ new/PyQt6-6.5.1/uic/compile_ui.py   2023-06-02 12:40:57.539929200 +0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2020 Riverbank Computing Limited.
+# Copyright (c) 2023 Riverbank Computing Limited.
 # Copyright (c) 2006 Thorsten Marek.
 # All right reserved.
 #
@@ -60,7 +60,7 @@
     sys.exit(app.exec())"""
 
 
-def compileUiDir(dir, recurse=False, map=None, **compileUi_args):
+def compileUiDir(dir, recurse=False, map=None, max_workers=0, 
**compileUi_args):
     """compileUiDir(dir, recurse=False, map=None, **compileUi_args)
 
     Creates Python modules from Qt Designer .ui files in a directory or
@@ -76,14 +76,20 @@
     created.  The callable should return a tuple of the name of the directory
     in which the Python module will be created and the (possibly modified)
     name of the module.  The default is None.
+    max_workers is the maximum number of worker processes to use. A value of 0
+    means only the current process is used.  A value of None means that the
+    number of processors on the machine is used.
     compileUi_args are any additional keyword arguments that are passed to
     the compileUi() function that is called to create each Python module.
     """
 
+    from functools import partial
     import os
 
-    # Compile a single .ui file.
-    def compile_ui(ui_dir, ui_file):
+    jobs = []
+
+    # Add a compilation job.
+    def add_job(ui_dir, ui_file):
         # Ignore if it doesn't seem to be a .ui file.
         if ui_file.endswith('.ui'):
             py_dir = ui_dir
@@ -94,30 +100,46 @@
             if map is not None:
                 py_dir, py_file = map(py_dir, py_file)
 
-            # Make sure the destination directory exists.
-            try:
-                os.makedirs(py_dir)
-            except:
-                pass
-
             ui_path = os.path.join(ui_dir, ui_file)
-            py_path = os.path.join(py_dir, py_file)
 
-            py_file = open(py_path, 'w', encoding='utf-8')
-
-            try:
-                compileUi(ui_path, py_file, **compileUi_args)
-            finally:
-                py_file.close()
+            jobs.append((ui_path, py_dir, py_file))
 
     if recurse:
         for root, _, files in os.walk(dir):
             for ui in files:
-                compile_ui(root, ui)
+                add_job(root, ui)
     else:
         for ui in os.listdir(dir):
             if os.path.isfile(os.path.join(dir, ui)):
-                compile_ui(dir, ui)
+                add_job(dir, ui)
+
+    if jobs and max_workers != 0:
+        from concurrent.futures import ProcessPoolExecutor
+
+        with ProcessPoolExecutor(max_workers=max_workers) as executor:
+            executor.map(partial(_run_job, **compileUi_args), jobs)
+    else:
+        for job in jobs:
+            _run_job(job, **compileUi_args)
+
+
+def _run_job(job, **compileUi_args):
+    """ Run a job to compile a single .ui file. """
+
+    import os
+
+    ui_path, py_dir, py_file = job
+
+    # Make sure the destination directory exists.
+    try:
+        os.makedirs(py_dir)
+    except:
+        pass
+
+    py_path = os.path.join(py_dir, py_file)
+
+    with open(py_path, 'w', encoding='utf-8') as py_f:
+        compileUi(ui_path, py_f, **compileUi_args)
 
 
 def compileUi(uifile, pyfile, execute=False, indent=4):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyQt6-6.5.0/uic/pyuic.py new/PyQt6-6.5.1/uic/pyuic.py
--- old/PyQt6-6.5.0/uic/pyuic.py        2023-04-05 14:16:47.664907200 +0200
+++ new/PyQt6-6.5.1/uic/pyuic.py        2023-06-02 12:40:57.532554100 +0200
@@ -16,6 +16,7 @@
 # WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
 
+import os
 import sys
 
 
@@ -52,7 +53,11 @@
     parser.add_argument('-i', '--indent', dest='indent', action='store',
             type=int, default=4, metavar="N",
             help="set indent width to N spaces, tab if N is 0 [default: 4]")
-    parser.add_argument('ui', help="the .ui file created by Qt Designer")
+    parser.add_argument('-w', '--max-workers', dest='max_workers',
+            action='store', type=int, default=0, metavar="N",
+            help="use a maximum of N worker processes when converting a 
directory [default: 0]")
+    parser.add_argument('ui',
+            help="the .ui file created by Qt Designer or a directory 
containing .ui files")
 
     args = parser.parse_args()
 
@@ -64,9 +69,13 @@
 
     try:
         if args.preview:
-            exit_status = preview(args.ui)
+            if os.path.isfile(args.ui):
+                exit_status = preview(args.ui)
+            else:
+                raise UIFileException(args.ui, "must be a file")
         else:
-            generate(args.ui, args.output, args.indent, args.execute)
+            generate(args.ui, args.output, args.indent, args.execute,
+                    args.max_workers)
             exit_status = 0
 
     except IOError as e:
@@ -109,24 +118,44 @@
     logger.setLevel(logging.DEBUG)
 
 
-def generate(ui_file, output, indent, execute):
+def generate(ui_file, output, indent, execute, max_workers):
     """ Generate the Python code. """
 
-    from .compile_ui import compileUi
+    from .exceptions import UIFileException
 
-    if output == '-':
-        import io
+    if os.path.isdir(ui_file):
+        if output == '-':
+            map = None
+        elif os.path.isdir(output) or not os.path.exists(output):
+            map = lambda d, f: (output, f)
+        else:
+            raise UIFileException(output,
+                    f"must be a directory as {ui_file} is a directory")
+
+        from .compile_ui import compileUiDir
+
+        compileUiDir(ui_file, recurse=False, map=map, max_workers=max_workers,
+                indent=indent, execute=execute)
 
-        pyfile = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
-        needs_close = False
+    elif os.path.isdir(output):
+        raise UIFileException(output,
+                f"cannot be a directory unless {ui_file} is a directory")
     else:
-        pyfile = open(output, 'wt', encoding='utf8')
-        needs_close = True
+        from .compile_ui import compileUi
+
+        if output == '-':
+            import io
+
+            pyfile = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
+            needs_close = False
+        else:
+            pyfile = open(output, 'wt', encoding='utf8')
+            needs_close = True
 
-    compileUi(ui_file, pyfile, execute, indent)
+        compileUi(ui_file, pyfile, execute, indent)
 
-    if needs_close:
-        pyfile.close()
+        if needs_close:
+            pyfile.close()
 
 
 def preview(ui_file):

Reply via email to