mercurial/revset.py
changeset 43076 2372284d9457
parent 42699 911e25dc9d8c
child 43077 687b865b95ad
--- a/mercurial/revset.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/mercurial/revset.py	Sun Oct 06 09:45:02 2019 -0400
@@ -93,17 +93,19 @@
 #
 # There are a few revsets that always redefine the order if 'define' is
 # specified: 'sort(X)', 'reverse(X)', 'x:y'.
-anyorder = 'any'        # don't care the order, could be even random-shuffled
+anyorder = 'any'  # don't care the order, could be even random-shuffled
 defineorder = 'define'  # ALWAYS redefine, or ALWAYS follow the current order
 followorder = 'follow'  # MUST follow the current order
 
 # helpers
 
+
 def getset(repo, subset, x, order=defineorder):
     if not x:
         raise error.ParseError(_("missing argument"))
     return methods[x[0]](repo, subset, *x[1:], order=order)
 
+
 def _getrevsource(repo, r):
     extra = repo[r].extra()
     for label in ('source', 'transplant_source', 'rebase_source'):
@@ -114,11 +116,14 @@
                 pass
     return None
 
+
 def _sortedb(xs):
     return sorted(pycompat.rapply(pycompat.maybebytestr, xs))
 
+
 # operator methods
 
+
 def stringset(repo, subset, x, order):
     if not x:
         raise error.ParseError(_("empty string is not a valid revision"))
@@ -127,6 +132,7 @@
         return baseset([x])
     return baseset()
 
+
 def rawsmartset(repo, subset, x, order):
     """argument is already a smartset, use that directly"""
     if order == followorder:
@@ -134,6 +140,7 @@
     else:
         return x & subset
 
+
 def rangeset(repo, subset, x, y, order):
     m = getset(repo, fullreposet(repo), x)
     n = getset(repo, fullreposet(repo), y)
@@ -142,10 +149,12 @@
         return baseset()
     return _makerangeset(repo, subset, m.first(), n.last(), order)
 
+
 def rangeall(repo, subset, x, order):
     assert x is None
     return _makerangeset(repo, subset, 0, repo.changelog.tiprev(), order)
 
+
 def rangepre(repo, subset, y, order):
     # ':y' can't be rewritten to '0:y' since '0' may be hidden
     n = getset(repo, fullreposet(repo), y)
@@ -153,12 +162,15 @@
         return baseset()
     return _makerangeset(repo, subset, 0, n.last(), order)
 
+
 def rangepost(repo, subset, x, order):
     m = getset(repo, fullreposet(repo), x)
     if not m:
         return baseset()
-    return _makerangeset(repo, subset, m.first(), repo.changelog.tiprev(),
-                         order)
+    return _makerangeset(
+        repo, subset, m.first(), repo.changelog.tiprev(), order
+    )
+
 
 def _makerangeset(repo, subset, m, n, order):
     if m == n:
@@ -178,12 +190,15 @@
         # carrying the sorting over when possible would be more efficient
         return subset & r
 
+
 def dagrange(repo, subset, x, y, order):
     r = fullreposet(repo)
-    xs = dagop.reachableroots(repo, getset(repo, r, x), getset(repo, r, y),
-                              includepath=True)
+    xs = dagop.reachableroots(
+        repo, getset(repo, r, x), getset(repo, r, y), includepath=True
+    )
     return subset & xs
 
+
 def andset(repo, subset, x, y, order):
     if order == anyorder:
         yorder = anyorder
@@ -191,6 +206,7 @@
         yorder = followorder
     return getset(repo, getset(repo, subset, x, order), y, yorder)
 
+
 def andsmallyset(repo, subset, x, y, order):
     # 'andsmally(x, y)' is equivalent to 'and(x, y)', but faster when y is small
     if order == anyorder:
@@ -199,9 +215,11 @@
         yorder = followorder
     return getset(repo, getset(repo, subset, y, yorder), x, order)
 
+
 def differenceset(repo, subset, x, y, order):
     return getset(repo, subset, x, order) - getset(repo, subset, y, anyorder)
 
+
 def _orsetlist(repo, subset, xs, order):
     assert xs
     if len(xs) == 1:
@@ -211,6 +229,7 @@
     b = _orsetlist(repo, subset, xs[p:], order)
     return a + b
 
+
 def orset(repo, subset, x, order):
     xs = getlist(x)
     if not xs:
@@ -221,12 +240,15 @@
     else:
         return _orsetlist(repo, subset, xs, order)
 
+
 def notset(repo, subset, x, order):
     return subset - getset(repo, subset, x, anyorder)
 
+
 def relationset(repo, subset, x, y, order):
     raise error.ParseError(_("can't use a relation in this context"))
 
+
 def _splitrange(a, b):
     """Split range with bounds a and b into two ranges at 0 and return two
     tuples of numbers for use as startdepth and stopdepth arguments of
@@ -257,14 +279,17 @@
         descdepths = (max(a, 0), b + 1)
     return ancdepths, descdepths
 
+
 def generationsrel(repo, subset, x, rel, z, order):
     # TODO: rewrite tests, and drop startdepth argument from ancestors() and
     # descendants() predicates
-    a, b = getintrange(z,
-                       _('relation subscript must be an integer or a range'),
-                       _('relation subscript bounds must be integers'),
-                       deffirst=-(dagop.maxlogdepth - 1),
-                       deflast=+(dagop.maxlogdepth - 1))
+    a, b = getintrange(
+        z,
+        _('relation subscript must be an integer or a range'),
+        _('relation subscript bounds must be integers'),
+        deffirst=-(dagop.maxlogdepth - 1),
+        deflast=+(dagop.maxlogdepth - 1),
+    )
     (ancstart, ancstop), (descstart, descstop) = _splitrange(a, b)
 
     if ancstart is None and descstart is None:
@@ -284,6 +309,7 @@
 
     return subset & s
 
+
 def relsubscriptset(repo, subset, x, y, z, order):
     # this is pretty basic implementation of 'x#y[z]' operator, still
     # experimental so undocumented. see the wiki for further ideas.
@@ -295,16 +321,22 @@
     relnames = [r for r in subscriptrelations.keys() if len(r) > 1]
     raise error.UnknownIdentifier(rel, relnames)
 
+
 def subscriptset(repo, subset, x, y, order):
     raise error.ParseError(_("can't use a subscript in this context"))
 
+
 def listset(repo, subset, *xs, **opts):
-    raise error.ParseError(_("can't use a list in this context"),
-                           hint=_('see \'hg help "revsets.x or y"\''))
+    raise error.ParseError(
+        _("can't use a list in this context"),
+        hint=_('see \'hg help "revsets.x or y"\''),
+    )
+
 
 def keyvaluepair(repo, subset, k, v, order):
     raise error.ParseError(_("can't use a key-value pair in this context"))
 
+
 def func(repo, subset, a, b, order):
     f = getsymbol(a)
     if f in symbols:
@@ -318,6 +350,7 @@
     syms = [s for (s, fn) in symbols.items() if keep(fn)]
     raise error.UnknownIdentifier(f, syms)
 
+
 # functions
 
 # symbols are callables like:
@@ -335,12 +368,15 @@
 
 predicate = registrar.revsetpredicate()
 
+
 @predicate('_destupdate')
 def _destupdate(repo, subset, x):
     # experimental revset for update destination
     args = getargsdict(x, 'limit', 'clean')
-    return subset & baseset([destutil.destupdate(repo,
-                            **pycompat.strkwargs(args))[0]])
+    return subset & baseset(
+        [destutil.destupdate(repo, **pycompat.strkwargs(args))[0]]
+    )
+
 
 @predicate('_destmerge')
 def _destmerge(repo, subset, x):
@@ -350,6 +386,7 @@
         sourceset = getset(repo, fullreposet(repo), x)
     return subset & baseset([destutil.destmerge(repo, sourceset=sourceset)])
 
+
 @predicate('adds(pattern)', safe=True, weight=30)
 def adds(repo, subset, x):
     """Changesets that add a file matching pattern.
