[PATCH 1 of 8] templater: pass context down to unwraphybrid()
Yuya Nishihara
yuya at tcha.org
Sat Mar 31 22:45:58 EDT 2018
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1521284945 -32400
# Sat Mar 17 20:09:05 2018 +0900
# Node ID 529838f7858556c0f9d180a276b483578c6d55d4
# Parent 02079695afdd39020b13f238c69691dce14b932f
templater: pass context down to unwraphybrid()
See the subsequent patches for why.
Unlike eval*() functions, flatten(), stringify(), and unwraphybrid() don't
take a mapping since these functions may be applied to a tree of generators
where each node should be bound to the mapping when it was evaluated.
diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py
--- a/mercurial/templatefuncs.py
+++ b/mercurial/templatefuncs.py
@@ -283,7 +283,7 @@ def ifcontains(context, mapping, args):
keytype = getattr(haystack, 'keytype', None)
try:
needle = evalrawexp(context, mapping, args[0])
- needle = templateutil.unwrapastype(needle, keytype or bytes)
+ needle = templateutil.unwrapastype(context, needle, keytype or bytes)
found = (needle in haystack)
except error.ParseError:
found = False
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -679,7 +679,7 @@ class engine(object):
if extramapping:
extramapping.update(mapping)
mapping = extramapping
- return templateutil.flatten(func(self, mapping, data))
+ return templateutil.flatten(self, func(self, mapping, data))
engines = {'default': engine}
diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -120,7 +120,7 @@ def hybridlist(data, name, fmt=None, gen
prefmt = pycompat.bytestr
return hybrid(gen, data, lambda x: {name: x}, lambda x: fmt % prefmt(x))
-def unwraphybrid(thing):
+def unwraphybrid(context, thing):
"""Return an object which can be stringified possibly by using a legacy
template"""
gen = getattr(thing, 'gen', None)
@@ -241,9 +241,9 @@ def _showcompatlist(context, mapping, na
if context.preload(endname):
yield context.process(endname, mapping)
-def flatten(thing):
+def flatten(context, thing):
"""Yield a single stream from a possibly nested set of iterators"""
- thing = unwraphybrid(thing)
+ thing = unwraphybrid(context, thing)
if isinstance(thing, bytes):
yield thing
elif isinstance(thing, str):
@@ -257,7 +257,7 @@ def flatten(thing):
yield pycompat.bytestr(thing)
else:
for i in thing:
- i = unwraphybrid(i)
+ i = unwraphybrid(context, i)
if isinstance(i, bytes):
yield i
elif i is None:
@@ -265,14 +265,14 @@ def flatten(thing):
elif not util.safehasattr(i, '__iter__'):
yield pycompat.bytestr(i)
else:
- for j in flatten(i):
+ for j in flatten(context, i):
yield j
-def stringify(thing):
+def stringify(context, thing):
"""Turn values into bytes by converting into text and concatenating them"""
if isinstance(thing, bytes):
return thing # retain localstr to be round-tripped
- return b''.join(flatten(thing))
+ return b''.join(flatten(context, thing))
def findsymbolicname(arg):
"""Find symbolic name for the given compiled expression; returns None
@@ -294,17 +294,17 @@ def evalrawexp(context, mapping, arg):
def evalfuncarg(context, mapping, arg):
"""Evaluate given argument as value type"""
- return _unwrapvalue(evalrawexp(context, mapping, arg))
+ return _unwrapvalue(context, evalrawexp(context, mapping, arg))
# TODO: unify this with unwrapvalue() once the bug of templatefunc.join()
# is fixed. we can't do that right now because join() has to take a generator
# of byte strings as it is, not a lazy byte string.
-def _unwrapvalue(thing):
+def _unwrapvalue(context, thing):
thing = unwrapvalue(thing)
# 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)
+ thing = stringify(context, thing)
return thing
def evalboolean(context, mapping, arg):
@@ -322,15 +322,15 @@ def evalboolean(context, mapping, arg):
return thing
# other objects are evaluated as strings, which means 0 is True, but
# empty dict/list should be False as they are expected to be ''
- return bool(stringify(thing))
+ return bool(stringify(context, thing))
def evaldate(context, mapping, arg, err=None):
"""Evaluate given argument as a date tuple or a date string; returns
a (unixtime, offset) tuple"""
- return unwrapdate(evalrawexp(context, mapping, arg), err)
+ return unwrapdate(context, evalrawexp(context, mapping, arg), err)
-def unwrapdate(thing, err=None):
- thing = _unwrapvalue(thing)
+def unwrapdate(context, thing, err=None):
+ thing = _unwrapvalue(context, thing)
try:
return dateutil.parsedate(thing)
except AttributeError:
@@ -341,17 +341,17 @@ def unwrapdate(thing, err=None):
raise error.ParseError(err)
def evalinteger(context, mapping, arg, err=None):
- return unwrapinteger(evalrawexp(context, mapping, arg), err)
+ return unwrapinteger(context, evalrawexp(context, mapping, arg), err)
-def unwrapinteger(thing, err=None):
- thing = _unwrapvalue(thing)
+def unwrapinteger(context, thing, err=None):
+ thing = _unwrapvalue(context, thing)
try:
return int(thing)
except (TypeError, ValueError):
raise error.ParseError(err or _('not an integer'))
def evalstring(context, mapping, arg):
- return stringify(evalrawexp(context, mapping, arg))
+ return stringify(context, evalrawexp(context, mapping, arg))
def evalstringliteral(context, mapping, arg):
"""Evaluate given argument as string template, but returns symbol name
@@ -361,7 +361,7 @@ def evalstringliteral(context, mapping,
thing = func(context, mapping, data, default=data)
else:
thing = func(context, mapping, data)
- return stringify(thing)
+ return stringify(context, thing)
_unwrapfuncbytype = {
None: _unwrapvalue,
@@ -370,13 +370,13 @@ def evalstringliteral(context, mapping,
int: unwrapinteger,
}
-def unwrapastype(thing, typ):
+def unwrapastype(context, thing, typ):
"""Move the inner value object out of the wrapper and coerce its type"""
try:
f = _unwrapfuncbytype[typ]
except KeyError:
raise error.ProgrammingError('invalid type specified: %r' % typ)
- return f(thing)
+ return f(context, thing)
def runinteger(context, mapping, data):
return int(data)
@@ -426,7 +426,7 @@ def runfilter(context, mapping, data):
arg, filt = data
thing = evalrawexp(context, mapping, arg)
try:
- thing = unwrapastype(thing, getattr(filt, '_intype', None))
+ thing = unwrapastype(context, thing, getattr(filt, '_intype', None))
return filt(thing)
except error.ParseError as e:
raise error.ParseError(bytes(e), hint=_formatfiltererror(arg, filt))
diff --git a/tests/test-template-engine.t b/tests/test-template-engine.t
--- a/tests/test-template-engine.t
+++ b/tests/test-template-engine.t
@@ -24,7 +24,7 @@
> v = v(**pycompat.strkwargs(props))
> elif callable(v):
> v = v(self, props)
- > v = templateutil.stringify(v)
+ > v = templateutil.stringify(self, v)
> tmpl = tmpl.replace(b'{{%s}}' % k, v)
> yield tmpl
>
More information about the Mercurial-devel
mailing list