# HG changeset patch # User Yuya Nishihara # Date 1504361634 -32400 # Node ID e60c601953d7102ef2c6d9d952b5cb7ef3e987b7 # Parent 86d050abd5c14cd02c5019c00726a71c0f684555 templater: extract helper to just evaluate template expression A named function can be easily grepped and is probably good for code readability. diff -r 86d050abd5c1 -r e60c601953d7 mercurial/templater.py --- a/mercurial/templater.py Sat Sep 02 23:09:34 2017 +0900 +++ b/mercurial/templater.py Sat Sep 02 23:13:54 2017 +0900 @@ -298,11 +298,17 @@ else: return None -def evalfuncarg(context, mapping, arg): +def evalrawexp(context, mapping, arg): + """Evaluate given argument as a bare template object which may require + further processing (such as folding generator of strings)""" func, data = arg - # func() may return string, generator of strings or arbitrary object such - # as date tuple, but filter does not want generator. - thing = func(context, mapping, data) + return func(context, mapping, data) + +def evalfuncarg(context, mapping, arg): + """Evaluate given argument as value type""" + thing = evalrawexp(context, mapping, arg) + # evalrawexp() may return string, generator of strings or arbitrary object + # such as date tuple, but filter does not want generator. if isinstance(thing, types.GeneratorType): thing = stringify(thing) return thing @@ -331,8 +337,7 @@ raise error.ParseError(err) def evalstring(context, mapping, arg): - func, data = arg - return stringify(func(context, mapping, data)) + return stringify(evalrawexp(context, mapping, arg)) def evalstringliteral(context, mapping, arg): """Evaluate given argument as string template, but returns symbol name @@ -380,8 +385,8 @@ return (runtemplate, ctmpl) def runtemplate(context, mapping, template): - for func, data in template: - yield func(context, mapping, data) + for arg in template: + yield evalrawexp(context, mapping, arg) def buildfilter(exp, context): n = getsymbol(exp[2]) @@ -415,15 +420,15 @@ return (runmap, (darg, targ)) def runmap(context, mapping, data): - (func, data), (tfunc, tdata) = data - d = func(context, mapping, data) + darg, targ = data + d = evalrawexp(context, mapping, darg) if util.safehasattr(d, 'itermaps'): diter = d.itermaps() else: try: diter = iter(d) except TypeError: - sym = findsymbolicname((func, data)) + sym = findsymbolicname(darg) if sym: raise error.ParseError(_("keyword '%s' is not iterable") % sym) else: @@ -435,7 +440,7 @@ if isinstance(v, dict): lm.update(v) lm['originalnode'] = mapping.get('node') - yield tfunc(context, lm, tdata) + 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. @@ -718,9 +723,9 @@ test = evalboolean(context, mapping, args[0]) if test: - yield args[1][0](context, mapping, args[1][1]) + yield evalrawexp(context, mapping, args[1]) elif len(args) == 3: - yield args[2][0](context, mapping, args[2][1]) + yield evalrawexp(context, mapping, args[2]) @templatefunc('ifcontains(needle, haystack, then[, else])') def ifcontains(context, mapping, args): @@ -734,9 +739,9 @@ haystack = evalfuncarg(context, mapping, args[1]) if needle in haystack: - yield args[2][0](context, mapping, args[2][1]) + yield evalrawexp(context, mapping, args[2]) elif len(args) == 4: - yield args[3][0](context, mapping, args[3][1]) + yield evalrawexp(context, mapping, args[3]) @templatefunc('ifeq(expr1, expr2, then[, else])') def ifeq(context, mapping, args): @@ -749,9 +754,9 @@ test = evalstring(context, mapping, args[0]) match = evalstring(context, mapping, args[1]) if test == match: - yield args[2][0](context, mapping, args[2][1]) + yield evalrawexp(context, mapping, args[2]) elif len(args) == 4: - yield args[3][0](context, mapping, args[3][1]) + yield evalrawexp(context, mapping, args[3]) @templatefunc('join(list, sep)') def join(context, mapping, args): @@ -760,7 +765,9 @@ # i18n: "join" is a keyword raise error.ParseError(_("join expects one or two arguments")) - joinset = args[0][0](context, mapping, args[0][1]) + # TODO: perhaps this should be evalfuncarg(), but it can't because hgweb + # abuses generator as a keyword that returns a list of dicts. + joinset = evalrawexp(context, mapping, args[0]) if util.safehasattr(joinset, 'itermaps'): jf = joinset.joinfmt joinset = [jf(x) for x in joinset.itermaps()]