@@ -362,6 +399,7 @@
     pat = getstring(x, _("adds requires a pattern"))
     return checkstatus(repo, subset, pat, 1)
 
+
 @predicate('ancestor(*changeset)', safe=True, weight=0.5)
 def ancestor(repo, subset, x):
     """A greatest common ancestor of the changesets.
@@ -383,14 +421,17 @@
         return baseset([r])
     return baseset()
 
-def _ancestors(repo, subset, x, followfirst=False, startdepth=None,
-               stopdepth=None):
+
+def _ancestors(
+    repo, subset, x, followfirst=False, startdepth=None, stopdepth=None
+):
     heads = getset(repo, fullreposet(repo), x)
     if not heads:
         return baseset()
     s = dagop.revancestors(repo, heads, followfirst, startdepth, stopdepth)
     return subset & s
 
+
 @predicate('ancestors(set[, depth])', safe=True)
 def ancestors(repo, subset, x):
     """Changesets that are ancestors of changesets in set, including the
@@ -406,8 +447,9 @@
         raise error.ParseError(_('ancestors takes at least 1 argument'))
     startdepth = stopdepth = None
     if 'startdepth' in args:
-        n = getinteger(args['startdepth'],
-                       "ancestors expects an integer startdepth")
+        n = getinteger(
+            args['startdepth'], "ancestors expects an integer startdepth"
+        )
         if n < 0:
             raise error.ParseError("negative startdepth")
         startdepth = n
@@ -417,8 +459,10 @@
         if n < 0:
             raise error.ParseError(_("negative depth"))
         stopdepth = n + 1
-    return _ancestors(repo, subset, args['set'],
-                      startdepth=startdepth, stopdepth=stopdepth)
+    return _ancestors(
+        repo, subset, args['set'], startdepth=startdepth, stopdepth=stopdepth
+    )
+
 
 @predicate('_firstancestors', safe=True)
 def _firstancestors(repo, subset, x):
@@ -426,6 +470,7 @@
     # Like ``ancestors(set)`` but follows only the first parents.
     return _ancestors(repo, subset, x, followfirst=True)
 
+
 def _childrenspec(repo, subset, x, n, order):
     """Changesets that are the Nth child of a changeset
     in set.
@@ -438,12 +483,14 @@
                 break
             if len(c) > 1:
                 raise error.RepoLookupError(
-                    _("revision in set has more than one child"))
+                    _("revision in set has more than one child")
+                )
             r = c[0].rev()
         else:
             cs.add(r)
     return subset & cs
 
+
 def ancestorspec(repo, subset, x, n, order):
     """``set~n``
     Changesets that are the Nth ancestor (first parents only) of a changeset
@@ -464,6 +511,7 @@
         ps.add(r)
     return subset & ps
 
+
 @predicate('author(string)', safe=True, weight=10)
 def author(repo, subset, x):
     """Alias for ``user(string)``.
@@ -471,8 +519,10 @@
     # i18n: "author" is a keyword
     n = getstring(x, _("author requires a string"))
     kind, pattern, matcher = _substringmatcher(n, casesensitive=False)
-    return subset.filter(lambda x: matcher(repo[x].user()),
-                         condrepr=('<user %r>', n))
+    return subset.filter(
+        lambda x: matcher(repo[x].user()), condrepr=('<user %r>', n)
+    )
+
 
 @predicate('bisect(string)', safe=True)
 def bisect(repo, subset, x):
@@ -491,12 +541,14 @@
     state = set(hbisect.get(repo, status))
     return subset & state
 
+
 # Backward-compatibility
 # - no help entry so that we do not advertise it any more
 @predicate('bisected', safe=True)
 def bisected(repo, subset, x):
     return bisect(repo, subset, x)
 
+
 @predicate('bookmark([name])', safe=True)
 def bookmark(repo, subset, x):
     """The named bookmark or all bookmarks.
@@ -506,9 +558,11 @@
     # i18n: "bookmark" is a keyword
     args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
     if args:
-        bm = getstring(args[0],
-                       # i18n: "bookmark" is a keyword
-                       _('the argument to bookmark must be a string'))
+        bm = getstring(
+            args[0],
+            # i18n: "bookmark" is a keyword
+            _('the argument to bookmark must be a string'),
+        )
         kind, pattern, matcher = stringutil.stringmatcher(bm)
         bms = set()
         if kind == 'literal':
@@ -516,8 +570,9 @@
                 pattern = repo._bookmarks.expandname(pattern)
             bmrev = repo._bookmarks.get(pattern, None)
             if not bmrev:
-                raise error.RepoLookupError(_("bookmark '%s' does not exist")
-                                            % pattern)
+                raise error.RepoLookupError(
+                    _("bookmark '%s' does not exist") % pattern
+                )
             bms.add(repo[bmrev].rev())
         else:
             matchrevs = set()
@@ -531,6 +586,7 @@
     bms -= {node.nullrev}
     return subset & bms
 
+
 @predicate('branch(string or set)', safe=True, weight=10)
 def branch(repo, subset, x):
     """
@@ -541,6 +597,7 @@
     :hg:`help revisions.patterns`.
     """
     getbi = repo.revbranchcache().branchinfo
+
     def getbranch(r):
         try:
             return getbi(r)[0]
@@ -558,22 +615,28 @@
             # note: falls through to the revspec case if no branch with
             # this name exists and pattern kind is not specified explicitly
             if repo.branchmap().hasbranch(pattern):
-                return subset.filter(lambda r: matcher(getbranch(r)),
-                                     condrepr=('<branch %r>', b))
+                return subset.filter(
+                    lambda r: matcher(getbranch(r)), condrepr=('<branch %r>', b)
+                )
             if b.startswith('literal:'):
-                raise error.RepoLookupError(_("branch '%s' does not exist")
-                                            % pattern)
+                raise error.RepoLookupError(
+                    _("branch '%s' does not exist") % pattern
+                )
         else:
-            return subset.filter(lambda r: matcher(getbranch(r)),
-                                 condrepr=('<branch %r>', b))
+            return subset.filter(
+                lambda r: matcher(getbranch(r)), condrepr=('<branch %r>', b)
+            )
 
     s = getset(repo, fullreposet(repo), x)
     b = set()
     for r in s:
         b.add(getbranch(r))
     c = s.__contains__
-    return subset.filter(lambda r: c(r) or getbranch(r) in b,
-                         condrepr=lambda: '<branch %r>' % _sortedb(b))
+    return subset.filter(
+        lambda r: c(r) or getbranch(r) in b,
+        condrepr=lambda: '<branch %r>' % _sortedb(b),
+    )
+
 
 @predicate('phasedivergent()', safe=True)
 def phasedivergent(repo, subset, x):
