Repository: spyder-ide/qtpy (language: python)

Issue:
Add official support for Python 3.11
Hi,

The recent PySide6 release 6.4.0.1 now supports Python 3.11 too.

Qtpy officially only supports 3.6 to 3.10 but not yet 3.11.

Here's the commit which added 3.10: https://github.com/spyder-ide/qtpy/commit/005641217fbece5e2844ffb844596c90ae3850b6 .

Thanks a lot for this amazing project!


Discussion / hints:
Hi @florisla thank you for the feedback and your nice words! We will do this in a future release :+1:



Fix patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a910d913..9f552ff8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -25,56 +25,65 @@ jobs:
       CI: 'True'
       PYTHON_VERSION: ${{ matrix.python-version }}
       USE_CONDA: ${{ matrix.use-conda }}
+      PYQT5_VERSION: ${{ matrix.pyqt5-version || matrix.qt5-version-default }}
+      PYQT5_QT_VERSION: ${{ matrix.pyqt5-qt-version || matrix.pyqt5-version || matrix.qt5-version-default }}
+      PYQT6_VERSION: ${{ matrix.pyqt6-version || matrix.qt6-version-default }}
+      PYQT6_QT_VERSION: ${{ matrix.pyqt6-qt-version || matrix.pyqt6-version || matrix.qt6-version-default }}
+      PYSIDE2_VERSION: ${{ matrix.pyside2-version || matrix.qt5-version-default }}
+      PYSIDE2_QT_VERSION: ${{ matrix.pyside2-qt-version || matrix.pyside2-version || matrix.qt5-version-default }}
+      PYSIDE6_VERSION: ${{ matrix.pyside6-version || matrix.qt6-version-default }}
+      PYSIDE6_QT_VERSION: ${{ matrix.pyside6-qt-version || matrix.pyside6-version || matrix.qt6-version-default }}
+      QSCINTILLA_VERSION: ${{ matrix.qscintilla-version || matrix.qscintilla-version-default }}
       SKIP_PIP_CHECK: ${{ matrix.skip-pip-check }}
-      PYQT5_VERSION: ${{ matrix.pyqt5-version }}
-      PYQT6_VERSION: ${{ matrix.pyqt6-version }}
-      PYSIDE2_VERSION: ${{ matrix.pyside2-version }}
-      PYSIDE6_VERSION: ${{ matrix.pyside6-version }}
-      PYQT5_QT_VERSION: ${{ matrix.pyqt5-qt-version }}
-      PYQT6_QT_VERSION: ${{ matrix.pyqt6-qt-version }}
-      PYSIDE2_QT_VERSION: ${{ matrix.pyside2-qt-version }}
-      PYSIDE6_QT_VERSION: ${{ matrix.pyside6-qt-version }}
-      QSCINTILLA_VERSION: '2.13'
     strategy:
       fail-fast: false
       matrix:
         os: [ubuntu-latest, windows-latest, macos-latest]
-        python-version: ['3.7', '3.10']
+        python-version: ['3.7', '3.11']
         use-conda: ['Yes', 'No']
+        qt5-version-default: ['5.12']
+        qt6-version-default: ['6.3']
+        qscintilla-version-default: ['2.13']
         include:
         - os: ubuntu-latest
           special-invocation: 'xvfb-run --auto-servernum '  # Needed for GUI tests to work
-        - python-version: '3.10'
-          skip-pyside2: true  # Skip Pyside2 on all Python 3.10 builds until it supports it
-        - use-conda: 'Yes'  # No PyQt6 conda packages yet
-          skip-pyqt6: true
-        - os: windows-latest
-          python-version: '3.10'
-          use-conda: 'No'
-          pyqt6-version: '6.4'  # Test upper bound
-          pyqt6-qt-version: '6.4'  # Test upper bound
-          pyside2-version: '5.15'  # No 5.12 wheel on Windows and Python 3.10
-          pyside6-version: '6.4'  # Test upper bound
-          pyside6-qt-version: '6.4'  # Test upper bound
+        - python-version: '3.11'
+          pyqt5-version: '5.15'  # Python 3.11 needs 5.15+
+          skip-pyside2: true  # Pyside2 doesn't support Python 3.11+ (and probably never will)
+          pyside6-version: '6.4'  # Python 3.11 needs 6.4+
+        - use-conda: 'Yes'
+          skip-pyqt6: true  # No PyQt6 conda packages yet
+          pyside6-version: '6.4'  # Conda only has 6.4+
+        - use-conda: 'No'
+          pyqt5-version: '5.15'  # Test with latest optional packages
+        - python-version: '3.7'
+          use-conda: 'Yes'
+          pyside2-version: '5.13'  # Conda needs 5.13+ to work reliably
+          pyside2-qt-version: '5.12'  # Conda only has 5.12 and 5.15, not 5.13
         - os: windows-latest
           python-version: '3.7'
           use-conda: 'Yes'
