Mercurial > public > mercurial-scm > hg
diff mercurial/templateutil.py @ 38267:fb874fc1d9b4
templater: abstract ifcontains() over wrapped types
This allows us to make .keytype private.
There's a minor BC that a hybrid dict/list of keytype=None now strictly
checks the type of the needle. For example, {ifcontains(rev, files)} no longer
matches a file named "1" at the rev=1. I made this change for consistency
with the get(dict, key) function. We can restore the old behavior by making
keytype=bytes the default if desired.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Mon, 19 Mar 2018 00:23:20 +0900 |
parents | 80f423a14c90 |
children | 49ef1539b84e |
line wrap: on
line diff
--- a/mercurial/templateutil.py Wed Mar 21 12:06:18 2018 +0900 +++ b/mercurial/templateutil.py Mon Mar 19 00:23:20 2018 +0900 @@ -38,6 +38,13 @@ __metaclass__ = abc.ABCMeta @abc.abstractmethod + def contains(self, context, mapping, item): + """Test if the specified item is in self + + The item argument may be a wrapped object. + """ + + @abc.abstractmethod def getmember(self, context, mapping, key): """Return a member item for the specified key @@ -91,6 +98,10 @@ def __init__(self, value): self._value = value + def contains(self, context, mapping, item): + item = stringify(context, mapping, item) + return item in self._value + def getmember(self, context, mapping, key): raise error.ParseError(_('%r is not a dictionary') % pycompat.bytestr(self._value)) @@ -125,6 +136,9 @@ def __init__(self, value): self._value = value + def contains(self, context, mapping, item): + raise error.ParseError(_("%r is not iterable") % self._value) + def getmember(self, context, mapping, key): raise error.ParseError(_('%r is not a dictionary') % self._value) @@ -171,6 +185,10 @@ self._joinfmt = joinfmt self.keytype = keytype # hint for 'x in y' where type(x) is unresolved + def contains(self, context, mapping, item): + item = unwrapastype(context, mapping, item, self.keytype) + return item in self._values + def getmember(self, context, mapping, key): # TODO: maybe split hybrid list/dict types? if not util.safehasattr(self._values, 'get'): @@ -255,6 +273,10 @@ def tomap(self): return self._makemap(self._key) + def contains(self, context, mapping, item): + w = makewrapped(context, mapping, self._value) + return w.contains(context, mapping, item) + def getmember(self, context, mapping, key): w = makewrapped(context, mapping, self._value) return w.getmember(context, mapping, key) @@ -302,6 +324,9 @@ self._tmpl = tmpl self._defaultsep = sep + def contains(self, context, mapping, item): + raise error.ParseError(_('not comparable')) + def getmember(self, context, mapping, key): raise error.ParseError(_('not a dictionary')) @@ -371,6 +396,10 @@ self._make = make self._args = args + def contains(self, context, mapping, item): + item = stringify(context, mapping, item) + return item in self.tovalue(context, mapping) + def _gen(self, context): return self._make(context, *self._args)