Patchwork [1,of,4] templater: make _hybrid not callable to avoid conflicting semantics

login
register
mail settings
Submitter Yuya Nishihara
Date Jan. 16, 2016, 12:47 p.m.
Message ID <34bd032d95483c8bbdcd.1452948470@mimosa>
Download mbox | patch
Permalink /patch/12794/
State Accepted
Headers show

Comments

Yuya Nishihara - Jan. 16, 2016, 12:47 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1452919357 -32400
#      Sat Jan 16 13:42:37 2016 +0900
# Node ID 34bd032d95483c8bbdcd6269d0cc04f921e3abdc
# Parent  0029c2bebc23182c34f83fa22abde1d5d4aebc51
templater: make _hybrid not callable to avoid conflicting semantics

In templater, a callable symbol exists for lazy evaluation, which should have
f(**mapping) signature. On the other hand, _hybrid.__call__(), which was
introduced by 0b241d7a8c62, generates mapping for each element.

This patch renames _hybrid.__call__() to _hybrid.itermaps() so that a _hybrid
object can be a value of a mapping dict.

  {namespaces % "{namespace}: {names % "{name }"}\n"}
                               ~~~~~
                               a _hybrid object

Patch

diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -34,7 +34,7 @@  class _hybrid(object):
             self.joinfmt = lambda x: x.values()[0]
     def __iter__(self):
         return self.gen
-    def __call__(self):
+    def itermaps(self):
         makemap = self._makemap
         for x in self.values:
             yield makemap(x)
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -281,8 +281,8 @@  def buildmap(exp, context):
 def runmap(context, mapping, data):
     func, data, ctmpl = data
     d = func(context, mapping, data)
-    if callable(d):
-        d = d()
+    if util.safehasattr(d, 'itermaps'):
+        d = d.itermaps()
 
     lm = mapping.copy()
 
@@ -483,9 +483,9 @@  def join(context, mapping, args):
         raise error.ParseError(_("join expects one or two arguments"))
 
     joinset = args[0][0](context, mapping, args[0][1])
-    if callable(joinset):
+    if util.safehasattr(joinset, 'itermaps'):
         jf = joinset.joinfmt
-        joinset = [jf(x) for x in joinset()]
+        joinset = [jf(x) for x in joinset.itermaps()]
 
     joiner = " "
     if len(args) > 1: