diff hgext/fsmonitor/__init__.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents 9f2189b6bf2a
children 687b865b95ad
line wrap: on
line diff
--- a/hgext/fsmonitor/__init__.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/hgext/fsmonitor/__init__.py	Sun Oct 06 09:45:02 2019 -0400
@@ -116,9 +116,7 @@
 import weakref
 
 from mercurial.i18n import _
-from mercurial.node import (
-    hex,
-)
+from mercurial.node import hex
 
 from mercurial import (
     context,
@@ -150,50 +148,60 @@
 configtable = {}
 configitem = registrar.configitem(configtable)
 
-configitem('fsmonitor', 'mode',
-    default='on',
+configitem(
+    'fsmonitor', 'mode', default='on',
 )
-configitem('fsmonitor', 'walk_on_invalidate',
-    default=False,
+configitem(
+    'fsmonitor', 'walk_on_invalidate', default=False,
 )
-configitem('fsmonitor', 'timeout',
-    default='2',
+configitem(
+    'fsmonitor', 'timeout', default='2',
 )
-configitem('fsmonitor', 'blacklistusers',
-    default=list,
+configitem(
+    'fsmonitor', 'blacklistusers', default=list,
 )
-configitem('fsmonitor', 'watchman_exe',
-    default='watchman',
+configitem(
+    'fsmonitor', 'watchman_exe', default='watchman',
 )
-configitem('fsmonitor', 'verbose',
-    default=True,
-    experimental=True,
+configitem(
+    'fsmonitor', 'verbose', default=True, experimental=True,
 )
-configitem('experimental', 'fsmonitor.transaction_notify',
-    default=False,
+configitem(
+    'experimental', 'fsmonitor.transaction_notify', default=False,
 )
 
 # This extension is incompatible with the following blacklisted extensions
 # and will disable itself when encountering one of these:
 _blacklist = ['largefiles', 'eol']
 
+
 def debuginstall(ui, fm):
-    fm.write("fsmonitor-watchman",
-             _("fsmonitor checking for watchman binary... (%s)\n"),
-               ui.configpath("fsmonitor", "watchman_exe"))
+    fm.write(
+        "fsmonitor-watchman",
+        _("fsmonitor checking for watchman binary... (%s)\n"),
+        ui.configpath("fsmonitor", "watchman_exe"),
+    )
     root = tempfile.mkdtemp()
     c = watchmanclient.client(ui, root)
     err = None
     try:
         v = c.command("version")
-        fm.write("fsmonitor-watchman-version",
-                 _(" watchman binary version %s\n"), v["version"])
+        fm.write(
+            "fsmonitor-watchman-version",
+            _(" watchman binary version %s\n"),
+            v["version"],
+        )
     except watchmanclient.Unavailable as e:
         err = str(e)
-    fm.condwrite(err, "fsmonitor-watchman-error",
-                 _(" watchman binary missing or broken: %s\n"), err)
+    fm.condwrite(
+        err,
+        "fsmonitor-watchman-error",
+        _(" watchman binary missing or broken: %s\n"),
+        err,
+    )
     return 1 if err else 0
 
+
 def _handleunavailable(ui, state, ex):
     """Exception handler for Watchman interaction exceptions"""
     if isinstance(ex, watchmanclient.Unavailable):
@@ -209,6 +217,7 @@
     else:
         ui.log('fsmonitor', 'Watchman exception: %s\n', ex)
 
+
 def _hashignore(ignore):
     """Calculate hash for ignore patterns and filenames
 
@@ -221,10 +230,12 @@
     sha1.update(repr(ignore))
     return sha1.hexdigest()
 
+
 _watchmanencoding = pywatchman.encoding.get_local_encoding()
 _fsencoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
 _fixencoding = codecs.lookup(_watchmanencoding) != codecs.lookup(_fsencoding)
 
+
 def _watchmantofsencoding(path):
     """Fix path to match watchman and local filesystem encoding
 
@@ -243,12 +254,14 @@
 
     return encoded
 
+
 def overridewalk(orig, self, match, subrepos, unknown, ignored, full=True):
     '''Replacement for dirstate.walk, hooking into Watchman.
 
     Whenever full is False, ignored is False, and the Watchman client is
     available, use Watchman combined with saved state to possibly return only a
     subset of files.'''
+
     def bail(reason):
         self._ui.debug('fsmonitor: fallback to core status, %s\n' % reason)
         return orig(match, subrepos, unknown, ignored, full=True)
@@ -335,18 +348,19 @@
         # Add a little slack over the top of the user query to allow for
         # overheads while transferring the data
         self._watchmanclient.settimeout(state.timeout + 0.1)
-        result = self._watchmanclient.command('query', {
-            'fields': ['mode', 'mtime', 'size', 'exists', 'name'],
-            'since': clock,
-            'expression': [
-                'not', [
-                    'anyof', ['dirname', '.hg'],
-                    ['name', '.hg', 'wholename']
-                ]
-            ],
-            'sync_timeout': int(state.timeout * 1000),
-            'empty_on_fresh_instance': state.walk_on_invalidate,
-        })
+        result = self._watchmanclient.command(
+            'query',
+            {
+                'fields': ['mode', 'mtime', 'size', 'exists', 'name'],
+                'since': clock,
+                'expression': [
+                    'not',
+                    ['anyof', ['dirname', '.hg'], ['name', '.hg', 'wholename']],
+                ],
+                'sync_timeout': int(state.timeout * 1000),
+                'empty_on_fresh_instance': state.walk_on_invalidate,
+            },
+        )
     except Exception as ex:
         _handleunavailable(self._ui, state, ex)
         self._watchmanclient.clearconnection()
@@ -398,8 +412,11 @@
             # record, mark it as deleted.  If we already have an entry
             # for fname then it was either part of walkexplicit or was
             # an earlier result that was a case change
-            if fname not in results and fname in dmap and (
-                    matchalways or matchfn(fname)):
+            if (
+                fname not in results
+                and fname in dmap
+                and (matchalways or matchfn(fname))
+            ):
                 results[fname] = None
         elif kind == dirkind:
             if fname in dmap and (matchalways or matchfn(fname)):
@@ -418,29 +435,43 @@
     if normalize:
         # any notable files that have changed case will already be handled
         # above, so just check membership in the foldmap
-        notefiles = set((normalize(f, True, True) for f in notefiles
-                         if normcase(f) not in foldmap))
-    visit = set((f for f in notefiles if (f not in results and matchfn(f)
-                                          and (f in dmap or not ignore(f)))))
+        notefiles = set(
+            (
+                normalize(f, True, True)
+                for f in notefiles
+                if normcase(f) not in foldmap
+            )
+        )
+    visit = set(
+        (
+            f
+            for f in notefiles
+            if (
+                f not in results and matchfn(f) and (f in dmap or not ignore(f))
+            )
+        )
+    )
 
     if not fresh_instance:
         if matchalways:
             visit.update(f for f in nonnormalset if f not in results)
             visit.update(f for f in copymap if f not in results)
         else:
-            visit.update(f for f in nonnormalset
-                         if f not in results and matchfn(f))
-            visit.update(f for f in copymap
-                         if f not in results and matchfn(f))
+            visit.update(
+                f for f in nonnormalset if f not in results and matchfn(f)
+            )
+            visit.update(f for f in copymap if f not in results and matchfn(f))
     else:
         if matchalways:
             visit.update(f for f, st in dmap.iteritems() if f not in results)
             visit.update(f for f in copymap if f not in results)
         else:
-            visit.update(f for f, st in dmap.iteritems()
-                         if f not in results and matchfn(f))
-            visit.update(f for f in copymap
-                         if f not in results and matchfn(f))
+            visit.update(
+                f
+                for f, st in dmap.iteritems()
+                if f not in results and matchfn(f)
+            )
+            visit.update(f for f in copymap if f not in results and matchfn(f))
 
     audit = pathutil.pathauditor(self._root, cached=True).check
     auditpass = [f for f in visit if audit(f)]
@@ -460,9 +491,18 @@
     del results['.hg']
     return results
 
+
 def overridestatus(
-        orig, self, node1='.', node2=None, match=None, ignored=False,
-        clean=False, unknown=False, listsubrepos=False):
+    orig,
+    self,
+    node1='.',
+    node2=None,
+    match=None,
+    ignored=False,
+    clean=False,
+    unknown=False,
+    listsubrepos=False,
+):
     listignored = ignored
     listclean = clean
     listunknown = unknown
@@ -508,10 +548,12 @@
     # HG_PENDING is set in the environment when the dirstate is being updated
     # in the middle of a transaction; we must not update our state in that
     # case, or we risk forgetting about changes in the working copy.
-    updatestate = (parentworking and match.always() and
-                   not isinstance(ctx2, (context.workingcommitctx,
-                                         context.memctx)) and
-                   'HG_PENDING' not in encoding.environ)
+    updatestate = (
+        parentworking
+        and match.always()
+        and not isinstance(ctx2, (context.workingcommitctx, context.memctx))
+        and 'HG_PENDING' not in encoding.environ
+    )
 
     try:
         if self._fsmonitorstate.walk_on_invalidate:
@@ -528,15 +570,21 @@
             # and return the initial clock.  In this mode we assume that
             # the filesystem will be slower than parsing a potentially
             # very large Watchman result set.
-            self._watchmanclient.settimeout(
-                self._fsmonitorstate.timeout + 0.1)
+            self._watchmanclient.settimeout(self._fsmonitorstate.timeout + 0.1)
         startclock = self._watchmanclient.getcurrentclock()
     except Exception as ex:
         self._watchmanclient.clearconnection()
         _handleunavailable(self.ui, self._fsmonitorstate, ex)
         # boo, Watchman failed. bail
-        return orig(node1, node2, match, listignored, listclean,
-                    listunknown, listsubrepos)
+        return orig(
+            node1,
+            node2,
+            match,
+            listignored,
+            listclean,
+            listunknown,
+            listsubrepos,
+        )
 
     if updatestate:
         # We need info about unknown files. This may make things slower the
@@ -549,8 +597,9 @@
         ps = poststatus(startclock)
         self.addpostdsstatus(ps)
 
-    r = orig(node1, node2, match, listignored, listclean, stateunknown,
-             listsubrepos)
+    r = orig(
+        node1, node2, match, listignored, listclean, stateunknown, listsubrepos
+    )
     modified, added, removed, deleted, unknown, ignored, clean = r
 
     if not listunknown:
@@ -570,8 +619,14 @@
 
         try:
             rv2 = orig(
-                node1, node2, match, listignored, listclean, listunknown,
-                listsubrepos)
+                node1,
+                node2,
+                match,
+                listignored,
+                listclean,
+                listunknown,
+                listsubrepos,
+            )
         finally:
             self.dirstate._fsmonitordisable = False
             self.ui.quiet = quiet
@@ -581,11 +636,14 @@
         with self.wlock():
             _cmpsets(
                 [modified, added, removed, deleted, unknown, ignored, clean],
-                rv2)
+                rv2,
+            )
         modified, added, removed, deleted, unknown, ignored, clean = rv2
 
     return scmutil.status(
-        modified, added, removed, deleted, unknown, ignored, clean)
+        modified, added, removed, deleted, unknown, ignored, clean
+    )
+
 
 class poststatus(object):
     def __init__(self, startclock):
@@ -594,10 +652,16 @@
     def __call__(self, wctx, status):
         clock = wctx.repo()._fsmonitorstate.getlastclock() or self._startclock
         hashignore = _hashignore(wctx.repo().dirstate._ignore)
-        notefiles = (status.modified + status.added + status.removed +
-                     status.deleted + status.unknown)
+        notefiles = (
+            status.modified
+            + status.added
+            + status.removed
+            + status.deleted
+            + status.unknown
+        )
         wctx.repo()._fsmonitorstate.set(clock, hashignore, notefiles)
 
+
 def makedirstate(repo, dirstate):
     class fsmonitordirstate(dirstate.__class__):
         def _fsmonitorinit(self, repo):
@@ -624,6 +688,7 @@
     dirstate.__class__ = fsmonitordirstate
     dirstate._fsmonitorinit(repo)
 
+
 def wrapdirstate(orig, self):
     ds = orig(self)
     # only override the dirstate when Watchman is available for the repo
@@ -631,15 +696,18 @@
         makedirstate(self, ds)
     return ds
 
+
 def extsetup(ui):
     extensions.wrapfilecache(
-        localrepo.localrepository, 'dirstate', wrapdirstate)
+        localrepo.localrepository, 'dirstate', wrapdirstate
+    )
     if pycompat.isdarwin:
         # An assist for avoiding the dangling-symlink fsevents bug
         extensions.wrapfunction(os, 'symlink', wrapsymlink)
 
     extensions.wrapfunction(merge, 'update', wrapupdate)
 
+
 def wrapsymlink(orig, source, link_name):
     ''' if we create a dangling symlink, also touch the parent dir
     to encourage fsevents notifications to work more correctly '''
@@ -651,6 +719,7 @@
         except OSError:
             pass
 
+
 class state_update(object):
     ''' This context manager is responsible for dispatching the state-enter
         and state-leave signals to the watchman service. The enter and leave
@@ -660,8 +729,15 @@
         leave, respectively. Similarly, if the distance is none, it will be
         calculated based on the oldnode and newnode in the leave method.'''
 
-    def __init__(self, repo, name, oldnode=None, newnode=None, distance=None,
-                 partial=False):
+    def __init__(
+        self,
+        repo,
+        name,
+        oldnode=None,
+        newnode=None,
+        distance=None,
+        partial=False,
+    ):
         self.repo = repo.unfiltered()
         self.name = name
         self.oldnode = oldnode
@@ -687,9 +763,7 @@
                 self._lock = self.repo.wlocknostateupdate()
             else:
                 self._lock = self.repo.wlock()
-        self.need_leave = self._state(
-            'state-enter',
-            hex(self.oldnode))
+        self.need_leave = self._state('state-enter', hex(self.oldnode))
         return self
 
     def __exit__(self, type_, value, tb):
@@ -704,11 +778,9 @@
                     self.newnode = self.repo['.'].node()
                 if self.distance is None:
                     self.distance = calcdistance(
-                        self.repo, self.oldnode, self.newnode)
-                self._state(
-                    'state-leave',
-                    hex(self.newnode),
-                    status=status)
+                        self.repo, self.oldnode, self.newnode
+                    )
+                self._state('state-leave', hex(self.newnode), status=status)
         finally:
             self.need_leave = False
             if self._lock:
@@ -718,39 +790,57 @@
         if not util.safehasattr(self.repo, '_watchmanclient'):
             return False
         try:
-            self.repo._watchmanclient.command(cmd, {
-                'name': self.name,
-                'metadata': {
-                    # the target revision
-                    'rev': commithash,
-                    # approximate number of commits between current and target
-                    'distance': self.distance if self.distance else 0,
-                    # success/failure (only really meaningful for state-leave)
-                    'status': status,
-                    # whether the working copy parent is changing
-                    'partial': self.partial,
-            }})
+            self.repo._watchmanclient.command(
+                cmd,
+                {
+                    'name': self.name,
+                    'metadata': {
+                        # the target revision
+                        'rev': commithash,
+                        # approximate number of commits between current and target
+                        'distance': self.distance if self.distance else 0,
+                        # success/failure (only really meaningful for state-leave)
+                        'status': status,
+                        # whether the working copy parent is changing
+                        'partial': self.partial,
+                    },
+                },
+            )
             return True
         except Exception as e:
             # Swallow any errors; fire and forget
             self.repo.ui.log(
-                'watchman', 'Exception %s while running %s\n', e, cmd)
+                'watchman', 'Exception %s while running %s\n', e, cmd
+            )
             return False
 
+
 # Estimate the distance between two nodes
 def calcdistance(repo, oldnode, newnode):
     anc = repo.changelog.ancestor(oldnode, newnode)
     ancrev = repo[anc].rev()
-    distance = (abs(repo[oldnode].rev() - ancrev)
-        + abs(repo[newnode].rev() - ancrev))
+    distance = abs(repo[oldnode].rev() - ancrev) + abs(
+        repo[newnode].rev() - ancrev
+    )
     return distance
 
+
 # Bracket working copy updates with calls to the watchman state-enter
 # and state-leave commands.  This allows clients to perform more intelligent
 # settling during bulk file change scenarios
 # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling
-def wrapupdate(orig, repo, node, branchmerge, force, ancestor=None,
-               mergeancestor=False, labels=None, matcher=None, **kwargs):
+def wrapupdate(
+    orig,
+    repo,
+    node,
+    branchmerge,
+    force,
+    ancestor=None,
+    mergeancestor=False,
+    labels=None,
+    matcher=None,
+    **kwargs
+):
 
     distance = 0
     partial = True
@@ -760,11 +850,26 @@
         partial = False
         distance = calcdistance(repo.unfiltered(), oldnode, newnode)
 
-    with state_update(repo, name="hg.update", oldnode=oldnode, newnode=newnode,
-                      distance=distance, partial=partial):
+    with state_update(
+        repo,
+        name="hg.update",
+        oldnode=oldnode,
+        newnode=newnode,
+        distance=distance,
+        partial=partial,
+    ):
         return orig(
-            repo, node, branchmerge, force, ancestor, mergeancestor,
-            labels, matcher, **kwargs)
+            repo,
+            node,
+            branchmerge,
+            force,
+            ancestor,
+            mergeancestor,
+            labels,
+            matcher,
+            **kwargs
+        )
+
 
 def repo_has_depth_one_nested_repo(repo):
     for f in repo.wvfs.listdir():
