# HG changeset patch # User Yuya Nishihara # Date 2018-03-18 06:14:58 # Node ID 54355c243042fca46e1041a5ed3a65e4aa788e91 # Parent 307ee888397544693d35c8958e6c448674245405 templatefilters: allow declaration of input data type Currently filters take an unwrapped value, which should have no hybrid magic but actually it does because stringify() relies on it. The 'intype' allows us to pre-process the magic by .e.g. evalstring() keeping filter functions as simple as they are now. stringify() is ported as an example. More follow. diff --git a/mercurial/registrar.py b/mercurial/registrar.py --- a/mercurial/registrar.py +++ b/mercurial/registrar.py @@ -324,7 +324,7 @@ class templatefilter(_templateregistrarb templatefilter = registrar.templatefilter() - @templatefilter('myfilter') + @templatefilter('myfilter', intype=bytes) def myfilterfunc(text): '''Explanation of this template filter .... ''' @@ -332,6 +332,9 @@ class templatefilter(_templateregistrarb The first string argument is used also in online help. + Optional argument 'intype' defines the type of the input argument, + which should be (bytes, int, or None for any.) + 'templatefilter' instance in example above can be used to decorate multiple functions. @@ -342,6 +345,9 @@ class templatefilter(_templateregistrarb Otherwise, explicit 'templatefilters.loadkeyword()' is needed. """ + def _extrasetup(self, name, func, intype=None): + func._intype = intype + class templatefunc(_templateregistrarbase): """Decorator to register template function diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py --- a/mercurial/templatefilters.py +++ b/mercurial/templatefilters.py @@ -354,12 +354,12 @@ def splitlines(text): def stringescape(text): return stringutil.escapestr(text) -@templatefilter('stringify') +@templatefilter('stringify', intype=bytes) def stringify(thing): """Any type. Turns the value into text by converting values into text and concatenating them. """ - return templateutil.stringify(thing) + return thing # coerced by the intype @templatefilter('stripdir') def stripdir(text): diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py --- a/mercurial/templateutil.py +++ b/mercurial/templateutil.py @@ -342,6 +342,7 @@ def evalstringliteral(context, mapping, return stringify(thing) _unwrapfuncbytype = { + None: _unwrapvalue, bytes: stringify, int: unwrapinteger, } @@ -400,8 +401,9 @@ def runtemplate(context, mapping, templa def runfilter(context, mapping, data): arg, filt = data - thing = evalfuncarg(context, mapping, arg) + thing = evalrawexp(context, mapping, arg) try: + thing = unwrapastype(thing, getattr(filt, '_intype', None)) return filt(thing) except (ValueError, AttributeError, TypeError): sym = findsymbolicname(arg)