@@ -587,6 +650,7 @@
     phasedivergent = obsmod.getrevs(repo, 'phasedivergent')
     return subset & phasedivergent
 
+
 @predicate('bundle()', safe=True)
 def bundle(repo, subset, x):
     """Changesets in the bundle.
@@ -599,6 +663,7 @@
         raise error.Abort(_("no bundle provided - specify with -R"))
     return subset & bundlerevs
 
+
 def checkstatus(repo, subset, pat, field):
     """Helper for status-related revsets (adds, removes, modifies).
     The field parameter says which kind is desired:
@@ -609,6 +674,7 @@
     hasset = matchmod.patkind(pat) == 'set'
 
     mcache = [None]
+
     def matches(x):
         c = repo[x]
         if not mcache[0] or hasset:
@@ -637,6 +703,7 @@
 
     return subset.filter(matches, condrepr=('<status[%r] %r>', field, pat))
 
+
 def _children(repo, subset, parentset):
     if not parentset:
         return baseset()
@@ -654,6 +721,7 @@
             cs.add(r)
     return baseset(cs)
 
+
 @predicate('children(set)', safe=True)
 def children(repo, subset, x):
     """Child changesets of changesets in set.
@@ -662,14 +730,17 @@
     cs = _children(repo, subset, s)
     return subset & cs
 
+
 @predicate('closed()', safe=True, weight=10)
 def closed(repo, subset, x):
     """Changeset is closed.
     """
     # i18n: "closed" is a keyword
     getargs(x, 0, 0, _("closed takes no arguments"))
-    return subset.filter(lambda r: repo[r].closesbranch(),
-                         condrepr='<branch closed>')
+    return subset.filter(
+        lambda r: repo[r].closesbranch(), condrepr='<branch closed>'
+    )
+
 
 # for internal use
 @predicate('_commonancestorheads(set)', safe=True)
@@ -684,6 +755,7 @@
     ancs = repo.changelog._commonancestorsheads(*list(startrevs))
     return subset & baseset(ancs)
 
+
 @predicate('commonancestors(set)', safe=True)
 def commonancestors(repo, subset, x):
     """Changesets that are ancestors of every changeset in set.
@@ -695,6 +767,7 @@
         subset &= dagop.revancestors(repo, baseset([r]))
     return subset
 
+
 @predicate('contains(pattern)', weight=100)
 def contains(repo, subset, x):
     """The revision's manifest contains a file matching pattern (but might not
@@ -722,6 +795,7 @@
 
     return subset.filter(matches, condrepr=('<contains %r>', pat))
 
+
 @predicate('converted([id])', safe=True)
 def converted(repo, subset, x):
     """Changesets converted from the given identifier in the old repository if
@@ -742,8 +816,10 @@
         source = repo[r].extra().get('convert_revision', None)
         return source is not None and (rev is None or source.startswith(rev))
 
-    return subset.filter(lambda r: _matchvalue(r),
-                         condrepr=('<converted %r>', rev))
+    return subset.filter(
+        lambda r: _matchvalue(r), condrepr=('<converted %r>', rev)
+    )
+
 
 @predicate('date(interval)', safe=True, weight=10)
 def date(repo, subset, x):
@@ -752,8 +828,10 @@
     # i18n: "date" is a keyword
     ds = getstring(x, _("date requires a string"))
     dm = dateutil.matchdate(ds)
-    return subset.filter(lambda x: dm(repo[x].date()[0]),
-                         condrepr=('<date %r>', ds))
+    return subset.filter(
+        lambda x: dm(repo[x].date()[0]), condrepr=('<date %r>', ds)
+    )
+
 
 @predicate('desc(string)', safe=True, weight=10)
 def desc(repo, subset, x):
@@ -767,17 +845,21 @@
 
     kind, pattern, matcher = _substringmatcher(ds, casesensitive=False)
 
-    return subset.filter(lambda r: matcher(repo[r].description()),
-                         condrepr=('<desc %r>', ds))
-
-def _descendants(repo, subset, x, followfirst=False, startdepth=None,
-                 stopdepth=None):
+    return subset.filter(
+        lambda r: matcher(repo[r].description()), condrepr=('<desc %r>', ds)
+    )
+
+
+def _descendants(
+    repo, subset, x, followfirst=False, startdepth=None, stopdepth=None
+):
     roots = getset(repo, fullreposet(repo), x)
     if not roots:
         return baseset()
     s = dagop.revdescendants(repo, roots, followfirst, startdepth, stopdepth)
     return subset & s
 
+
 @predicate('descendants(set[, depth])', safe=True)
 def descendants(repo, subset, x):
     """Changesets which are descendants of changesets in set, including the
@@ -793,8 +875,9 @@
         raise error.ParseError(_('descendants takes at least 1 argument'))
     startdepth = stopdepth = None
     if 'startdepth' in args:
-        n = getinteger(args['startdepth'],
-                       "descendants expects an integer startdepth")
+        n = getinteger(
+            args['startdepth'], "descendants expects an integer startdepth"
+        )
         if n < 0:
             raise error.ParseError("negative startdepth")
         startdepth = n
@@ -804,8 +887,10 @@
         if n < 0:
             raise error.ParseError(_("negative depth"))
         stopdepth = n + 1
-    return _descendants(repo, subset, args['set'],
-                        startdepth=startdepth, stopdepth=stopdepth)
+    return _descendants(
+        repo, subset, args['set'], startdepth=startdepth, stopdepth=stopdepth
+    )
+
 
 @predicate('_firstdescendants', safe=True)
 def _firstdescendants(repo, subset, x):
@@ -813,6 +898,7 @@
     # Like ``descendants(set)`` but follows only the first parents.
     return _descendants(repo, subset, x, followfirst=True)
 
+
 @predicate('destination([set])', safe=True, weight=10)
 def destination(repo, subset, x):
     """Changesets that were created by a graft, transplant or rebase operation,
@@ -855,8 +941,11 @@
             r = src
             src = _getrevsource(repo, r)
 
-    return subset.filter(dests.__contains__,
-                         condrepr=lambda: '<destination %r>' % _sortedb(dests))
+    return subset.filter(
+        dests.__contains__,
+        condrepr=lambda: '<destination %r>' % _sortedb(dests),
+    )
+
 
 @predicate('contentdivergent()', safe=True)
 def contentdivergent(repo, subset, x):
@@ -869,6 +958,7 @@
     contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
     return subset & contentdivergent
 
