1""":module: watchdog.observers
2:synopsis: Observer that picks a native implementation if available.
3:author: [email protected] (Yesudeep Mangalapilly)
4:author: [email protected] (Mickaël Schoentgen)
5
6Classes
7=======
8.. autoclass:: Observer
9   :members:
10   :show-inheritance:
11   :inherited-members:
12
13Observer thread that schedules watching directories and dispatches
14calls to event handlers.
15
16You can also import platform specific classes directly and use it instead
17of :class:`Observer`.  Here is a list of implemented observer classes.:
18
19============== ================================ ==============================
20Class          Platforms                        Note
21============== ================================ ==============================
22|Inotify|      Linux 2.6.13+                    ``inotify(7)`` based observer
23|FSEvents|     macOS                            FSEvents based observer
24|Kqueue|       macOS and BSD with kqueue(2)     ``kqueue(2)`` based observer
25|WinApi|       Microsoft Windows                Windows API-based observer
26|Polling|      Any                              fallback implementation
27============== ================================ ==============================
28
29.. |Inotify|     replace:: :class:`.inotify.InotifyObserver`
30.. |FSEvents|    replace:: :class:`.fsevents.FSEventsObserver`
31.. |Kqueue|      replace:: :class:`.kqueue.KqueueObserver`
32.. |WinApi|      replace:: :class:`.read_directory_changes.WindowsApiObserver`
33.. |Polling|     replace:: :class:`.polling.PollingObserver`
34
35"""
36
37from __future__ import annotations
38
39import contextlib
40import warnings
41from typing import TYPE_CHECKING, Protocol
42
43from watchdog.utils import UnsupportedLibcError, platform
44
45if TYPE_CHECKING:
46    from watchdog.observers.api import BaseObserver
47
48
49class ObserverType(Protocol):
50    def __call__(self, *, timeout: float = ...) -> BaseObserver: ...
51
52
53def _get_observer_cls() -> ObserverType:
54    if platform.is_linux():
55        with contextlib.suppress(UnsupportedLibcError):
56            from watchdog.observers.inotify import InotifyObserver
57
58            return InotifyObserver
59    elif platform.is_darwin():
60        try:
61            from watchdog.observers.fsevents import FSEventsObserver
62        except Exception:
63            try:
64                from watchdog.observers.kqueue import KqueueObserver
65            except Exception:
66                warnings.warn("Failed to import fsevents and kqueue. Fall back to polling.", stacklevel=1)
67            else:
68                warnings.warn("Failed to import fsevents. Fall back to kqueue", stacklevel=1)
69                return KqueueObserver
70        else:
71            return FSEventsObserver
72    elif platform.is_windows():
73        try:
74            from watchdog.observers.read_directory_changes import WindowsApiObserver
75        except Exception:
76            warnings.warn("Failed to import `read_directory_changes`. Fall back to polling.", stacklevel=1)
77        else:
78            return WindowsApiObserver
79    elif platform.is_bsd():
80        from watchdog.observers.kqueue import KqueueObserver
81
82        return KqueueObserver
83
84    from watchdog.observers.polling import PollingObserver
85
86    return PollingObserver
87
88
89Observer = _get_observer_cls()
90
91__all__ = ["Observer"]
92