changeset 31880:a0f2d83f8083

templater: remove __iter__() from _hybrid, resolve it explicitly The goal is to fix "{hybrid_obj|json}" output. A _hybrid object must act as a list or a dict as well as a generator of legacy template strings. Before, _hybrid.__iter__() was assigned for legacy template, which conflicted with list.__iter__() API. This patch drops _hybrid.__iter__() and makes stringify/flatten functions unwrap a generator instead.
author Yuya Nishihara <yuya@tcha.org>
date Tue, 04 Apr 2017 22:19:02 +0900
parents 868ec199cad0
children 31dad7a5b4ed
files mercurial/templatefilters.py mercurial/templatekw.py mercurial/templater.py
diffstat 3 files changed, 10 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/templatefilters.py	Sun Apr 24 19:15:34 2016 +0900
+++ b/mercurial/templatefilters.py	Tue Apr 04 22:19:02 2017 +0900
@@ -350,6 +350,7 @@
     """Any type. Turns the value into text by converting values into
     text and concatenating them.
     """
+    thing = templatekw.unwraphybrid(thing)
     if util.safehasattr(thing, '__iter__') and not isinstance(thing, str):
         return "".join([stringify(t) for t in thing if t is not None])
     if thing is None:
--- a/mercurial/templatekw.py	Sun Apr 24 19:15:34 2016 +0900
+++ b/mercurial/templatekw.py	Tue Apr 04 22:19:02 2017 +0900
@@ -35,8 +35,6 @@
         self.values = values
         self._makemap = makemap
         self.joinfmt = joinfmt
-    def __iter__(self):
-        return self.gen
     def itermaps(self):
         makemap = self._makemap
         for x in self.values:
@@ -50,6 +48,13 @@
             raise AttributeError(name)
         return getattr(self.values, name)
 
+def unwraphybrid(thing):
+    """Return an object which can be stringified possibly by using a legacy
+    template"""
+    if not util.safehasattr(thing, 'gen'):
+        return thing
+    return thing.gen
+
 def showlist(name, values, plural=None, element=None, separator=' ', **args):
     if not element:
         element = name
--- a/mercurial/templater.py	Sun Apr 24 19:15:34 2016 +0900
+++ b/mercurial/templater.py	Tue Apr 04 22:19:02 2017 +0900
@@ -1020,6 +1020,7 @@
 
 def _flatten(thing):
     '''yield a single stream from a possibly nested set of iterators'''
+    thing = templatekw.unwraphybrid(thing)
     if isinstance(thing, str):
         yield thing
     elif thing is None:
@@ -1028,6 +1029,7 @@
         yield str(thing)
     else:
         for i in thing:
+            i = templatekw.unwraphybrid(i)
             if isinstance(i, str):
                 yield i
             elif i is None: