diff -r 7259f0ddfc0f -r ee0d74083a22 mercurial/templater.py --- a/mercurial/templater.py Mon Oct 09 12:47:22 2017 -0700 +++ b/mercurial/templater.py Tue Sep 19 23:13:46 2017 +0900 @@ -333,12 +333,12 @@ # empty dict/list should be False as they are expected to be '' return bool(stringify(thing)) -def evalinteger(context, mapping, arg, err): +def evalinteger(context, mapping, arg, err=None): v = evalfuncarg(context, mapping, arg) try: return int(v) except (TypeError, ValueError): - raise error.ParseError(err) + raise error.ParseError(err or _('not an integer')) def evalstring(context, mapping, arg): return stringify(evalrawexp(context, mapping, arg)) @@ -353,6 +353,20 @@ thing = func(context, mapping, data) return stringify(thing) +_evalfuncbytype = { + bool: evalboolean, + bytes: evalstring, + int: evalinteger, +} + +def evalastype(context, mapping, arg, typ): + """Evaluate given argument and coerce its type""" + try: + f = _evalfuncbytype[typ] + except KeyError: + raise error.ProgrammingError('invalid type specified: %r' % typ) + return f(context, mapping, arg) + def runinteger(context, mapping, data): return int(data) @@ -782,8 +796,9 @@ # i18n: "ifcontains" is a keyword raise error.ParseError(_("ifcontains expects three or four arguments")) - needle = evalstring(context, mapping, args[0]) haystack = evalfuncarg(context, mapping, args[1]) + needle = evalastype(context, mapping, args[0], + getattr(haystack, 'keytype', None) or bytes) if needle in haystack: yield evalrawexp(context, mapping, args[2])