+
 @predicate('expectsize(set[, size])', safe=True, takeorder=True)
 def expectsize(repo, subset, x, order):
     """Return the given revset if size matches the revset size.
@@ -884,21 +974,25 @@
     err = ''
     if 'size' not in args or 'set' not in args:
         raise error.ParseError(_('invalid set of arguments'))
-    minsize, maxsize = getintrange(args['size'],
-                                   _('expectsize requires a size range'
-                                     ' or a positive integer'),
-                                   _('size range bounds must be integers'),
-                                   minsize, maxsize)
+    minsize, maxsize = getintrange(
+        args['size'],
+        _('expectsize requires a size range' ' or a positive integer'),
+        _('size range bounds must be integers'),
+        minsize,
+        maxsize,
+    )
     if minsize < 0 or maxsize < 0:
         raise error.ParseError(_('negative size'))
     rev = getset(repo, fullreposet(repo), args['set'], order=order)
     if minsize != maxsize and (len(rev) < minsize or len(rev) > maxsize):
-        err = _('revset size mismatch.'
-                ' expected between %d and %d, got %d') % (minsize, maxsize,
-                                                          len(rev))
+        err = _(
+            'revset size mismatch.' ' expected between %d and %d, got %d'
+        ) % (minsize, maxsize, len(rev))
     elif minsize == maxsize and len(rev) != minsize:
-        err = _('revset size mismatch.'
-                ' expected %d, got %d') % (minsize, len(rev))
+        err = _('revset size mismatch.' ' expected %d, got %d') % (
+            minsize,
+            len(rev),
+        )
     if err:
         raise error.RepoLookupError(err)
     if order == followorder:
@@ -906,17 +1000,21 @@
     else:
         return rev & subset
 
+
 @predicate('extdata(source)', safe=False, weight=100)
 def extdata(repo, subset, x):
     """Changesets in the specified extdata source. (EXPERIMENTAL)"""
     # i18n: "extdata" is a keyword
     args = getargsdict(x, 'extdata', 'source')
-    source = getstring(args.get('source'),
-                       # i18n: "extdata" is a keyword
-                       _('extdata takes at least 1 string argument'))
+    source = getstring(
+        args.get('source'),
+        # i18n: "extdata" is a keyword
+        _('extdata takes at least 1 string argument'),
+    )
     data = scmutil.extdatasource(repo, source)
     return subset & baseset(data)
 
+
 @predicate('extinct()', safe=True)
 def extinct(repo, subset, x):
     """Obsolete changesets with obsolete descendants only.
@@ -926,6 +1024,7 @@
     extincts = obsmod.getrevs(repo, 'extinct')
     return subset & extincts
 
+
 @predicate('extra(label, [value])', safe=True)
 def extra(repo, subset, x):
     """Changesets with the given label in the extra metadata, with the given
@@ -939,22 +1038,26 @@
         # i18n: "extra" is a keyword
         raise error.ParseError(_('extra takes at least 1 argument'))
     # i18n: "extra" is a keyword
-    label = getstring(args['label'], _('first argument to extra must be '
-                                       'a string'))
+    label = getstring(
+        args['label'], _('first argument to extra must be ' 'a string')
+    )
     value = None
 
     if 'value' in args:
         # i18n: "extra" is a keyword
-        value = getstring(args['value'], _('second argument to extra must be '
-                                           'a string'))
+        value = getstring(
+            args['value'], _('second argument to extra must be ' 'a string')
+        )
         kind, value, matcher = stringutil.stringmatcher(value)
 
     def _matchvalue(r):
         extra = repo[r].extra()
         return label in extra and (value is None or matcher(extra[label]))
 
-    return subset.filter(lambda r: _matchvalue(r),
-                         condrepr=('<extra[%r] %r>', label, value))
+    return subset.filter(
+        lambda r: _matchvalue(r), condrepr=('<extra[%r] %r>', label, value)
+    )
+
 
 @predicate('filelog(pattern)', safe=True)
 def filelog(repo, subset, x):
@@ -1019,12 +1122,14 @@
 
     return subset & s
 
+
 @predicate('first(set, [n])', safe=True, takeorder=True, weight=0)
 def first(repo, subset, x, order):
     """An alias for limit().
     """
     return limit(repo, subset, x, order)
 
+
 def _follow(repo, subset, x, name, followfirst=False):
     args = getargsdict(x, name, 'file startrev')
     revs = None
@@ -1039,8 +1144,9 @@
             ctx = mctx = repo[r]
             if r is None:
                 ctx = repo['.']
-            m = matchmod.match(repo.root, repo.getcwd(), [x],
-                               ctx=mctx, default='path')
+            m = matchmod.match(
+                repo.root, repo.getcwd(), [x], ctx=mctx, default='path'
+            )
             fctxs.extend(ctx[f].introfilectx() for f in ctx.manifest().walk(m))
         s = dagop.filerevancestors(fctxs, followfirst)
     else:
@@ -1050,6 +1156,7 @@
 
     return subset & s
 
+
 @predicate('follow([file[, startrev]])', safe=True)
 def follow(repo, subset, x):
     """
@@ -1059,6 +1166,7 @@
     """
     return _follow(repo, subset, x, 'follow')
 
+
 @predicate('_followfirst', safe=True)
 def _followfirst(repo, subset, x):
     # ``followfirst([file[, startrev]])``
@@ -1066,8 +1174,10 @@
     # of every revisions or files revisions.
     return _follow(repo, subset, x, '_followfirst', followfirst=True)
 
-@predicate('followlines(file, fromline:toline[, startrev=., descend=False])',
-           safe=True)
+
+@predicate(
+    'followlines(file, fromline:toline[, startrev=., descend=False])', safe=True
+)
 def followlines(repo, subset, x):
     """Changesets modifying `file` in line range ('fromline', 'toline').
 
@@ -1089,7 +1199,8 @@
         if len(revs) != 1:
             raise error.ParseError(
                 # i18n: "followlines" is a keyword
-                _("followlines expects exactly one revision"))
+                _("followlines expects exactly one revision")
+            )
         rev = revs.last()
 
     pat = getstring(args['file'], _("followlines requires a pattern"))
@@ -1097,29 +1208,45 @@
     msg = _("followlines expects exactly one file")
     fname = scmutil.parsefollowlinespattern(repo, rev, pat, msg)
     fromline, toline = util.processlinerange(
-        *getintrange(args['lines'][0],
-                     # i18n: "followlines" is a keyword
-                     _("followlines expects a line number or a range"),
-                     _("line range bounds must be integers")))
+        *getintrange(
+            args['lines'][0],
+            # i18n: "followlines" is a keyword
+            _("followlines expects a line number or a range"),
+            _("line range bounds must be integers"),
+        )
+    )
 
     fctx = repo[rev].filectx(fname)
     descend = False
     if 'descend' in args:
-        descend = getboolean(args['descend'],
-                             # i18n: "descend" is a keyword
-                             _("descend argument must be a boolean"))
+        descend = getboolean(
+            args['descend'],
+            # i18n: "descend" is a keyword
+            _("descend argument must be a boolean"),
+        )
     if descend:
         rs = generatorset(
-            (c.rev() for c, _linerange
-             in dagop.blockdescendants(fctx, fromline, toline)),
-            iterasc=True)
+            (
+                c.rev()
+                for c, _linerange in dagop.blockdescendants(
+                    fctx, fromline, toline
+                )
+            ),
+            iterasc=True,
+        )
     else:
         rs = generatorset(
-            (c.rev() for c, _linerange
-             in dagop.blockancestors(fctx, fromline, toline)),
-            iterasc=False)
+            (
+                c.rev()
+                for c, _linerange in dagop.blockancestors(
+                    fctx, fromline, toline
+                )
+            ),
+            iterasc=False,
+        )
     return subset & rs
 
+
 @predicate('all()', safe=True)
 def getall(repo, subset, x):
     """All changesets, the same as ``0:tip``.
@@ -1128,6 +1255,7 @@
     getargs(x, 0, 0, _("all takes no arguments"))
     return subset & spanset(repo)  # drop "null" if any
 
+
 @predicate('grep(regex)', weight=10)
 def grep(repo, subset, x):
     """Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
