def test_file_lifecyle(): start_watching() mkfile(p('a')) touch(p('a')) mv(p('a'), p('b')) rm(p('b')) expect_event(FileCreatedEvent(p('a'))) if not platform.is_windows(): expect_event(DirModifiedEvent(p())) if platform.is_linux(): expect_event(FileClosedEvent(p('a'))) expect_event(DirModifiedEvent(p())) expect_event(FileModifiedEvent(p('a'))) if platform.is_linux(): expect_event(FileClosedEvent(p('a'))) expect_event(DirModifiedEvent(p())) expect_event(FileMovedEvent(p('a'), p('b'))) if not platform.is_windows(): expect_event(DirModifiedEvent(p())) expect_event(DirModifiedEvent(p())) expect_event(FileDeletedEvent(p('b'))) if not platform.is_windows(): expect_event(DirModifiedEvent(p()))
def test_recursive_off(): mkdir(p('dir1')) start_watching(recursive=False) touch(p('dir1', 'a')) with pytest.raises(Empty): event_queue.get(timeout=5) mkfile(p('b')) expect_event(FileCreatedEvent(p('b'))) if not platform.is_windows(): expect_event(DirModifiedEvent(p())) if platform.is_linux(): expect_event(FileClosedEvent(p('b'))) # currently limiting these additional events to macOS only, see https://github.com/gorakhargosh/watchdog/pull/779 if platform.is_darwin(): mkdir(p('dir1', 'dir2')) with pytest.raises(Empty): event_queue.get(timeout=5) mkfile(p('dir1', 'dir2', 'somefile')) with pytest.raises(Empty): event_queue.get(timeout=5) mkdir(p('dir3')) expect_event(DirModifiedEvent(p())) # the contents of the parent directory changed mv(p('dir1', 'dir2', 'somefile'), p('somefile')) expect_event(FileMovedEvent(p('dir1', 'dir2', 'somefile'), p('somefile'))) expect_event(DirModifiedEvent(p())) mv(p('dir1', 'dir2'), p('dir2')) expect_event(DirMovedEvent(p('dir1', 'dir2'), p('dir2'))) expect_event(DirModifiedEvent(p()))
def encode(path): if isinstance(path, str_cls): try: path = path.encode(fs_encoding, 'strict') except (UnicodeEncodeError) as e: if not platform.is_linux(): raise path = path.encode(fs_fallback_encoding, 'strict') return path
def decode(path): if isinstance(path, bytes_cls): try: path = path.decode(fs_encoding, 'strict') except UnicodeDecodeError: if not platform.is_linux(): raise path = path.decode(fs_fallback_encoding, 'strict') return path
def test_modify(): mkfile(p('a')) start_watching() touch(p('a')) expect_event(FileModifiedEvent(p('a'))) if platform.is_linux(): event = event_queue.get(timeout=5)[0] assert event.src_path == p('a') assert isinstance(event, FileClosedEvent)
def start_watching(path=None, use_full_emitter=False): path = p('') if path is None else path global emitter if platform.is_linux() and use_full_emitter: emitter = InotifyFullEmitter(event_queue, ObservedWatch(path, recursive=True)) else: emitter = Emitter(event_queue, ObservedWatch(path, recursive=True)) if platform.is_darwin(): # FSEvents will report old evens (like create for mkdtemp in test # setup. Waiting for a considerable time seems to 'flush' the events. time.sleep(10) emitter.start()
def test_create(): start_watching() open(p('a'), 'a').close() expect_event(FileCreatedEvent(p('a'))) if not platform.is_windows(): expect_event(DirModifiedEvent(p())) if platform.is_linux(): event = event_queue.get(timeout=5)[0] assert event.src_path == p('a') assert isinstance(event, FileClosedEvent)
def start_watching(path=None, use_full_emitter=False, recursive=True): # todo: check if other platforms expect the trailing slash (e.g. `p('')`) path = p() if path is None else path global emitter if platform.is_linux() and use_full_emitter: emitter = InotifyFullEmitter(event_queue, ObservedWatch(path, recursive=recursive)) else: emitter = Emitter(event_queue, ObservedWatch(path, recursive=recursive)) if platform.is_darwin(): emitter.suppress_history = True emitter.start()
def test_modify(): touch(p('a')) start_watching() touch(p('a')) # Because the tests run so fast then on macOS it is almost certain that # we receive a coalesced event from fseventsd here, which triggers an # additional file created event and dir modified event here. if platform.is_darwin(): expect_event(FileCreatedEvent(p('a'))) expect_event(DirModifiedEvent(p())) expect_event(FileModifiedEvent(p('a'))) if platform.is_linux(): event = event_queue.get(timeout=5)[0] assert event.src_path == p('a') assert isinstance(event, FileClosedEvent)
def start_watching(path=None, use_full_emitter=False, recursive=True): # todo: check if other platforms expect the trailing slash (e.g. `p('')`) path = p() if path is None else path global emitter if platform.is_linux() and use_full_emitter: emitter = InotifyFullEmitter(event_queue, ObservedWatch(path, recursive=recursive)) else: emitter = Emitter(event_queue, ObservedWatch(path, recursive=recursive)) emitter.start() if platform.is_darwin(): # FSEvents _may_ report the event for the creation of `tmpdir`, # however, we're racing with fseventd there - if other filesystem # events happened _after_ `tmpdir` was created, but _before_ we # created the emitter then we won't get this event. # As such, let's create a sentinel event that tells us that we are # good to go. sentinel_file = os.path.join( path, '.sentinel' if isinstance(path, str) else '.sentinel'.encode()) touch(sentinel_file) sentinel_events = [ FileCreatedEvent(sentinel_file), DirModifiedEvent(path), FileModifiedEvent(sentinel_file) ] next_sentinel_event = sentinel_events.pop(0) now = time.monotonic() while time.monotonic() <= now + 30.0: try: event = event_queue.get(timeout=0.5)[0] if event == next_sentinel_event: if not sentinel_events: break next_sentinel_event = sentinel_events.pop(0) except Empty: pass time.sleep(0.1) else: assert False, "Sentinel event never arrived!"
def _is_remote_filesystem(path): from utils import log from watchdog.utils import platform if not platform.is_linux(): return False remote_fs_types = ['cifs', 'smbfs', 'nfs', 'nfs4'] escaped_path = encode_path(path.rstrip('/').replace(' ', '\\040')) try: with open('/proc/mounts', 'r') as f: for line in f: _, mount_point, fstype = line.split()[:3] if mount_point == escaped_path: log("[fstype] type is \"%s\" '%s' " % (fstype, path.decode('utf-8'))) return fstype in remote_fs_types log("[fstype] path not in /proc/mounts '%s' " % escaped_path.decode('utf-8')) return False except (IOError, ValueError) as e: log("[fstype] failed to read /proc/mounts. %s, %s" % (type(e), e)) return False
def _get_native_observer(): """ Return native observer... or fail. """ from watchdog.utils import platform if platform.is_linux(): from watchdog.observers.inotify import InotifyObserver return InotifyObserver if platform.is_windows(): # TODO: find a reliable way of checking Windows version and import # polling explicitly for Windows XP try: from watchdog.observers.read_directory_changes import ( WindowsApiObserver) return WindowsApiObserver except: raise AssertionError('Native observer not supported.') raise AssertionError('Native observer not supported.')
import contextlib import logging import os from functools import partial import pytest from watchdog.events import DirCreatedEvent, DirDeletedEvent, DirModifiedEvent from watchdog.observers.api import ObservedWatch from watchdog.utils import platform from watchdog.utils.compat import Queue from .shell import mkdtemp, rm if platform.is_linux(): from watchdog.observers.inotify import InotifyFullEmitter, InotifyEmitter logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def setup_function(function): global p, event_queue tmpdir = os.path.realpath(mkdtemp()) p = partial(os.path.join, tmpdir) event_queue = Queue() @contextlib.contextmanager def watching(path=None, use_full_emitter=False): path = p("") if path is None else path
import os import threading import time import pytest import logging from tests import Queue from functools import partial from .shell import mkdir, touch, mv, rm, mkdtemp from watchdog.utils import platform from watchdog.utils.unicode_paths import str_cls from watchdog.events import * from watchdog.observers.api import ObservedWatch # pytestmark = pytest.mark.skipif(not platform.is_linux() and not platform.is_darwin(), # reason="") if platform.is_linux(): from watchdog.observers.inotify import InotifyEmitter as Emitter from watchdog.observers.inotify import InotifyFullEmitter elif platform.is_darwin(): from watchdog.observers.fsevents2 import FSEventsEmitter as Emitter elif platform.is_windows(): from watchdog.observers.read_directory_changes import WindowsApiEmitter as Emitter logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def setup_function(function): global p, event_queue tmpdir = os.path.realpath(mkdtemp()) p = partial(os.path.join, tmpdir)
from functools import partial from .shell import mkdir, touch, mv, rm, mkdtemp from watchdog.utils import platform from watchdog.utils.unicode_paths import str_cls from watchdog.events import ( FileDeletedEvent, FileModifiedEvent, FileCreatedEvent, FileMovedEvent, DirDeletedEvent, DirModifiedEvent, DirCreatedEvent, ) from watchdog.observers.api import ObservedWatch if platform.is_linux(): from watchdog.observers.inotify import ( InotifyEmitter as Emitter, InotifyFullEmitter, ) elif platform.is_darwin(): pytestmark = pytest.mark.skip("FIXME: It is a matter of bad comparisons between bytes and str.") from watchdog.observers.fsevents2 import FSEventsEmitter as Emitter else: pytestmark = pytest.mark.skip("GNU/Linux and macOS only.") logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def setup_function(function):
# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import pytest from watchdog.utils import platform if not platform.is_linux(): # noqa pytest.skip("GNU/Linux only.", allow_module_level=True) # noqa import os import random from watchdog.observers.inotify_buffer import InotifyBuffer from .shell import mkdir, touch, mv, rm, mount_tmpfs, unmount def wait_for_move_event(read_event): while True: event = read_event() if isinstance(event, tuple) or event.is_move: return event
from keyring.backend import _load_backend "ensure that all keyring backends are loaded" backends = ('file', 'Gnome', 'Google', 'keyczar', 'multi', 'OS_X', 'pyfs', 'SecretService', 'Windows') list(map(_load_backend, backends)) import keyring.backend keyring.backend._load_backends = _load_backends if getattr(sys, 'frozen', False): def _certs_where(): return str((Path(sys._MEIPASS)) / 'res' / 'cacert.pem') requests.certs.where = _certs_where os.environ['REQUESTS_CA_BUNDLE'] = requests.certs.where() logging.info("Setting certificate path to " + requests.certs.where()) fs_encoding = sys.getfilesystemencoding() if not fs_encoding and platform.is_linux(): def _watchdog_encode(path): if isinstance(path, unicode): path = path.encode('utf-8', 'strict') return path def _watchdog_decode(path): if isinstance(path, str): path = path.decode('utf-8', 'strict') return path import watchdog.utils.unicode_paths watchdog.utils.unicode_paths.encode = _watchdog_encode watchdog.utils.unicode_paths.decode = _watchdog_decode
from __future__ import unicode_literals import os import time import pytest import logging from functools import partial from . import Queue, Empty from .shell import mkdir, touch, mv, rm from watchdog.utils import platform from watchdog.utils.unicode_paths import str_cls from watchdog.events import (FileDeletedEvent, FileModifiedEvent, FileCreatedEvent, FileMovedEvent, DirDeletedEvent, DirModifiedEvent, DirCreatedEvent, DirMovedEvent) from watchdog.observers.api import ObservedWatch if platform.is_linux(): from watchdog.observers.inotify import ( InotifyEmitter as Emitter, InotifyFullEmitter, ) elif platform.is_darwin(): pytestmark = pytest.mark.skip("FIXME: issue #546.") from watchdog.observers.fsevents2 import FSEventsEmitter as Emitter elif platform.is_windows(): from watchdog.observers.read_directory_changes import (WindowsApiEmitter as Emitter) elif platform.is_bsd(): from watchdog.observers.kqueue import (KqueueEmitter as Emitter) logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__)
# Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import unicode_literals import os import random import pytest from tests import tmpdir, p # pytest magic from .shell import mkdir, touch, mv from watchdog.observers.api import ObservedWatch from watchdog.utils import platform pytestmark = pytest.mark.skipif(not platform.is_linux(), reason="") if platform.is_linux(): from watchdog.observers.inotify import InotifyEmitter from watchdog.observers.inotify_buffer import InotifyBuffer def wait_for_move_event(read_event): while True: event = read_event() if isinstance(event, tuple) or event.is_move: return event @pytest.mark.timeout(5) def test_move_from(p): mkdir(p('dir1'))
from __future__ import unicode_literals import os import pytest import logging import contextlib from tests import Queue from functools import partial from .shell import rm, mkdtemp from watchdog.utils import platform from watchdog.events import DirCreatedEvent, DirDeletedEvent, DirModifiedEvent from watchdog.observers.api import ObservedWatch if platform.is_linux(): from watchdog.observers.inotify import InotifyFullEmitter, InotifyEmitter logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def setup_function(function): global p, event_queue tmpdir = os.path.realpath(mkdtemp()) p = partial(os.path.join, tmpdir) event_queue = Queue() @contextlib.contextmanager def watching(path=None, use_full_emitter=False): path = p('') if path is None else path global emitter
# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import unicode_literals import pytest from watchdog.utils import platform if not platform.is_linux(): pytest.skip("GNU/Linux only.", allow_module_level=True) import os import random from watchdog.observers.inotify_buffer import InotifyBuffer from .shell import mkdir, touch, mv, rm def wait_for_move_event(read_event): while True: event = read_event() if isinstance(event, tuple) or event.is_move: return event
# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import random import pytest from watchdog.utils import platform from .shell import mkdir, mv, rm, touch pytestmark = pytest.mark.skipif(not platform.is_linux(), reason="") if platform.is_linux(): from watchdog.observers.inotify_buffer import InotifyBuffer def wait_for_move_event(read_event): while True: event = read_event() if isinstance(event, tuple) or event.is_move: return event @pytest.mark.timeout(5) def test_move_from(p): mkdir(p("dir1")) mkdir(p("dir2"))
# limitations under the License. from __future__ import unicode_literals import os import time import pytest import logging from tests import Queue from functools import partial from .shell import mkdir, touch, mv, rm, mkdtemp from watchdog.utils import platform from watchdog.utils.unicode_paths import str_cls from watchdog.events import * from watchdog.observers.api import ObservedWatch pytestmark = pytest.mark.skipif(not platform.is_linux() and not platform.is_darwin(), reason="") if platform.is_linux(): from watchdog.observers.inotify import InotifyEmitter as Emitter elif platform.is_darwin(): from watchdog.observers.fsevents2 import FSEventsEmitter as Emitter logging.basicConfig(level=logging.DEBUG) def setup_function(function): global p, event_queue tmpdir = os.path.realpath(mkdtemp()) p = partial(os.path.join, tmpdir) event_queue = Queue()
|Polling| Any fallback implementation ============== ================================ ============================== .. |Inotify| replace:: :class:`.inotify.InotifyObserver` .. |FSEvents| replace:: :class:`.fsevents.FSEventsObserver` .. |Kqueue| replace:: :class:`.kqueue.KqueueObserver` .. |WinApi| replace:: :class:`.read_directory_changes.WindowsApiObserver` .. |Polling| replace:: :class:`.polling.PollingObserver` """ import warnings from watchdog.utils import platform from watchdog.utils import UnsupportedLibc if platform.is_linux(): try: from .inotify import InotifyObserver as Observer except UnsupportedLibc: from .polling import PollingObserver as Observer elif platform.is_darwin(): try: from .fsevents import FSEventsObserver as Observer except Exception: try: from .kqueue import KqueueObserver as Observer warnings.warn("Failed to import fsevents. Fall back to kqueue") except Exception: from .polling import PollingObserver as Observer warnings.warn(
DirCreatedEvent, DirDeletedEvent, DirModifiedEvent, FileCreatedEvent, FileDeletedEvent, FileModifiedEvent, FileMovedEvent, ) from watchdog.observers.api import ObservedWatch from watchdog.utils import platform from watchdog.utils.compat import Empty, Queue from watchdog.utils.unicode_paths import str_cls from .shell import mkdir, mkdtemp, mv, rm, touch pytestmark = pytest.mark.skipif(not platform.is_linux() and not platform.is_darwin(), reason="") if platform.is_linux(): from watchdog.observers.inotify import InotifyEmitter as Emitter from watchdog.observers.inotify import InotifyFullEmitter elif platform.is_darwin(): pytestmark = pytest.mark.skip("WATCHDOG-8") from watchdog.observers.fsevents2 import FSEventsEmitter as Emitter logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def setup_function(function): global p, event_queue
from .shell import mkfile, mkdir, touch, mv, rm from watchdog.utils import platform from watchdog.events import ( FileDeletedEvent, FileModifiedEvent, FileCreatedEvent, FileMovedEvent, DirDeletedEvent, DirModifiedEvent, DirCreatedEvent, DirMovedEvent, FileClosedEvent, ) from watchdog.observers.api import ObservedWatch if platform.is_linux(): from watchdog.observers.inotify import ( InotifyEmitter as Emitter, InotifyFullEmitter, ) elif platform.is_darwin(): from watchdog.observers.fsevents import FSEventsEmitter as Emitter elif platform.is_windows(): from watchdog.observers.read_directory_changes import ( WindowsApiEmitter as Emitter ) elif platform.is_bsd(): from watchdog.observers.kqueue import ( KqueueEmitter as Emitter )
subdirectories under a directory, additional watches must be created. This emitter implementation therefore automatically adds watches for sub-directories if running in recursive mode. Some extremely useful articles and documentation: .. _inotify FAQ: http://inotify.aiken.cz/?section=inotify&page=faq&lang=en .. _intro to inotify: http://www.linuxjournal.com/article/8478 """ from __future__ import with_statement from watchdog.utils import platform import errno if platform.is_linux(): import os import struct import threading import ctypes from ctypes import\ c_int,\ c_char_p,\ c_uint32 from pathtools.path import absolute_path from watchdog.utils import\ has_attribute,\ ctypes_find_library from watchdog.observers.api import\
# limitations under the License. from __future__ import unicode_literals import os import time import pytest import logging from tests import Queue from functools import partial from .shell import mkdir, touch, mv, rm, mkdtemp from watchdog.utils import platform from watchdog.utils.unicode_paths import str_cls from watchdog.events import * from watchdog.observers.api import ObservedWatch pytestmark = pytest.mark.skipif(not platform.is_linux() and not platform.is_darwin(), reason="") if platform.is_linux(): from watchdog.observers.inotify import InotifyEmitter as Emitter elif platform.is_darwin(): from watchdog.observers.fsevents2 import FSEventsEmitter as Emitter from watchdog.observers.inotify import InotifyFullEmitter logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def setup_function(function): global p, event_queue tmpdir = os.path.realpath(mkdtemp()) p = partial(os.path.join, tmpdir) event_queue = Queue()