mercurial/templatekw.py
changeset 43076 2372284d9457
parent 42518 88ba0ff94605
child 43077 687b865b95ad
--- a/mercurial/templatekw.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/mercurial/templatekw.py	Sun Oct 06 09:45:02 2019 -0400
@@ -29,9 +29,7 @@
     templateutil,
     util,
 )
-from .utils import (
-    stringutil,
-)
+from .utils import stringutil
 
 _hybrid = templateutil.hybrid
 hybriddict = templateutil.hybriddict
@@ -40,6 +38,7 @@
 compatlist = templateutil.compatlist
 _showcompatlist = templateutil._showcompatlist
 
+
 def getlatesttags(context, mapping, pattern=None):
     '''return date, distance and name for the latest tag of rev'''
     repo = context.resource(mapping, 'repo')
@@ -66,9 +65,11 @@
         if rev in latesttags:
             continue
         ctx = repo[rev]
-        tags = [t for t in ctx.tags()
-                if (repo.tagtype(t) and repo.tagtype(t) != 'local'
-                    and match(t))]
+        tags = [
+            t
+            for t in ctx.tags()
+            if (repo.tagtype(t) and repo.tagtype(t) != 'local' and match(t))
+        ]
         if tags:
             latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
             continue
@@ -80,6 +81,7 @@
                     # comparison in this case.
                     pdate, pdist, ptag = max(ptags)
                 else:
+
                     def key(x):
                         tag = x[2][0]
                         if ctx.rev() is None:
@@ -93,6 +95,7 @@
                         # Smallest number of changes since tag wins. Date is
                         # used as tiebreaker.
                         return [-changessincetag, x[0]]
+
                     pdate, pdist, ptag = max(ptags, key=key)
             else:
                 pdate, pdist, ptag = ptags[0]
@@ -104,29 +107,37 @@
         latesttags[rev] = pdate, pdist + 1, ptag
     return latesttags[rev]
 
+
 def getlogcolumns():
     """Return a dict of log column labels"""
     _ = pycompat.identity  # temporarily disable gettext
     # i18n: column positioning for "hg log"
-    columns = _('bookmark:    %s\n'
-                'branch:      %s\n'
-                'changeset:   %s\n'
-                'copies:      %s\n'
-                'date:        %s\n'
-                'extra:       %s=%s\n'
-                'files+:      %s\n'
-                'files-:      %s\n'
-                'files:       %s\n'
-                'instability: %s\n'
-                'manifest:    %s\n'
-                'obsolete:    %s\n'
-                'parent:      %s\n'
-                'phase:       %s\n'
-                'summary:     %s\n'
-                'tag:         %s\n'
-                'user:        %s\n')
-    return dict(zip([s.split(':', 1)[0] for s in columns.splitlines()],
-                    i18n._(columns).splitlines(True)))
+    columns = _(
+        'bookmark:    %s\n'
+        'branch:      %s\n'
+        'changeset:   %s\n'
+        'copies:      %s\n'
+        'date:        %s\n'
+        'extra:       %s=%s\n'
+        'files+:      %s\n'
+        'files-:      %s\n'
+        'files:       %s\n'
+        'instability: %s\n'
+        'manifest:    %s\n'
+        'obsolete:    %s\n'
+        'parent:      %s\n'
+        'phase:       %s\n'
+        'summary:     %s\n'
+        'tag:         %s\n'
+        'user:        %s\n'
+    )
+    return dict(
+        zip(
+            [s.split(':', 1)[0] for s in columns.splitlines()],
+            i18n._(columns).splitlines(True),
+        )
+    )
+
 
 # basic internal templates
 _changeidtmpl = '{rev}:{node|formatnode}'
@@ -137,7 +148,7 @@
     'manifest': _changeidtmpl,
     'file_copy': '{name} ({source})',
     'envvar': '{key}={value}',
-    'extra': '{key}={value|stringescape}'
+    'extra': '{key}={value|stringescape}',
 }
 # filecopy is preserved for compatibility reasons
 defaulttempl['filecopy'] = defaulttempl['file_copy']
@@ -146,11 +157,13 @@
 keywords = {}
 templatekeyword = registrar.templatekeyword(keywords)
 