@@ -1139,7 +1267,8 @@
         gr = re.compile(getstring(x, _("grep requires a string")))
     except re.error as e:
         raise error.ParseError(
-            _('invalid match pattern: %s') % stringutil.forcebytestr(e))
+            _('invalid match pattern: %s') % stringutil.forcebytestr(e)
+        )
 
     def matches(x):
         c = repo[x]
@@ -1150,6 +1279,7 @@
 
     return subset.filter(matches, condrepr=('<grep %r>', gr.pattern))
 
+
 @predicate('_matchfiles', safe=True)
 def _matchfiles(repo, subset, x):
     # _matchfiles takes a revset list of prefixed arguments:
@@ -1178,16 +1308,18 @@
             exc.append(value)
         elif prefix == 'r:':
             if rev is not None:
-                raise error.ParseError('_matchfiles expected at most one '
-                                       'revision')
-            if value == '': # empty means working directory
+                raise error.ParseError(
+                    '_matchfiles expected at most one ' 'revision'
+                )
+            if value == '':  # empty means working directory
                 rev = node.wdirrev
             else:
                 rev = value
         elif prefix == 'd:':
             if default is not None:
-                raise error.ParseError('_matchfiles expected at most one '
-                                       'default mode')
+                raise error.ParseError(
+                    '_matchfiles expected at most one ' 'default mode'
+                )
             default = value
         else:
             raise error.ParseError('invalid _matchfiles prefix: %s' % prefix)
@@ -1201,6 +1333,7 @@
     # revisions is quite expensive.
     getfiles = repo.changelog.readfiles
     wdirrev = node.wdirrev
+
     def matches(x):
         if x == wdirrev:
             files = repo[x].files()
@@ -1209,9 +1342,15 @@
 
         if not mcache[0] or (hasset and rev is None):
             r = x if rev is None else rev
-            mcache[0] = matchmod.match(repo.root, repo.getcwd(), pats,
-                                       include=inc, exclude=exc, ctx=repo[r],
-                                       default=default)
+            mcache[0] = matchmod.match(
+                repo.root,
+                repo.getcwd(),
+                pats,
+                include=inc,
+                exclude=exc,
+                ctx=repo[r],
+                default=default,
+            )
         m = mcache[0]
 
         for f in files:
@@ -1219,10 +1358,19 @@
                 return True
         return False
 
-    return subset.filter(matches,
-                         condrepr=('<matchfiles patterns=%r, include=%r '
-                                   'exclude=%r, default=%r, rev=%r>',
-                                   pats, inc, exc, default, rev))
+    return subset.filter(
+        matches,
+        condrepr=(
+            '<matchfiles patterns=%r, include=%r '
+            'exclude=%r, default=%r, rev=%r>',
+            pats,
+            inc,
+            exc,
+            default,
+            rev,
+        ),
+    )
+
 
 @predicate('file(pattern)', safe=True, weight=10)
 def hasfile(repo, subset, x):
@@ -1237,6 +1385,7 @@
     pat = getstring(x, _("file requires a pattern"))
     return _matchfiles(repo, subset, ('string', 'p:' + pat))
 
+
 @predicate('head()', safe=True)
 def head(repo, subset, x):
     """Changeset is a named branch head.
@@ -1249,6 +1398,7 @@
         hs.update(cl.rev(h) for h in ls)
     return subset & baseset(hs)
 
+
 @predicate('heads(set)', safe=True, takeorder=True)
 def heads(repo, subset, x, order):
     """Members of set with no children in set.
@@ -1270,6 +1420,7 @@
     heads = baseset(heads)
     return subset & heads
 
+
 @predicate('hidden()', safe=True)
 def hidden(repo, subset, x):
     """Hidden changesets.
@@ -1279,6 +1430,7 @@
     hiddenrevs = repoview.filterrevs(repo, 'visible')
     return subset & hiddenrevs
 
+
 @predicate('keyword(string)', safe=True, weight=10)
 def keyword(repo, subset, x):
     """Search commit message, user name, and names of changed files for
@@ -1292,11 +1444,14 @@
 
     def matches(r):
         c = repo[r]
-        return any(kw in encoding.lower(t)
-                   for t in c.files() + [c.user(), c.description()])
+        return any(
+            kw in encoding.lower(t)
+            for t in c.files() + [c.user(), c.description()]
+        )
 
     return subset.filter(matches, condrepr=('<keyword %r>', kw))
 
+
 @predicate('limit(set[, n[, offset]])', safe=True, takeorder=True, weight=0)
 def limit(repo, subset, x, order):
     """First n members of set, defaulting to 1, starting from offset.
@@ -1319,6 +1474,7 @@
         return subset & ls
     return ls & subset
 
+
 @predicate('last(set, [n])', safe=True, takeorder=True)
 def last(repo, subset, x, order):
     """Last n members of set, defaulting to 1.
@@ -1339,6 +1495,7 @@
     ls.reverse()
     return ls & subset
 
+
 @predicate('max(set)', safe=True)
 def maxrev(repo, subset, x):
     """Changeset with highest revision number in set.
@@ -1354,6 +1511,7 @@
         pass
     return baseset(datarepr=('<max %r, %r>', subset, os))
 
+
 @predicate('merge()', safe=True)
 def merge(repo, subset, x):
     """Changeset is a merge changeset.
@@ -1362,13 +1520,16 @@
     getargs(x, 0, 0, _("merge takes no arguments"))
     cl = repo.changelog
     nullrev = node.nullrev
+
     def ismerge(r):
         try:
             return cl.parentrevs(r)[1] != nullrev
         except error.WdirUnsupported:
             return bool(repo[r].p2())
+
     return subset.filter(ismerge, condrepr='<merge>')
 
+
 @predicate('branchpoint()', safe=True)
 def branchpoint(repo, subset, x):
     """Changesets with more than one child.
@@ -1381,13 +1542,15 @@
     # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset
     # (and if it is not, it should.)
     baserev = min(subset)
-    parentscount = [0]*(len(repo) - baserev)
+    parentscount = [0] * (len(repo) - baserev)
     for r in cl.revs(start=baserev + 1):
         for p in cl.parentrevs(r):
             if p >= baserev:
                 parentscount[p - baserev] += 1
-    return subset.filter(lambda r: parentscount[r - baserev] > 1,
-                         condrepr='<branchpoint>')
+    return subset.filter(
+        lambda r: parentscount[r - baserev] > 1, condrepr='<branchpoint>'
+    )
+
 
 @predicate('min(set)', safe=True)
 def minrev(repo, subset, x):
@@ -1404,6 +1567,7 @@
         pass
     return baseset(datarepr=('<min %r, %r>', subset, os))
 
+
 @predicate('modifies(pattern)', safe=True, weight=30)
 def modifies(repo, subset, x):
     """Changesets modifying files matched by pattern.
@@ -1416,6 +1580,7 @@
     pat = getstring(x, _("modifies requires a pattern"))
     return checkstatus(repo, subset, pat, 0)
 
