From 8462e8e3a67e92119c191245adbcd6db4572286d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Clgen=20Sar=C4=B1kavak?= Date: Sat, 7 Mar 2026 12:31:56 +0300 Subject: [PATCH] Fix the target-version value in ruff config Relates to #307 --- pyproject.toml | 2 +- tests/conftest.py | 4 ++-- watchfiles/cli.py | 6 +++--- watchfiles/filters.py | 3 ++- watchfiles/main.py | 15 ++++++++------- watchfiles/run.py | 25 +++++++++++++------------ 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0c23a3e3..93e6f5ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,7 +89,7 @@ omit = ["*/__main__.py"] [tool.ruff] line-length = 120 -target-version = "py38" +target-version = "py39" lint.mccabe = { max-complexity = 14 } lint.extend-select = ["Q", "RUF100", "C90", "UP", "I"] lint.flake8-quotes = { inline-quotes = "single", multiline-quotes = "double" } diff --git a/tests/conftest.py b/tests/conftest.py index ed9fed0b..4ea76fd2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,7 @@ from pathlib import Path from threading import Thread from time import sleep, time -from typing import TYPE_CHECKING, Any, List, Set, Tuple +from typing import TYPE_CHECKING, Any import pytest @@ -61,7 +61,7 @@ def start(path: Path): t.join() -ChangesType = List[Set[Tuple[int, str]]] +ChangesType = list[set[tuple[int, str]]] class MockRustNotify: diff --git a/watchfiles/cli.py b/watchfiles/cli.py index f1e1ddd5..6a5c87ef 100644 --- a/watchfiles/cli.py +++ b/watchfiles/cli.py @@ -5,7 +5,7 @@ import sys from pathlib import Path from textwrap import dedent -from typing import Any, Callable, List, Optional, Tuple, Union, cast +from typing import Any, Callable, Optional, Union, cast from . import Change from .filters import BaseFilter, DefaultFilter, PythonFilter @@ -196,8 +196,8 @@ def import_exit(function_path: str) -> Any: def build_filter( filter_name: str, ignore_paths_str: Optional[str] -) -> Tuple[Union[None, DefaultFilter, Callable[[Change, str], bool]], str]: - ignore_paths: List[Path] = [] +) -> tuple[Union[None, DefaultFilter, Callable[[Change, str], bool]], str]: + ignore_paths: list[Path] = [] if ignore_paths_str: ignore_paths = [Path(p).resolve() for p in ignore_paths_str.split(',')] diff --git a/watchfiles/filters.py b/watchfiles/filters.py index d97dfe87..f04ec605 100644 --- a/watchfiles/filters.py +++ b/watchfiles/filters.py @@ -1,8 +1,9 @@ import logging import os import re +from collections.abc import Sequence from pathlib import Path -from typing import TYPE_CHECKING, Optional, Sequence, Union +from typing import TYPE_CHECKING, Optional, Union __all__ = 'BaseFilter', 'DefaultFilter', 'PythonFilter' logger = logging.getLogger('watchfiles.watcher') diff --git a/watchfiles/main.py b/watchfiles/main.py index 5af1363f..eae31f55 100644 --- a/watchfiles/main.py +++ b/watchfiles/main.py @@ -2,9 +2,10 @@ import os import sys import warnings +from collections.abc import AsyncGenerator, Generator from enum import IntEnum from pathlib import Path -from typing import TYPE_CHECKING, AsyncGenerator, Callable, Generator, Optional, Set, Tuple, Union +from typing import TYPE_CHECKING, Callable, Optional, Union import anyio @@ -31,7 +32,7 @@ def raw_str(self) -> str: return self.name -FileChange = Tuple[Change, str] +FileChange = tuple[Change, str] """ A tuple representing a file change, first element is a [`Change`][watchfiles.Change] member, second is the path of the file or directory that changed. @@ -63,7 +64,7 @@ def watch( poll_delay_ms: int = 300, recursive: bool = True, ignore_permission_denied: Optional[bool] = None, -) -> Generator[Set[FileChange], None, None]: +) -> Generator[set[FileChange], None, None]: """ Watch one or more paths and yield a set of changes whenever files change. @@ -164,7 +165,7 @@ async def awatch( # C901 poll_delay_ms: int = 300, recursive: bool = True, ignore_permission_denied: Optional[bool] = None, -) -> AsyncGenerator[Set[FileChange], None]: +) -> AsyncGenerator[set[FileChange], None]: """ Asynchronous equivalent of [`watch`][watchfiles.watch] using threads to wait for changes. Arguments match those of [`watch`][watchfiles.watch] except `stop_event`. @@ -289,8 +290,8 @@ async def stop_soon(): def _prep_changes( - raw_changes: Set[Tuple[int, str]], watch_filter: Optional[Callable[[Change, str], bool]] -) -> Set[FileChange]: + raw_changes: set[tuple[int, str]], watch_filter: Optional[Callable[[Change, str], bool]] +) -> set[FileChange]: # if we wanted to be really snazzy, we could move this into rust changes = {(Change(change), path) for change, path in raw_changes} if watch_filter: @@ -298,7 +299,7 @@ def _prep_changes( return changes -def _log_changes(changes: Set[FileChange]) -> None: +def _log_changes(changes: set[FileChange]) -> None: if logger.isEnabledFor(logging.INFO): # pragma: no branch count = len(changes) plural = '' if count == 1 else 's' diff --git a/watchfiles/run.py b/watchfiles/run.py index f1d589ed..65d20917 100644 --- a/watchfiles/run.py +++ b/watchfiles/run.py @@ -7,12 +7,13 @@ import signal import subprocess import sys +from collections.abc import Generator from importlib import import_module from multiprocessing import get_context from multiprocessing.context import SpawnProcess from pathlib import Path from time import sleep -from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, List, Optional, Set, Tuple, Union +from typing import TYPE_CHECKING, Any, Callable, Optional, Union import anyio @@ -29,10 +30,10 @@ def run_process( *paths: Union[Path, str], target: Union[str, Callable[..., Any]], - args: Tuple[Any, ...] = (), - kwargs: Optional[Dict[str, Any]] = None, + args: tuple[Any, ...] = (), + kwargs: Optional[dict[str, Any]] = None, target_type: "Literal['function', 'command', 'auto']" = 'auto', - callback: Optional[Callable[[Set[FileChange]], None]] = None, + callback: Optional[Callable[[set[FileChange]], None]] = None, watch_filter: Optional[Callable[[Change, str], bool]] = DefaultFilter(), grace_period: float = 0, debounce: int = 1_600, @@ -157,10 +158,10 @@ def foobar(a, b, c): async def arun_process( *paths: Union[Path, str], target: Union[str, Callable[..., Any]], - args: Tuple[Any, ...] = (), - kwargs: Optional[Dict[str, Any]] = None, + args: tuple[Any, ...] = (), + kwargs: Optional[dict[str, Any]] = None, target_type: "Literal['function', 'command', 'auto']" = 'auto', - callback: Optional[Callable[[Set[FileChange]], Any]] = None, + callback: Optional[Callable[[set[FileChange]], Any]] = None, watch_filter: Optional[Callable[[Change, str], bool]] = DefaultFilter(), grace_period: float = 0, debounce: int = 1_600, @@ -239,7 +240,7 @@ async def main(): spawn_context = get_context('spawn') -def split_cmd(cmd: str) -> List[str]: +def split_cmd(cmd: str) -> list[str]: import platform posix = platform.uname().system.lower() != 'windows' @@ -249,9 +250,9 @@ def split_cmd(cmd: str) -> List[str]: def start_process( target: Union[str, Callable[..., Any]], target_type: "Literal['function', 'command']", - args: Tuple[Any, ...], - kwargs: Optional[Dict[str, Any]], - changes: Optional[Set[FileChange]] = None, + args: tuple[Any, ...], + kwargs: Optional[dict[str, Any]], + changes: Optional[set[FileChange]] = None, ) -> 'CombinedProcess': if changes is None: changes_env_var = '[]' @@ -368,7 +369,7 @@ def exitcode(self) -> Optional[int]: return self._p.returncode -def run_function(function: str, tty_path: Optional[str], args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> None: +def run_function(function: str, tty_path: Optional[str], args: tuple[Any, ...], kwargs: dict[str, Any]) -> None: with set_tty(tty_path): func = import_string(function) func(*args, **kwargs)