+
 @templatekeyword('author', requires={'ctx'})
 def showauthor(context, mapping):
     """Alias for ``{user}``"""
     return showuser(context, mapping)
 
+
 @templatekeyword('bisect', requires={'repo', 'ctx'})
 def showbisect(context, mapping):
     """String. The changeset bisection status."""
@@ -158,6 +171,7 @@
     ctx = context.resource(mapping, 'ctx')
     return hbisect.label(repo, ctx.node())
 
+
 @templatekeyword('branch', requires={'ctx'})
 def showbranch(context, mapping):
     """String. The name of the branch on which the changeset was
@@ -166,6 +180,7 @@
     ctx = context.resource(mapping, 'ctx')
     return ctx.branch()
 
+
 @templatekeyword('branches', requires={'ctx'})
 def showbranches(context, mapping):
     """List of strings. The name of the branch on which the
@@ -175,10 +190,12 @@
     ctx = context.resource(mapping, 'ctx')
     branch = ctx.branch()
     if branch != 'default':
-        return compatlist(context, mapping, 'branch', [branch],
-                          plural='branches')
+        return compatlist(
+            context, mapping, 'branch', [branch], plural='branches'
+        )
     return compatlist(context, mapping, 'branch', [], plural='branches')
 
+
 @templatekeyword('bookmarks', requires={'repo', 'ctx'})
 def showbookmarks(context, mapping):
     """List of strings. Any bookmarks associated with the
@@ -192,6 +209,7 @@
     f = _showcompatlist(context, mapping, 'bookmark', bookmarks)
     return _hybrid(f, bookmarks, makemap, pycompat.identity)
 
+
 @templatekeyword('children', requires={'ctx'})
 def showchildren(context, mapping):
     """List of strings. The children of the changeset."""
@@ -199,6 +217,7 @@
     childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
     return compatlist(context, mapping, 'children', childrevs, element='child')
 
+
 # Deprecated, but kept alive for help generation a purpose.
 @templatekeyword('currentbookmark', requires={'repo', 'ctx'})
 def showcurrentbookmark(context, mapping):
@@ -206,6 +225,7 @@
     (DEPRECATED)"""
     return showactivebookmark(context, mapping)
 
+
 @templatekeyword('activebookmark', requires={'repo', 'ctx'})
 def showactivebookmark(context, mapping):
     """String. The active bookmark, if it is associated with the changeset."""
@@ -216,6 +236,7 @@
         return active
     return ''
 
+
 @templatekeyword('date', requires={'ctx'})
 def showdate(context, mapping):
     """Date information. The date when the changeset was committed."""
@@ -224,6 +245,7 @@
     # python-hglib splits date at decimal separator.
     return templateutil.date(ctx.date(), showfmt='%d.0%d')
 
+
 @templatekeyword('desc', requires={'ctx'})
 def showdescription(context, mapping):
     """String. The text of the changeset description."""
@@ -237,6 +259,7 @@
     else:
         return s.strip()
 
+
 @templatekeyword('diffstat', requires={'ui', 'ctx'})
 def showdiffstat(context, mapping):
     """String. Statistics of changes with the following format:
@@ -250,6 +273,7 @@
     maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
     return '%d: +%d/-%d' % (len(stats), adds, removes)
 
+
 @templatekeyword('envvars', requires={'ui'})
 def showenvvars(context, mapping):
     """A dictionary of environment variables. (EXPERIMENTAL)"""
@@ -258,6 +282,7 @@
     env = util.sortdict((k, env[k]) for k in sorted(env))
     return compatdict(context, mapping, 'envvar', env, plural='envvars')
 
+
 @templatekeyword('extras', requires={'ctx'})
 def showextras(context, mapping):
     """List of dicts with key, value entries of the 'extras'
@@ -268,19 +293,26 @@
     makemap = lambda k: {'key': k, 'value': extras[k]}
     c = [makemap(k) for k in extras]
     f = _showcompatlist(context, mapping, 'extra', c, plural='extras')
-    return _hybrid(f, extras, makemap,
-                   lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k])))
+    return _hybrid(
+        f,
+        extras,
+        makemap,
+        lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k])),
+    )
+
 
 def _getfilestatus(context, mapping, listall=False):
     ctx = context.resource(mapping, 'ctx')
     revcache = context.resource(mapping, 'revcache')
     if 'filestatus' not in revcache or revcache['filestatusall'] < listall:
