From 11c7f9f24420fd5fbe00f27c7588228bc1031b8f Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Nov 2018 17:07:42 +0000 Subject: [PATCH] Allow watching a file that didn't exist before If a watch request fails because the file didn't exist, an `OSError` is correctly raised, but the alias remains in the list of requests. Therefore it isn't possible to catch the exception, and retry the watch request once the file has been created. This patch adds the watch request to the request queue after attempting to call `_setup_watch`, to ensure it doesn't get left in the queue if the setup fails. --- aionotify/base.py | 2 +- tests/test_usage.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/aionotify/base.py b/aionotify/base.py index 113f68d..6aae1e4 100644 --- a/aionotify/base.py +++ b/aionotify/base.py @@ -53,10 +53,10 @@ def watch(self, path, flags, *, alias=None): alias = path if alias in self.requests: raise ValueError("A watch request is already scheduled for alias %s" % alias) - self.requests[alias] = (path, flags) if self._fd is not None: # We've started, register the watch immediately. self._setup_watch(alias, path, flags) + self.requests[alias] = (path, flags) def unwatch(self, alias): """Stop watching a given rule.""" diff --git a/tests/test_usage.py b/tests/test_usage.py index f156291..1bf26e5 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -197,6 +197,20 @@ def test_rename_detection(self): # And it's over. yield from self._assert_no_events() + @asyncio.coroutine + def test_watch_after_created(self): + """It should be possible to retry watching a file that didn't exist.""" + yield from self.watcher.setup(self.loop) + + full_path = os.path.join(self.testdir, 'a') + with self.assertRaises(OSError): + self.watcher.watch(full_path, aionotify.Flags.MODIFY) + + self._touch('a') + self.watcher.watch(full_path, aionotify.Flags.MODIFY) + + yield from self._assert_no_events() + class ErrorTests(AIONotifyTestCase): """Test error cases."""