templatefilters: allow declaration of input data type
authorYuya Nishihara <yuya@tcha.org>
Sun, 18 Mar 2018 15:14:58 +0900
changeset 37222 54355c243042
parent 37221 307ee8883975
child 37223 08e042f0a67c
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.
mercurial/registrar.py
mercurial/templatefilters.py
mercurial/templateutil.py
--- a/mercurial/registrar.py	Mon Mar 19 20:39:06 2018 +0900
+++ b/mercurial/registrar.py	Sun Mar 18 15:14:58 2018 +0900
@@ -324,7 +324,7 @@
 
         templatefilter = registrar.templatefilter()
 
-        @templatefilter('myfilter')
+        @templatefilter('myfilter', intype=bytes)
         def myfilterfunc(text):
             '''Explanation of this template filter ....
             '''
@@ -332,6 +332,9 @@
 
     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 @@
     Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
     """
 
+    def _extrasetup(self, name, func, intype=None):
+        func._intype = intype
+
 class templatefunc(_templateregistrarbase):
     """Decorator to register template function
 
--- a/mercurial/templatefilters.py	Mon Mar 19 20:39:06 2018 +0900
+++ b/mercurial/templatefilters.py	Sun Mar 18 15:14:58 2018 +0900
@@ -354,12 +354,12 @@
 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):
--- a/mercurial/templateutil.py	Mon Mar 19 20:39:06 2018 +0900
+++ b/mercurial/templateutil.py	Sun Mar 18 15:14:58 2018 +0900
@@ -342,6 +342,7 @@
     return stringify(thing)
 
 _unwrapfuncbytype = {
+    None: _unwrapvalue,
     bytes: stringify,
     int: unwrapinteger,
 }
@@ -400,8 +401,9 @@
 
 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)