-          pyqt5-qt-version: '5.9'
-          pyqt6-qt-version: '6.2'
-          skip-pyside6: true  # test hangs
+          pyqt5-version: '5.9'  # Test lower bound
+          skip-pyside6: true  # Test hangs
+        - os: windows-latest
+          python-version: '3.7'
+          use-conda: 'No'
+          pyqt6-version: 6.2  # Test lower bound
+          pyside6-version: 6.2  # Test lower bound
         - os: windows-latest
-          python-version: '3.10'
+          python-version: '3.11'
           use-conda: 'Yes'
-          skip-pyside6: true  # test hangs
+          skip-pyside6: true  # Test hangs
         - os: macos-latest
           python-version: '3.7'
           use-conda: 'No'
-          skip-pyside6: true  # pytest-qt crashes on pytest startup under this environment
+          pyqt6-version: 6.4  # Test upper bound
+          pyside2-version: 5.15  # Test upper bound
     steps:
       - name: Checkout branch
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
       - name: Setup Python
-        uses: actions/setup-python@v2
+        uses: actions/setup-python@v4
         with:
           python-version: '3.x'
       - name: Install Linux system packages
diff --git a/pyproject.toml b/pyproject.toml
index f6c16894..15caa0ee 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,5 @@
 [build-system]
 requires = [
     "setuptools>=42",
-    "wheel",
 ]
 build-backend = "setuptools.build_meta"
diff --git a/setup.cfg b/setup.cfg
index 63b88881..30000855 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -10,7 +10,6 @@ author_email = spyder.python@gmail.com
 maintainer = Spyder Development Team and QtPy Contributors
 maintainer_email = spyder.python@gmail.com
 license = MIT
-license_file = LICENSE.txt
 license_files =
     AUTHORS.md
     LICENSE.txt
@@ -28,6 +27,7 @@ classifiers =
     Programming Language :: Python :: 3.8
     Programming Language :: Python :: 3.9
     Programming Language :: Python :: 3.10
+    Programming Language :: Python :: 3.11
     Topic :: Software Development :: Libraries
     Topic :: Software Development :: User Interfaces
     Topic :: Software Development :: Widget Sets


Test patch:
diff --git a/.github/workflows/test.sh b/.github/workflows/test.sh
index d77fa0fe..a3c98f55 100755
--- a/.github/workflows/test.sh
+++ b/.github/workflows/test.sh
@@ -9,19 +9,29 @@ conda remove -q -n test-env --all || true
 # Create and activate conda environment for this test
 BINDING=$(echo "$1" | tr '[:lower:]' '[:upper:]')
 QT_VERSION_VAR=${BINDING}_QT_VERSION
-# pytest-qt >=4 doesn't support Qt >=5.9
-if [ "${!QT_VERSION_VAR:0:3}" = "5.9" ]; then PYTESTQT_VERSION="=3.3.0"; PYTEST_VERSION=">=6,!=7.0.0,!=7.0.1,<7.2.0"; fi
-conda create -q -n test-env python=${PYTHON_VERSION} pytest${PYTEST_VERSION:-">=6,!=7.0.0,!=7.0.1"} "pytest-cov>=3.0.0" pytest-qt${PYTESTQT_VERSION:-} pip${PIP_VERSION:-}
+
+# pytest-qt >=4 doesn't support Qt <=5.9
+if [ "${!QT_VERSION_VAR:0:3}" = "5.9" ]; then
+    PYTESTQT_VERSION="=3.3.0"
+    PYTEST_VERSION=">=6,!=7.0.0,!=7.0.1,<7.2.0"
+fi
+
+conda create -q -n test-env python=${PYTHON_VERSION} pytest${PYTEST_VERSION:-">=6,!=7.0.0,!=7.0.1"} "pytest-cov>=3.0.0" pytest-qt${PYTESTQT_VERSION:-}
 conda activate test-env
 
 if [ "$USE_CONDA" = "Yes" ]; then
 
     if [ "${1}" = "pyqt5" ]; then
