diff mercurial/templatekw.py @ 34581:ee0d74083a22

templater: store revisions as ints so min/max won't compare them as strings Because a template value has no explicit type (like ancient PHP), ifcontains() has to coerce the type of the needle. Before, it was always converted to a string, which meant any container type should be a list/dict of strings. This no longer works since we've introduced min/max functions. In order to work around the untyped nature of templater, this patch adds a type specifier to hybrid dict/list. It isn't named as "valuetype" since the _hybrid class can also wrap a dict.
author Yuya Nishihara <yuya@tcha.org>
date Tue, 19 Sep 2017 23:13:46 +0900
parents 0a0a72c043ac
children eb7fffdc6e5b
line wrap: on
line diff
--- a/mercurial/templatekw.py	Mon Oct 09 12:47:22 2017 -0700
+++ b/mercurial/templatekw.py	Tue Sep 19 23:13:46 2017 +0900
@@ -37,12 +37,13 @@
     - "{files|json}"
     """
 
-    def __init__(self, gen, values, makemap, joinfmt):
+    def __init__(self, gen, values, makemap, joinfmt, keytype=None):
         if gen is not None:
             self.gen = gen  # generator or function returning generator
         self._values = values
         self._makemap = makemap
         self.joinfmt = joinfmt
+        self.keytype = keytype  # hint for 'x in y' where type(x) is unresolved
     def gen(self):
         """Default generator to stringify this as {join(self, ' ')}"""
         for i, x in enumerate(self._values):
@@ -788,15 +789,14 @@
     repo = args['repo']
     ctx = args['ctx']
     pctxs = scmutil.meaningfulparents(repo, ctx)
-    # ifcontains() needs a list of str
-    prevs = ["%d" % p.rev() for p in pctxs]
+    prevs = [p.rev() for p in pctxs]
     parents = [[('rev', p.rev()),
                 ('node', p.hex()),
                 ('phase', p.phasestr())]
                for p in pctxs]
     f = _showlist('parent', parents, args)
-    return _hybrid(f, prevs, lambda x: {'ctx': repo[int(x)], 'revcache': {}},
-                   lambda x: scmutil.formatchangeid(repo[int(x)]))
+    return _hybrid(f, prevs, lambda x: {'ctx': repo[x], 'revcache': {}},
+                   lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
 
 @templatekeyword('phase')
 def showphase(repo, ctx, templ, **args):
@@ -818,12 +818,10 @@
     be evaluated"""
     args = pycompat.byteskwargs(args)
     repo = args['ctx'].repo()
-    # ifcontains() needs a list of str
-    revs = ["%d" % r for r in revs]
-    f = _showlist(name, revs, args)
+    f = _showlist(name, ['%d' % r for r in revs], args)
     return _hybrid(f, revs,
-                   lambda x: {name: x, 'ctx': repo[int(x)], 'revcache': {}},
-                   pycompat.identity)
+                   lambda x: {name: x, 'ctx': repo[x], 'revcache': {}},
+                   pycompat.identity, keytype=int)
 
 @templatekeyword('subrepos')
 def showsubrepos(**args):