-        stat = ctx.p1().status(ctx, listignored=listall, listclean=listall,
-                               listunknown=listall)
+        stat = ctx.p1().status(
+            ctx, listignored=listall, listclean=listall, listunknown=listall
+        )
         revcache['filestatus'] = stat
         revcache['filestatusall'] = listall
     return revcache['filestatus']
 
+
 def _getfilestatusmap(context, mapping, listall=False):
     revcache = context.resource(mapping, 'revcache')
     if 'filestatusmap' not in revcache or revcache['filestatusall'] < listall:
@@ -290,8 +322,8 @@
             statmap.update((f, char) for f in files)
     return revcache['filestatusmap']  # {path: statchar}
 
-@templatekeyword('file_copies',
-                 requires={'repo', 'ctx', 'cache', 'revcache'})
+
+@templatekeyword('file_copies', requires={'repo', 'ctx', 'cache', 'revcache'})
 def showfilecopies(context, mapping):
     """List of strings. Files copied in this changeset with
     their sources.
@@ -305,8 +337,10 @@
             cache['getcopies'] = scmutil.getcopiesfn(repo)
         getcopies = cache['getcopies']
         copies = getcopies(ctx)
-    return templateutil.compatfilecopiesdict(context, mapping, 'file_copy',
-                                             copies)
+    return templateutil.compatfilecopiesdict(
+        context, mapping, 'file_copy', copies
+    )
+
 
 # showfilecopiesswitch() displays file copies only if copy records are
 # provided before calling the templater, usually with a --copies
@@ -317,29 +351,37 @@
     only if the --copied switch is set.
     """
     copies = context.resource(mapping, 'revcache').get('copies') or []
-    return templateutil.compatfilecopiesdict(context, mapping, 'file_copy',
-                                             copies)
+    return templateutil.compatfilecopiesdict(
+        context, mapping, 'file_copy', copies
+    )
+
 
 @templatekeyword('file_adds', requires={'ctx', 'revcache'})
 def showfileadds(context, mapping):
     """List of strings. Files added by this changeset."""
     ctx = context.resource(mapping, 'ctx')
-    return templateutil.compatfileslist(context, mapping, 'file_add',
-                                        ctx.filesadded())
+    return templateutil.compatfileslist(
+        context, mapping, 'file_add', ctx.filesadded()
+    )
+
 
 @templatekeyword('file_dels', requires={'ctx', 'revcache'})
 def showfiledels(context, mapping):
     """List of strings. Files removed by this changeset."""
     ctx = context.resource(mapping, 'ctx')
-    return templateutil.compatfileslist(context, mapping, 'file_del',
-                                        ctx.filesremoved())
+    return templateutil.compatfileslist(
+        context, mapping, 'file_del', ctx.filesremoved()
+    )
+
 
 @templatekeyword('file_mods', requires={'ctx', 'revcache'})
 def showfilemods(context, mapping):
     """List of strings. Files modified by this changeset."""
     ctx = context.resource(mapping, 'ctx')
-    return templateutil.compatfileslist(context, mapping, 'file_mod',
-                                        ctx.filesmodified())
+    return templateutil.compatfileslist(
+        context, mapping, 'file_mod', ctx.filesmodified()
+    )
+
 
 @templatekeyword('files', requires={'ctx'})
 def showfiles(context, mapping):
@@ -349,6 +391,7 @@
     ctx = context.resource(mapping, 'ctx')
     return templateutil.compatfileslist(context, mapping, 'file', ctx.files())
 
+
 @templatekeyword('graphnode', requires={'repo', 'ctx'})
 def showgraphnode(context, mapping):
     """String. The character representing the changeset node in an ASCII
@@ -357,9 +400,11 @@
     ctx = context.resource(mapping, 'ctx')
     return getgraphnode(repo, ctx)
 
+
 def getgraphnode(repo, ctx):
     return getgraphnodecurrent(repo, ctx) or getgraphnodesymbol(ctx)
 
+
 def getgraphnodecurrent(repo, ctx):
     wpnodes = repo.dirstate.parents()
     if wpnodes[1] == nullid:
@@ -369,6 +414,7 @@
     else:
         return ''
 
+
 def getgraphnodesymbol(ctx):
     if ctx.obsolete():
         return 'x'
@@ -379,18 +425,21 @@
     else:
         return 'o'
 
+
 @templatekeyword('graphwidth', requires=())
 def showgraphwidth(context, mapping):
     """Integer. The width of the graph drawn by 'log --graph' or zero."""
     # just hosts documentation; should be overridden by template mapping
     return 0
 
+
 @templatekeyword('index', requires=())
 def showindex(context, mapping):
     """Integer. The current iteration of the loop. (0 indexed)"""
     # just hosts documentation; should be overridden by template mapping
     raise error.Abort(_("can't use index in this context"))
 
+
 @templatekeyword('latesttag', requires={'repo', 'ctx', 'cache'})
 def showlatesttag(context, mapping):
     """List of strings. The global tags on the most recent globally
@@ -399,6 +448,7 @@
     """
     return showlatesttags(context, mapping, None)
 
+
 def showlatesttags(context, mapping, pattern):
     """helper method for the latesttag keyword and function"""
     latesttags = getlatesttags(context, mapping, pattern)
@@ -409,19 +459,21 @@
     makemap = lambda v: {
         'changes': _showchangessincetag,
         'distance': latesttags[1],
-        'latesttag': v,   # BC with {latesttag % '{latesttag}'}
-        'tag': v
+        'latesttag': v,  # BC with {latesttag % '{latesttag}'}
+        'tag': v,
     }
 
     tags = latesttags[2]
     f = _showcompatlist(context, mapping, 'latesttag', tags, separator=':')
     return _hybrid(f, tags, makemap, pycompat.identity)
 
+
 @templatekeyword('latesttagdistance', requires={'repo', 'ctx', 'cache'})
 def showlatesttagdistance(context, mapping):
     """Integer. Longest path to the latest tag."""
     return getlatesttags(context, mapping)[1]
 
+
 @templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'})
 def showchangessincelatesttag(context, mapping):
     """Integer. All ancestors not in the latest tag."""
@@ -429,6 +481,7 @@
     mapping = context.overlaymap(mapping, {'tag': tag})
     return _showchangessincetag(context, mapping)
 
+
 def _showchangessincetag(context, mapping):
     repo = context.resource(mapping, 'repo')
     ctx = context.resource(mapping, 'ctx')
@@ -443,9 +496,11 @@
 
     return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
 
+
 # teach templater latesttags.changes is switched to (context, mapping) API
 _showchangessincetag._requires = {'repo', 'ctx'}
 
+
 @templatekeyword('manifest', requires={'repo', 'ctx'})
 def showmanifest(context, mapping):
     repo = context.resource(mapping, 'repo')
@@ -459,8 +514,10 @@
     mhex = hex(mnode)
     mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex})
     f = context.process('manifest', mapping)
-    return templateutil.hybriditem(f, None, f,
-                                   lambda x: {'rev': mrev, 'node': mhex})
+    return templateutil.hybriditem(
+        f, None, f, lambda x: {'rev': mrev, 'node': mhex}
+    )
+
 
 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx'})
 def showobsfate(context, mapping):
@@ -475,20 +532,24 @@
     values = []
 
     for x in succsandmarkers.tovalue(context, mapping):
-        v = obsutil.obsfateprinter(ui, repo, x['successors'], x['markers'],
-                                   scmutil.formatchangeid)
+        v = obsutil.obsfateprinter(
+            ui, repo, x['successors'], x['markers'], scmutil.formatchangeid
+        )
         values.append(v)
 
     return compatlist(context, mapping, "fate", values)
 
+
 def shownames(context, mapping, namespace):
     """helper method to generate a template keyword for a namespace"""
     repo = context.resource(mapping, 'repo')
     ctx = context.resource(mapping, 'ctx')
     ns = repo.names[namespace]
     names = ns.names(repo, ctx.node())
-    return compatlist(context, mapping, ns.templatename, names,
-                      plural=namespace)
+    return compatlist(
+        context, mapping, ns.templatename, names, plural=namespace
+    )
+
 
 @templatekeyword('namespaces', requires={'repo', 'ctx'})
 def shownamespaces(context, mapping):
@@ -498,6 +559,7 @@
     ctx = context.resource(mapping, 'ctx')
 
     namespaces = util.sortdict()
+
     def makensmapfn(ns):
         # 'name' for iterating over namespaces, templatename for local reference
         return lambda v: {'name': v, ns.templatename: v}
@@ -519,6 +581,7 @@
 
     return _hybrid(f, namespaces, makemap, pycompat.identity)
 
+
 @templatekeyword('negrev', requires={'repo', 'ctx'})
 def shownegrev(context, mapping):
     """Integer. The repository-local changeset negative revision number,
@@ -530,6 +593,7 @@
     repo = context.resource(mapping, 'repo')
     return rev - len(repo)
 
+
 @templatekeyword('node', requires={'ctx'})
 def shownode(context, mapping):
     """String. The changeset identification hash, as a 40 hexadecimal
@@ -538,6 +602,7 @@
     ctx = context.resource(mapping, 'ctx')
     return ctx.hex()
 
+
 @templatekeyword('obsolete', requires={'ctx'})
 def showobsolete(context, mapping):
     """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
@@ -546,12 +611,14 @@
         return 'obsolete'
     return ''
 
+
 @templatekeyword('path', requires={'fctx'})
 def showpath(context, mapping):
     """String. Repository-absolute path of the current file. (EXPERIMENTAL)"""
     fctx = context.resource(mapping, 'fctx')
     return fctx.path()
 
+
 @templatekeyword('peerurls', requires={'repo'})
 def showpeerurls(context, mapping):
     """A dictionary of repository locations defined in the [paths] section
@@ -560,13 +627,16 @@
     # see commands.paths() for naming of dictionary keys
     paths = repo.ui.paths
     urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
+
     def makemap(k):
         p = paths[k]
         d = {'name': k, 'url': p.rawloc}
         d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
         return d
+
     return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
 
+
 @templatekeyword("predecessors", requires={'repo', 'ctx'})
 def showpredecessors(context, mapping):
     """Returns the list of the closest visible predecessors. (EXPERIMENTAL)"""
@@ -575,9 +645,13 @@
     predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
     predecessors = pycompat.maplist(hex, predecessors)
 
-    return _hybrid(None, predecessors,
-                   lambda x: {'ctx': repo[x]},
-                   lambda x: scmutil.formatchangeid(repo[x]))
+    return _hybrid(
+        None,
+        predecessors,
+        lambda x: {'ctx': repo[x]},
+        lambda x: scmutil.formatchangeid(repo[x]),
+    )
+
 
 @templatekeyword('reporoot', requires={'repo'})
 def showreporoot(context, mapping):
@@ -585,12 +659,14 @@
     repo = context.resource(mapping, 'repo')
     return repo.root
 
+
 @templatekeyword('size', requires={'fctx'})
 def showsize(context, mapping):
     """Integer. Size of the current file in bytes. (EXPERIMENTAL)"""
     fctx = context.resource(mapping, 'fctx')
     return fctx.size()
 
+
 # requires 'fctx' to denote {status} depends on (ctx, path) pair
 @templatekeyword('status', requires={'ctx', 'fctx', 'revcache'})
 def showstatus(context, mapping):
@@ -604,6 +680,7 @@
         statmap = _getfilestatusmap(context, mapping, listall=True)
     return statmap.get(path)
 
+
 @templatekeyword("successorssets", requires={'repo', 'ctx'})
 def showsuccessorssets(context, mapping):
     """Returns a string of sets of successors for a changectx. Format used
@@ -619,8 +696,12 @@
 
     data = []
     for ss in ssets:
-        h = _hybrid(None, ss, lambda x: {'ctx': repo[x]},
-                    lambda x: scmutil.formatchangeid(repo[x]))
+        h = _hybrid(
+            None,
+            ss,
+            lambda x: {'ctx': repo[x]},
+            lambda x: scmutil.formatchangeid(repo[x]),
+        )
         data.append(h)
 
     # Format the successorssets
@@ -630,8 +711,10 @@
     def gen(data):
         yield "; ".join(render(d) for d in data)
 
-    return _hybrid(gen(data), data, lambda x: {'successorset': x},
-                   pycompat.identity)
+    return _hybrid(
+        gen(data), data, lambda x: {'successorset': x}, pycompat.identity
+    )
+
 
 @templatekeyword("succsandmarkers", requires={'repo', 'ctx'})
 def showsuccsandmarkers(context, mapping):
