diff --git a/docs/conf.py b/docs/conf.py index 816b5b9..02f7925 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,6 +10,8 @@ # All configuration values have a default; values that are commented out # serve to show the default. +from __future__ import annotations + import sys import os diff --git a/pyproject.toml b/pyproject.toml index e0bef18..2f66b00 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,11 +65,15 @@ select = [ "W", # pycodestyle warnings "F", # pyflakes "UP", # pyupgrade + "I002", # missing-required-import ] ignore = [ "UP031", # printf-string-formatting, not enforced by pyupgrade "UP032", # f-string, not enforced by pyupgrade ] +[tool.ruff.lint.isort] +required-imports = ["from __future__ import annotations"] + [tool.ruff.lint.pycodestyle] max-line-length = 120 diff --git a/src/pytestqt/__init__.py b/src/pytestqt/__init__.py index 66b5a5f..688f95d 100644 --- a/src/pytestqt/__init__.py +++ b/src/pytestqt/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + # _version is automatically generated by setuptools_scm from pytestqt._version import version diff --git a/src/pytestqt/exceptions.py b/src/pytestqt/exceptions.py index 90b7f7c..bdc72da 100644 --- a/src/pytestqt/exceptions.py +++ b/src/pytestqt/exceptions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import functools import sys import traceback @@ -33,7 +35,7 @@ def capture_exceptions() -> Iterator[CapturedExceptions]: def _except_hook( type_: type[BaseException], value: BaseException, - tback: Optional[TracebackType], + tback: TracebackType | None, exceptions: CapturedExceptions, ) -> None: """Hook functions installed by _QtExceptionCaptureManager""" @@ -47,7 +49,7 @@ class _QtExceptionCaptureManager: """ def __init__(self) -> None: - self.old_hook: Optional[ExceptHook] = None + self.old_hook: ExceptHook | None = None self.exceptions: CapturedExceptions = [] def start(self) -> None: diff --git a/src/pytestqt/logging.py b/src/pytestqt/logging.py index 5ae4e0d..10a701b 100644 --- a/src/pytestqt/logging.py +++ b/src/pytestqt/logging.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import namedtuple from contextlib import contextmanager import datetime diff --git a/src/pytestqt/modeltest.py b/src/pytestqt/modeltest.py index 6e364b4..e60609d 100644 --- a/src/pytestqt/modeltest.py +++ b/src/pytestqt/modeltest.py @@ -41,6 +41,8 @@ # # $QT_END_LICENSE$ +from __future__ import annotations + import enum import collections diff --git a/src/pytestqt/plugin.py b/src/pytestqt/plugin.py index 7264616..207351f 100644 --- a/src/pytestqt/plugin.py +++ b/src/pytestqt/plugin.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import warnings import pytest diff --git a/src/pytestqt/qt_compat.py b/src/pytestqt/qt_compat.py index d25e0a4..4f3e6bf 100644 --- a/src/pytestqt/qt_compat.py +++ b/src/pytestqt/qt_compat.py @@ -8,6 +8,8 @@ Based on from https://github.com/epage/PythonUtils. """ +from __future__ import annotations + from collections import namedtuple, OrderedDict import os import sys diff --git a/src/pytestqt/qtbot.py b/src/pytestqt/qtbot.py index fa24d3e..c62b73c 100644 --- a/src/pytestqt/qtbot.py +++ b/src/pytestqt/qtbot.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections.abc import Callable import contextlib from types import TracebackType @@ -6,7 +8,6 @@ from typing import ( TYPE_CHECKING, Literal, - Optional, Any, cast, ) @@ -190,7 +191,7 @@ def __init__(self, request: FixtureRequest) -> None: self.wait_until = self.waitUntil self.wait_callback = self.waitCallback - def _should_raise(self, raising_arg: Optional[bool]) -> bool: + def _should_raise(self, raising_arg: bool | None) -> bool: ini_val = self._request.config.getini("qt_default_raising") if raising_arg is not None: @@ -201,7 +202,7 @@ def _should_raise(self, raising_arg: Optional[bool]) -> bool: return True def addWidget( - self, widget: QWidget, *, before_close_func: Optional[BeforeCloseFunc] = None + self, widget: QWidget, *, before_close_func: BeforeCloseFunc | None = None ) -> None: """ Adds a widget to be tracked by this bot. This is not required, but will ensure that the @@ -222,7 +223,7 @@ def addWidget( def waitActive( self, widget: QWidget, *, timeout: int = 5000 - ) -> "_WaitWidgetContextManager": + ) -> _WaitWidgetContextManager: """ Context manager that waits for ``timeout`` milliseconds or until the window is active. If window is not exposed within ``timeout`` milliseconds, raise @@ -251,7 +252,7 @@ def waitActive( def waitExposed( self, widget: QWidget, *, timeout: int = 5000 - ) -> "_WaitWidgetContextManager": + ) -> _WaitWidgetContextManager: """ Context manager that waits for ``timeout`` milliseconds or until the window is exposed. If the window is not exposed within ``timeout`` milliseconds, raise @@ -336,9 +337,9 @@ def waitSignal( signal: SignalInstance, *, timeout: int = 5000, - raising: Optional[bool] = None, - check_params_cb: Optional[CheckParamsCb] = None, - ) -> "SignalBlocker": + raising: bool | None = None, + check_params_cb: CheckParamsCb | None = None, + ) -> SignalBlocker: """ .. versionadded:: 1.2 @@ -404,10 +405,10 @@ def waitSignals( signals: list[SignalInstance], *, timeout: int = 5000, - raising: Optional[bool] = None, - check_params_cbs: Optional[list[CheckParamsCb]] = None, + raising: bool | None = None, + check_params_cbs: list[CheckParamsCb] | None = None, order: WaitSignalsOrder = "none", - ) -> "MultiSignalBlocker": + ) -> MultiSignalBlocker: """ .. versionadded:: 1.4 @@ -526,7 +527,7 @@ def assertNotEmitted( spy.assert_not_emitted() def waitUntil( - self, callback: Callable[[], Optional[bool]], *, timeout: int = 5000 + self, callback: Callable[[], bool | None], *, timeout: int = 5000 ) -> None: """ .. versionadded:: 2.0 @@ -599,8 +600,8 @@ def timed_out(): self.wait(10) def waitCallback( - self, *, timeout: int = 5000, raising: Optional[bool] = None - ) -> "CallbackBlocker": + self, *, timeout: int = 5000, raising: bool | None = None + ) -> CallbackBlocker: """ .. versionadded:: 3.1 @@ -642,7 +643,7 @@ def waitCallback( return blocker @contextlib.contextmanager - def captureExceptions(self) -> Iterator["CapturedExceptions"]: + def captureExceptions(self) -> Iterator[CapturedExceptions]: """ .. versionadded:: 2.1 @@ -667,7 +668,7 @@ def captureExceptions(self) -> Iterator["CapturedExceptions"]: yield exceptions def screenshot( - self, widget: QWidget, suffix: str = "", region: Optional[QRect] = None + self, widget: QWidget, suffix: str = "", region: QRect | None = None ) -> Path: """ .. versionadded:: 4.1 @@ -783,7 +784,7 @@ def _add_widget( item: pytest.Item, widget: QWidget, *, - before_close_func: Optional[BeforeCloseFunc] = None, + before_close_func: BeforeCloseFunc | None = None, ) -> None: """ Register a widget into the given pytest item for later closing. @@ -849,9 +850,9 @@ def __enter__(self) -> Self: def __exit__( self, - exc_type: Optional[type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType], + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, ) -> None: __tracebackhide__ = True try: diff --git a/src/pytestqt/utils.py b/src/pytestqt/utils.py index b9e0a37..d479e63 100644 --- a/src/pytestqt/utils.py +++ b/src/pytestqt/utils.py @@ -1,9 +1,10 @@ -from typing import Optional +from __future__ import annotations + import pytest -def get_marker(item: pytest.Item, name: str) -> Optional["pytest.Mark"]: +def get_marker(item: pytest.Item, name: str) -> pytest.Mark | None: """Get a marker from a pytest item. This is here in order to stay compatible with pytest < 3.6 and not produce diff --git a/src/pytestqt/wait_signal.py b/src/pytestqt/wait_signal.py index 8361d44..11a0edd 100644 --- a/src/pytestqt/wait_signal.py +++ b/src/pytestqt/wait_signal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections.abc import Callable import functools import dataclasses diff --git a/tests/conftest.py b/tests/conftest.py index e09ea8b..52978e7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import time import pytest diff --git a/tests/test_basics.py b/tests/test_basics.py index 5f9fa01..7868171 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import weakref import pytest diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 9262804..ca28f0b 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sys import pytest diff --git a/tests/test_logging.py b/tests/test_logging.py index 4a772ce..b76e2e0 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import datetime import pytest diff --git a/tests/test_modeltest.py b/tests/test_modeltest.py index 4c9084b..cf73fbe 100644 --- a/tests/test_modeltest.py +++ b/tests/test_modeltest.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pytest from pytestqt.qt_compat import qt_api diff --git a/tests/test_qtbot_pep8_aliases.py b/tests/test_qtbot_pep8_aliases.py index e208a9d..8dc0cd9 100644 --- a/tests/test_qtbot_pep8_aliases.py +++ b/tests/test_qtbot_pep8_aliases.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import inspect from collections.abc import Iterator from unittest.mock import MagicMock diff --git a/tests/test_qtest_proxies.py b/tests/test_qtest_proxies.py index bae015c..486d85b 100644 --- a/tests/test_qtest_proxies.py +++ b/tests/test_qtest_proxies.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pytest from pytestqt.qt_compat import qt_api diff --git a/tests/test_screenshot.py b/tests/test_screenshot.py index 4032873..11439c1 100644 --- a/tests/test_screenshot.py +++ b/tests/test_screenshot.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pathlib import pytest diff --git a/tests/test_wait_signal.py b/tests/test_wait_signal.py index f498a76..453f95a 100644 --- a/tests/test_wait_signal.py +++ b/tests/test_wait_signal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import functools import fnmatch diff --git a/tests/test_wait_until.py b/tests/test_wait_until.py index 9884ffa..5816fcf 100644 --- a/tests/test_wait_until.py +++ b/tests/test_wait_until.py @@ -1,5 +1,6 @@ +from __future__ import annotations + from collections.abc import Callable, Iterator -from typing import Optional import pytest @@ -30,7 +31,7 @@ def ticks(self) -> int: def test_wait_until( qtbot: QtBot, - wait_4_ticks_callback: Callable[[], Optional[bool]], + wait_4_ticks_callback: Callable[[], bool | None], tick_counter: Counter, ) -> None: tick_counter.start(100) @@ -40,7 +41,7 @@ def test_wait_until( def test_wait_until_timeout( qtbot: QtBot, - wait_4_ticks_callback: Callable[[], Optional[bool]], + wait_4_ticks_callback: Callable[[], bool | None], tick_counter: Counter, ) -> None: tick_counter.start(200) @@ -61,7 +62,7 @@ def test_pep8_alias(qtbot: QtBot) -> None: @pytest.fixture(params=["predicate", "assert"]) def wait_4_ticks_callback( request: pytest.FixtureRequest, tick_counter: Counter -) -> Callable[[], Optional[bool]]: +) -> Callable[[], bool | None]: """Parametrized fixture which returns the two possible callback methods that can be passed to ``waitUntil``: predicate and assertion. """