# HG changeset patch # User Yuya Nishihara # Date 1491311942 -32400 # Node ID a0f2d83f8083196b7ec235565078afa1b2f2f0e0 # Parent 868ec199cad0d9f25684962ec4ed41d5dc6050a1 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. diff -r 868ec199cad0 -r a0f2d83f8083 mercurial/templatefilters.py --- 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: diff -r 868ec199cad0 -r a0f2d83f8083 mercurial/templatekw.py --- 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 diff -r 868ec199cad0 -r a0f2d83f8083 mercurial/templater.py --- 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: