diff --git a/aionotify/base.py b/aionotify/base.py index 113f68d..6775996 100644 --- a/aionotify/base.py +++ b/aionotify/base.py @@ -7,7 +7,7 @@ import ctypes import struct -from . import aioutils +from . import aioutils, enums Event = collections.namedtuple('Event', ['flags', 'cookie', 'name', 'alias']) @@ -124,10 +124,16 @@ def get_event(self): # Event for a removed watch, skip it. continue + alias = self.aliases[wd] + if flags & enums.Flags.IGNORED: + del self.descriptors[alias] + del self.requests[alias] + del self.aliases[wd] + decoded_path = struct.unpack('%ds' % length, path)[0].rstrip(b'\x00').decode('utf-8') return Event( flags=flags, cookie=cookie, name=decoded_path, - alias=self.aliases[wd], + alias=alias, ) diff --git a/tests/test_usage.py b/tests/test_usage.py index f156291..c4e9a4d 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -59,6 +59,14 @@ def _unlink(self, filename, *, parent=None): path = os.path.join(parent or self.testdir, filename) os.unlink(path) + def _mkdir(self, dirname, *, parent=None): + path = os.path.join(parent or self.testdir, dirname) + os.mkdir(path) + + def _rmdir(self, dirname, *, parent=None): + path = os.path.join(parent or self.testdir, dirname) + os.rmdir(path) + def _rename(self, source, target, *, parent=None): source_path = os.path.join(parent or self.testdir, source) target_path = os.path.join(parent or self.testdir, target) @@ -197,6 +205,24 @@ def test_rename_detection(self): # And it's over. yield from self._assert_no_events() + @asyncio.coroutine + def test_remove_directory(self): + """ A deleted file or directory should be unwatched.""" + full_path = os.path.join(self.testdir, 'a') + self._mkdir('a') + self.watcher.watch(full_path, aionotify.Flags.IGNORED) + yield from self.watcher.setup(self.loop) + + self._rmdir('a') + event = yield from self.watcher.get_event() + self._assert_file_event(event, '', flags=aionotify.Flags.IGNORED, alias=full_path) + + # Make sure we can watch the same path again (#2) + self._mkdir('a') + self.watcher.watch(full_path, aionotify.Flags.IGNORED) + + yield from self._assert_no_events() + class ErrorTests(AIONotifyTestCase): """Test error cases."""