Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pytest-qt for openSUSE:Factory checked in at 2024-01-05 21:45:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytest-qt (Old) and /work/SRC/openSUSE:Factory/.python-pytest-qt.new.28375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-qt" Fri Jan 5 21:45:53 2024 rev:14 rq:1137115 version:4.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytest-qt/python-pytest-qt.changes 2023-06-26 18:16:06.250473110 +0200 +++ /work/SRC/openSUSE:Factory/.python-pytest-qt.new.28375/python-pytest-qt.changes 2024-01-05 21:47:15.271101832 +0100 @@ -1,0 +2,18 @@ +Fri Jan 5 17:11:51 UTC 2024 - Dirk Müller <dmuel...@suse.com> + +- update to 4.3.1: + * Added official support for Python 3.12. + * Python 3.7 is no longer supported. + * qapp now sets up the QApplication instance with a command + line argument like this QApplication([prog_name]) instead of + using an empty list QApplication([]). Here prog_name is the + name of the app which defaults to pytest-qt-app, but can be + redefined in the pytest.ini file, see :ref:`qapp + fixture<setting-qapp-name>`. Alternatively, the arguments + that will be passed to QApplication can be defined explicitly + using the qapp_args fixture. This means that the default + behavior of the qapp_args fixture is now also changed + accordingly: it now returns the list [prog_name] instead of + an empty list. + +------------------------------------------------------------------- Old: ---- pytest-qt-4.2.0.tar.gz New: ---- pytest-qt-4.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytest-qt.spec ++++++ --- /var/tmp/diff_new_pack.sA5wRw/_old 2024-01-05 21:47:15.815121740 +0100 +++ /var/tmp/diff_new_pack.sA5wRw/_new 2024-01-05 21:47:15.815121740 +0100 @@ -1,7 +1,7 @@ # # spec file # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -66,14 +66,14 @@ %{?sle15_python_module_pythons} Name: python-pytest-qt%{psuffix} -Version: 4.2.0 +Version: 4.3.1 Release: 0 Summary: Pytest support for PyQt and PySide applications License: MIT Group: Development/Languages/Python URL: https://github.com/pytest-dev/pytest-qt Source: https://files.pythonhosted.org/packages/source/p/pytest-qt/pytest-qt-%{version}.tar.gz -BuildRequires: %{python_module base >= 3.7} +BuildRequires: %{python_module base >= 3.8} BuildRequires: %{python_module pip} BuildRequires: %{python_module setuptools_scm} BuildRequires: %{python_module setuptools} ++++++ pytest-qt-4.2.0.tar.gz -> pytest-qt-4.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/.github/workflows/deploy.yml new/pytest-qt-4.3.1/.github/workflows/deploy.yml --- old/pytest-qt-4.2.0/.github/workflows/deploy.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-qt-4.3.1/.github/workflows/deploy.yml 2023-12-22 21:55:58.000000000 +0100 @@ -0,0 +1,45 @@ +name: deploy + +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+" + +jobs: + + package: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build and Check Package + uses: hynek/build-and-inspect-python-package@v1.5 + + deploy: + needs: [package] + + if: github.repository == 'pytest-dev/pytest-qt' + + runs-on: ubuntu-latest + environment: deploy + + permissions: + id-token: write # For PyPI trusted publishers. + contents: write # For release. + + steps: + - uses: actions/checkout@v3 + + - name: Download Package + uses: actions/download-artifact@v3 + with: + name: Packages + path: dist + + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@v1.8.5 + + - name: GitHub Release + uses: softprops/action-gh-release@v1 + with: + body_path: scripts/latest-release-notes.md + files: dist/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/.github/workflows/main.yml new/pytest-qt-4.3.1/.github/workflows/main.yml --- old/pytest-qt-4.2.0/.github/workflows/main.yml 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/.github/workflows/main.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,107 +0,0 @@ -name: build - -on: [push, pull_request] - -jobs: - build: - - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - - matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11-dev"] - qt-lib: [pyqt5, pyqt6, pyside2, pyside6] - os: [ubuntu-20.04, windows-latest, macos-latest] - include: - - python-version: "3.7" - tox-env: "py37" - - python-version: "3.8" - tox-env: "py38" - - python-version: "3.9" - tox-env: "py39" - - python-version: "3.10" - tox-env: "py310" - - python-version: "3.11-dev" - tox-env: "py311" - # https://bugreports.qt.io/browse/PYSIDE-1797 - exclude: - - qt-lib: pyside6 - os: macos-latest - python-version: "3.7" - - qt-lib: pyside6 - os: ubuntu-20.04 - python-version: "3.7" - # Not installable so far - - qt-lib: pyside6 - python-version: "3.11-dev" - - qt-lib: pyside2 - os: windows-latest - python-version: "3.11-dev" - - steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python-version }} - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install tox - if [ "${{ matrix.os }}" == "ubuntu-20.04" ]; then - sudo apt-get update -y - sudo apt-get install -y libgles2-mesa-dev - fi - shell: bash - - name: Test with tox - run: | - tox -e ${{ matrix.tox-env }}-${{ matrix.qt-lib }} -- -ra --color=yes - - checks: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: "3.7" - - name: Install tox - run: | - python -m pip install --upgrade pip - pip install tox - - name: Linting - run: | - tox -e linting - - name: Docs - run: | - tox -e docs - - deploy: - - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - - runs-on: ubuntu-latest - - needs: [build, checks] - - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: "3.7" - - name: Build package - run: | - python -m pip install --upgrade pip setuptools - pip install wheel - python setup.py sdist bdist_wheel - - name: Publish package to PyPI - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: pypa/gh-action-pypi-publish@v1.5.0 - with: - user: __token__ - password: ${{ secrets.pypi_token }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/.github/workflows/test.yml new/pytest-qt-4.3.1/.github/workflows/test.yml --- old/pytest-qt-4.2.0/.github/workflows/test.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-qt-4.3.1/.github/workflows/test.yml 2023-12-22 21:55:58.000000000 +0100 @@ -0,0 +1,66 @@ +name: test + +on: [push, pull_request] + +# Cancel running jobs for the same workflow and branch. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + package: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build and Check Package + uses: hynek/build-and-inspect-python-package@v1.5 + + test: + + needs: [package] + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + qt-lib: [pyqt5, pyqt6, pyside2, pyside6] + os: [ubuntu-latest, windows-latest, macos-latest] + exclude: + # Not installable: + # ERROR: Could not find a version that satisfies the requirement pyside2 (from versions: none) + - python-version: "3.11" + qt-lib: pyside2 + os: windows-latest + - python-version: "3.12" + qt-lib: pyside2 + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + + - name: Download Package + uses: actions/download-artifact@v3 + with: + name: Packages + path: dist + + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install tox + if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then + sudo apt-get update -y + sudo apt-get install -y libgles2-mesa-dev + fi + shell: bash + + - name: Test + shell: bash + run: | + tox -e py-${{ matrix.qt-lib }} --installpkg `find dist/*.tar.gz` -- -ra diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/.pre-commit-config.yaml new/pytest-qt-4.3.1/.pre-commit-config.yaml --- old/pytest-qt-4.2.0/.pre-commit-config.yaml 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/.pre-commit-config.yaml 2023-12-22 21:55:58.000000000 +0100 @@ -1,6 +1,6 @@ repos: - repo: https://github.com/PyCQA/autoflake - rev: v1.7.6 + rev: v2.2.1 hooks: - id: autoflake name: autoflake @@ -8,34 +8,34 @@ language: python files: \.py$ - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: debug-statements - repo: https://github.com/asottile/pyupgrade - rev: v3.1.0 + rev: v3.15.0 hooks: - id: pyupgrade - repo: https://github.com/psf/black - rev: 22.10.0 + rev: 23.12.0 hooks: - id: black args: [--safe, --quiet] language_version: python3 - repo: https://github.com/asottile/blacken-docs - rev: v1.12.1 + rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==20.8b1] + additional_dependencies: [black==23.1.0] language_version: python3 - repo: https://github.com/PyCQA/flake8 - rev: 5.0.4 + rev: 6.1.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.9.0 + rev: v1.10.0 hooks: - id: rst-backticks - repo: local @@ -43,6 +43,6 @@ - id: rst name: rst entry: rst-lint --encoding utf-8 - files: ^(CHANGELOG.rst|HOWTORELEASE.rst|README.rst)$ + files: ^(HOWTORELEASE.rst|README.rst)$ language: python additional_dependencies: [pygments, restructuredtext_lint] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/.readthedocs.yml new/pytest-qt-4.3.1/.readthedocs.yml --- old/pytest-qt-4.2.0/.readthedocs.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-qt-4.3.1/.readthedocs.yml 2023-12-22 21:55:58.000000000 +0100 @@ -0,0 +1,14 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +sphinx: + configuration: docs/conf.py + +python: + install: + - path: . + - requirements: docs/requirements.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/CHANGELOG.rst new/pytest-qt-4.3.1/CHANGELOG.rst --- old/pytest-qt-4.2.0/CHANGELOG.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/CHANGELOG.rst 2023-12-22 21:55:58.000000000 +0100 @@ -1,3 +1,28 @@ +4.3.1 (2023-12-22) +------------------ + +- Added official support for Python 3.12. +- Python 3.7 is no longer supported. + +- ``qapp`` now sets up the ``QApplication`` instance with a command line argument like this + ``QApplication([prog_name])`` instead of using an empty list ``QApplication([])``. + Here ``prog_name`` is the name of the app which defaults to ``pytest-qt-app``, but can + be redefined in the ``pytest.ini`` file, see :ref:`qapp fixture<setting-qapp-name>`. + Alternatively, the arguments that will be passed to ``QApplication`` can be defined + explicitly using the ``qapp_args`` fixture. This means that the default behavior of + the ``qapp_args`` fixture is now also changed accordingly: it now returns the list + ``[prog_name]`` instead of an empty list. Thanks to `@The-Compiler`_ (`#483`_) and + `@hakonhagland`_ (`#515`_). + +.. _#515: https://github.com/pytest-dev/pytest-qt/pull/515 +.. _#483: https://github.com/pytest-dev/pytest-qt/issues/483 + +4.3.0 (2023-12-22) +------------------ + +- Failure during publish. + + 4.2.0 (2022-10-25) ------------------ @@ -731,6 +756,7 @@ .. _@fabioz: https://github.com/fabioz .. _@fogo: https://github.com/fogo .. _@gqmelo: https://github.com/gqmelo +.. _@hakonhagland: https://github.com/hakonhagland .. _@itghisi: https://github.com/itghisi .. _@jdreaver: https://github.com/jdreaver .. _@mitya57: https://github.com/mitya57 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/PKG-INFO new/pytest-qt-4.3.1/PKG-INFO --- old/pytest-qt-4.2.0/PKG-INFO 2022-10-25 17:01:14.000000000 +0200 +++ new/pytest-qt-4.3.1/PKG-INFO 2023-12-22 21:56:16.508681800 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pytest-qt -Version: 4.2.0 +Version: 4.3.1 Summary: pytest support for PyQt and PySide applications Home-page: http://github.com/pytest-dev/pytest-qt Author: Bruno Oliveira @@ -13,18 +13,25 @@ Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Desktop Environment :: Window Managers Classifier: Topic :: Software Development :: Quality Assurance Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: User Interfaces -Requires-Python: >=3.7 +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: pytest>=3.0.0 Provides-Extra: doc +Requires-Dist: sphinx; extra == "doc" +Requires-Dist: sphinx_rtd_theme; extra == "doc" Provides-Extra: dev -License-File: LICENSE +Requires-Dist: pre-commit; extra == "dev" +Requires-Dist: tox; extra == "dev" ========= pytest-qt @@ -64,7 +71,7 @@ .. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pytest-qt.svg :target: https://anaconda.org/conda-forge/pytest-qt -.. |ci| image:: https://github.com/pytest-dev/pytest-qt/workflows/build/badge.svg +.. |ci| image:: https://github.com/pytest-dev/pytest-qt/workflows/test/badge.svg :target: https://github.com/pytest-dev/pytest-qt/actions .. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-qt.svg @@ -116,7 +123,7 @@ - ``PyQt5`` To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to -``pyqt5``, ``pyside2``, or ``pyqt6``: +``pyside6``, ``pyside2``, ``pyqt6`` or ``pyqt5``: .. code-block:: ini diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/README.rst new/pytest-qt-4.3.1/README.rst --- old/pytest-qt-4.2.0/README.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/README.rst 2023-12-22 21:55:58.000000000 +0100 @@ -36,7 +36,7 @@ .. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pytest-qt.svg :target: https://anaconda.org/conda-forge/pytest-qt -.. |ci| image:: https://github.com/pytest-dev/pytest-qt/workflows/build/badge.svg +.. |ci| image:: https://github.com/pytest-dev/pytest-qt/workflows/test/badge.svg :target: https://github.com/pytest-dev/pytest-qt/actions .. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-qt.svg @@ -88,7 +88,7 @@ - ``PyQt5`` To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to -``pyqt5``, ``pyside2``, or ``pyqt6``: +``pyside6``, ``pyside2``, ``pyqt6`` or ``pyqt5``: .. code-block:: ini diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/conf.py new/pytest-qt-4.3.1/docs/conf.py --- old/pytest-qt-4.2.0/docs/conf.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/docs/conf.py 2023-12-22 21:55:58.000000000 +0100 @@ -16,7 +16,7 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath("..")) +sys.path.insert(0, os.path.abspath("../src")) # -- General configuration ----------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/intro.rst new/pytest-qt-4.3.1/docs/intro.rst --- old/pytest-qt-4.2.0/docs/intro.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/docs/intro.rst 2023-12-22 21:55:58.000000000 +0100 @@ -6,8 +6,7 @@ for `PyQt5`_, `PyQt6`_, `PySide2`_ and `PySide6`_ applications. The main usage is to use the ``qtbot`` fixture, responsible for handling ``qApp`` -creation as needed and provides methods to simulate user interaction, -like key presses and mouse clicks: +creation as needed, and registering widgets for testing: .. code-block:: python @@ -16,8 +15,8 @@ widget = HelloWidget() qtbot.addWidget(widget) - # click in the Greet button and make sure it updates the appropriate label - qtbot.mouseClick(widget.button_greet, QtCore.Qt.LeftButton) + # Click the greet button and make sure the appropriate label is updated. + widget.button_greet.click() assert widget.greet_label.text() == "Hello!" @@ -86,7 +85,7 @@ - ``PyQt5`` To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to -``pyqt6``, ``pyside2``, ``pyqt6`` or ```pyqt5``: +``pyside6``, ``pyside2``, ``pyqt6`` or ``pyqt5``: .. code-block:: ini diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/note_dialogs.rst new/pytest-qt-4.3.1/docs/note_dialogs.rst --- old/pytest-qt-4.2.0/docs/note_dialogs.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/docs/note_dialogs.rst 2023-12-22 21:55:58.000000000 +0100 @@ -49,12 +49,14 @@ .. code-block:: python def test_form_registration(qtbot, monkeypatch): - form = RegistrationForm() + user = User.empty_user() + form = RegistrationForm(user) monkeypatch.setattr( - AskNameAndAgeDialog, "ask", classmethod(lambda *args: ("Jonh", 30)) + AskNameAndAgeDialog, "ask", classmethod(lambda *args: ("John", 30)) ) - qtbot.click(form.enter_info()) - # calls AskNameAndAgeDialog.ask - # test that the rest of the form correctly behaves as if - # user entered "Jonh" and 30 as name and age + # Clicking on the button will call AskNameAndAgeDialog.ask in its slot. + form.enter_info_button.click() + + assert user.name == "John" + assert user.age == 30 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/qapplication.rst new/pytest-qt-4.3.1/docs/qapplication.rst --- old/pytest-qt-4.2.0/docs/qapplication.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/docs/qapplication.rst 2023-12-22 21:55:58.000000000 +0100 @@ -26,7 +26,7 @@ exit_calls = [] monkeypatch.setattr(QApplication, "exit", lambda: exit_calls.append(1)) button = get_app_exit_button() - qtbot.click(button) + button.click() assert exit_calls == [1] @@ -37,7 +37,7 @@ def test_exit_button(qtbot): with mock.patch.object(QApplication, "exit"): button = get_app_exit_button() - qtbot.click(button) + button.click() assert QApplication.exit.call_count == 1 @@ -75,6 +75,8 @@ The ``qapp`` fixture will then use the returned class instead of the default ``QApplication`` from ``QtWidgets``. +.. _setting-qapp-name: + Setting a QApplication name --------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/reference.rst new/pytest-qt-4.3.1/docs/reference.rst --- old/pytest-qt-4.2.0/docs/reference.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/docs/reference.rst 2023-12-22 21:55:58.000000000 +0100 @@ -48,6 +48,8 @@ .. module:: pytestqt.logging .. autoclass:: Record +.. _qapp-fixture: + qapp fixture ------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/requirements.txt new/pytest-qt-4.3.1/docs/requirements.txt --- old/pytest-qt-4.2.0/docs/requirements.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-qt-4.3.1/docs/requirements.txt 2023-12-22 21:55:58.000000000 +0100 @@ -0,0 +1,2 @@ +sphinx +sphinx-rtd-theme diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/tutorial.rst new/pytest-qt-4.3.1/docs/tutorial.rst --- old/pytest-qt-4.2.0/docs/tutorial.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/docs/tutorial.rst 2023-12-22 21:55:58.000000000 +0100 @@ -18,25 +18,38 @@ .. _here: https://github.com/nicoddemus/PySide-Examples/blob/master/examples/dialogs/findfiles.py -To test this widget's basic functionality, create a test function:: +To test this widget's basic functionality, create a test function: - def test_basic_search(qtbot, tmpdir): - ''' +.. code-block:: python + + def test_basic_search(qtbot, tmp_path): + """ test to ensure basic find files functionality is working. - ''' - tmpdir.join('video1.avi').ensure() - tmpdir.join('video1.srt').ensure() + """ + tmp_path.joinpath("video1.avi").touch() + tmp_path.joinpath("video1.srt").touch() - tmpdir.join('video2.avi').ensure() - tmpdir.join('video2.srt').ensure() + tmp_path.joinpath("video2.avi").touch() + tmp_path.joinpath("video2.srt").touch() Here the first parameter indicates that we will be using a ``qtbot`` fixture to control our widget. + +.. note:: + + It is not necessary to create a QApplication instance, since the ``qtbot`` fixture will + do this for you. The ``QApplication`` object is accessible through the + :ref:`qapp fixture<qapp-fixture>` that returns a pointer equivalent to the global + ``qApp`` pointer. + The other parameter is pytest's standard tmpdir_ that we use to create some files that will be used during our test. +.. _QApplication.instance(): https://doc.qt.io/qtforpython-6/PySide6/QtWidgets/QApplication.html .. _tmpdir: http://pytest.org/latest/tmpdir.html -Now we create the widget to test and register it:: +Now we create the widget to test and register it: + +.. code-block:: python window = Window() window.show() @@ -45,24 +58,50 @@ .. tip:: Registering widgets is not required, but recommended because it will ensure those widgets get properly closed after each test is done. -Now we use ``qtbot`` methods to simulate user interaction with the dialog:: +Now we can interact with the widgets directly: + +.. code-block:: python window.fileComboBox.clear() - qtbot.keyClicks(window.fileComboBox, '*.avi') + window.fileComboBox.setCurrentText("*.avi") window.directoryComboBox.clear() - qtbot.keyClicks(window.directoryComboBox, str(tmpdir)) + window.directoryComboBox.setCurrentText(str(tmp_path)) + + +We use the ``QComboBox.setCurrentText`` method to change the current item selected in the combo box. -The method ``keyClicks`` is used to enter text in the editable combo box, selecting the desired mask -and directory. -We then simulate a user clicking the button with the ``mouseClick`` method:: +.. _note-about-qtbot-methods: - qtbot.mouseClick(window.findButton, QtCore.Qt.LeftButton) +.. note:: + + In general, prefer to use a widget's own methods to interact with it: ``QComboBox.setCurrentIndex``, ``QLineEdit.setText``, + etc. Those methods will emit the appropriate signal, so the test will work just the same as if the user themselves + have interacted with the controls. + + Note that ``qtbot`` provides a number of methods to simulate actual interaction, for example ``keyClicks``, ``mouseClick``, + etc. Those methods should be used only in specialized situations, for example if you are creating a custom drawing widget + and want to simulate actual clicks. + + For normal interactions, always prefer widget methods (``setCurrentIndex``, ``setText``, etc) -- ``qtbot``'s methods + (``keyClicks``, ``mouseClick``, etc) will trigger an actual event, which will then need to be processed in the next + pass of the event loop, making the test unreliable and flaky. Also some operations are hard to simulate using + raw clicks, for example selecting an item on a ``QComboBox``, which will need two ``mouseClick`` + calls to simulate properly, while figuring out where to click. + + +We then simulate a user clicking the button: + +.. code-block:: python + + window.findButton.click() Once this is done, we inspect the results widget to ensure that it contains the expected files we -created earlier:: +created earlier: + +.. code-block:: python assert window.filesTable.rowCount() == 2 - assert window.filesTable.item(0, 0).text() == 'video1.avi' - assert window.filesTable.item(1, 0).text() == 'video2.avi' + assert window.filesTable.item(0, 0).text() == "video1.avi" + assert window.filesTable.item(1, 0).text() == "video2.avi" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/docs/virtual_methods.rst new/pytest-qt-4.3.1/docs/virtual_methods.rst --- old/pytest-qt-4.2.0/docs/virtual_methods.rst 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/docs/virtual_methods.rst 2023-12-22 21:55:58.000000000 +0100 @@ -3,17 +3,24 @@ .. versionadded:: 1.1 +.. note:: + + ``PySide6 6.5.2+`` automatically captures exceptions that happen during the Qt event loop and + re-raises them when control is moved back to Python, so the functionality described here + does not work with ``PySide6`` (nor is necessary). + It is common in Qt programming to override virtual C++ methods to customize behavior, like listening for mouse events, implement drawing routines, etc. Fortunately, all Python bindings for Qt support overriding these virtual methods -naturally in your Python code:: +naturally in your Python code: - class MyWidget(QWidget): +.. code-block:: python + class MyWidget(QWidget): # mouseReleaseEvent def mouseReleaseEvent(self, ev): - print('mouse released at: %s' % ev.pos()) + print(f"mouse released at: {ev.pos()}") In ``PyQt5`` and ``PyQt6``, exceptions in virtual methods will by default call abort(), which will crash the interpreter. All other Qt wrappers will print the @@ -22,12 +29,14 @@ This might be surprising for Python users which are used to exceptions being raised at the calling point: For example, the following code will just -print a stack trace without raising any exception:: +print a stack trace without raising any exception: - class MyWidget(QWidget): +.. code-block:: python + class MyWidget(QWidget): def mouseReleaseEvent(self, ev): - raise RuntimeError('unexpected error') + raise RuntimeError("unexpected error") + w = MyWidget() QTest.mouseClick(w, QtCore.Qt.LeftButton) @@ -49,7 +58,9 @@ -------------------------------------- You can disable the automatic exception hook on individual tests by using a -``qt_no_exception_capture`` marker:: +``qt_no_exception_capture`` marker: + +.. code-block:: python @pytest.mark.qt_no_exception_capture def test_buttons(qtbot): @@ -71,3 +82,9 @@ actually trigger an ``abort()``, crashing the Python interpreter. For this reason, disabling exception capture in ``PyQt5.5+`` and ``PyQt6`` is not recommended unless you install your own exception hook. + +.. note:: + + As explained in the note at the top of the page, ``PySide6 6.5.2+`` has its own + exception capture mechanism, so this option has no effect when using this + library. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/pytest.ini new/pytest-qt-4.3.1/pytest.ini --- old/pytest-qt-4.2.0/pytest.ini 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-qt-4.3.1/pytest.ini 2023-12-22 21:55:58.000000000 +0100 @@ -0,0 +1,6 @@ +[pytest] +testpaths = tests +addopts = --strict-markers --strict-config +xfail_strict = true +markers = + filterwarnings: pytest's filterwarnings marker diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/setup.cfg new/pytest-qt-4.3.1/setup.cfg --- old/pytest-qt-4.2.0/setup.cfg 2022-10-25 17:01:14.000000000 +0200 +++ new/pytest-qt-4.3.1/setup.cfg 2023-12-22 21:56:16.508681800 +0100 @@ -1,13 +1,3 @@ -[bdist_wheel] -universal = 1 - -[tool:pytest] -testpaths = tests -addopts = --strict-markers --strict-config -xfail_strict = true -markers = - filterwarnings: pytest's filterwarnings marker - [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/setup.py new/pytest-qt-4.3.1/setup.py --- old/pytest-qt-4.2.0/setup.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/setup.py 2023-12-22 21:55:58.000000000 +0100 @@ -18,12 +18,13 @@ author_email="nicodde...@gmail.com", description="pytest support for PyQt and PySide applications", long_description=Path("README.rst").read_text(encoding="UTF-8"), + long_description_content_type="text/x-rst", license="MIT", keywords="pytest qt test unittest", url="http://github.com/pytest-dev/pytest-qt", use_scm_version={"write_to": "src/pytestqt/_version.py"}, setup_requires=["setuptools_scm"], - python_requires=">=3.7", + python_requires=">=3.8", classifiers=[ "Development Status :: 5 - Production/Stable", "Framework :: Pytest", @@ -31,10 +32,11 @@ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Desktop Environment :: Window Managers", "Topic :: Software Development :: Quality Assurance", "Topic :: Software Development :: Testing", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/src/pytest_qt.egg-info/PKG-INFO new/pytest-qt-4.3.1/src/pytest_qt.egg-info/PKG-INFO --- old/pytest-qt-4.2.0/src/pytest_qt.egg-info/PKG-INFO 2022-10-25 17:01:14.000000000 +0200 +++ new/pytest-qt-4.3.1/src/pytest_qt.egg-info/PKG-INFO 2023-12-22 21:56:16.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pytest-qt -Version: 4.2.0 +Version: 4.3.1 Summary: pytest support for PyQt and PySide applications Home-page: http://github.com/pytest-dev/pytest-qt Author: Bruno Oliveira @@ -13,18 +13,25 @@ Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Desktop Environment :: Window Managers Classifier: Topic :: Software Development :: Quality Assurance Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: User Interfaces -Requires-Python: >=3.7 +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: pytest>=3.0.0 Provides-Extra: doc +Requires-Dist: sphinx; extra == "doc" +Requires-Dist: sphinx_rtd_theme; extra == "doc" Provides-Extra: dev -License-File: LICENSE +Requires-Dist: pre-commit; extra == "dev" +Requires-Dist: tox; extra == "dev" ========= pytest-qt @@ -64,7 +71,7 @@ .. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pytest-qt.svg :target: https://anaconda.org/conda-forge/pytest-qt -.. |ci| image:: https://github.com/pytest-dev/pytest-qt/workflows/build/badge.svg +.. |ci| image:: https://github.com/pytest-dev/pytest-qt/workflows/test/badge.svg :target: https://github.com/pytest-dev/pytest-qt/actions .. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-qt.svg @@ -116,7 +123,7 @@ - ``PyQt5`` To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to -``pyqt5``, ``pyside2``, or ``pyqt6``: +``pyside6``, ``pyside2``, ``pyqt6`` or ``pyqt5``: .. code-block:: ini diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/src/pytest_qt.egg-info/SOURCES.txt new/pytest-qt-4.3.1/src/pytest_qt.egg-info/SOURCES.txt --- old/pytest-qt-4.2.0/src/pytest_qt.egg-info/SOURCES.txt 2022-10-25 17:01:14.000000000 +0200 +++ new/pytest-qt-4.3.1/src/pytest_qt.egg-info/SOURCES.txt 2023-12-22 21:56:16.000000000 +0100 @@ -3,16 +3,18 @@ .pre-commit-config.yaml .project .pydevproject +.readthedocs.yml CHANGELOG.rst HOWTORELEASE.rst LICENSE README.rst +pytest.ini requirements.txt -setup.cfg setup.py tox.ini .github/FUNDING.yml -.github/workflows/main.yml +.github/workflows/deploy.yml +.github/workflows/test.yml docs/.gitignore docs/Makefile docs/changelog.rst @@ -26,6 +28,7 @@ docs/note_dialogs.rst docs/qapplication.rst docs/reference.rst +docs/requirements.txt docs/signals.rst docs/troubleshooting.rst docs/tutorial.rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/src/pytestqt/_version.py new/pytest-qt-4.3.1/src/pytestqt/_version.py --- old/pytest-qt-4.2.0/src/pytestqt/_version.py 2022-10-25 17:01:14.000000000 +0200 +++ new/pytest-qt-4.3.1/src/pytestqt/_version.py 2023-12-22 21:56:16.000000000 +0100 @@ -1,5 +1,16 @@ -# coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control -__version__ = version = '4.2.0' -__version_tuple__ = version_tuple = (4, 2, 0) +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '4.3.1' +__version_tuple__ = version_tuple = (4, 3, 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/src/pytestqt/exceptions.py new/pytest-qt-4.3.1/src/pytestqt/exceptions.py --- old/pytest-qt-4.2.0/src/pytestqt/exceptions.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/src/pytestqt/exceptions.py 2023-12-22 21:55:58.000000000 +0100 @@ -79,7 +79,7 @@ stream.write("Exceptions caught in Qt event loop:\n") sep = "_" * 80 + "\n" stream.write(sep) - for (exc_type, value, tback) in exceptions: + for exc_type, value, tback in exceptions: traceback.print_exception(exc_type, value, tback, file=stream) stream.write(sep) return stream.getvalue() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/src/pytestqt/modeltest.py new/pytest-qt-4.3.1/src/pytestqt/modeltest.py --- old/pytest-qt-4.2.0/src/pytestqt/modeltest.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/src/pytestqt/modeltest.py 2023-12-22 21:55:58.000000000 +0100 @@ -54,7 +54,6 @@ class _ChangeInFlight(enum.Enum): - COLUMNS_INSERTED = enum.auto() COLUMNS_MOVED = enum.auto() COLUMNS_REMOVED = enum.auto() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/src/pytestqt/plugin.py new/pytest-qt-4.3.1/src/pytestqt/plugin.py --- old/pytest-qt-4.2.0/src/pytestqt/plugin.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/src/pytestqt/plugin.py 2023-12-22 21:55:58.000000000 +0100 @@ -12,7 +12,7 @@ @pytest.fixture(scope="session") -def qapp_args(): +def qapp_args(pytestconfig): """ Fixture that provides QApplication arguments to use. @@ -23,9 +23,19 @@ @pytest.fixture(scope="session") def qapp_args(): - return ["--arg"] + return ["prog_name", "--arg=foo"] + + + Note that it can only be overridden once at session scope. + It is not possible to override this per unit test since a QApplication + cannot be destroyed and recreated within the same app. + + The default value is a list with one element which is determined the same + way as for ``QApplication.applicationName()``, + see :ref:`qapp fixture<setting-qapp-name>` for more information. + """ - return [] + return [pytestconfig.getini("qt_qapp_name")] @pytest.fixture(scope="session") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/src/pytestqt/qtbot.py new/pytest-qt-4.3.1/src/pytestqt/qtbot.py --- old/pytest-qt-4.2.0/src/pytestqt/qtbot.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/src/pytestqt/qtbot.py 2023-12-22 21:55:58.000000000 +0100 @@ -55,34 +55,41 @@ Those methods are just forwarded directly to the `QTest API`_. Consult the documentation for more information. + .. note:: + These methods should be rarely be used, in general prefer to interact with widgets + using their own methods such as ``QComboBox.setCurrentText``, ``QLineEdit.setText``, etc. + Doing so will have the same effect as users interacting with the widget, but are more reliable. + + See :ref:`this note in the tutorial <note-about-qtbot-methods>` for more information. + --- Below are methods used to simulate sending key events to widgets: - .. staticmethod:: keyClick (widget, key[, modifier=Qt.NoModifier[, delay=-1]]) - .. staticmethod:: keyClicks (widget, key_sequence[, modifier=Qt.NoModifier[, delay=-1]]) - .. staticmethod:: keyEvent (action, widget, key[, modifier=Qt.NoModifier[, delay=-1]]) - .. staticmethod:: keyPress (widget, key[, modifier=Qt.NoModifier[, delay=-1]]) - .. staticmethod:: keyRelease (widget, key[, modifier=Qt.NoModifier[, delay=-1]]) + .. staticmethod:: keyClick (widget, key[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]]) + .. staticmethod:: keyClicks (widget, key_sequence[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]]) + .. staticmethod:: keyEvent (action, widget, key[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]]) + .. staticmethod:: keyPress (widget, key[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]]) + .. staticmethod:: keyRelease (widget, key[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]]) Sends one or more keyboard events to a widget. :param QWidget widget: the widget that will receive the event - :param str|int key: key to send, it can be either a Qt.Key_* constant or a single character string. + :param str|int key: key to send, it can be either a Qt.Key.Key_* constant or a single character string. .. _keyboard modifiers: :param Qt.KeyboardModifier modifier: flags OR'ed together representing other modifier keys also pressed. Possible flags are: - * ``Qt.NoModifier``: No modifier key is pressed. - * ``Qt.ShiftModifier``: A Shift key on the keyboard is pressed. - * ``Qt.ControlModifier``: A Ctrl key on the keyboard is pressed. - * ``Qt.AltModifier``: An Alt key on the keyboard is pressed. - * ``Qt.MetaModifier``: A Meta key on the keyboard is pressed. - * ``Qt.KeypadModifier``: A keypad button is pressed. - * ``Qt.GroupSwitchModifier``: X11 only. A Mode_switch key on the keyboard is pressed. + * ``Qt.KeyboardModifier.NoModifier``: No modifier key is pressed. + * ``Qt.KeyboardModifier.ShiftModifier``: A Shift key on the keyboard is pressed. + * ``Qt.KeyboardModifier.ControlModifier``: A Ctrl key on the keyboard is pressed. + * ``Qt.KeyboardModifier.AltModifier``: An Alt key on the keyboard is pressed. + * ``Qt.KeyboardModifier.MetaModifier``: A Meta key on the keyboard is pressed. + * ``Qt.KeyboardModifier.KeypadModifier``: A keypad button is pressed. + * ``Qt.KeyboardModifier.GroupSwitchModifier``: X11 only. A Mode_switch key on the keyboard is pressed. :param int delay: after the event, delay the test for this milliseconds (if > 0). @@ -91,7 +98,7 @@ Auxiliary method that converts the given constant to its equivalent ascii. - :param Qt.Key_* key: one of the constants for keys in the Qt namespace. + :param Qt.Key.Key_* key: one of the constants for keys in the Qt namespace. :return type: str :returns: the equivalent character string. @@ -102,11 +109,11 @@ Below are methods used to simulate sending mouse events to widgets. - .. staticmethod:: mouseClick (widget, button[, stateKey=0[, pos=QPoint()[, delay=-1]]]) - .. staticmethod:: mouseDClick (widget, button[, stateKey=0[, pos=QPoint()[, delay=-1]]]) + .. staticmethod:: mouseClick (widget, button[, modifier=0[, pos=QPoint()[, delay=-1]]]) + .. staticmethod:: mouseDClick (widget, button[, modifier=0[, pos=QPoint()[, delay=-1]]]) .. staticmethod:: mouseMove (widget[, pos=QPoint()[, delay=-1]]) - .. staticmethod:: mousePress (widget, button[, stateKey=0[, pos=QPoint()[, delay=-1]]]) - .. staticmethod:: mouseRelease (widget, button[, stateKey=0[, pos=QPoint()[, delay=-1]]]) + .. staticmethod:: mousePress (widget, button[, modifier=0[, pos=QPoint()[, delay=-1]]]) + .. staticmethod:: mouseRelease (widget, button[, modifier=0[, pos=QPoint()[, delay=-1]]]) Sends a mouse moves and clicks to a widget. @@ -128,10 +135,12 @@ :param Qt.KeyboardModifier modifier: flags OR'ed together representing other modifier keys also pressed. See `keyboard modifiers`_. - :param QPoint position: position of the mouse pointer. + :param QPoint pos: position of the mouse pointer. :param int delay: after the event, delay the test for this milliseconds (if > 0). + .. note:: In the PySide bindings, the *modifier* argument is called *stateKey*. + .. _QTest API: http://doc.qt.io/qt-5/qtest.html @@ -594,7 +603,9 @@ .. code-block:: python with qtbot.capture_exceptions() as exceptions: - qtbot.click(button) + qtbot.mouseClick( + button, QtCore.MouseButton.LeftButton # for PyQt6 + ) # ... or QtCore.LeftButton in PyQt5 # exception is a list of sys.exc_info tuples assert len(exceptions) == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/tests/test_basics.py new/pytest-qt-4.3.1/tests/test_basics.py --- old/pytest-qt-4.2.0/tests/test_basics.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/tests/test_basics.py 2023-12-22 21:55:58.000000000 +0100 @@ -546,7 +546,7 @@ @pytest.fixture(scope='session') def qapp_args(): - return ['--test-arg'] + return ['prog_name', '--test-arg'] """ ) testdir.makepyfile( @@ -559,6 +559,22 @@ result.stdout.fnmatch_lines(["*= 1 passed in *"]) +def test_qapp_args_default(testdir): + """ + Test QApplication default arguments. + """ + + testdir.makepyfile( + """ + def test_args(qapp): + args = qapp.arguments() + assert args[0] == 'pytest-qt-qapp' + """ + ) + result = testdir.runpytest_subprocess() + result.stdout.fnmatch_lines(["*= 1 passed in *"]) + + def test_importerror(monkeypatch): def _fake_import(name, *args): raise ModuleNotFoundError(f"Failed to import {name}") @@ -592,7 +608,6 @@ ], ) def test_already_loaded_backend(monkeypatch, option_api, backend): - import builtins class Mock: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/tests/test_exceptions.py new/pytest-qt-4.3.1/tests/test_exceptions.py --- old/pytest-qt-4.2.0/tests/test_exceptions.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/tests/test_exceptions.py 2023-12-22 21:55:58.000000000 +0100 @@ -3,6 +3,15 @@ import pytest from pytestqt.exceptions import capture_exceptions, format_captured_exceptions +from pytestqt.qt_compat import qt_api + +# PySide6 is automatically captures exceptions during the event loop, +# and re-raises them when control gets back to Python, so the related +# functionality does not work, nor is needed for the end user. +exception_capture_pyside6 = pytest.mark.skipif( + qt_api.pytest_qt_api == "pyside6", + reason="pytest-qt capture not working/needed on PySide6", +) @pytest.mark.parametrize("raise_error", [False, True]) @@ -42,10 +51,24 @@ ) result = testdir.runpytest() if raise_error: - expected_lines = ["*Exceptions caught in Qt event loop:*"] - if sys.version_info.major == 3: - expected_lines.append("RuntimeError: original error") - expected_lines.extend(["*ValueError: mistakes were made*", "*1 failed*"]) + if qt_api.pytest_qt_api == "pyside6": + # PySide6 automatically captures exceptions during the event loop, + # and re-raises them when control gets back to Python. + # This results in the exception not being captured by + # us, and a more natural traceback which includes the app.sendEvent line. + expected_lines = [ + "*RuntimeError: original error", + "*app.sendEvent*", + "*ValueError: mistakes were made*", + "*1 failed*", + ] + else: + expected_lines = [ + "*Exceptions caught in Qt event loop:*", + "RuntimeError: original error", + "*ValueError: mistakes were made*", + "*1 failed*", + ] result.stdout.fnmatch_lines(expected_lines) assert "pytest.fail" not in "\n".join(result.outlines) else: @@ -65,7 +88,6 @@ assert "ValueError: errors were made" in lines -@pytest.mark.skipif(sys.version_info.major == 2, reason="Python 3 only") def test_format_captured_exceptions_chained(): try: try: @@ -84,6 +106,7 @@ @pytest.mark.parametrize("no_capture_by_marker", [True, False]) +@exception_capture_pyside6 def test_no_capture(testdir, no_capture_by_marker): """ Make sure options that disable exception capture are working (either marker @@ -99,15 +122,15 @@ """ [pytest] qt_no_exception_capture = 1 - """ + """ ) testdir.makepyfile( - """ + f""" import pytest import sys from pytestqt.qt_compat import qt_api - # PyQt 5.5+ will crash if there's no custom exception handler installed + # PyQt 5.5+ will crash if there's no custom exception handler installed. sys.excepthook = lambda *args: None class MyWidget(qt_api.QtWidgets.QWidget): @@ -120,9 +143,7 @@ w = MyWidget() qtbot.addWidget(w) qtbot.mouseClick(w, qt_api.QtCore.Qt.MouseButton.LeftButton) - """.format( - marker_code=marker_code - ) + """ ) res = testdir.runpytest() res.stdout.fnmatch_lines(["*1 passed*"]) @@ -265,6 +286,7 @@ @pytest.mark.qt_no_exception_capture +@exception_capture_pyside6 def test_capture_exceptions_context_manager(qapp): """Test capture_exceptions() context manager. @@ -319,6 +341,7 @@ result.stdout.fnmatch_lines(["*1 passed*"]) +@exception_capture_pyside6 def test_exceptions_to_stderr(qapp, capsys): """ Exceptions should still be reported to stderr. @@ -341,9 +364,9 @@ assert 'raise RuntimeError("event processed")' in err -@pytest.mark.xfail( - condition=sys.version_info[:2] == (3, 4), - reason="failing in Python 3.4, which is about to be dropped soon anyway", +@exception_capture_pyside6 +@pytest.mark.skipif( + sys.version_info[:2] == (3, 12), reason="#532 requires investigation" ) def test_exceptions_dont_leak(testdir): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/tests/test_modeltest.py new/pytest-qt-4.3.1/tests/test_modeltest.py --- old/pytest-qt-4.2.0/tests/test_modeltest.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/tests/test_modeltest.py 2023-12-22 21:55:58.000000000 +0100 @@ -113,8 +113,19 @@ check_model(BrokenTypeModel(), should_pass=False) +def check_broken_flag_or(): + flag = qt_api.QtCore.Qt.AlignmentFlag + try: + int(flag.AlignHorizontal_Mask | flag.AlignVertical_Mask) + except SystemError: + # Should not be happening anywhere else + assert sys.version_info[:2] == (3, 11) and qt_api.pytest_qt_api == "pyside2" + return True + return False + + xfail_py311_pyside2 = pytest.mark.xfail( - sys.version_info[:2] == (3, 11) and qt_api.pytest_qt_api == "pyside2", + check_broken_flag_or(), reason="Fails to OR mask flags", ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/tests/test_wait_signal.py new/pytest-qt-4.3.1/tests/test_wait_signal.py --- old/pytest-qt-4.2.0/tests/test_wait_signal.py 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/tests/test_wait_signal.py 2023-12-22 21:55:58.000000000 +0100 @@ -617,7 +617,7 @@ @staticmethod def get_signal_from_code(signaller, code): """Converts a code such as 'A1' to a signal (signaller.signal_args for example).""" - assert type(code) == str and len(code) == 2 + assert type(code) is str and len(code) == 2 signal = signaller.signal_args if code[0] == "A" else signaller.signal_args_2 return signal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-qt-4.2.0/tox.ini new/pytest-qt-4.3.1/tox.ini --- old/pytest-qt-4.2.0/tox.ini 2022-10-25 17:01:03.000000000 +0200 +++ new/pytest-qt-4.3.1/tox.ini 2023-12-22 21:55:58.000000000 +0100 @@ -1,5 +1,5 @@ [tox] -envlist = py{37,38,39,310}-{pyqt5,pyside2,pyside6,pyqt6}, linting +envlist = py{38,39,310,311,312}-{pyqt5,pyside2,pyside6,pyqt6} [testenv] deps= @@ -9,7 +9,7 @@ pyqt5: pyqt5 pyqt6: pyqt6 commands= - pytest {posargs} + pytest --color=yes {posargs} setenv= pyside6: PYTEST_QT_API=pyside6 pyside2: PYTEST_QT_API=pyside2 @@ -17,12 +17,10 @@ pyqt6: PYTEST_QT_API=pyqt6 QT_QPA_PLATFORM=offscreen -passenv=DISPLAY XAUTHORITY USER USERNAME COLUMNS - -[testenv:linting] -skip_install = True -deps = pre-commit -commands = pre-commit run --all-files --show-diff-on-failure +passenv= + DISPLAY + XAUTHORITY + COLUMNS [testenv:docs] usedevelop = True