Mercurial > hg
changeset 37404:7c902a8345ef
templater: complain about invalid application of '%' operator (BC)
Before, '{x % y % z ...}' was silently evaluated as '{x % y}'. We no longer
need this hack since the web template bugs was fixed by earlier patches.
At this point, the error message may contain '<generator *>', which will
be fixed later.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 18 Mar 2018 21:01:23 +0900 |
parents | 448f7ec247e2 |
children | da8e9ecac4a4 |
files | mercurial/templateutil.py tests/test-command-template.t |
diffstat | 2 files changed, 27 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/templateutil.py Sun Mar 18 21:18:57 2018 +0900 +++ b/mercurial/templateutil.py Sun Mar 18 21:01:23 2018 +0900 @@ -567,6 +567,20 @@ return (_("template filter '%s' is not compatible with keyword '%s'") % (fn, sym)) +def _checkeditermaps(darg, d): + try: + for v in d: + if not isinstance(v, dict): + raise TypeError + yield v + except TypeError: + sym = findsymbolicname(darg) + if sym: + raise error.ParseError(_("keyword '%s' is not iterable of mappings") + % sym) + else: + raise error.ParseError(_("%r is not iterable of mappings") % d) + def _iteroverlaymaps(context, origmapping, newmappings): """Generate combined mappings from the original mapping and an iterable of partial mappings to override the original""" @@ -578,28 +592,17 @@ def runmap(context, mapping, data): darg, targ = data d = evalrawexp(context, mapping, darg) + # TODO: a generator should be rejected because it is a thunk of lazy + # string, but we can't because hgweb abuses generator as a keyword + # that returns a list of dicts. if isinstance(d, wrapped): diter = d.itermaps(context) else: - try: - diter = iter(d) - except TypeError: - sym = findsymbolicname(darg) - if sym: - raise error.ParseError(_("keyword '%s' is not iterable") % sym) - else: - raise error.ParseError(_("%r is not iterable") % d) - + diter = _checkeditermaps(darg, d) for i, v in enumerate(diter): - if isinstance(v, dict): - lm = context.overlaymap(mapping, v) - lm['index'] = i - yield evalrawexp(context, lm, targ) - else: - # v is not an iterable of dicts, this happen when 'key' - # has been fully expanded already and format is useless. - # If so, return the expanded value. - yield v + lm = context.overlaymap(mapping, v) + lm['index'] = i + yield evalrawexp(context, lm, targ) def runmember(context, mapping, data): darg, memb = data
--- a/tests/test-command-template.t Sun Mar 18 21:18:57 2018 +0900 +++ b/tests/test-command-template.t Sun Mar 18 21:01:23 2018 +0900 @@ -3210,10 +3210,13 @@ $ hg log -R latesttag -r tip -T '{rev % "a"}\n' - hg: parse error: keyword 'rev' is not iterable + hg: parse error: keyword 'rev' is not iterable of mappings [255] $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n' - hg: parse error: None is not iterable + hg: parse error: None is not iterable of mappings + [255] + $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}' + hg: parse error: <generator *> is not iterable of mappings (glob) [255] Test new-style inline templating of non-list/dict type: @@ -3228,7 +3231,7 @@ $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}' branch: default $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}' - hg: parse error: None is not iterable + hg: parse error: None is not iterable of mappings [255] $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}' branch: default