Skip to content

Commit

Permalink
Merge branch 'master' into add-attributes-only
Browse files Browse the repository at this point in the history
  • Loading branch information
BoboTiG authored Aug 11, 2024
2 parents 550ec1d + 2872c7e commit 6c8b6c7
Show file tree
Hide file tree
Showing 31 changed files with 160 additions and 137 deletions.
16 changes: 8 additions & 8 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ task:
image_family: freebsd-12-2

install_script:
- pkg install -y python38 py38-sqlite3
- pkg install -y python39 py39-sqlite3
# Print the Python version, only to be sure we are running the version we want
- python3.8 -c 'import platform; print("Python", platform.python_version())'
- python3.9 -c 'import platform; print("Python", platform.python_version())'
# Check SQLite3 is installed
- python3.8 -c 'import sqlite3; print("SQLite3", sqlite3.version)'
- python3.9 -c 'import sqlite3; print("SQLite3", sqlite3.version)'
setup_script:
- python3.8 -m ensurepip
- python3.8 -m pip install -U pip
- python3.8 -m pip install -r requirements-tests.txt
- python3.9 -m ensurepip
- python3.9 -m pip install -U pip
- python3.9 -m pip install -r requirements-tests.txt
lint_script:
- python3.8 -m ruff src
- python3.9 -m ruff src
tests_script:
- python3.8 -bb -m pytest tests
- python3.9 -bb -m pytest tests
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Language aware diff headers
# https://tekin.co.uk/2020/10/better-git-diff-output-for-ruby-python-elixir-and-more
# https://gist.github.com/tekin/12500956bd56784728e490d8cef9cb81
# https://github.com/git/git/blob/master/userdiff.c
*.c diff=cpp
*.py diff=python
1 change: 0 additions & 1 deletion .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ jobs:
- name: Build wheels
run: python -m cibuildwheel
env:
CIBW_SKIP: "cp36-*" # skip 3.6 wheels
CIBW_ARCHS_MACOS: "x86_64 universal2 arm64"
- name: Artifacts list
run: ls -l wheelhouse
Expand Down
9 changes: 1 addition & 8 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,11 @@ jobs:
emoji: 🪟
runs-on: [windows-latest]
python:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "pypy-3.8"
- "3.13-dev"
- "pypy-3.9"
include:
- tox:
Expand All @@ -73,15 +72,9 @@ jobs:
emoji: 🐧
runs-on: [ubuntu-latest]
exclude:
- os:
matrix: macos
python: "pypy-3.8"
- os:
matrix: macos
python: "pypy-3.9"
- os:
matrix: windows
python: "pypy-3.8"
- os:
matrix: windows
python: "pypy-3.9"
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Watchdog

Python API and shell utilities to monitor file system events.

Works on 3.8+.
Works on 3.9+.

Example API Usage
-----------------
Expand Down Expand Up @@ -211,7 +211,7 @@ appropriate observer like in the example above, do::
Dependencies
------------

1. Python 3.8 or above.
1. Python 3.9 or above.
2. XCode_ (only on macOS when installing from sources)
3. PyYAML_ (only for ``watchmedo``)

Expand Down
24 changes: 21 additions & 3 deletions changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,32 @@
Changelog
---------

4.0.2 (dev)
5.0.0 (dev)
~~~~~~~~~~~

2024-xx-xx • `full history <https://github.com/gorakhargosh/watchdog/compare/v4.0.1...HEAD>`__
2024-xx-xx • `full history <https://github.com/gorakhargosh/watchdog/compare/v4.0.2...HEAD>`__

- Drop support for Python 3.8 (`#1055 <https://github.com/gorakhargosh/watchdog/pull/1055>`__)
- [core] Enable ``disallow_untyped_calls`` Mypy rule (`#1055 <https://github.com/gorakhargosh/watchdog/pull/1055>`__)
- [core] Deleted the ``BaseObserverSubclassCallable`` class. Use ``type[BaseObserver]`` directly (`#1055 <https://github.com/gorakhargosh/watchdog/pull/1055>`__)
- [inotify] Renamed the ``inotify_event_struct`` class to ``InotifyEventStruct`` (`#1055 <https://github.com/gorakhargosh/watchdog/pull/1055>`__)
- [windows] Renamed the ``FILE_NOTIFY_INFORMATION`` class to ``FileNotifyInformation`` (`#1055 <https://github.com/gorakhargosh/watchdog/pull/1055>`__)
- Thanks to our beloved contributors: @BoboTiG

4.0.2
~~~~~

2024-08-11 • `full history <https://github.com/gorakhargosh/watchdog/compare/v4.0.1...v4.0.2>`__

- Add support for Python 3.13 (`#1052 <https://github.com/gorakhargosh/watchdog/pull/1052>`__)
- [core] Run ``ruff``, apply several fixes (`#1033 <https://github.com/gorakhargosh/watchdog/pull/1033>`__)
- [core] Remove execution rights from ``events.py``
- [documentation] Update ``PatternMatchingEventHandler`` docstrings (`#1048 <https://github.com/gorakhargosh/watchdog/pull/1048>`__)
- [documentation] Simplify the quickstart example (`#1047 <https://github.com/gorakhargosh/watchdog/pull/1047>`__)
- [fsevents] Add missing ``event_filter`` keyword-argument to ``FSEventsObserver.schedule()`` (`#1049 <https://github.com/gorakhargosh/watchdog/pull/1049>`__)
- Thanks to our beloved contributors: @BoboTiG
- [utils] Fix a possible race condition in ``AutoRestartTrick`` (`#1002 <https://github.com/gorakhargosh/watchdog/pull/1002>`__)
- [watchmedo] Remove execution rights from ``watchmedo.py``
- Thanks to our beloved contributors: @BoboTiG, @nbelakovski, @ivg

4.0.1
~~~~~
Expand Down
2 changes: 1 addition & 1 deletion docs/source/global.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.. |author_email| replace:: [email protected]
.. |copyright| replace:: Copyright 2012-2024 Google, Inc & contributors.
.. |project_name| replace:: ``watchdog``
.. |project_version| replace:: 4.0.2
.. |project_version| replace:: 5.0.0

.. _issue tracker: https://github.com/gorakhargosh/watchdog/issues
.. _code repository: https://github.com/gorakhargosh/watchdog
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Watchdog

Python API library and shell utilities to monitor file system events.

Works on 3.8+.
Works on 3.9+.

Directory monitoring made easy with
-----------------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Installation
============
|project_name| requires 3.8+ to work. See a list of :ref:`installation-dependencies`.
|project_name| requires 3.9+ to work. See a list of :ref:`installation-dependencies`.

Installing from PyPI using pip
------------------------------
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ follow_imports = "skip"
# Ensure full coverage
#disallow_untyped_defs = true [TODO]
disallow_incomplete_defs = true
#disallow_untyped_calls = true [TODO]
disallow_untyped_calls = true

