commit cef367d5a30420d93301507cf0956eaa30f02e9f from: Jelmer Vernooij date: Tue May 24 16:03:58 2022 UTC Drop inotify-based watch that was always flaky. Fixes #886 commit - 68fee245f414f76c48996c61da8527a7a984e101 commit + cef367d5a30420d93301507cf0956eaa30f02e9f blob - b607e7858e6564a7ff30aafc75bc95bedd204a66 blob + d0f5aac913a25f276b42468a9f032aba5cd125bb --- NEWS +++ NEWS @@ -1,5 +1,8 @@ 0.20.42 UNRELEASED + * Drop ``RefsContainer.watch`` that was always flaky. + (Jelmer Vernooij, #886) + 0.20.41 2022-05-24 * Fix wheel uploading, properly. (Ruslan Kuprieiev) blob - 4420cec17956cbf21104a77d322d3732dbb0cc5e blob + 1a1fc547e1d0a4f8c074ca2bbc52ff21d66589a7 --- dulwich/refs.py +++ dulwich/refs.py @@ -429,37 +429,8 @@ class RefsContainer(object): else: ret[src] = dst return ret - - def watch(self): - """Watch for changes to the refs in this container. - - Returns a context manager that yields tuples with (refname, new_sha) - """ - raise NotImplementedError(self.watch) - - -class _DictRefsWatcher(object): - def __init__(self, refs): - self._refs = refs - - def __enter__(self): - from queue import Queue - - self.queue = Queue() - self._refs._watchers.add(self) - return self - - def __next__(self): - return self.queue.get() - def _notify(self, entry): - self.queue.put_nowait(entry) - def __exit__(self, exc_type, exc_val, exc_tb): - self._refs._watchers.remove(self) - return False - - class DictRefsContainer(RefsContainer): """RefsContainer backed by a simple dict. @@ -486,9 +457,6 @@ class DictRefsContainer(RefsContainer): for watcher in self._watchers: watcher._notify((ref, newsha)) - def watch(self): - return _DictRefsWatcher(self) - def set_symbolic_ref( self, name, @@ -642,50 +610,6 @@ class InfoRefsContainer(RefsContainer): return self._refs[name] -class _InotifyRefsWatcher(object): - def __init__(self, path): - import pyinotify - from queue import Queue - - self.path = os.fsdecode(path) - self.manager = pyinotify.WatchManager() - self.manager.add_watch( - self.path, - pyinotify.IN_DELETE | pyinotify.IN_CLOSE_WRITE | pyinotify.IN_MOVED_TO, - rec=True, - auto_add=True, - ) - - self.notifier = pyinotify.ThreadedNotifier( - self.manager, default_proc_fun=self._notify - ) - self.queue = Queue() - - def _notify(self, event): - if event.dir: - return - if event.pathname.endswith(".lock"): - return - ref = os.fsencode(os.path.relpath(event.pathname, self.path)) - if event.maskname == "IN_DELETE": - self.queue.put_nowait((ref, None)) - elif event.maskname in ("IN_CLOSE_WRITE", "IN_MOVED_TO"): - with open(event.pathname, "rb") as f: - sha = f.readline().rstrip(b"\n\r") - self.queue.put_nowait((ref, sha)) - - def __next__(self): - return self.queue.get() - - def __enter__(self): - self.notifier.start() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.notifier.stop() - return False - - class DiskRefsContainer(RefsContainer): """Refs container that reads refs from disk.""" @@ -1085,12 +1009,7 @@ class DiskRefsContainer(RefsContainer): return True - def watch(self): - import pyinotify # noqa: F401 - return _InotifyRefsWatcher(self.path) - - def _split_ref_line(line): """Split a single ref line into a tuple of SHA1 and name.""" fields = line.rstrip(b"\n\r").split(b" ") blob - cd0a116915e93278f65b6b86369233742c93b37e blob + 47e38a2eb776e39b8b38ad685df9bd3adcc4cc3c --- dulwich/tests/test_refs.py +++ dulwich/tests/test_refs.py @@ -355,40 +355,7 @@ class RefsContainerTests(object): ) self.assertNotIn(b"refs/remotes/origin/other", self._refs) - def test_watch(self): - self.skipTest("watch sometimes hangs") - try: - watcher = self._refs.watch() - except (NotImplementedError, ImportError): - self.skipTest("watching not supported") - with watcher: - self._refs[ - b"refs/remotes/origin/other" - ] = b"48d01bd4b77fed026b154d16493e5deab78f02ec" - change = next(watcher) - self.assertEqual( - ( - b"refs/remotes/origin/other", - b"48d01bd4b77fed026b154d16493e5deab78f02ec", - ), - change, - ) - self._refs[ - b"refs/remotes/origin/other" - ] = b"48d01bd4b77fed026b154d16493e5deab78f02ed" - change = next(watcher) - self.assertEqual( - ( - b"refs/remotes/origin/other", - b"48d01bd4b77fed026b154d16493e5deab78f02ed", - ), - change, - ) - del self._refs[b"refs/remotes/origin/other"] - change = next(watcher) - self.assertEqual((b"refs/remotes/origin/other", None), change) - class DictRefsContainerTests(RefsContainerTests, TestCase): def setUp(self): TestCase.setUp(self) blob - 4f2e21a721c32c19ba5d4c4d3753af038c2c17f7 blob + b85a69e625e0293c3cfaa15788a0e83961c3d395 --- setup.py +++ setup.py @@ -78,7 +78,6 @@ if has_setuptools: 'fastimport': ['fastimport'], 'https': ['urllib3[secure]>=1.24.1'], 'pgp': ['gpg'], - 'watch': ['pyinotify'], 'paramiko': ['paramiko'], } setup_kwargs['install_requires'] = ['urllib3>=1.24.1', 'certifi']