From 2f5377acb378be034c24e3b21742f0c3e3283649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Schoentgen?= Date: Tue, 3 Sep 2024 22:49:14 +0200 Subject: [PATCH] Enable OS specific Mypy checks (#1064) * Enable OS specific Mypy checks It would have helped to catch #1062 before the release. * ci: split & improve --- .github/workflows/tests.yml | 57 +++++++++++++++----------------- changelog.rst | 3 +- src/watchdog/observers/kqueue.py | 8 ++--- src/watchdog/observers/winapi.py | 12 +++---- src/watchdog/tricks/__init__.py | 2 +- tox.ini | 19 +++++++++-- 6 files changed, 56 insertions(+), 45 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index df3f0ad1..27a01252 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,20 +11,35 @@ concurrency: cancel-in-progress: true jobs: + quality: + name: 🧑‍🏭 Quality & Docs + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + cache: pip + + - name: Install dependencies + run: python -m pip install tox + + - name: Run linters + run: python -m tox -q -e types,lint + + - name: Build the documentation + run: python -m tox -q -e docs + tox: name: ${{ matrix.tox.name }} ${{ matrix.os.emoji }} ${{ matrix.os.name }} ${{ matrix.python }} runs-on: ${{ matrix.os.runs-on }} - timeout-minutes: ${{ matrix.tox.timeout }} + timeout-minutes: 15 strategy: fail-fast: false matrix: - tox: - - name: Types - environment: types - timeout: 15 - - name: Test - environment: py - timeout: 15 os: - name: Linux matrix: linux @@ -45,25 +60,6 @@ jobs: - "3.12" - "3.13-dev" - "pypy-3.9" - include: - - tox: - name: Linter - environment: lint - timeout: 5 - python: "3.11" - os: - name: Linux - emoji: 🐧 - runs-on: [ubuntu-latest] - - tox: - name: Docs - environment: docs - timeout: 5 - python: "3.11" - os: - name: Linux - emoji: 🐧 - runs-on: [ubuntu-latest] exclude: - os: matrix: macos @@ -72,7 +68,6 @@ jobs: matrix: windows python: "pypy-3.9" - steps: - name: Checkout uses: actions/checkout@v4 @@ -83,8 +78,8 @@ jobs: python-version: ${{ matrix.python }} cache: pip - - name: Install test dependencies + - name: Install dependencies run: python -m pip install tox - - name: Run ${{ matrix.tox.name }} in tox - run: python -m tox -q -e ${{ matrix.tox.environment }} + - name: Run tests + run: python -m tox -q -e py diff --git a/changelog.rst b/changelog.rst index 95c4a26c..db29f2db 100644 --- a/changelog.rst +++ b/changelog.rst @@ -8,8 +8,9 @@ Changelog 2024-xx-xx • `full history `__ +- Enable OS specific Mypy checks (`#1064 `__) - [watchmedo] Fix ``tricks`` argument type of ``schedule_tricks()`` (`#1063 `__) -- Thanks to our beloved contributors: @BoboTiG, @gnought +- Thanks to our beloved contributors: @gnought, @BoboTiG 5.0.1 ~~~~~ diff --git a/src/watchdog/observers/kqueue.py b/src/watchdog/observers/kqueue.py index 9f049ae6..2f9d0c6f 100644 --- a/src/watchdog/observers/kqueue.py +++ b/src/watchdog/observers/kqueue.py @@ -121,23 +121,23 @@ def absolute_path(path: bytes | str) -> bytes | str: def is_deleted(kev: select.kevent) -> bool: """Determines whether the given kevent represents deletion.""" - return kev.fflags & select.KQ_NOTE_DELETE + return kev.fflags & select.KQ_NOTE_DELETE > 0 def is_modified(kev: select.kevent) -> bool: """Determines whether the given kevent represents modification.""" fflags = kev.fflags - return (fflags & select.KQ_NOTE_EXTEND) or (fflags & select.KQ_NOTE_WRITE) + return (fflags & select.KQ_NOTE_EXTEND > 0) or (fflags & select.KQ_NOTE_WRITE > 0) def is_attrib_modified(kev: select.kevent) -> bool: """Determines whether the given kevent represents attribute modification.""" - return kev.fflags & select.KQ_NOTE_ATTRIB + return kev.fflags & select.KQ_NOTE_ATTRIB > 0 def is_renamed(kev: select.kevent) -> bool: """Determines whether the given kevent represents movement.""" - return kev.fflags & select.KQ_NOTE_RENAME + return kev.fflags & select.KQ_NOTE_RENAME > 0 class KeventDescriptorSet: diff --git a/src/watchdog/observers/winapi.py b/src/watchdog/observers/winapi.py index 2e929bb7..1247e1f8 100644 --- a/src/watchdog/observers/winapi.py +++ b/src/watchdog/observers/winapi.py @@ -83,25 +83,25 @@ class OVERLAPPED(ctypes.Structure): def _errcheck_bool(value: Any | None, func: Any, args: Any) -> Any: if not value: - raise ctypes.WinError() + raise ctypes.WinError() # type: ignore[attr-defined] return args def _errcheck_handle(value: Any | None, func: Any, args: Any) -> Any: if not value: - raise ctypes.WinError() + raise ctypes.WinError() # type: ignore[attr-defined] if value == INVALID_HANDLE_VALUE: - raise ctypes.WinError() + raise ctypes.WinError() # type: ignore[attr-defined] return args def _errcheck_dword(value: Any | None, func: Any, args: Any) -> Any: if value == 0xFFFFFFFF: - raise ctypes.WinError() + raise ctypes.WinError() # type: ignore[attr-defined] return args -kernel32 = ctypes.WinDLL("kernel32") +kernel32 = ctypes.WinDLL("kernel32") # type: ignore[attr-defined] ReadDirectoryChangesW = kernel32.ReadDirectoryChangesW ReadDirectoryChangesW.restype = BOOL @@ -334,7 +334,7 @@ def read_directory_changes(handle: HANDLE, path: str, *, recursive: bool) -> tup None, ) except OSError as e: - if e.winerror == ERROR_OPERATION_ABORTED: + if e.winerror == ERROR_OPERATION_ABORTED: # type: ignore[attr-defined] return event_buffer.raw, 0 # Handle the case when the root path is deleted diff --git a/src/watchdog/tricks/__init__.py b/src/watchdog/tricks/__init__.py index cbec37ed..0a8fc49c 100644 --- a/src/watchdog/tricks/__init__.py +++ b/src/watchdog/tricks/__init__.py @@ -287,4 +287,4 @@ def kill_process(pid: int, stop_signal: int) -> None: else: def kill_process(pid: int, stop_signal: int) -> None: - os.killpg(os.getpgid(pid), stop_signal) # type: ignore[attr-defined] + os.killpg(os.getpgid(pid), stop_signal) diff --git a/tox.ini b/tox.ini index 39ddbd28..0080220d 100644 --- a/tox.ini +++ b/tox.ini @@ -40,5 +40,20 @@ usedevelop = true deps = -r requirements-tests.txt commands = - # "--platform win32" to not fail on ctypes.windll (it does not affect the overall check on other OSes) - mypy --platform win32 docs/source/examples src + # General + python -m mypy docs/source/examples + python -m mypy src + + # OS specific + python -m mypy --platform darwin --disable-error-code unused-ignore \ + src/watchdog/observers/fsevents.py \ + src/watchdog/observers/fsevents2.py + python -m mypy --platform freebsd --disable-error-code unused-ignore \ + src/watchdog/observers/kqueue.py + python -m mypy --platform linux --disable-error-code unused-ignore \ + src/watchdog/observers/inotify.py \ + src/watchdog/observers/inotify_buffer.py \ + src/watchdog/observers/inotify_c.py + python -m mypy --platform win32 --disable-error-code unused-ignore \ + src/watchdog/observers/read_directory_changes.py \ + src/watchdog/observers/winapi.py