@@ -655,9 +738,12 @@
         successors = i['successors']
 
         successors = [hex(n) for n in successors]
-        successors = _hybrid(None, successors,
-                             lambda x: {'ctx': repo[x]},
-                             lambda x: scmutil.formatchangeid(repo[x]))
+        successors = _hybrid(
+            None,
+            successors,
+            lambda x: {'ctx': repo[x]},
+            lambda x: scmutil.formatchangeid(repo[x]),
+        )
 
         # Format markers
         finalmarkers = []
@@ -674,6 +760,7 @@
 
     return templateutil.mappinglist(data)
 
+
 @templatekeyword('p1', requires={'ctx'})
 def showp1(context, mapping):
     """Changeset. The changeset's first parent. ``{p1.rev}`` for the revision
@@ -681,6 +768,7 @@
     ctx = context.resource(mapping, 'ctx')
     return templateutil.mappingdict({'ctx': ctx.p1()}, tmpl=_changeidtmpl)
 
+
 @templatekeyword('p2', requires={'ctx'})
 def showp2(context, mapping):
     """Changeset. The changeset's second parent. ``{p2.rev}`` for the revision
@@ -688,6 +776,7 @@
     ctx = context.resource(mapping, 'ctx')
     return templateutil.mappingdict({'ctx': ctx.p2()}, tmpl=_changeidtmpl)
 
+
 @templatekeyword('p1rev', requires={'ctx'})
 def showp1rev(context, mapping):
     """Integer. The repository-local revision number of the changeset's
@@ -695,6 +784,7 @@
     ctx = context.resource(mapping, 'ctx')
     return ctx.p1().rev()
 
+
 @templatekeyword('p2rev', requires={'ctx'})
 def showp2rev(context, mapping):
     """Integer. The repository-local revision number of the changeset's
@@ -702,6 +792,7 @@
     ctx = context.resource(mapping, 'ctx')
     return ctx.p2().rev()
 
+
 @templatekeyword('p1node', requires={'ctx'})
 def showp1node(context, mapping):
     """String. The identification hash of the changeset's first parent,
@@ -710,6 +801,7 @@
     ctx = context.resource(mapping, 'ctx')
     return ctx.p1().hex()
 
+
 @templatekeyword('p2node', requires={'ctx'})
 def showp2node(context, mapping):
     """String. The identification hash of the changeset's second
@@ -718,6 +810,7 @@
     ctx = context.resource(mapping, 'ctx')
     return ctx.p2().hex()
 
