diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index b0fa1525..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,67 +0,0 @@ -version: 2 - -main: &main - machine: true - steps: - - checkout - - run: - command: docker pull dorowu/ubuntu-desktop-lxde-vnc:trusty - - run: - name: Install system packages - command: | - sudo apt-get update - sudo apt-get install libpulse-dev - sudo apt-get install libegl1-mesa - - run: - command: ./.circleci/install.sh - - run: - command: ./.circleci/test-pyqt5.sh - - run: - command: ./.circleci/test-pyside2.sh - - run: - command: ./.circleci/test-pyqt4.sh - - run: - command: ./.circleci/test-pyside.sh - - run: - command: ./.circleci/coverage.sh - -jobs: - python2.7: - <<: *main - environment: - - PYTHON_VERSION: "2.7" - - USE_CONDA: "Yes" - - python3.5: - <<: *main - environment: - - PYTHON_VERSION: "3.5" - - USE_CONDA: "Yes" - - python3.6: - <<: *main - environment: - - PYTHON_VERSION: "3.6" - - USE_CONDA: "Yes" - - python2.7-pip: - <<: *main - environment: - - PYTHON_VERSION: "2.7" - - USE_CONDA: "No" - - python3.6-pip: - <<: *main - environment: - - PYTHON_VERSION: "3.6" - - USE_CONDA: "No" - -workflows: - version: 2 - build_and_test: - jobs: - - python2.7 - - python3.5 - - python3.6 - - python2.7-pip - - python3.6-pip diff --git a/.circleci/install.sh b/.circleci/install.sh deleted file mode 100755 index c51c2df7..00000000 --- a/.circleci/install.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -ex - -export TRAVIS_OS_NAME="linux" -export CONDA_DEPENDENCIES_FLAGS="--quiet" -export CONDA_DEPENDENCIES="pytest pytest-cov mock" -export PIP_DEPENDENCIES="coveralls" - -# Download and install miniconda and conda/pip dependencies -# with astropy helpers -echo -e "PYTHON = $PYTHON_VERSION \n============" -git clone git://github.com/astropy/ci-helpers.git > /dev/null -source ci-helpers/travis/setup_conda_$TRAVIS_OS_NAME.sh - -# Activate conda -source $HOME/miniconda/etc/profile.d/conda.sh -conda activate test - -# Install the package in develop mode -pip install -e . diff --git a/.circleci/test-pyqt4.sh b/.circleci/test-pyqt4.sh deleted file mode 100755 index b38caf11..00000000 --- a/.circleci/test-pyqt4.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -ex - -source $HOME/miniconda/etc/profile.d/conda.sh -conda activate test - -if [ "$USE_CONDA" = "No" ]; then - exit 0 -elif [ "$PYTHON_VERSION" = "3.5" ]; then - # conda-forge doesn't provide packages for - # Python 3.5 anymore. - exit 0 -else - conda remove -q qt pyqt - conda install -q -c conda-forge qt=4.* pyqt=4.* -fi - -python qtpy/tests/runtests.py diff --git a/.circleci/test-pyqt5.sh b/.circleci/test-pyqt5.sh deleted file mode 100755 index d614ec71..00000000 --- a/.circleci/test-pyqt5.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -ex - -source $HOME/miniconda/etc/profile.d/conda.sh -conda activate test - -# Select build with QtMultimedia -if [ "$PYTHON_VERSION" = "2.7" ]; then - export BUILD=py27h22d08a2_0 -elif [ "$PYTHON_VERSION" = "3.5" ]; then - export BUILD=py35h751905a_0 -else - export BUILD=py36h751905a_0 -fi - -if [ "$USE_CONDA" = "Yes" ]; then - conda install -q qt=5.* pyqt=5.9.2=$BUILD - conda install -q sip=4.19.8 -else - if [ "$PYTHON_VERSION" = "2.7" ]; then - # There are no pyqt5 wheels for Python 2 - exit 0 - else - # We are getting segfaults in 5.10 - pip install -q pyqt5==5.9.2 - fi -fi - -python qtpy/tests/runtests.py diff --git a/.circleci/test-pyside.sh b/.circleci/test-pyside.sh deleted file mode 100755 index 65ef35af..00000000 --- a/.circleci/test-pyside.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -ex - -source $HOME/miniconda/etc/profile.d/conda.sh -conda activate test - -if [ "$USE_CONDA" = "No" ]; then - exit 0 -elif [ "$PYTHON_VERSION" = "3.5" ]; then - # conda-forge doesn't provide packages for - # Python 3.5 anymore. - exit 0 -else - conda remove -q qt pyqt - conda install -q -c conda-forge qt=4.* pyside -fi - -python qtpy/tests/runtests.py diff --git a/.circleci/test-pyside2.sh b/.circleci/test-pyside2.sh deleted file mode 100755 index 5afb72f5..00000000 --- a/.circleci/test-pyside2.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -ex - -source $HOME/miniconda/etc/profile.d/conda.sh -conda activate test - -if [ "$USE_CONDA" = "Yes" ]; then - # There are no conda packages for PySide2 - exit 0 -else - pip uninstall -q -y pyqt5 sip - # Simple solution to avoid failures with the - # Qt3D modules - pip install -q pyside2==5.12.3 -fi - -python qtpy/tests/runtests.py - -pip uninstall -y -q pyside2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..6b17fee8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,109 @@ +name: Tests + +on: + # This avoids having duplicate builds for a pull request + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + linux: + name: Linux Py${{ matrix.PYTHON_VERSION }} conda=${{ matrix.USE_CONDA }} + runs-on: ubuntu-latest + env: + CI: True + PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }} + USE_CONDA: ${{ matrix.USE_CONDA }} + strategy: + fail-fast: false + matrix: + PYTHON_VERSION: ['2.7', '3.6', '3.8'] + USE_CONDA: ['Yes', 'No'] + steps: + - name: Checkout branch + uses: actions/checkout@v2 + - name: Install System Packages + run: | + sudo apt update + sudo apt install libpulse-dev + sudo apt install libegl1-mesa + - name: Install Conda + uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: '' + auto-update-conda: true + auto-activate-base: false + - name: Test PyQt5 + shell: bash -l {0} + run: | + eval "$(conda shell.bash hook)" + xvfb-run --auto-servernum bash -l ./.github/workflows/test-pyqt5.sh + - name: Test PySide2 + shell: bash -l {0} + run: xvfb-run --auto-servernum bash -l ./.github/workflows/test-pyside2.sh + - name: Upload coverage + if: matrix.PYTHON_VERSION == '3.8' + shell: bash -l {0} + run: bash -l ./.github/workflows/coverage.sh + + macos: + name: Mac Py${{ matrix.PYTHON_VERSION }} conda=${{ matrix.USE_CONDA }} + runs-on: macos-latest + env: + CI: True + PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }} + USE_CONDA: ${{ matrix.USE_CONDA }} + strategy: + fail-fast: false + matrix: + PYTHON_VERSION: ['2.7', '3.6', '3.8'] + USE_CONDA: ['Yes', 'No'] + exclude: + - PYTHON_VERSION: '2.7' + USE_CONDA: 'Yes' + steps: + - name: Checkout branch + uses: actions/checkout@v2 + - name: Install Conda + uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: '' + auto-update-conda: true + auto-activate-base: false + - name: Test PyQt5 + shell: bash -l {0} + run: bash -l ./.github/workflows/test-pyqt5.sh + - name: Test PySide2 + shell: bash -l {0} + run: bash -l ./.github/workflows/test-pyside2.sh + + windows: + name: Windows Py${{ matrix.PYTHON_VERSION }} conda=${{ matrix.USE_CONDA }} + runs-on: windows-latest + env: + CI: True + PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }} + USE_CONDA: ${{ matrix.USE_CONDA }} + strategy: + fail-fast: false + matrix: + PYTHON_VERSION: ['2.7', '3.6', '3.8'] + USE_CONDA: ['Yes', 'No'] + steps: + - name: Checkout branch + uses: actions/checkout@v2 + - name: Install Conda + uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: '' + auto-update-conda: true + auto-activate-base: true + - name: Test PyQt5 + shell: bash -l {0} + run: bash -l ./.github/workflows/test-pyqt5.sh + - name: Test PySide2 + shell: bash -l {0} + run: bash -l ./.github/workflows/test-pyside2.sh diff --git a/.circleci/coverage.sh b/.github/workflows/coverage.sh similarity index 61% rename from .circleci/coverage.sh rename to .github/workflows/coverage.sh index f9c4f704..f68ecb3e 100755 --- a/.circleci/coverage.sh +++ b/.github/workflows/coverage.sh @@ -1,9 +1,10 @@ #!/bin/bash -export COVERALLS_REPO_TOKEN="xh75EzxFFMoTEyNPo3wXxXv8OVkul3eE5" -export PATH="$HOME/miniconda/bin:$PATH" -source activate test +eval "$(conda shell.bash hook)" +conda deactivate +conda activate test-pyqt5 +export COVERALLS_REPO_TOKEN="xh75EzxFFMoTEyNPo3wXxXv8OVkul3eE5" coveralls # Don't fail at this step diff --git a/.github/workflows/test-pyqt5.sh b/.github/workflows/test-pyqt5.sh new file mode 100755 index 00000000..678a3ec7 --- /dev/null +++ b/.github/workflows/test-pyqt5.sh @@ -0,0 +1,58 @@ +#!/bin/bash -ex + +# Create conda environment for this test +conda create -n test-pyqt5 +conda activate test-pyqt5 + +# Select build with QtMultimedia +if [ "$(uname)" == "Darwin" ]; then + + if [ "$PYTHON_VERSION" = "2.7" ]; then + export QT_VER=5.9 + elif [ "$PYTHON_VERSION" = "3.6" ]; then + export QT_VER=5.12 + else + export QT_VER=5.* + fi + +elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then + + if [ "$PYTHON_VERSION" = "2.7" ]; then + export QT_VER=5.9 + elif [ "$PYTHON_VERSION" = "3.6" ]; then + export QT_VER=5.12 + else + export QT_VER=5.* + fi + +else + + if [ "$PYTHON_VERSION" = "2.7" ]; then + exit 0 + elif [ "$PYTHON_VERSION" = "3.6" ]; then + export QT_VER=5.9 + else + export QT_VER=5.* + fi + +fi + +if [ "$USE_CONDA" = "Yes" ]; then + conda install coveralls mock pytest pytest-cov python="$PYTHON_VERSION" -c conda-forge -q + conda install -q qt=$QT_VER pyqt=$QT_VER -c conda-forge -q +else + if [ "$PYTHON_VERSION" = "2.7" ]; then + # There are no pyqt5 wheels for Python 2 + exit 0 + else + # We are getting segfaults in 5.10 + conda install coveralls mock pytest pytest-cov python="$PYTHON_VERSION" -c anaconda -q + pip install -q pyqt5 PyQtWebEngine + fi +fi + +# Install package +python -m pip install -e . + +# Run tests +python qtpy/tests/runtests.py diff --git a/.github/workflows/test-pyside2.sh b/.github/workflows/test-pyside2.sh new file mode 100755 index 00000000..f5e1c271 --- /dev/null +++ b/.github/workflows/test-pyside2.sh @@ -0,0 +1,23 @@ +#!/bin/bash -ex + +# Create conda environment for this test +conda create -n test-pyside2 +conda activate test-pyside2 + +if [ "$USE_CONDA" = "Yes" ]; then + # There are no conda packages for PySide2 + exit 0 +elif [ "$PYTHON_VERSION" != "3.6" ] && [ "$RUNNER_OS" = "Windows" ]; then + # There is no wheel for PySide 5.12 on Windows and Python 2.7 or 3.8 + exit 0 +else + # Simple solution to avoid failures with the Qt3D modules + conda install coveralls mock pytest pytest-cov python="$PYTHON_VERSION" -c conda-forge -q + pip install -q pyside2==5.12 +fi + +# Install package +python -m pip install -e . + +# Run tests +python qtpy/tests/runtests.py diff --git a/.gitignore b/.gitignore index 9f30b4e8..2aa984af 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,7 @@ toread.md .chache .idea/ +# Macos +*.DS_Store + # End of File diff --git a/AUTHORS.md b/AUTHORS.md index a6b4d15e..cb19d7b5 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,16 +1,17 @@ -Maintainer -========== +# Authors -Gonzalo Peña-Castellanos ([@goanpeca](http://github.com/goanpeca)) +## Maintainer -Main Authors -============ +Spyder Development Team ([Spyder-IDE](http://github.com/spyder-ide)) + + +## Main Authors * Colin Duquesnoy ([@ColinDuquesnoy](http://github.com/ColinDuquesnoy)) -* [The Spyder Development Team](https://github.com/spyder-ide/spyder/graphs/contributors) +* [The QtPy Contributors](https://github.com/spyder-ide/qtpy/graphs/contributors) + -Contributors -============ +## Contributors -* Thomas Robitaille ([@astrofrog](http://www.github.com/astrofrog)) \ No newline at end of file +* Thomas Robitaille ([@astrofrog](http://www.github.com/astrofrog)) diff --git a/README.md b/README.md index 24fd048c..22f3d008 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,10 @@ [![OpenCollective Backers](https://opencollective.com/spyder/backers/badge.svg?color=blue)](#backers) [![Join the chat at https://gitter.im/spyder-ide/public](https://badges.gitter.im/spyder-ide/spyder.svg)](https://gitter.im/spyder-ide/public)
[![PyPI status](https://img.shields.io/pypi/status/qtpy.svg)](https://github.com/spyder-ide/qtpy) -[![Build status](https://ci.appveyor.com/api/projects/status/62y6i02vhn4hefg0/branch/master?svg=true)](https://ci.appveyor.com/project/spyder-ide/qtpy/branch/master) -[![CircleCI](https://circleci.com/gh/spyder-ide/qtpy.svg?style=shield)](https://circleci.com/gh/spyder-ide/qtpy) +[![Github build status](https://github.com/spyder-ide/qtpy/workflows/Tests/badge.svg)](https://github.com/spyder-ide/qtpy/actions) [![Coverage Status](https://coveralls.io/repos/github/spyder-ide/qtpy/badge.svg?branch=master)](https://coveralls.io/github/spyder-ide/qtpy?branch=master) -*Copyright © 2009–2019 The Spyder Development Team* +*Copyright © 2009–2021 The Spyder Development Team* ## Description diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 5869caa7..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,56 +0,0 @@ -# https://ci.appveyor.com/project/goanpeca/qtpy - -branches: - only: - - master - -environment: - global: - PYTHON: "C:\\conda" - CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci-helpers\\appveyor\\windows_sdk.cmd" - PYTHON_ARCH: "64" # needs to be set for CMD_IN_ENV to succeed. If a mix - # of 32 bit and 64 bit builds are needed, move this - # to the matrix section. - - matrix: - # Qt4 - - PYTHON_VERSION: "2.7" - CONDA_DEPENDENCIES: "pytest pytest-cov mock qt=4.* pyside" - - PYTHON_VERSION: "2.7" - CONDA_DEPENDENCIES: "pytest pytest-cov mock qt=4.* pyqt=4.*" - - PYTHON_VERSION: "3.5" - CONDA_DEPENDENCIES: "pytest pytest-cov mock qt=4.* pyqt=4.*" - # Qt5 - - PYTHON_VERSION: "2.7" - CONDA_DEPENDENCIES: "pytest pytest-cov mock qt=5.* pyqt=5.*" - - PYTHON_VERSION: "3.5" - CONDA_DEPENDENCIES: "pytest pytest-cov mock qt=5.* pyqt=5.*" - - PYTHON_VERSION: "3.6" - CONDA_DEPENDENCIES: "pytest pytest-cov mock" - PIP_DEPENDENCIES: "pyqt5==5.9.2" - PIP_DEPENDENCIES_FLAGS: "-q" - -platform: - -x64 - -install: - # If there is a newer build queued for the same PR, cancel this one. - # The AppVeyor 'rollout builds' option is supposed to serve the same - # purpose but it is problematic because it tends to cancel builds pushed - # directly to master instead of just PR builds (or the converse). - # credits: JuliaLang developers. - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` - https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` - Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` - throw "There are newer queued builds for this pull request, failing early." } - - "git clone git://github.com/astropy/ci-helpers.git" - - "powershell ci-helpers/appveyor/install-miniconda.ps1" - - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - - "activate test" - - "python setup.py develop" - -# Not a .NET project, we build in the install step instead -build: false - -test_script: - - "%CMD_IN_ENV% python qtpy/tests/runtests.py" diff --git a/qtpy/QtCore.py b/qtpy/QtCore.py index a15ae3bf..d4bbd0d3 100644 --- a/qtpy/QtCore.py +++ b/qtpy/QtCore.py @@ -44,7 +44,7 @@ from PyQt4.QtCore import QCoreApplication from PyQt4.QtCore import Qt from PyQt4.QtCore import pyqtSignal as Signal - from PyQt4.Qtcore import pyqtBoundSignal as SignalInstance + from PyQt4.QtCore import pyqtBoundSignal as SignalInstance from PyQt4.QtCore import pyqtSlot as Slot from PyQt4.QtCore import pyqtProperty as Property from PyQt4.QtGui import (QItemSelection, QItemSelectionModel, diff --git a/qtpy/tests/test_patch_qcombobox.py b/qtpy/tests/test_patch_qcombobox.py index fcafe56a..1e1f04a3 100644 --- a/qtpy/tests/test_patch_qcombobox.py +++ b/qtpy/tests/test_patch_qcombobox.py @@ -4,7 +4,7 @@ import sys import pytest -from qtpy import PYSIDE2, QtGui, QtWidgets +from qtpy import PYQT5, PYSIDE2, QtGui, QtWidgets PY3 = sys.version[0] == "3" @@ -86,8 +86,9 @@ def test_patched_qcombobox(): assert widget.itemText(6) == 'f' -@pytest.mark.skipif((PYSIDE2 and os.environ.get('CI', None) is not None), - reason="It segfaults in our CIs with PYSIDE2") +@pytest.mark.skipif(((PYSIDE2 or PYQT5) + and os.environ.get('CI', None) is not None), + reason="It segfaults in our CIs with PYSIDE2 or PYQT5") def test_model_item(): """ This is a regression test for an issue that caused the call to item(0) diff --git a/qtpy/tests/test_qtcore.py b/qtpy/tests/test_qtcore.py index c32bcafe..81c1e6c4 100644 --- a/qtpy/tests/test_qtcore.py +++ b/qtpy/tests/test_qtcore.py @@ -18,6 +18,8 @@ def test_DateTime_toPython(): assert QtCore.QDateTime.toPython is not None +@pytest.mark.skipif(PYSIDE2, + reason="Doesn't seem to be present on PySide2") def test_QtCore_SignalInstance(): class ClassWithSignal(QtCore.QObject): signal = QtCore.Signal() diff --git a/qtpy/tests/test_qtmultimedia.py b/qtpy/tests/test_qtmultimedia.py index 7fc5cf66..1fc7ec97 100644 --- a/qtpy/tests/test_qtmultimedia.py +++ b/qtpy/tests/test_qtmultimedia.py @@ -5,7 +5,7 @@ import pytest -@pytest.mark.skipif(os.name == 'nt' and sys.version_info[:2] == (3, 5), +@pytest.mark.skipif(sys.version_info[0] == 3, reason="Conda packages don't seem to include QtMultimedia") def test_qtmultimedia(): """Test the qtpy.QtMultimedia namespace""" diff --git a/qtpy/tests/test_qtmultimediawidgets.py b/qtpy/tests/test_qtmultimediawidgets.py index 2bb52d51..bd659e51 100644 --- a/qtpy/tests/test_qtmultimediawidgets.py +++ b/qtpy/tests/test_qtmultimediawidgets.py @@ -6,7 +6,7 @@ from qtpy import PYQT5, PYSIDE2 @pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") -@pytest.mark.skipif(os.name == 'nt' and sys.version_info[:2] == (3, 5), +@pytest.mark.skipif(sys.version_info[0] == 3, reason="Conda packages don't seem to include QtMultimedia") def test_qtmultimediawidgets(): """Test the qtpy.QtMultimediaWidgets namespace""" diff --git a/qtpy/tests/test_uic.py b/qtpy/tests/test_uic.py index 9a0fd280..9c885f7f 100644 --- a/qtpy/tests/test_uic.py +++ b/qtpy/tests/test_uic.py @@ -3,7 +3,7 @@ import contextlib import pytest -from qtpy import PYSIDE2, QtWidgets +from qtpy import PYQT5, PYSIDE2, QtWidgets from qtpy.QtWidgets import QComboBox from qtpy import uic from qtpy.uic import loadUi @@ -42,8 +42,9 @@ def get_qapp(icon_path=None): return qapp -@pytest.mark.skipif((PYSIDE2 and os.environ.get('CI', None) is not None), - reason="It segfaults in our CIs with PYSIDE2") +@pytest.mark.skipif(((PYSIDE2 or PYQT5) + and os.environ.get('CI', None) is not None), + reason="It segfaults in our CIs with PYSIDE2 or PYQT5") def test_load_ui(): """ Make sure that the patched loadUi function behaves as expected with a @@ -55,8 +56,9 @@ def test_load_ui(): assert isinstance(ui.comboBox, QComboBox) -@pytest.mark.skipif((PYSIDE2 and os.environ.get('CI', None) is not None), - reason="It segfaults in our CIs with PYSIDE2") +@pytest.mark.skipif(((PYSIDE2 or PYQT5) + and os.environ.get('CI', None) is not None), + reason="It segfaults in our CIs with PYSIDE2 or PYQT5") def test_load_ui_custom_auto(tmpdir): """ Test that we can load a .ui file with custom widgets without having to diff --git a/setup.py b/setup.py index 439525f9..3b582d49 100644 --- a/setup.py +++ b/setup.py @@ -23,13 +23,14 @@ name='QtPy', version=version_ns['__version__'], packages=find_packages(exclude=['contrib', 'docs', 'tests*']), + python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*', keywords=["qt PyQt4 PyQt5 PySide"], url='https://github.com/spyder-ide/qtpy', license='MIT', - author='Colin Duquesnoy, The Spyder Development Team', - author_email='goanpeca@gmail.com', - maintainer='Gonzalo Peña-Castellanos', - maintainer_email='goanpeca@gmail.com', + author='Colin Duquesnoy and the Spyder Development Team', + author_email='spyder.python@gmail.com', + maintainer='Spyder Development Team and QtPy Contributors', + maintainer_email='spyder.python@gmail.com', description='Provides an abstraction layer on top of the various Qt ' 'bindings (PyQt5, PyQt4 and PySide) and additional custom ' 'QWidgets.', @@ -45,7 +46,8 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5'] + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + ] )