@@ -774,13 +879,19 @@
             return True
     return False
 
+
 def reposetup(ui, repo):
     # We don't work with largefiles or inotify
     exts = extensions.enabled()
     for ext in _blacklist:
         if ext in exts:
-            ui.warn(_('The fsmonitor extension is incompatible with the %s '
-                      'extension and has been disabled.\n') % ext)
+            ui.warn(
+                _(
+                    'The fsmonitor extension is incompatible with the %s '
+                    'extension and has been disabled.\n'
+                )
+                % ext
+            )
             return
 
     if repo.local():
@@ -824,7 +935,8 @@
             def wlock(self, *args, **kwargs):
                 l = super(fsmonitorrepo, self).wlock(*args, **kwargs)
                 if not ui.configbool(
-                    "experimental", "fsmonitor.transaction_notify"):
+                    "experimental", "fsmonitor.transaction_notify"
+                ):
                     return l
                 if l.held != 1:
                     return l
@@ -844,8 +956,7 @@
                     l.releasefn = staterelease
                 except Exception as e:
                     # Swallow any errors; fire and forget
-                    self.ui.log(
-                        'watchman', 'Exception in state update %s\n', e)
+                    self.ui.log('watchman', 'Exception in state update %s\n', e)
                 return l
 
         repo.__class__ = fsmonitorrepo