commit - 68fee245f414f76c48996c61da8527a7a984e101
commit + cef367d5a30420d93301507cf0956eaa30f02e9f
blob - b607e7858e6564a7ff30aafc75bc95bedd204a66
blob + d0f5aac913a25f276b42468a9f032aba5cd125bb
--- NEWS
+++ NEWS
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
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.
for watcher in self._watchers:
watcher._notify((ref, newsha))
- def watch(self):
- return _DictRefsWatcher(self)
-
def set_symbolic_ref(
self,
name,
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."""
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
)
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
'fastimport': ['fastimport'],
'https': ['urllib3[secure]>=1.24.1'],
'pgp': ['gpg'],
- 'watch': ['pyinotify'],
'paramiko': ['paramiko'],
}
setup_kwargs['install_requires'] = ['urllib3>=1.24.1', 'certifi']