##// END OF EJS Templates
templater: promote getmember() to an interface of wrapped types
Yuya Nishihara -
r38261:06d11cd9 default
parent child Browse files
Show More
@@ -713,6 +713,9 b' class sessionvars(templateutil.wrapped):'
713 def __copy__(self):
713 def __copy__(self):
714 return sessionvars(copy.copy(self._vars), self._start)
714 return sessionvars(copy.copy(self._vars), self._start)
715
715
716 def getmember(self, context, mapping, key):
717 return self._vars.get(key)
718
716 def itermaps(self, context):
719 def itermaps(self, context):
717 separator = self._start
720 separator = self._start
718 for key, value in sorted(self._vars.iteritems()):
721 for key, value in sorted(self._vars.iteritems()):
@@ -262,12 +262,13 b' def get(context, mapping, args):'
262 raise error.ParseError(_("get() expects two arguments"))
262 raise error.ParseError(_("get() expects two arguments"))
263
263
264 dictarg = evalwrapped(context, mapping, args[0])
264 dictarg = evalwrapped(context, mapping, args[0])
265 if not util.safehasattr(dictarg, 'getmember'):
265 key = evalfuncarg(context, mapping, args[1])
266 try:
267 return dictarg.getmember(context, mapping, key)
268 except error.ParseError as err:
266 # i18n: "get" is a keyword
269 # i18n: "get" is a keyword
267 raise error.ParseError(_("get() expects a dict as first argument"))
270 hint = _("get() expects a dict as first argument")
268
271 raise error.ParseError(bytes(err), hint=hint)
269 key = evalfuncarg(context, mapping, args[1])
270 return dictarg.getmember(context, mapping, key)
271
272
272 @templatefunc('if(expr, then[, else])')
273 @templatefunc('if(expr, then[, else])')
273 def if_(context, mapping, args):
274 def if_(context, mapping, args):
@@ -38,6 +38,14 b' class wrapped(object):'
38 __metaclass__ = abc.ABCMeta
38 __metaclass__ = abc.ABCMeta
39
39
40 @abc.abstractmethod
40 @abc.abstractmethod
41 def getmember(self, context, mapping, key):
42 """Return a member item for the specified key
43
44 A returned object may be either a wrapped object or a pure value
45 depending on the self type.
46 """
47
48 @abc.abstractmethod
41 def itermaps(self, context):
49 def itermaps(self, context):
42 """Yield each template mapping"""
50 """Yield each template mapping"""
43
51
@@ -72,6 +80,10 b' class wrappedbytes(wrapped):'
72 def __init__(self, value):
80 def __init__(self, value):
73 self._value = value
81 self._value = value
74
82
83 def getmember(self, context, mapping, key):
84 raise error.ParseError(_('%r is not a dictionary')
85 % pycompat.bytestr(self._value))
86
75 def itermaps(self, context):
87 def itermaps(self, context):
76 raise error.ParseError(_('%r is not iterable of mappings')
88 raise error.ParseError(_('%r is not iterable of mappings')
77 % pycompat.bytestr(self._value))
89 % pycompat.bytestr(self._value))
@@ -91,6 +103,9 b' class wrappedvalue(wrapped):'
91 def __init__(self, value):
103 def __init__(self, value):
92 self._value = value
104 self._value = value
93
105
106 def getmember(self, context, mapping, key):
107 raise error.ParseError(_('%r is not a dictionary') % self._value)
108
94 def itermaps(self, context):
109 def itermaps(self, context):
95 raise error.ParseError(_('%r is not iterable of mappings')
110 raise error.ParseError(_('%r is not iterable of mappings')
96 % self._value)
111 % self._value)
@@ -196,6 +211,10 b' class mappable(wrapped):'
196 def tomap(self):
211 def tomap(self):
197 return self._makemap(self._key)
212 return self._makemap(self._key)
198
213
214 def getmember(self, context, mapping, key):
215 w = makewrapped(context, mapping, self._value)
216 return w.getmember(context, mapping, key)
217
199 def itermaps(self, context):
218 def itermaps(self, context):
200 yield self.tomap()
219 yield self.tomap()
201
220
@@ -231,6 +250,9 b' class _mappingsequence(wrapped):'
231 self._tmpl = tmpl
250 self._tmpl = tmpl
232 self._defaultsep = sep
251 self._defaultsep = sep
233
252
253 def getmember(self, context, mapping, key):
254 raise error.ParseError(_('not a dictionary'))
255
234 def join(self, context, mapping, sep):
256 def join(self, context, mapping, sep):
235 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context))
257 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context))
236 if self._name:
258 if self._name:
@@ -294,6 +316,9 b' class mappedgenerator(wrapped):'
294 def _gen(self, context):
316 def _gen(self, context):
295 return self._make(context, *self._args)
317 return self._make(context, *self._args)
296
318
319 def getmember(self, context, mapping, key):
320 raise error.ParseError(_('not a dictionary'))
321
297 def itermaps(self, context):
322 def itermaps(self, context):
298 raise error.ParseError(_('list of strings is not mappable'))
323 raise error.ParseError(_('list of strings is not mappable'))
299
324
@@ -678,15 +703,13 b' def runmember(context, mapping, data):'
678 lm = context.overlaymap(mapping, d.tomap())
703 lm = context.overlaymap(mapping, d.tomap())
679 return runsymbol(context, lm, memb)
704 return runsymbol(context, lm, memb)
680 try:
705 try:
681 if util.safehasattr(d, 'getmember'):
706 return d.getmember(context, mapping, memb)
682 return d.getmember(context, mapping, memb)
707 except error.ParseError as err:
683 raise error.ParseError
684 except error.ParseError:
685 sym = findsymbolicname(darg)
708 sym = findsymbolicname(darg)
686 if sym:
709 if not sym:
687 raise error.ParseError(_("keyword '%s' has no member") % sym)
710 raise
688 else:
711 hint = _("keyword '%s' does not support member operation") % sym
689 raise error.ParseError(_("%r has no member") % pycompat.bytestr(d))
712 raise error.ParseError(bytes(err), hint=hint)
690
713
691 def runnegate(context, mapping, data):
714 def runnegate(context, mapping, data):
692 data = evalinteger(context, mapping, data,
715 data = evalinteger(context, mapping, data,
@@ -3345,10 +3345,11 b' Test evaluation of dot operator:'
3345 default
3345 default
3346
3346
3347 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3347 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3348 hg: parse error: keyword 'author' has no member
3348 hg: parse error: 'test' is not a dictionary
3349 (keyword 'author' does not support member operation)
3349 [255]
3350 [255]
3350 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3351 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3351 hg: parse error: 'a' has no member
3352 hg: parse error: 'a' is not a dictionary
3352 [255]
3353 [255]
3353
3354
3354 Test the sub function of templating for expansion:
3355 Test the sub function of templating for expansion:
@@ -3851,7 +3852,8 b' Test get function:'
3851 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3852 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3852 default
3853 default
3853 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3854 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3854 hg: parse error: get() expects a dict as first argument
3855 hg: parse error: not a dictionary
3856 (get() expects a dict as first argument)
3855 [255]
3857 [255]
3856
3858
3857 Test json filter applied to hybrid object:
3859 Test json filter applied to hybrid object:
General Comments 0
You need to be logged in to leave comments. Login now