+
 @predicate('named(namespace)')
 def named(repo, subset, x):
     """The changesets in a given namespace.
@@ -1426,15 +1591,16 @@
     # i18n: "named" is a keyword
     args = getargs(x, 1, 1, _('named requires a namespace argument'))
 
-    ns = getstring(args[0],
-                   # i18n: "named" is a keyword
-                   _('the argument to named must be a string'))
+    ns = getstring(
+        args[0],
+        # i18n: "named" is a keyword
+        _('the argument to named must be a string'),
+    )
     kind, pattern, matcher = stringutil.stringmatcher(ns)
     namespaces = set()
     if kind == 'literal':
         if pattern not in repo.names:
-            raise error.RepoLookupError(_("namespace '%s' does not exist")
-                                        % ns)
+            raise error.RepoLookupError(_("namespace '%s' does not exist") % ns)
         namespaces.add(repo.names[pattern])
     else:
         for name, ns in repo.names.iteritems():
@@ -1450,6 +1616,7 @@
     names -= {node.nullrev}
     return subset & names
 
+
 @predicate('id(string)', safe=True)
 def node_(repo, subset, x):
     """Revision non-ambiguously specified by the given hex string prefix.
@@ -1481,6 +1648,7 @@
     result = baseset([rn])
     return result & subset
 
+
 @predicate('none()', safe=True)
 def none(repo, subset, x):
     """No changesets.
@@ -1489,6 +1657,7 @@
     getargs(x, 0, 0, _("none takes no arguments"))
     return baseset()
 
+
 @predicate('obsolete()', safe=True)
 def obsolete(repo, subset, x):
     """Mutable changeset with a newer version."""
@@ -1497,6 +1666,7 @@
     obsoletes = obsmod.getrevs(repo, 'obsolete')
     return subset & obsoletes
 
+
 @predicate('only(set, [set])', safe=True)
 def only(repo, subset, x):
     """Changesets that are ancestors of the first set that are not ancestors
@@ -1513,8 +1683,11 @@
             return baseset()
 
         descendants = set(dagop.revdescendants(repo, include, False))
-        exclude = [rev for rev in cl.headrevs()
-            if not rev in descendants and not rev in include]
+        exclude = [
+            rev
+            for rev in cl.headrevs()
+            if not rev in descendants and not rev in include
+        ]
     else:
         exclude = getset(repo, fullreposet(repo), args[1])
 
@@ -1523,6 +1696,7 @@
     # some optimizations from the fact this is a baseset.
     return subset & results
 
+
 @predicate('origin([set])', safe=True)
 def origin(repo, subset, x):
     """
@@ -1555,6 +1729,7 @@
     # some optimizations from the fact this is a baseset.
     return subset & o
 
+
 @predicate('outgoing([path])', safe=False, weight=10)
 def outgoing(repo, subset, x):
     """Changesets not found in the specified destination repository, or the
@@ -1565,6 +1740,7 @@
         discovery,
         hg,
     )
+
     # i18n: "outgoing" is a keyword
     l = getargs(x, 0, 1, _("outgoing takes one or no arguments"))
     # i18n: "outgoing" is a keyword
@@ -1574,8 +1750,10 @@
         dest = None
     path = repo.ui.paths.getpath(dest, default=('default-push', 'default'))
     if not path:
-        raise error.Abort(_('default repository not configured!'),
-                hint=_("see 'hg help config.paths'"))
+        raise error.Abort(
+            _('default repository not configured!'),
+            hint=_("see 'hg help config.paths'"),
+        )
     dest = path.pushloc or path.loc
     branches = path.branch, []
 
@@ -1590,6 +1768,7 @@
     o = {cl.rev(r) for r in outgoing.missing}
     return subset & o
 
+
 @predicate('p1([set])', safe=True)
 def p1(repo, subset, x):
     """First parent of changesets in set, or the working directory.
@@ -1612,6 +1791,7 @@
     # some optimizations from the fact this is a baseset.
     return subset & ps
 
+
 @predicate('p2([set])', safe=True)
 def p2(repo, subset, x):
     """Second parent of changesets in set, or the working directory.
@@ -1640,9 +1820,11 @@
     # some optimizations from the fact this is a baseset.
     return subset & ps
 
+
 def parentpost(repo, subset, x, order):
     return p1(repo, subset, x)
 
+
 @predicate('parents([set])', safe=True)
 def parents(repo, subset, x):
     """
@@ -1663,16 +1845,19 @@
     ps -= {node.nullrev}
     return subset & ps
 
+
 def _phase(repo, subset, *targets):
     """helper to select all rev in <targets> phases"""
     return repo._phasecache.getrevset(repo, targets, subset)
 
+
 @predicate('_phase(idx)', safe=True)
 def phase(repo, subset, x):
-    l = getargs(x, 1, 1, ("_phase requires one argument"))
-    target = getinteger(l[0], ("_phase expects a number"))
+    l = getargs(x, 1, 1, "_phase requires one argument")
+    target = getinteger(l[0], "_phase expects a number")
     return _phase(repo, subset, target)
 
+
 @predicate('draft()', safe=True)
 def draft(repo, subset, x):
     """Changeset in draft phase."""
@@ -1681,6 +1866,7 @@
     target = phases.draft
     return _phase(repo, subset, target)
 
+
 @predicate('secret()', safe=True)
 def secret(repo, subset, x):
     """Changeset in secret phase."""
@@ -1689,6 +1875,7 @@
     target = phases.secret
     return _phase(repo, subset, target)
 
+
 @predicate('stack([revs])', safe=True)
 def stack(repo, subset, x):
     """Experimental revset for the stack of changesets or working directory
@@ -1704,6 +1891,7 @@
 
     return subset & stacks
 
+
 def parentspec(repo, subset, x, n, order):
     """``set^0``
     The set.
@@ -1737,6 +1925,7 @@
                     ps.add(parents[1].rev())
     return subset & ps
 
+
 @predicate('present(set)', safe=True, takeorder=True)
 def present(repo, subset, x, order):
     """An empty set, if any revision in set isn't found; otherwise,
@@ -1751,12 +1940,14 @@
     except error.RepoLookupError:
         return baseset()
 
+
 # for internal use
 @predicate('_notpublic', safe=True)
 def _notpublic(repo, subset, x):
     getargs(x, 0, 0, "_notpublic takes no arguments")
     return _phase(repo, subset, phases.draft, phases.secret)
 
+
 # for internal use
 @predicate('_phaseandancestors(phasename, set)', safe=True)
 def _phaseandancestors(repo, subset, x):
@@ -1770,7 +1961,7 @@
     secret = phases.secret
     phasenamemap = {
         '_notpublic': draft,
-        'draft': draft, # follow secret's ancestors
+        'draft': draft,  # follow secret's ancestors
         'secret': secret,
     }
     if phasename not in phasenamemap:
@@ -1784,10 +1975,11 @@
 
     revs = dagop.revancestors(repo, s, cutfunc=cutfunc)
 
-    if phasename == 'draft': # need to remove secret changesets
+    if phasename == 'draft':  # need to remove secret changesets
         revs = revs.filter(lambda r: getphase(repo, r) == draft)
     return subset & revs
 
+
 @predicate('public()', safe=True)
 def public(repo, subset, x):
     """Changeset in public phase."""
@@ -1795,6 +1987,7 @@
     getargs(x, 0, 0, _("public takes no arguments"))
     return _phase(repo, subset, phases.public)
 
+
 @predicate('remote([id [,path]])', safe=False)
 def remote(repo, subset, x):
     """Local revision that corresponds to the given identifier in a
@@ -1802,13 +1995,14 @@
     synonym for the current local branch.
     """
 
