--- a/mercurial/templateutil.py Tue Jun 12 23:17:38 2018 +0900
+++ b/mercurial/templateutil.py Sat Jun 09 13:34:47 2018 +0900
@@ -85,6 +85,10 @@
"""
@abc.abstractmethod
+ def tobool(self, context, mapping):
+ """Return a boolean representation of the inner value"""
+
+ @abc.abstractmethod
def tovalue(self, context, mapping):
"""Move the inner value object out or create a value representation
@@ -136,6 +140,9 @@
def show(self, context, mapping):
return self._value
+ def tobool(self, context, mapping):
+ return bool(self._value)
+
def tovalue(self, context, mapping):
return self._value
@@ -169,6 +176,14 @@
return b''
return pycompat.bytestr(self._value)
+ def tobool(self, context, mapping):
+ if self._value is None:
+ return False
+ if isinstance(self._value, bool):
+ return self._value
+ # otherwise evaluate as string, which means 0 is True
+ return bool(pycompat.bytestr(self._value))
+
def tovalue(self, context, mapping):
return self._value
@@ -201,6 +216,9 @@
def tomap(self, context):
return {'unixtime': self._unixtime, 'tzoffset': self._tzoffset}
+ def tobool(self, context, mapping):
+ return True
+
def tovalue(self, context, mapping):
return (self._unixtime, self._tzoffset)
@@ -272,6 +290,9 @@
return gen()
return gen
+ def tobool(self, context, mapping):
+ return bool(self._values)
+
def tovalue(self, context, mapping):
# TODO: make it non-recursive for trivial lists/dicts
xs = self._values
@@ -327,6 +348,9 @@
return gen()
return gen
+ def tobool(self, context, mapping):
+ return bool(self.tovalue(context, mapping))
+
def tovalue(self, context, mapping):
return _unthunk(context, mapping, self._value)
@@ -396,6 +420,9 @@
def itermaps(self, context):
return self._make(context, *self._args)
+ def tobool(self, context, mapping):
+ return _nonempty(self.itermaps(context))
+
class mappinglist(_mappingsequence):
"""Wrapper for list of template mappings"""
@@ -406,6 +433,9 @@
def itermaps(self, context):
return iter(self._mappings)
+ def tobool(self, context, mapping):
+ return bool(self._mappings)
+
class mappedgenerator(wrapped):
"""Wrapper for generator of strings which acts as a list
@@ -449,6 +479,9 @@
def show(self, context, mapping):
return self.join(context, mapping, '')
+ def tobool(self, context, mapping):
+ return _nonempty(self._gen(context))
+
def tovalue(self, context, mapping):
return [stringify(context, mapping, x) for x in self._gen(context)]
@@ -607,6 +640,13 @@
else:
return None
+def _nonempty(xiter):
+ try:
+ next(xiter)
+ return True
+ except StopIteration:
+ return False
+
def _unthunk(context, mapping, thing):
"""Evaluate a lazy byte string into value"""
if not isinstance(thing, types.GeneratorType):
@@ -655,13 +695,7 @@
thing = stringutil.parsebool(data)
else:
thing = func(context, mapping, data)
- if isinstance(thing, wrapped):
- thing = thing.tovalue(context, mapping)
- if isinstance(thing, bool):
- 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(context, mapping, thing))
+ return makewrapped(context, mapping, thing).tobool(context, mapping)
def evaldate(context, mapping, arg, err=None):
"""Evaluate given argument as a date tuple or a date string; returns