Hello community,
here is the log from the commit of package python-watchdog for openSUSE:Factory checked in at 2018-11-20 22:43:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-watchdog (Old)
and /work/SRC/openSUSE:Factory/.python-watchdog.new.19453 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-watchdog"
Tue Nov 20 22:43:13 2018 rev:4 rq:650294 version:0.9.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-watchdog/python-watchdog.changes 2018-08-24 17:01:35.877893089 +0200
+++ /work/SRC/openSUSE:Factory/.python-watchdog.new.19453/python-watchdog.changes 2018-11-20 22:43:26.314260537 +0100
@@ -1,0 +2,8 @@
+Mon Nov 19 13:00:25 UTC 2018 - John Paul Adrian Glaubitz
+
+- Update to version 0.8.3
+- Cherry-pick upstream patch to fix testsuite
+ + add-missing-conftest.patch
+- Update BuildRequires from setup.py
+
+-------------------------------------------------------------------
Old:
----
watchdog-0.8.3.tar.gz
New:
----
add-missing-conftest.patch
watchdog-0.9.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-watchdog.spec ++++++
--- /var/tmp/diff_new_pack.q0GD6x/_old 2018-11-20 22:43:28.734259624 +0100
+++ /var/tmp/diff_new_pack.q0GD6x/_new 2018-11-20 22:43:28.738259623 +0100
@@ -12,20 +12,23 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-watchdog
-Version: 0.8.3
+Version: 0.9.0
Release: 0
Summary: Filesystem events monitoring
License: Apache-2.0
Group: Development/Languages/Python
URL: http://github.com/gorakhargosh/watchdog
Source: https://files.pythonhosted.org/packages/source/w/watchdog/watchdog-%{version}.tar.gz
+Patch0: add-missing-conftest.patch
BuildRequires: %{python_module pathtools}
+BuildRequires: %{python_module pytest-cov}
+BuildRequires: %{python_module pytest-timeout >= 0.3}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
@@ -52,6 +55,7 @@
%prep
%setup -q -n watchdog-%{version}
+%patch0 -p1
chmod -x README.rst
# Remove all shebangs
find src -name "*.py" | xargs sed -i -e '/^#!\//, 1d'
++++++ add-missing-conftest.patch ++++++
diff -Nru watchdog-0.9.0.old/tests/conftest.py watchdog-0.9.0/tests/conftest.py
--- watchdog-0.9.0.old/tests/conftest.py 1970-01-01 01:00:00.000000000 +0100
+++ watchdog-0.9.0/tests/conftest.py 2018-11-19 13:54:38.883980668 +0100
@@ -0,0 +1,22 @@
+from functools import partial
+import os
+import pytest
+from tests import shell
+
+
+@pytest.fixture()
+def tmpdir(request):
+ path = os.path.realpath(shell.mkdtemp())
+ def finalizer():
+ shell.rm(path, recursive=True)
+ request.addfinalizer(finalizer)
+ return path
+
+
+@pytest.fixture()
+def p(tmpdir, *args):
+ """
+ Convenience function to join the temporary directory path
+ with the provided arguments.
+ """
+ return partial(os.path.join, tmpdir)
++++++ watchdog-0.8.3.tar.gz -> watchdog-0.9.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/AUTHORS new/watchdog-0.9.0/AUTHORS
--- old/watchdog-0.8.3/AUTHORS 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/AUTHORS 2018-08-28 02:33:44.000000000 +0200
@@ -6,6 +6,7 @@
-----------------------------------
Adrian Tejn Kern
Andrew Schaaf
+Danilo de Jesus da Silva Bellini
David LaPalomento
Filip Noetzel
Gary van der Merwe
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/PKG-INFO new/watchdog-0.9.0/PKG-INFO
--- old/watchdog-0.8.3/PKG-INFO 2015-02-11 11:25:48.000000000 +0100
+++ new/watchdog-0.9.0/PKG-INFO 2018-08-28 22:42:19.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: watchdog
-Version: 0.8.3
+Version: 0.9.0
Summary: Filesystem events monitoring
Home-page: http://github.com/gorakhargosh/watchdog
Author: Yesudeep Mangalapilly
@@ -174,7 +174,7 @@
pip install pytest
pip install -e .
- py.tests tests
+ py.test tests
Supported Platforms
@@ -317,7 +317,16 @@
Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: C
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Monitoring
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/README.rst new/watchdog-0.9.0/README.rst
--- old/watchdog-0.8.3/README.rst 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/README.rst 2018-08-27 23:46:08.000000000 +0200
@@ -166,7 +166,7 @@
pip install pytest
pip install -e .
- py.tests tests
+ py.test tests
Supported Platforms
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/docs/source/global.rst.inc new/watchdog-0.9.0/docs/source/global.rst.inc
--- old/watchdog-0.8.3/docs/source/global.rst.inc 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/docs/source/global.rst.inc 2018-08-28 22:25:40.000000000 +0200
@@ -4,7 +4,7 @@
.. |author_email| replace:: yesudeep@gmail.com
.. |copyright| replace:: Copyright 2012 Google, Inc.
.. |project_name| replace:: ``watchdog``
-.. |project_version| replace:: 0.8.3
+.. |project_version| replace:: 0.9.0
.. _issue tracker: http://github.com/gorakhargosh/watchdog/issues
.. _code repository: http://github.com/gorakhargosh/watchdog
@@ -30,7 +30,7 @@
.. _inotify-tools: http://github.com/rvoicilas/inotify-tools
.. _jnotify: http://jnotify.sourceforge.net/
.. _LibYAML: http://pyyaml.org/wiki/LibYAML
-.. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.2/
+.. _nose: http://nose.readthedocs.org/en/latest/
.. _pip: http://pypi.python.org/pypi/pip
.. _pnotify: http://mark.heily.com/pnotify
.. _pyfilesystem: http://code.google.com/p/pyfilesystem
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/docs/source/quickstart.rst new/watchdog-0.9.0/docs/source/quickstart.rst
--- old/watchdog-0.8.3/docs/source/quickstart.rst 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/docs/source/quickstart.rst 2018-08-27 23:46:08.000000000 +0200
@@ -32,7 +32,6 @@
file system changes and simply log them to the console::
import sys
- import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
@@ -47,8 +46,8 @@
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
- while True:
- time.sleep(1)
+ while observer.isAlive():
+ observer.join(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/setup.cfg new/watchdog-0.9.0/setup.cfg
--- old/watchdog-0.8.3/setup.cfg 2015-02-11 11:25:48.000000000 +0100
+++ new/watchdog-0.9.0/setup.cfg 2018-08-28 22:42:19.000000000 +0200
@@ -9,5 +9,4 @@
[egg_info]
tag_build =
tag_date = 0
-tag_svn_revision = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/setup.py new/watchdog-0.9.0/setup.py
--- old/watchdog-0.8.3/setup.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/setup.py 2018-08-28 21:28:26.000000000 +0200
@@ -81,7 +81,11 @@
if sys.version_info < (2, 7, 0):
tests_require.append('unittest2')
-install_requires = ['PyYAML >=3.10', 'argh >=0.24.1', 'pathtools >=0.1.1']
+install_requires = [
+ "PyYAML<3.13" if sys.version_info[:2] == (3, 2) else "PyYAML>=3.10",
+ "argh>=0.24.1",
+ "pathtools>=0.1.1",
+]
if sys.version_info < (2, 7, 0):
# argparse is merged into Python 2.7 in the Python 2x series
# and Python 3.2 in the Python 3x series.
@@ -131,7 +135,16 @@
'Operating System :: Microsoft :: Windows :: Windows NT/2000',
'Operating System :: OS Independent',
'Programming Language :: Python',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.2',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: Implementation :: PyPy',
'Programming Language :: C',
'Topic :: Software Development :: Libraries',
'Topic :: System :: Monitoring',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/__init__.py new/watchdog-0.9.0/src/watchdog/observers/__init__.py
--- old/watchdog-0.8.3/src/watchdog/observers/__init__.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/__init__.py 2018-08-28 03:15:25.000000000 +0200
@@ -90,3 +90,5 @@
else:
from .polling import PollingObserver as Observer
+
+__all__ = ["Observer"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/fsevents.py new/watchdog-0.9.0/src/watchdog/observers/fsevents.py
--- old/watchdog-0.8.3/src/watchdog/observers/fsevents.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/fsevents.py 2018-08-28 03:24:46.000000000 +0200
@@ -137,7 +137,7 @@
callback,
self.pathnames)
_fsevents.read_events(self)
- except Exception as e:
+ except:
pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/fsevents2.py new/watchdog-0.9.0/src/watchdog/observers/fsevents2.py
--- old/watchdog-0.8.3/src/watchdog/observers/fsevents2.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/fsevents2.py 2018-08-28 02:57:26.000000000 +0200
@@ -71,7 +71,6 @@
kFSEventStreamEventFlagItemFinderInfoMod,
kFSEventStreamEventFlagItemChangeOwner,
kFSEventStreamEventFlagItemXattrMod,
- kFSEventStreamEventFlagItemIsFile,
kFSEventStreamEventFlagItemIsDir,
kFSEventStreamEventFlagItemIsSymlink,
)
@@ -88,8 +87,8 @@
self._run_loop = None
if isinstance(path, bytes):
- self._path = path.decode('utf-8')
- self._path = unicodedata.normalize('NFC', self._path)
+ path = path.decode('utf-8')
+ self._path = unicodedata.normalize('NFC', path)
context = None
latency = 1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/inotify.py new/watchdog-0.9.0/src/watchdog/observers/inotify.py
--- old/watchdog-0.8.3/src/watchdog/observers/inotify.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/inotify.py 2018-08-28 02:48:58.000000000 +0200
@@ -124,7 +124,9 @@
if self._inotify:
self._inotify.close()
- def queue_events(self, timeout):
+ def queue_events(self, timeout, full_events=False):
+ #If "full_events" is true, then the method will report unmatched move events as seperate events
+ #This behavior is by default only called by a InotifyFullEmitter
with self._lock:
event = self._inotify.read_event()
if event is None:
@@ -144,8 +146,12 @@
src_path = self._decode_path(event.src_path)
if event.is_moved_to:
- cls = DirCreatedEvent if event.is_directory else FileCreatedEvent
- self.queue_event(cls(src_path))
+ if (full_events):
+ cls = DirMovedEvent if event.is_directory else FileMovedEvent
+ self.queue_event(cls(None, src_path))
+ else:
+ cls = DirCreatedEvent if event.is_directory else FileCreatedEvent
+ self.queue_event(cls(src_path))
self.queue_event(DirModifiedEvent(os.path.dirname(src_path)))
if event.is_directory and self.watch.is_recursive:
for sub_event in generate_sub_created_events(src_path):
@@ -156,13 +162,14 @@
elif event.is_modify:
cls = DirModifiedEvent if event.is_directory else FileModifiedEvent
self.queue_event(cls(src_path))
- elif event.is_delete_self:
- cls = DirDeletedEvent if event.is_directory else FileDeletedEvent
- self.queue_event(cls(src_path))
- elif event.is_delete or event.is_moved_from:
+ elif event.is_delete or (event.is_moved_from and not full_events):
cls = DirDeletedEvent if event.is_directory else FileDeletedEvent
self.queue_event(cls(src_path))
self.queue_event(DirModifiedEvent(os.path.dirname(src_path)))
+ elif event.is_moved_from and full_events:
+ cls = DirMovedEvent if event.is_directory else FileMovedEvent
+ self.queue_event(cls(src_path, None))
+ self.queue_event(DirModifiedEvent(os.path.dirname(src_path)))
elif event.is_create:
cls = DirCreatedEvent if event.is_directory else FileCreatedEvent
self.queue_event(cls(src_path))
@@ -175,12 +182,37 @@
return unicode_paths.decode(path)
+class InotifyFullEmitter(InotifyEmitter):
+ """
+ inotify(7)-based event emitter. By default this class produces move events even if they are not matched
+ Such move events will have a ``None`` value for the unmatched part.
+
+ :param event_queue:
+ The event queue to fill with events.
+ :param watch:
+ A watch object representing the directory to monitor.
+ :type watch:
+ :class:`watchdog.observers.api.ObservedWatch`
+ :param timeout:
+ Read events blocking timeout (in seconds).
+ :type timeout:
+ ``float``
+ """
+ def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT):
+ InotifyEmitter.__init__(self, event_queue, watch, timeout)
+
+ def queue_events(self, timeout, events=True):
+ InotifyEmitter.queue_events(self, timeout, full_events=events)
+
class InotifyObserver(BaseObserver):
"""
Observer thread that schedules watching directories and dispatches
calls to event handlers.
"""
- def __init__(self, timeout=DEFAULT_OBSERVER_TIMEOUT):
- BaseObserver.__init__(self, emitter_class=InotifyEmitter,
+ def __init__(self, timeout=DEFAULT_OBSERVER_TIMEOUT, generate_full_events=False):
+ if (generate_full_events):
+ BaseObserver.__init__(self, emitter_class=InotifyFullEmitter, timeout=timeout)
+ else:
+ BaseObserver.__init__(self, emitter_class=InotifyEmitter,
timeout=timeout)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/inotify_buffer.py new/watchdog-0.9.0/src/watchdog/observers/inotify_buffer.py
--- old/watchdog-0.8.3/src/watchdog/observers/inotify_buffer.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/inotify_buffer.py 2018-08-27 23:46:08.000000000 +0200
@@ -55,7 +55,8 @@
IN_MOVE_TO event, remove the previous added matching IN_MOVE_FROM event
and add them back to the queue as a tuple.
"""
- while self.should_keep_running():
+ deleted_self = False
+ while self.should_keep_running() and not deleted_self:
inotify_events = self._inotify.read_events()
for inotify_event in inotify_events:
logger.debug("in-event %s", inotify_event)
@@ -74,3 +75,7 @@
else:
self._queue.put(inotify_event)
+ if inotify_event.is_delete_self and \
+ inotify_event.src_path == self._inotify.path:
+ # Deleted the watched directory, stop watching for events
+ deleted_self = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/inotify_c.py new/watchdog-0.9.0/src/watchdog/observers/inotify_c.py
--- old/watchdog-0.8.3/src/watchdog/observers/inotify_c.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/inotify_c.py 2018-08-28 01:40:17.000000000 +0200
@@ -32,7 +32,7 @@
libc_path = None
try:
libc_path = ctypes.util.find_library('c')
- except (OSError, IOError):
+ except (OSError, IOError, RuntimeError):
# Note: find_library will on some platforms raise these undocumented
# errors, e.g.on android IOError "No usable temporary directory found"
# will be raised.
@@ -45,7 +45,19 @@
try:
return ctypes.CDLL('libc.so')
except (OSError, IOError):
+ pass
+
+ try:
return ctypes.CDLL('libc.so.6')
+ except (OSError, IOError):
+ pass
+
+ # uClibc
+ try:
+ return ctypes.CDLL('libc.so.0')
+ except (OSError, IOError) as err:
+ raise err
+
libc = _load_libc()
@@ -248,7 +260,8 @@
Path string for which the watch will be removed.
"""
with self._lock:
- wd = self._remove_watch_bookkeeping(path)
+ wd = self._wd_for_path.pop(path)
+ del self._path_for_wd[wd]
if inotify_rm_watch(self._inotify_fd, wd) == -1:
Inotify._raise_error()
@@ -257,8 +270,9 @@
Closes the inotify instance and removes all associated watches.
"""
with self._lock:
- wd = self._wd_for_path[self._path]
- inotify_rm_watch(self._inotify_fd, wd)
+ if self._path in self._wd_for_path:
+ wd = self._wd_for_path[self._path]
+ inotify_rm_watch(self._inotify_fd, wd)
os.close(self._inotify_fd)
def read_events(self, event_buffer_size=DEFAULT_EVENT_BUFFER_SIZE):
@@ -322,7 +336,9 @@
if inotify_event.is_ignored:
# Clean up book-keeping for deleted watches.
- self._remove_watch_bookkeeping(src_path)
+ path = self._path_for_wd.pop(wd)
+ if self._wd_for_path[path] == wd:
+ del self._wd_for_path[path]
continue
event_list.append(inotify_event)
@@ -387,11 +403,6 @@
self._path_for_wd[wd] = path
return wd
- def _remove_watch_bookkeeping(self, path):
- wd = self._wd_for_path.pop(path)
- del self._path_for_wd[wd]
- return wd
-
@staticmethod
def _raise_error():
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/polling.py new/watchdog-0.9.0/src/watchdog/observers/polling.py
--- old/watchdog-0.8.3/src/watchdog/observers/polling.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/polling.py 2018-08-28 03:25:42.000000000 +0200
@@ -88,7 +88,13 @@
# Get event diff between fresh snapshot and previous snapshot.
# Update snapshot.
- new_snapshot = self._take_snapshot()
+ try:
+ new_snapshot = self._take_snapshot()
+ except OSError:
+ self.queue_event(DirDeletedEvent(self.watch.path))
+ self.stop()
+ return
+
events = DirectorySnapshotDiff(self._snapshot, new_snapshot)
self._snapshot = new_snapshot
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/read_directory_changes.py new/watchdog-0.9.0/src/watchdog/observers/read_directory_changes.py
--- old/watchdog-0.8.3/src/watchdog/observers/read_directory_changes.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/read_directory_changes.py 2018-08-28 03:15:27.000000000 +0200
@@ -19,14 +19,12 @@
from __future__ import with_statement
-import ctypes
import threading
import os.path
import time
from watchdog.events import (
DirCreatedEvent,
- DirDeletedEvent,
DirMovedEvent,
DirModifiedEvent,
FileCreatedEvent,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/observers/winapi.py new/watchdog-0.9.0/src/watchdog/observers/winapi.py
--- old/watchdog-0.8.3/src/watchdog/observers/winapi.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/observers/winapi.py 2018-08-28 03:15:29.000000000 +0200
@@ -39,7 +39,6 @@
from __future__ import with_statement
import ctypes.wintypes
-import struct
from functools import reduce
try:
@@ -63,7 +62,7 @@
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
FILE_FLAG_OVERLAPPED = 0x40000000
-FILE_LIST_DIRECTORY = 0x01
+FILE_LIST_DIRECTORY = 1
FILE_SHARE_READ = 0x01
FILE_SHARE_WRITE = 0x02
FILE_SHARE_DELETE = 0x04
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/tricks/__init__.py new/watchdog-0.9.0/src/watchdog/tricks/__init__.py
--- old/watchdog-0.8.3/src/watchdog/tricks/__init__.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/tricks/__init__.py 2018-08-27 23:46:08.000000000 +0200
@@ -138,13 +138,13 @@
kill_after=10):
super(AutoRestartTrick, self).__init__(
patterns, ignore_patterns, ignore_directories)
- self.command = ['setsid'] + command
+ self.command = command
self.stop_signal = stop_signal
self.kill_after = kill_after
self.process = None
def start(self):
- self.process = subprocess.Popen(self.command)
+ self.process = subprocess.Popen(self.command, preexec_fn=os.setsid)
def stop(self):
if self.process is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/utils/__init__.py new/watchdog-0.9.0/src/watchdog/utils/__init__.py
--- old/watchdog-0.8.3/src/watchdog/utils/__init__.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/utils/__init__.py 2018-08-28 01:38:03.000000000 +0200
@@ -33,9 +33,8 @@
import os
import sys
import threading
-import watchdog.utils.platform
+from watchdog.utils import platform
from watchdog.utils.compat import Event
-from collections import namedtuple
if sys.version_info[0] == 2 and platform.is_windows():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/utils/dirsnapshot.py new/watchdog-0.9.0/src/watchdog/utils/dirsnapshot.py
--- old/watchdog-0.8.3/src/watchdog/utils/dirsnapshot.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/utils/dirsnapshot.py 2018-08-28 02:49:06.000000000 +0200
@@ -47,7 +47,6 @@
import errno
import os
from stat import S_ISDIR
-from watchdog.utils import platform
from watchdog.utils import stat as default_stat
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/utils/echo.py new/watchdog-0.9.0/src/watchdog/utils/echo.py
--- old/watchdog-0.8.3/src/watchdog/utils/echo.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/utils/echo.py 2018-08-27 23:46:08.000000000 +0200
@@ -41,10 +41,17 @@
return item.__name__
-def is_classmethod(instancemethod):
+def is_classmethod(instancemethod, klass):
" Determine if an instancemethod is a classmethod. "
- return instancemethod.__self__ is not None
+ return inspect.ismethod(instancemethod) and instancemethod.__self__ is klass
+def is_static_method(method, klass):
+ """Returns True if method is an instance method of klass."""
+ for c in klass.mro():
+ if name(method) in c.__dict__:
+ return isinstance(c.__dict__[name(method)], staticmethod)
+ else:
+ return False
def is_class_private_name(name):
" Determine if a name is a class private name. "
@@ -115,20 +122,24 @@
never_echo = "__str__", "__repr__", # Avoid recursion printing method calls
if mname in never_echo:
pass
- elif is_classmethod(method):
+ elif is_classmethod(method, klass):
setattr(klass, mname, classmethod(echo(method.__func__, write)))
else:
setattr(klass, mname, echo(method, write))
-
def echo_class(klass, write=sys.stdout.write):
""" Echo calls to class methods and static functions
"""
for _, method in inspect.getmembers(klass, inspect.ismethod):
+ #In python 3 only class methods are returned here, but in python2 instance methods are too.
echo_instancemethod(klass, method, write)
for _, fn in inspect.getmembers(klass, inspect.isfunction):
- setattr(klass, name(fn), staticmethod(echo(fn, write)))
-
+ if is_static_method(fn, klass):
+ setattr(klass, name(fn), staticmethod(echo(fn, write)))
+ else:
+ #It's not a class or a static method, so it must be an instance method.
+ #This should only be called in python 3, because in python 3 instance methods are considered functions.
+ echo_instancemethod(klass, fn, write)
def echo_module(mod, write=sys.stdout.write):
""" Echo calls to functions and methods in a module.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/utils/platform.py new/watchdog-0.9.0/src/watchdog/utils/platform.py
--- old/watchdog-0.8.3/src/watchdog/utils/platform.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/utils/platform.py 2018-08-27 23:46:08.000000000 +0200
@@ -33,7 +33,7 @@
return PLATFORM_DARWIN
elif sys.platform.startswith('linux'):
return PLATFORM_LINUX
- elif sys.platform.startswith('bsd'):
+ elif sys.platform.startswith(('dragonfly', 'freebsd', 'netbsd', 'openbsd', )):
return PLATFORM_BSD
else:
return PLATFORM_UNKNOWN
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/version.py new/watchdog-0.9.0/src/watchdog/version.py
--- old/watchdog-0.8.3/src/watchdog/version.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/version.py 2018-08-28 22:25:40.000000000 +0200
@@ -20,8 +20,8 @@
# When updating this version number, please update the
# ``docs/source/global.rst.inc`` file as well.
VERSION_MAJOR = 0
-VERSION_MINOR = 8
-VERSION_BUILD = 3
+VERSION_MINOR = 9
+VERSION_BUILD = 0
VERSION_INFO = (VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD)
VERSION_STRING = "%d.%d.%d" % VERSION_INFO
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog/watchmedo.py new/watchdog-0.9.0/src/watchdog/watchmedo.py
--- old/watchdog-0.8.3/src/watchdog/watchmedo.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog/watchmedo.py 2018-08-27 23:46:08.000000000 +0200
@@ -418,6 +418,9 @@
default=False,
help="Ignore events that occur while command is still being executed " \
"to avoid multiple simultaneous instances")
+@arg('--debug-force-polling',
+ default=False,
+ help='[debug] forces polling')
@expects_obj
def shell_command(args):
"""
@@ -426,12 +429,16 @@
:param args:
Command line argument options.
"""
- from watchdog.observers import Observer
from watchdog.tricks import ShellCommandTrick
if not args.command:
args.command = None
+ if args.debug_force_polling:
+ from watchdog.observers.polling import PollingObserver as Observer
+ else:
+ from watchdog.observers import Observer
+
patterns, ignore_patterns = parse_patterns(args.patterns,
args.ignore_patterns)
handler = ShellCommandTrick(shell_command=args.command,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog.egg-info/PKG-INFO new/watchdog-0.9.0/src/watchdog.egg-info/PKG-INFO
--- old/watchdog-0.8.3/src/watchdog.egg-info/PKG-INFO 2015-02-11 11:25:48.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog.egg-info/PKG-INFO 2018-08-28 22:42:19.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: watchdog
-Version: 0.8.3
+Version: 0.9.0
Summary: Filesystem events monitoring
Home-page: http://github.com/gorakhargosh/watchdog
Author: Yesudeep Mangalapilly
@@ -174,7 +174,7 @@
pip install pytest
pip install -e .
- py.tests tests
+ py.test tests
Supported Platforms
@@ -317,7 +317,16 @@
Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: C
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Monitoring
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog.egg-info/SOURCES.txt new/watchdog-0.9.0/src/watchdog.egg-info/SOURCES.txt
--- old/watchdog-0.8.3/src/watchdog.egg-info/SOURCES.txt 2015-02-11 11:25:48.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog.egg-info/SOURCES.txt 2018-08-28 22:42:19.000000000 +0200
@@ -64,6 +64,7 @@
tests/test_delayed_queue.py
tests/test_emitter.py
tests/test_inotify_buffer.py
+tests/test_inotify_c.py
tests/test_observer.py
tests/test_skip_repeats_queue.py
tests/test_snapshot_diff.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/src/watchdog.egg-info/requires.txt new/watchdog-0.9.0/src/watchdog.egg-info/requires.txt
--- old/watchdog-0.8.3/src/watchdog.egg-info/requires.txt 2015-02-11 11:25:48.000000000 +0100
+++ new/watchdog-0.9.0/src/watchdog.egg-info/requires.txt 2018-08-28 22:42:19.000000000 +0200
@@ -1,3 +1,3 @@
-PyYAML >=3.10
-argh >=0.24.1
-pathtools >=0.1.1
\ No newline at end of file
+PyYAML>=3.10
+argh>=0.24.1
+pathtools>=0.1.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/__init__.py new/watchdog-0.9.0/tests/__init__.py
--- old/watchdog-0.8.3/tests/__init__.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/tests/__init__.py 2018-08-28 02:40:39.000000000 +0200
@@ -14,14 +14,7 @@
# 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 pytest
-from . import shell
from sys import version_info
-from functools import partial
-
-__all__ = ['unittest', 'Queue', 'tmpdir', 'p']
if version_info < (2, 7):
import unittest2 as unittest
@@ -33,20 +26,4 @@
except ImportError:
from queue import Queue # Python 3
-
-@pytest.fixture()
-def tmpdir(request):
- path = os.path.realpath(shell.mkdtemp())
- def finalizer():
- shell.rm(path, recursive=True)
- request.addfinalizer(finalizer)
- return path
-
-
-@pytest.fixture()
-def p(tmpdir, *args):
- """
- Convenience function to join the temporary directory path
- with the provided arguments.
- """
- return partial(os.path.join, tmpdir)
+__all__ = ["unittest", "Queue"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/legacy/test_watchdog_events.py new/watchdog-0.9.0/tests/legacy/test_watchdog_events.py
--- old/watchdog-0.8.3/tests/legacy/test_watchdog_events.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/tests/legacy/test_watchdog_events.py 2018-08-28 02:55:59.000000000 +0200
@@ -19,13 +19,10 @@
from tests import unittest
-from utils import list_attributes
from watchdog.utils import has_attribute
from pathtools.patterns import filter_paths
from watchdog.events import (
- FileSystemEvent,
- FileSystemMovedEvent,
FileDeletedEvent,
FileModifiedEvent,
FileCreatedEvent,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/legacy/test_watchdog_observers_polling.py new/watchdog-0.9.0/tests/legacy/test_watchdog_observers_polling.py
--- old/watchdog-0.8.3/tests/legacy/test_watchdog_observers_polling.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/tests/legacy/test_watchdog_observers_polling.py 2018-08-28 02:13:03.000000000 +0200
@@ -18,7 +18,6 @@
import os
-import sys
from tests import unittest
try:
@@ -134,6 +133,35 @@
got = set()
while True:
+ try:
+ event, _ = self.event_queue.get_nowait()
+ got.add(event)
+ except queue.Empty:
+ break
+
+ self.assertEqual(expected, got)
+
+ def test_delete_watched_dir(self):
+ SLEEP_TIME = 0.4
+ self.emitter.start()
+ rm(p(''), recursive=True)
+ sleep(SLEEP_TIME)
+ self.emitter.stop()
+
+ # What we need here for the tests to pass is a collection type
+ # that is:
+ # * unordered
+ # * non-unique
+ # A multiset! Python's collections.Counter class seems appropriate.
+ expected = set(
+ [
+
+ DirDeletedEvent(os.path.dirname(p(''))),
+ ]
+ )
+
+ got = set()
+ while True:
try:
event, _ = self.event_queue.get_nowait()
got.add(event)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/shell.py new/watchdog-0.9.0/tests/shell.py
--- old/watchdog-0.8.3/tests/shell.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/tests/shell.py 2018-08-28 03:15:12.000000000 +0200
@@ -28,7 +28,6 @@
import tempfile
import shutil
import errno
-import time
# def tree(path='.', show_files=False):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/test_emitter.py new/watchdog-0.9.0/tests/test_emitter.py
--- old/watchdog-0.8.3/tests/test_emitter.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/tests/test_emitter.py 2018-08-28 02:49:20.000000000 +0200
@@ -24,7 +24,15 @@
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.events import (
+ FileDeletedEvent,
+ FileModifiedEvent,
+ FileCreatedEvent,
+ FileMovedEvent,
+ DirDeletedEvent,
+ DirModifiedEvent,
+ DirCreatedEvent,
+)
from watchdog.observers.api import ObservedWatch
pytestmark = pytest.mark.skipif(not platform.is_linux() and not platform.is_darwin(), reason="")
@@ -32,8 +40,10 @@
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):
@@ -43,10 +53,14 @@
event_queue = Queue()
-def start_watching(path=None):
+def start_watching(path=None, use_full_emitter=False):
path = p('') if path is None else path
global emitter
- emitter = Emitter(event_queue, ObservedWatch(path, recursive=True))
+ 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.
@@ -131,6 +145,16 @@
assert isinstance(event, FileCreatedEvent)
assert event.src_path == p('dir2', 'b')
+def test_move_to_full():
+ mkdir(p('dir1'))
+ mkdir(p('dir2'))
+ touch(p('dir1', 'a'))
+ start_watching(p('dir2'), use_full_emitter=True)
+ mv(p('dir1', 'a'), p('dir2', 'b'))
+ event = event_queue.get(timeout=5)[0]
+ assert isinstance(event, FileMovedEvent)
+ assert event.dest_path == p('dir2', 'b')
+ assert event.src_path == None #Should equal none since the path was not watched
def test_move_from():
mkdir(p('dir1'))
@@ -142,7 +166,17 @@
event = event_queue.get(timeout=5)[0]
assert isinstance(event, FileDeletedEvent)
assert event.src_path == p('dir1', 'a')
-
+
+def test_move_from_full():
+ mkdir(p('dir1'))
+ mkdir(p('dir2'))
+ touch(p('dir1', 'a'))
+ start_watching(p('dir1'), use_full_emitter=True)
+ mv(p('dir1', 'a'), p('dir2', 'b'))
+ event = event_queue.get(timeout=5)[0]
+ assert isinstance(event, FileMovedEvent)
+ assert event.src_path == p('dir1', 'a')
+ assert event.dest_path == None #Should equal None since path not watched
def test_separate_consecutive_moves():
mkdir(p('dir1'))
@@ -175,6 +209,34 @@
event_queue.get(timeout=5)[0]
+def test_fast_subdirectory_creation_deletion():
+ root_dir = p('dir1')
+ sub_dir = p('dir1', 'subdir1')
+ times = 30
+ mkdir(root_dir)
+ start_watching(root_dir)
+ for unused in range(times):
+ mkdir(sub_dir)
+ rm(sub_dir, True)
+ count = {DirCreatedEvent: 0,
+ DirModifiedEvent: 0,
+ DirDeletedEvent: 0}
+ etype_for_dir = {DirCreatedEvent: sub_dir,
+ DirModifiedEvent: root_dir,
+ DirDeletedEvent: sub_dir}
+ for unused in range(times * 4):
+ event = event_queue.get(timeout=5)[0]
+ logger.debug(event)
+ etype = type(event)
+ count[etype] += 1
+ assert event.src_path == etype_for_dir[etype]
+ assert count[DirCreatedEvent] >= count[DirDeletedEvent]
+ assert count[DirCreatedEvent] + count[DirDeletedEvent] >= count[DirModifiedEvent]
+ assert count == {DirCreatedEvent: times,
+ DirModifiedEvent: times * 2,
+ DirDeletedEvent: times}
+
+
def test_passing_unicode_should_give_unicode():
start_watching(p(''))
touch(p('a'))
@@ -186,4 +248,4 @@
start_watching(p('').encode())
touch(p('a'))
event = event_queue.get(timeout=5)[0]
- assert isinstance(event.src_path, bytes)
+ assert isinstance(event.src_path, bytes)
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/test_inotify_buffer.py new/watchdog-0.9.0/tests/test_inotify_buffer.py
--- old/watchdog-0.8.3/tests/test_inotify_buffer.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/tests/test_inotify_buffer.py 2018-08-28 02:49:24.000000000 +0200
@@ -18,14 +18,11 @@
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 .shell import mkdir, touch, mv, rm
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
@@ -104,6 +101,19 @@
inotify.close()
+@pytest.mark.timeout(5)
+def test_delete_watched_directory(p):
+ mkdir(p('dir'))
+ inotify = InotifyBuffer(p('dir').encode())
+ rm(p('dir'), recursive=True)
+
+ # Wait for the event to be picked up
+ inotify.read_event()
+
+ # Ensure InotifyBuffer shuts down cleanly without raising an exception
+ inotify.close()
+
+
def test_close_should_terminate_thread(p):
inotify = InotifyBuffer(p('').encode(), recursive=True)
assert inotify.is_alive()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/test_inotify_c.py new/watchdog-0.9.0/tests/test_inotify_c.py
--- old/watchdog-0.8.3/tests/test_inotify_c.py 1970-01-01 01:00:00.000000000 +0100
+++ new/watchdog-0.9.0/tests/test_inotify_c.py 2018-08-27 23:46:08.000000000 +0200
@@ -0,0 +1,117 @@
+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
+ Emitter = InotifyFullEmitter if use_full_emitter else InotifyEmitter
+ emitter = Emitter(event_queue, ObservedWatch(path, recursive=True))
+ emitter.start()
+ yield
+ emitter.stop()
+ emitter.join(5)
+
+
+def teardown_function(function):
+ rm(p(''), recursive=True)
+ assert not emitter.is_alive()
+
+
+@pytest.mark.skipif(not platform.is_linux(),
+ reason="Testing with inotify messages (Linux only)")
+def test_late_double_deletion(monkeypatch):
+ inotify_fd = type(str("FD"), (object,), {})() # Empty object
+ inotify_fd.last = 0
+ inotify_fd.wds = []
+
+ # CREATE DELETE CREATE DELETE DELETE_SELF IGNORE DELETE_SELF IGNORE
+ inotify_fd.buf = (
+ # IN_CREATE|IS_DIR (wd = 1, path = subdir1)
+ b"\x01\x00\x00\x00\x00\x01\x00\x40\x00\x00\x00\x00\x10\x00\x00\x00"
+ b"\x73\x75\x62\x64\x69\x72\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ # IN_DELETE|IS_DIR (wd = 1, path = subdir1)
+ b"\x01\x00\x00\x00\x00\x02\x00\x40\x00\x00\x00\x00\x10\x00\x00\x00"
+ b"\x73\x75\x62\x64\x69\x72\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ ) * 2 + (
+ # IN_DELETE_SELF (wd = 2)
+ b"\x02\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ # IN_IGNORE (wd = 2)
+ b"\x02\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ # IN_DELETE_SELF (wd = 3)
+ b"\x03\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ # IN_IGNORE (wd = 3)
+ b"\x03\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ )
+
+ os_read_bkp = os.read
+ def fakeread(fd, length):
+ if fd is inotify_fd:
+ result, fd.buf = fd.buf[:length], fd.buf[length:]
+ return result
+ return os_read_bkp(fd, length)
+
+ os_close_bkp = os.close
+ def fakeclose(fd):
+ if fd is not inotify_fd:
+ os_close_bkp(fd)
+
+ def inotify_init():
+ return inotify_fd
+
+ def inotify_add_watch(fd, path, mask):
+ fd.last += 1
+ logger.debug("New wd = %d" % fd.last)
+ fd.wds.append(fd.last)
+ return fd.last
+
+ def inotify_rm_watch(fd, wd):
+ logger.debug("Removing wd = %d" % wd)
+ fd.wds.remove(wd)
+ return 0
+
+ # Mocks the API!
+ from watchdog.observers import inotify_c
+ monkeypatch.setattr(os, "read", fakeread)
+ monkeypatch.setattr(os, "close", fakeclose)
+ monkeypatch.setattr(inotify_c, "inotify_init", inotify_init)
+ monkeypatch.setattr(inotify_c, "inotify_add_watch", inotify_add_watch)
+ monkeypatch.setattr(inotify_c, "inotify_rm_watch", inotify_rm_watch)
+
+ with watching(p('')):
+ # Watchdog Events
+ for evt_cls in [DirCreatedEvent, DirDeletedEvent] * 2:
+ event = event_queue.get(timeout=5)[0]
+ assert isinstance(event, evt_cls)
+ assert event.src_path == p('subdir1')
+ event = event_queue.get(timeout=5)[0]
+ assert isinstance(event, DirModifiedEvent)
+ assert event.src_path == p('').rstrip(os.path.sep)
+
+ assert inotify_fd.last == 3 # Number of directories
+ assert inotify_fd.buf == b"" # Didn't miss any event
+ assert inotify_fd.wds == [2, 3] # Only 1 is removed explicitly
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/watchdog-0.8.3/tests/test_snapshot_diff.py new/watchdog-0.9.0/tests/test_snapshot_diff.py
--- old/watchdog-0.8.3/tests/test_snapshot_diff.py 2015-02-11 10:54:50.000000000 +0100
+++ new/watchdog-0.9.0/tests/test_snapshot_diff.py 2018-08-28 02:55:21.000000000 +0200
@@ -15,7 +15,6 @@
# limitations under the License.
import time
-from tests import tmpdir, p # pytest magic
from .shell import mkdir, touch, mv
from watchdog.utils.dirsnapshot import DirectorySnapshot
from watchdog.utils.dirsnapshot import DirectorySnapshotDiff