-    from . import hg # avoid start-up nasties
+    from . import hg  # avoid start-up nasties
+
     # i18n: "remote" is a keyword
     l = getargs(x, 0, 2, _("remote takes zero, one, or two arguments"))
 
     q = '.'
     if len(l) > 0:
-    # i18n: "remote" is a keyword
+        # i18n: "remote" is a keyword
         q = getstring(l[0], _("remote requires a string id"))
     if q == '.':
         q = repo['.'].branch()
@@ -1830,6 +2024,7 @@
             return baseset([r])
     return baseset()
 
+
 @predicate('removes(pattern)', safe=True, weight=30)
 def removes(repo, subset, x):
     """Changesets which remove files matching pattern.
@@ -1842,6 +2037,7 @@
     pat = getstring(x, _("removes requires a pattern"))
     return checkstatus(repo, subset, pat, 2)
 
+
 @predicate('rev(number)', safe=True)
 def rev(repo, subset, x):
     """Revision with the given numeric identifier.
@@ -1858,6 +2054,7 @@
         return baseset()
     return subset & baseset([l])
 
+
 @predicate('_rev(number)', safe=True)
 def _rev(repo, subset, x):
     # internal version of "rev(x)" that raise error if "x" is invalid
@@ -1869,9 +2066,10 @@
     except (TypeError, ValueError):
         # i18n: "rev" is a keyword
         raise error.ParseError(_("rev expects a number"))
-    repo.changelog.node(l) # check that the rev exists
+    repo.changelog.node(l)  # check that the rev exists
     return subset & baseset([l])
 
+
 @predicate('revset(set)', safe=True, takeorder=True)
 def revsetpredicate(repo, subset, x, order):
     """Strictly interpret the content as a revset.
@@ -1882,6 +2080,7 @@
     """
     return getset(repo, subset, x, order)
 
+
 @predicate('matching(revision [, field])', safe=True)
 def matching(repo, subset, x):
     """Changesets in which a given set of fields match the set of fields in the
@@ -1914,10 +2113,11 @@
 
     fieldlist = ['metadata']
     if len(l) > 1:
-            fieldlist = getstring(l[1],
-                # i18n: "matching" is a keyword
-                _("matching requires a string "
-                "as its second argument")).split()
+        fieldlist = getstring(
+            l[1],
+            # i18n: "matching" is a keyword
+            _("matching requires a string " "as its second argument"),
+        ).split()
 
     # Make sure that there are no repeated fields,
     # expand the 'special' 'metadata' field type
@@ -1943,14 +2143,26 @@
     # We may want to match more than one field
     # Not all fields take the same amount of time to be matched
     # Sort the selected fields in order of increasing matching cost
-    fieldorder = ['phase', 'parents', 'user', 'date', 'branch', 'summary',
-        'files', 'description', 'substate', 'diff']
+    fieldorder = [
+        'phase',
+        'parents',
+        'user',
+        'date',
+        'branch',
+        'summary',
+        'files',
+        'description',
+        'substate',
+        'diff',
+    ]
+
     def fieldkeyfunc(f):
         try:
             return fieldorder.index(f)
         except ValueError:
             # assume an unknown field is very costly
             return len(fieldorder)
+
     fields = list(fields)
     fields.sort(key=fieldkeyfunc)
 
@@ -1967,15 +2179,18 @@
         'phase': lambda r: repo[r].phase(),
         'substate': lambda r: repo[r].substate,
         'summary': lambda r: repo[r].description().splitlines()[0],
-        'diff': lambda r: list(repo[r].diff(
-            opts=diffutil.diffallopts(repo.ui, {'git': True}))),
+        'diff': lambda r: list(
+            repo[r].diff(opts=diffutil.diffallopts(repo.ui, {'git': True}))
+        ),
     }
     for info in fields:
         getfield = _funcs.get(info, None)
         if getfield is None:
             raise error.ParseError(
                 # i18n: "matching" is a keyword
-                _("unexpected field name passed to matching: %s") % info)
+                _("unexpected field name passed to matching: %s")
+                % info
+            )
         getfieldfuncs.append(getfield)
     # convert the getfield array of functions into a "getinfo" function
     # which returns an array of field values (or a single value if there
@@ -1995,6 +2210,7 @@
 
     return subset.filter(matches, condrepr=('<matching%r %r>', fields, revs))
 
+
 @predicate('reverse(set)', safe=True, takeorder=True, weight=0)
 def reverse(repo, subset, x, order):
     """Reverse order of set.
@@ -2004,19 +2220,23 @@
         l.reverse()
     return l
 
+
 @predicate('roots(set)', safe=True)
 def roots(repo, subset, x):
     """Changesets in set with no parent changeset in set.
     """
     s = getset(repo, fullreposet(repo), x)
     parents = repo.changelog.parentrevs
+
     def filter(r):
         for p in parents(r):
             if 0 <= p and p in s:
                 return False
         return True
+
     return subset & s.filter(filter, condrepr='<roots>')
 
+
 _sortkeyfuncs = {
     'rev': lambda c: c.rev(),
     'branch': lambda c: c.branch(),
@@ -2026,6 +2246,7 @@
     'date': lambda c: c.date()[0],
 }
 
+
 def _getsortargs(x):
     """Parse sort options into (set, [(key, reverse)], opts)"""
     args = getargsdict(x, 'sort', 'set keys topo.firstbranch')
@@ -2040,18 +2261,20 @@
     keyflags = []
     for k in keys.split():
         fk = k
-        reverse = (k.startswith('-'))
+        reverse = k.startswith('-')
         if reverse:
             k = k[1:]
         if k not in _sortkeyfuncs and k != 'topo':
             raise error.ParseError(
-                _("unknown sort key %r") % pycompat.bytestr(fk))
+                _("unknown sort key %r") % pycompat.bytestr(fk)
+            )
         keyflags.append((k, reverse))
 
     if len(keyflags) > 1 and any(k == 'topo' for k, reverse in keyflags):
         # i18n: "topo" is a keyword
-        raise error.ParseError(_('topo sort order cannot be combined '
-                                 'with other sort keys'))
+        raise error.ParseError(
+            _('topo sort order cannot be combined ' 'with other sort keys')
+        )
 
     opts = {}
     if 'topo.firstbranch' in args:
@@ -2059,13 +2282,19 @@
             opts['topo.firstbranch'] = args['topo.firstbranch']
         else:
             # i18n: "topo" and "topo.firstbranch" are keywords
-            raise error.ParseError(_('topo.firstbranch can only be used '
-                                     'when using the topo sort key'))
+            raise error.ParseError(
+                _(
+                    'topo.firstbranch can only be used '
+                    'when using the topo sort key'
+                )
+            )
 
     return args['set'], keyflags, opts
 
