Patchwork [5,of,6] templater: implement _hybrid.__contains__ so that ifcontains can accept dict

login
register
mail settings
Submitter Yuya Nishihara
Date March 8, 2015, 11:56 a.m.
Message ID <600b24dca4f75c9692e5.1425815767@mimosa>
Download mbox | patch
Permalink /patch/7936/
State Accepted
Headers show

Comments

Yuya Nishihara - March 8, 2015, 11:56 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1424268093 -32400
#      Wed Feb 18 23:01:33 2015 +0900
# Node ID 600b24dca4f75c9692e599febe5a85e435fb79c1
# Parent  473605474f5e6585ba8336ac1feb411a74316b16
templater: implement _hybrid.__contains__ so that ifcontains can accept dict

d8fb835376d1 is fine for "{revset()}", but "i.values()[0]" does not work if
each item has more than one values such as "{bookmarks}".

This fixes the problem by using list.__contains__ or dict.__contains__
appropriately.

Patch

diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -12,6 +12,8 @@  import hbisect
 # This helper class allows us to handle both:
 #  "{files}" (legacy command-line-specific list hack) and
 #  "{files % '{file}\n'}" (hgweb-style with inlining and function support)
+# and to access raw values:
+#  "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
 
 class _hybrid(object):
     def __init__(self, gen, values, makemap, joinfmt=None):
@@ -28,6 +30,8 @@  class _hybrid(object):
         makemap = self._makemap
         for x in self.values:
             yield makemap(x)
+    def __contains__(self, x):
+        return x in self.values
     def __len__(self):
         return len(self.values)
 
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -330,10 +330,7 @@  def ifcontains(context, mapping, args):
     item = stringify(args[0][0](context, mapping, args[0][1]))
     items = args[1][0](context, mapping, args[1][1])
 
-    # Iterating over items gives a formatted string, so we iterate
-    # directly over the raw values.
-    if ((callable(items) and item in [i.values()[0] for i in items()]) or
-        (isinstance(items, str) and item in items)):
+    if item in items:
         yield _evalifliteral(args[2], context, mapping)
     elif len(args) == 4:
         yield _evalifliteral(args[3], context, mapping)
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -47,6 +47,9 @@  Second branch starting at nullrev:
   fourth (second)
   $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
   second -> fourth
+  $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
+  8 t
+  7 f
 
 Quoting for ui.logtemplate
 
@@ -2386,6 +2389,10 @@  Test current bookmark templating
   2 bar foo
   1 baz
   0 
+  $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
+  2 t
+  1 f
+  0 f
 
 Test stringify on sub expressions