templater: find keyword name more thoroughly on filtering error

Before, it could spill an internal representation of compiled template such
as [(<function runsymbol at 0x....>, 'extras'), ...]. Show less cryptic
message if no symbol found.

New findsymbolicname() function will be also used by dict() constructor.
This commit is contained in:
Yuya Nishihara 2017-04-08 23:33:32 +09:00
parent ada544b9a5
commit d86057a7bc
2 changed files with 26 additions and 5 deletions

View File

@ -284,6 +284,18 @@ def gettemplate(exp, context):
return context._load(exp[1])
raise error.ParseError(_("expected template specifier"))
def findsymbolicname(arg):
"""Find symbolic name for the given compiled expression; returns None
if nothing found reliably"""
while True:
func, data = arg
if func is runsymbol:
return data
elif func is runfilter:
arg = data[0]
else:
return None
def evalfuncarg(context, mapping, arg):
func, data = arg
# func() may return string, generator of strings or arbitrary object such
@ -387,12 +399,13 @@ def runfilter(context, mapping, data):
try:
return filt(thing)
except (ValueError, AttributeError, TypeError):
if isinstance(arg[1], tuple):
dt = arg[1][1]
sym = findsymbolicname(arg)
if sym:
msg = (_("template filter '%s' is not compatible with keyword '%s'")
% (filt.func_name, sym))
else:
dt = arg[1]
raise error.Abort(_("template filter '%s' is not compatible with "
"keyword '%s'") % (filt.func_name, dt))
msg = _("incompatible use of template filter '%s'") % filt.func_name
raise error.Abort(msg)
def buildmap(exp, context):
func, data = compileexp(exp[1], context, methods)

View File

@ -2684,6 +2684,14 @@ Behind the scenes, this will throw ValueError
hg: parse error: date expects a date information
[255]
$ hg tip -T '{author|email|shortdate}\n'
abort: template filter 'shortdate' is not compatible with keyword 'author'
[255]
$ hg tip -T '{get(extras, "branch")|shortdate}\n'
abort: incompatible use of template filter 'shortdate'
[255]
Error in nested template:
$ hg log -T '{"date'