+
 @templatekeyword('parents', requires={'repo', 'ctx'})
 def showparents(context, mapping):
     """List of strings. The parents of the changeset in "rev:node"
@@ -727,13 +820,19 @@
     ctx = context.resource(mapping, 'ctx')
     pctxs = scmutil.meaningfulparents(repo, ctx)
     prevs = [p.rev() for p in pctxs]
-    parents = [[('rev', p.rev()),
-                ('node', p.hex()),
-                ('phase', p.phasestr())]
-               for p in pctxs]
+    parents = [
+        [('rev', p.rev()), ('node', p.hex()), ('phase', p.phasestr())]
+        for p in pctxs
+    ]
     f = _showcompatlist(context, mapping, 'parent', parents)
-    return _hybrid(f, prevs, lambda x: {'ctx': repo[x]},
-                   lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
+    return _hybrid(
+        f,
+        prevs,
+        lambda x: {'ctx': repo[x]},
+        lambda x: scmutil.formatchangeid(repo[x]),
+        keytype=int,
+    )
+
 
 @templatekeyword('phase', requires={'ctx'})
 def showphase(context, mapping):
@@ -741,18 +840,21 @@
     ctx = context.resource(mapping, 'ctx')
     return ctx.phasestr()
 
+
 @templatekeyword('phaseidx', requires={'ctx'})
 def showphaseidx(context, mapping):
     """Integer. The changeset phase index. (ADVANCED)"""
     ctx = context.resource(mapping, 'ctx')
     return ctx.phase()
 
+
 @templatekeyword('rev', requires={'ctx'})
 def showrev(context, mapping):
     """Integer. The repository-local changeset revision number."""
     ctx = context.resource(mapping, 'ctx')
     return scmutil.intrev(ctx)
 
+
 def showrevslist(context, mapping, name, revs):
     """helper to generate a list of revisions in which a mapped template will
     be evaluated"""
@@ -761,9 +863,15 @@
     def f():
         srevs = ['%d' % r for r in revs]
         return _showcompatlist(context, mapping, name, srevs)
-    return _hybrid(f, revs,
-                   lambda x: {name: x, 'ctx': repo[x]},
-                   pycompat.identity, keytype=int)
+
+    return _hybrid(
+        f,
+        revs,
+        lambda x: {name: x, 'ctx': repo[x]},
+        pycompat.identity,
+        keytype=int,
+    )
+
 
 @templatekeyword('subrepos', requires={'ctx'})
 def showsubrepos(context, mapping):
@@ -776,12 +884,13 @@
     subrepos = []
     for sub in substate:
         if sub not in psubstate or substate[sub] != psubstate[sub]:
-            subrepos.append(sub) # modified or newly added in ctx
+            subrepos.append(sub)  # modified or newly added in ctx
     for sub in psubstate:
         if sub not in substate:
-            subrepos.append(sub) # removed in ctx
+            subrepos.append(sub)  # removed in ctx
     return compatlist(context, mapping, 'subrepo', sorted(subrepos))
 
+
 # don't remove "showtags" definition, even though namespaces will put
 # a helper function for "tags" keyword into "keywords" map automatically,
 # because online help text is built without namespaces initialization
@@ -790,26 +899,35 @@
     """List of strings. Any tags associated with the changeset."""
     return shownames(context, mapping, 'tags')
 
+
 @templatekeyword('termwidth', requires={'ui'})
 def showtermwidth(context, mapping):
     """Integer. The width of the current terminal."""
     ui = context.resource(mapping, 'ui')
     return ui.termwidth()
 
+
 @templatekeyword('user', requires={'ctx'})
 def showuser(context, mapping):
     """String. The unmodified author of the changeset."""
     ctx = context.resource(mapping, 'ctx')
     return ctx.user()
 
+
 @templatekeyword('instabilities', requires={'ctx'})
 def showinstabilities(context, mapping):
     """List of strings. Evolution instabilities affecting the changeset.
     (EXPERIMENTAL)
     """
     ctx = context.resource(mapping, 'ctx')
-    return compatlist(context, mapping, 'instability', ctx.instabilities(),
-                      plural='instabilities')
+    return compatlist(
+        context,
+        mapping,
+        'instability',
+        ctx.instabilities(),
+        plural='instabilities',
+    )
+
 
 @templatekeyword('verbosity', requires={'ui'})
 def showverbosity(context, mapping):
@@ -825,6 +943,7 @@
         return 'verbose'
     return ''
 
+
 @templatekeyword('whyunstable', requires={'repo', 'ctx'})
 def showwhyunstable(context, mapping):
     """List of dicts explaining all instabilities of a changeset.
@@ -841,20 +960,27 @@
     for entry in entries:
         if entry.get('divergentnodes'):
             dnodes = entry['divergentnodes']
-            dnhybrid = _hybrid(None, [dnode.hex() for dnode in dnodes],
-                               lambda x: {'ctx': repo[x]},
-                               lambda x: formatnode(repo[x]))
+            dnhybrid = _hybrid(
+                None,
+                [dnode.hex() for dnode in dnodes],
+                lambda x: {'ctx': repo[x]},
+                lambda x: formatnode(repo[x]),
+            )
             entry['divergentnodes'] = dnhybrid
 
-    tmpl = ('{instability}:{if(divergentnodes, " ")}{divergentnodes} '
-            '{reason} {node|short}')
+    tmpl = (
+        '{instability}:{if(divergentnodes, " ")}{divergentnodes} '
+        '{reason} {node|short}'
+    )
     return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n')
 
+
 def loadkeyword(ui, extname, registrarobj):
     """Load template keyword from specified registrarobj
     """
     for name, func in registrarobj._table.iteritems():
         keywords[name] = func
 
+
 # tell hggettext to extract docstrings from these functions:
 i18nfunctions = keywords.values()