# Restrict dynamic typing (a little)
# e.g. `x: List[Any]` or x: List`
Expand All @@ -31,7 +31,7 @@ addopts = """
[tool.ruff]
line-length = 120
indent-width = 4
target-version = "py38"
target-version = "py39"

[tool.ruff.lint]
extend-select = ["ALL"]
Expand All @@ -53,14 +53,14 @@ ignore = [
"FBT",
"FIX",
"ISC001",
"N", # Requires a major version number bump
"N818",
"PERF203", # TODO
"PL",
"PTH", # TODO?
"S",
"TD",
"TRY003",
"UP", # TODO when minimum python version will be 3.10
"UP",
]
fixable = ["ALL"]

Expand Down
2 changes: 1 addition & 1 deletion requirements-tests.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
eventlet
eventlet; python_version < "3.13"
flaky
pytest
pytest-cov
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"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",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: C",
"Topic :: Software Development :: Libraries",
Expand All @@ -154,6 +154,6 @@
"watchmedo = watchdog.watchmedo:main [watchmedo]",
]
},
python_requires=">=3.8",
python_requires=">=3.9",
zip_safe=False,
)
4 changes: 2 additions & 2 deletions src/watchdog/observers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@
from watchdog.utils import UnsupportedLibc, platform

if TYPE_CHECKING:
from watchdog.observers.api import BaseObserverSubclassCallable
from watchdog.observers.api import BaseObserver


def _get_observer_cls() -> BaseObserverSubclassCallable:
def _get_observer_cls() -> type[BaseObserver]:
if platform.is_linux():
with contextlib.suppress(UnsupportedLibc):
from watchdog.observers.inotify import InotifyObserver
Expand Down
6 changes: 1 addition & 5 deletions src/watchdog/observers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import threading
from pathlib import Path

from watchdog.utils import BaseThread, Protocol
from watchdog.utils import BaseThread
from watchdog.utils.bricks import SkipRepeatsQueue

DEFAULT_EMITTER_TIMEOUT = 1 # in seconds.
Expand Down Expand Up @@ -385,7 +385,3 @@ def dispatch_events(self, event_queue):
if handler in self._handlers.get(watch, []):
handler.dispatch(event)
event_queue.task_done()


class BaseObserverSubclassCallable(Protocol):
def __call__(self, timeout: float = ...) -> BaseObserver: ...
12 changes: 6 additions & 6 deletions src/watchdog/observers/fsevents2.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import unicodedata
import warnings
from threading import Thread
from typing import List, Optional, Type
from typing import Optional

# pyobjc
import AppKit
Expand Down Expand Up @@ -83,7 +83,7 @@ class FSEventsQueue(Thread):

def __init__(self, path):
Thread.__init__(self)
self._queue: queue.Queue[Optional[List[NativeEvent]]] = queue.Queue()
self._queue: queue.Queue[Optional[list[NativeEvent]]] = queue.Queue()
self._run_loop = None

if isinstance(path, bytes):
Expand Down Expand Up @@ -125,9 +125,9 @@ def stop(self):
if self._run_loop is not None:
CFRunLoopStop(self._run_loop)

def _callback(self, streamRef, clientCallBackInfo, numEvents, eventPaths, eventFlags, eventIDs):
events = [NativeEvent(path, flags, _id) for path, flags, _id in zip(eventPaths, eventFlags, eventIDs)]
logger.debug("FSEvents callback. Got %d events:", numEvents)
def _callback(self, stream_ref, client_callback_info, num_events, event_paths, event_flags, event_ids):
events = [NativeEvent(path, flags, _id) for path, flags, _id in zip(event_paths, event_flags, event_ids)]
logger.debug("FSEvents callback. Got %d events:", num_events)
for e in events:
logger.debug(e)
self._queue.put(events)
Expand Down Expand Up @@ -198,7 +198,7 @@ def queue_events(self, timeout):
while i < len(events):
event = events[i]

cls: Type[FileSystemEvent]
cls: type[FileSystemEvent]
# For some reason the create and remove flags are sometimes also
# set for rename and modify type events, so let those take
# precedence.
Expand Down
3 changes: 1 addition & 2 deletions src/watchdog/observers/inotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
import logging
import os
import threading
from typing import Type

from watchdog.events import (
DirAttribEvent,
Expand Down Expand Up @@ -143,7 +142,7 @@ def queue_events(self, timeout, full_events=False):
if event is None:
return

cls: Type[FileSystemEvent]
cls: type[FileSystemEvent]
if isinstance(event, tuple):
move_from, move_to = event
src_path = self._decode_path(move_from.src_path)
Expand Down
4 changes: 2 additions & 2 deletions src/watchdog/observers/inotify_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from __future__ import annotations

import logging
from typing import TYPE_CHECKING, List, Tuple, Union
from typing import TYPE_CHECKING, Union

from watchdog.observers.inotify_c import Inotify, InotifyEvent
from watchdog.utils import BaseThread
Expand Down Expand Up @@ -54,7 +54,7 @@ def close(self):

def _group_events(self, event_list):
"""Group any matching move events"""
grouped: List[Union[InotifyEvent, Tuple[InotifyEvent, InotifyEvent]]] = []
grouped: list[Union[InotifyEvent, tuple[InotifyEvent, InotifyEvent]]] = []
for inotify_event in event_list:
logger.debug("in-event %s", inotify_event)

Expand Down
4 changes: 2 additions & 2 deletions src/watchdog/observers/inotify_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class InotifyConstants:
)


class inotify_event_struct(ctypes.Structure):
class InotifyEventStruct(ctypes.Structure):
"""Structure representation of the inotify_event structure
(used in buffer size calculations)::
Expand All @@ -135,7 +135,7 @@ class inotify_event_struct(ctypes.Structure):
)


EVENT_SIZE = ctypes.sizeof(inotify_event_struct)
EVENT_SIZE = ctypes.sizeof(InotifyEventStruct)
DEFAULT_NUM_EVENTS = 2048
DEFAULT_EVENT_BUFFER_SIZE = DEFAULT_NUM_EVENTS * (EVENT_SIZE + 16)

Expand Down
10 changes: 5 additions & 5 deletions src/watchdog/observers/read_directory_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ class WindowsApiEmitter(EventEmitter):
def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT, event_filter=None):
super().__init__(event_queue, watch, timeout, event_filter)
self._lock = threading.Lock()
self._handle = None
self._whandle = None

def on_thread_start(self):
self._handle = get_directory_handle(self.watch.path)
self._whandle = get_directory_handle(self.watch.path)

if platform.python_implementation() == "PyPy":

Expand All @@ -62,11 +62,11 @@ def start(self):
sleep(0.01)

def on_thread_stop(self):
if self._handle:
close_directory_handle(self._handle)
if self._whandle:
close_directory_handle(self._whandle)

def _read_events(self):
return read_events(self._handle, self.watch.path, self.watch.is_recursive)
return read_events(self._whandle, self.watch.path, self.watch.is_recursive)

def queue_events(self, timeout):
winapi_events = self._read_events()
Expand Down
Loading

0 comments on commit 6c8b6c7

Please sign in to comment.