-@predicate('sort(set[, [-]key... [, ...]])', safe=True, takeorder=True,
-           weight=10)
+
+@predicate(
+    'sort(set[, [-]key... [, ...]])', safe=True, takeorder=True, weight=10
+)
 def sort(repo, subset, x, order):
     """Sort set by keys. The default sort order is ascending, specify a key
     as ``-key`` to sort in descending order.
@@ -2096,9 +2325,10 @@
         firstbranch = ()
         if 'topo.firstbranch' in opts:
             firstbranch = getset(repo, subset, opts['topo.firstbranch'])
-        revs = baseset(dagop.toposort(revs, repo.changelog.parentrevs,
-                                      firstbranch),
-                       istopo=True)
+        revs = baseset(
+            dagop.toposort(revs, repo.changelog.parentrevs, firstbranch),
+            istopo=True,
+        )
         if keyflags[0][1]:
             revs.reverse()
         return revs
@@ -2109,6 +2339,7 @@
         ctxs.sort(key=_sortkeyfuncs[k], reverse=reverse)
     return baseset([c.rev() for c in ctxs])
 
+
 @predicate('subrepo([pattern])')
 def subrepo(repo, subset, x):
     """Changesets that add, modify or remove the given subrepo.  If no subrepo
@@ -2153,6 +2384,7 @@
 
     return subset.filter(matches, condrepr=('<subrepo %r>', pat))
 
+
 def _mapbynodefunc(repo, s, f):
     """(repo, smartset, [node] -> [node]) -> smartset
 
@@ -2167,6 +2399,7 @@
     result = set(torev(n) for n in f(tonode(r) for r in s) if n in nodemap)
     return smartset.baseset(result - repo.changelog.filteredrevs)
 
+
 @predicate('successors(set)', safe=True)
 def successors(repo, subset, x):
     """All successors for set, including the given set themselves"""
@@ -2175,9 +2408,11 @@
     d = _mapbynodefunc(repo, s, f)
     return subset & d
 
+
 def _substringmatcher(pattern, casesensitive=True):
     kind, pattern, matcher = stringutil.stringmatcher(
-        pattern, casesensitive=casesensitive)
+        pattern, casesensitive=casesensitive
+    )
     if kind == 'literal':
         if not casesensitive:
             pattern = encoding.lower(pattern)
@@ -2186,6 +2421,7 @@
             matcher = lambda s: pattern in s
     return kind, pattern, matcher
 
+
 @predicate('tag([name])', safe=True)
 def tag(repo, subset, x):
     """The specified tag by name, or all tagged revisions if no name is given.
@@ -2197,16 +2433,19 @@
     args = getargs(x, 0, 1, _("tag takes one or no arguments"))
     cl = repo.changelog
     if args:
-        pattern = getstring(args[0],
-                            # i18n: "tag" is a keyword
-                            _('the argument to tag must be a string'))
+        pattern = getstring(
+            args[0],
+            # i18n: "tag" is a keyword
+            _('the argument to tag must be a string'),
+        )
         kind, pattern, matcher = stringutil.stringmatcher(pattern)
         if kind == 'literal':
             # avoid resolving all tags
             tn = repo._tagscache.tags.get(pattern, None)
             if tn is None:
-                raise error.RepoLookupError(_("tag '%s' does not exist")
-                                            % pattern)
+                raise error.RepoLookupError(
+                    _("tag '%s' does not exist") % pattern
+                )
             s = {repo[tn].rev()}
         else:
             s = {cl.rev(n) for t, n in repo.tagslist() if matcher(t)}
@@ -2214,10 +2453,12 @@
         s = {cl.rev(n) for t, n in repo.tagslist() if t != 'tip'}
     return subset & s
 
+
 @predicate('tagged', safe=True)
 def tagged(repo, subset, x):
     return tag(repo, subset, x)
 
+
 @predicate('orphan()', safe=True)
 def orphan(repo, subset, x):
     """Non-obsolete changesets with obsolete ancestors. (EXPERIMENTAL)
@@ -2237,6 +2478,7 @@
     """
     return author(repo, subset, x)
 
+
 @predicate('wdir()', safe=True, weight=0)
 def wdir(repo, subset, x):
     """Working directory. (EXPERIMENTAL)"""
@@ -2246,6 +2488,7 @@
         return baseset([node.wdirrev])
     return baseset()
 
+
 def _orderedlist(repo, subset, x):
     s = getstring(x, "internal error")
     if not s:
@@ -2268,12 +2511,16 @@
         for r in revs:
             if r in seen:
                 continue
-            if (r in subset
-                or r in _virtualrevs and isinstance(subset, fullreposet)):
+            if (
+                r in subset
+                or r in _virtualrevs
+                and isinstance(subset, fullreposet)
+            ):
                 ls.append(r)
             seen.add(r)
     return baseset(ls)
 
+
 # for internal use
 @predicate('_list', safe=True, takeorder=True)
 def _list(repo, subset, x, order):
@@ -2283,6 +2530,7 @@
     else:
         return _orderedlist(repo, subset, x)
 
+
 def _orderedintlist(repo, subset, x):
     s = getstring(x, "internal error")
     if not s:
@@ -2291,6 +2539,7 @@
     s = subset
     return baseset([r for r in ls if r in s])
 
+
 # for internal use
 @predicate('_intlist', safe=True, takeorder=True, weight=0)
 def _intlist(repo, subset, x, order):
@@ -2300,6 +2549,7 @@
     else:
         return _orderedintlist(repo, subset, x)
 
+
 def _orderedhexlist(repo, subset, x):
     s = getstring(x, "internal error")
     if not s:
@@ -2309,6 +2559,7 @@
     s = subset
     return baseset([r for r in ls if r in s])
 
+
 # for internal use
 @predicate('_hexlist', safe=True, takeorder=True)
 def _hexlist(repo, subset, x, order):
@@ -2318,6 +2569,7 @@
     else:
         return _orderedhexlist(repo, subset, x)
 
+
 methods = {
     "range": rangeset,
     "rangeall": rangeall,
@@ -2348,13 +2600,16 @@
     "generations": generationsrel,
 }
 
+
 def lookupfn(repo):
     return lambda symbol: scmutil.isrevsymbol(repo, symbol)
 
+
 def match(ui, spec, lookup=None):
     """Create a matcher for a single revision spec"""
     return matchany(ui, [spec], lookup=lookup)
 
+
 def matchany(ui, specs, lookup=None, localalias=None):
     """Create a matcher that will include any revisions matching one of the
     given specs
@@ -2366,16 +2621,20 @@
     precedence over [revsetalias] config section.
     """
     if not specs:
+
         def mfunc(repo, subset=None):
             return baseset()
+
         return mfunc
     if not all(specs):
         raise error.ParseError(_("empty query"))
     if len(specs) == 1:
         tree = revsetlang.parse(specs[0], lookup)
     else:
-        tree = ('or',
-                ('list',) + tuple(revsetlang.parse(s, lookup) for s in specs))
+        tree = (
+            'or',
+            ('list',) + tuple(revsetlang.parse(s, lookup) for s in specs),
+        )
 
     aliases = []
     warn = None
@@ -2391,8 +2650,10 @@
     tree = revsetlang.optimize(tree)
     return makematcher(tree)
 
+
 def makematcher(tree):
     """Create a matcher from an evaluatable tree"""
+
     def mfunc(repo, subset=None, order=None):
         if order is None:
             if subset is None:
@@ -2402,8 +2663,10 @@
         if subset is None:
             subset = fullreposet(repo)
         return getset(repo, subset, tree, order)
+
     return mfunc
 
+
 def loadpredicate(ui, extname, registrarobj):
     """Load revset predicates from specified registrarobj
     """
@@ -2412,6 +2675,7 @@
         if func._safe:
             safesymbols.add(name)
 
+
 # load built-in predicates explicitly to setup safesymbols
 loadpredicate(None, None, predicate)