-        conda install -q qt=${PYQT5_QT_VERSION:-"5.12"} pyqt=${PYQT5_VERSION:-"5"}
+        if [ "${PYQT5_VERSION:0:4}" = "5.15" ]; then
+            # Must specify versions individually with PyQt 5.15 to avoid compat issues with Python 3.11
+            conda install -q qt-main=${PYQT5_QT_VERSION} qt-webengine=${PYQT5_QT_VERSION} pyqt=${PYQT5_VERSION}
+        else
+            conda install -q qt=${PYQT5_QT_VERSION} pyqt=${PYQT5_VERSION}
+        fi
     elif [ "${1}" = "pyside2" ]; then
-        conda install -q qt=${PYSIDE2_QT_VERSION:-"5.12"} pyside2=${PYSIDE2_VERSION:-"5"}
+        conda install -q qt=${PYSIDE2_QT_VERSION} pyside2=${PYSIDE2_VERSION}
     elif [ "${1}" = "pyside6" ]; then
-	conda install -q pyside6=${PYSIDE6_VERSION:-"6.4"}
+        conda install -q qt6-main=${PYSIDE6_QT_VERSION} pyside6=${PYSIDE6_VERSION}
     else
         exit 1
     fi
@@ -29,16 +39,16 @@ if [ "$USE_CONDA" = "Yes" ]; then
 else
 
     if [ "${1}" = "pyqt5" ]; then
-        pip install pyqt5==${PYQT5_VERSION:-"5.15"}.* PyQtWebEngine==${PYQT5_VERSION:-"5.15"}.* QScintilla==${QSCINTILLA_VERSION:-"2.13"}.*
+        pip install pyqt5==${PYQT5_VERSION}.* PyQtWebEngine==${PYQT5_VERSION}.* QScintilla==${QSCINTILLA_VERSION}.*
     elif [ "${1}" = "pyqt6" ]; then
-        pip install pyqt6==${PYQT6_VERSION:-"6.3"}.* PyQt6-WebEngine==${PYQT6_VERSION:-"6.3"}.* PyQt6-Qt6==${PYQT6_QT_VERSION:-"6.3"}.* PyQt6-QScintilla==${QSCINTILLA_VERSION:-"2.13"}.*
+        pip install pyqt6==${PYQT6_VERSION}.* PyQt6-WebEngine==${PYQT6_VERSION}.* PyQt6-Qt6==${PYQT6_QT_VERSION}.* PyQt6-QScintilla==${QSCINTILLA_VERSION}.*
     elif [ "${1}" = "pyside2" ]; then
-        pip install pyside2==${PYSIDE2_VERSION:-"5.12"}.*
+        pip install pyside2==${PYSIDE2_VERSION}.*
     elif [ "${1}" = "pyside6" ]; then
-        if [ "${PYSIDE6_VERSION:-"6.2":0:3}" = "6.2" ]; then
-            pip install pyside6==${PYSIDE6_VERSION:-"6.2"}.*
+        if [ "${PYSIDE6_VERSION:0:3}" = "6.2" ]; then
+            pip install pyside6==${PYSIDE6_VERSION}.*
         else
-            pip install pyside6==${PYSIDE6_VERSION:-"6.3"}.* pyside6-addons==${PYSIDE6_VERSION:-"6.3"}.* pyside6-essentials==${PYSIDE6_VERSION:-"6.3"}.*
+            pip install pyside6==${PYSIDE6_VERSION}.* pyside6-addons==${PYSIDE6_VERSION}.* pyside6-essentials==${PYSIDE6_VERSION}.*
         fi
     else
         exit 1