comparison mercurial/templateutil.py @ 38453:dae829b4de78

templater: introduce filter() function to remove empty items from list The primary use case is to filter out "tip" from a list of tags.
author Yuya Nishihara <yuya@tcha.org>
date Thu, 14 Jun 2018 22:33:26 +0900
parents b6294c113794
children bc8d925342f0
comparison
equal deleted inserted replaced
38452:b6294c113794 38453:dae829b4de78
61 def getmax(self, context, mapping): 61 def getmax(self, context, mapping):
62 """Return the largest item, which may be either a wrapped or a pure 62 """Return the largest item, which may be either a wrapped or a pure
63 value depending on the self type""" 63 value depending on the self type"""
64 64
65 @abc.abstractmethod 65 @abc.abstractmethod
66 def filter(self, context, mapping, select):
67 """Return new container of the same type which includes only the
68 selected elements
69
70 select() takes each item as a wrapped object and returns True/False.
71 """
72
73 @abc.abstractmethod
66 def itermaps(self, context): 74 def itermaps(self, context):
67 """Yield each template mapping""" 75 """Yield each template mapping"""
68 76
69 @abc.abstractmethod 77 @abc.abstractmethod
70 def join(self, context, mapping, sep): 78 def join(self, context, mapping, sep):
128 def _getby(self, context, mapping, func): 136 def _getby(self, context, mapping, func):
129 if not self._value: 137 if not self._value:
130 raise error.ParseError(_('empty string')) 138 raise error.ParseError(_('empty string'))
131 return func(pycompat.iterbytestr(self._value)) 139 return func(pycompat.iterbytestr(self._value))
132 140
141 def filter(self, context, mapping, select):
142 raise error.ParseError(_('%r is not filterable')
143 % pycompat.bytestr(self._value))
144
133 def itermaps(self, context): 145 def itermaps(self, context):
134 raise error.ParseError(_('%r is not iterable of mappings') 146 raise error.ParseError(_('%r is not iterable of mappings')
135 % pycompat.bytestr(self._value)) 147 % pycompat.bytestr(self._value))
136 148
137 def join(self, context, mapping, sep): 149 def join(self, context, mapping, sep):
160 172
161 def getmin(self, context, mapping): 173 def getmin(self, context, mapping):
162 raise error.ParseError(_("%r is not iterable") % self._value) 174 raise error.ParseError(_("%r is not iterable") % self._value)
163 175
164 def getmax(self, context, mapping): 176 def getmax(self, context, mapping):
177 raise error.ParseError(_("%r is not iterable") % self._value)
178
179 def filter(self, context, mapping, select):
165 raise error.ParseError(_("%r is not iterable") % self._value) 180 raise error.ParseError(_("%r is not iterable") % self._value)
166 181
167 def itermaps(self, context): 182 def itermaps(self, context):
168 raise error.ParseError(_('%r is not iterable of mappings') 183 raise error.ParseError(_('%r is not iterable of mappings')
169 % self._value) 184 % self._value)
204 219
205 def getmin(self, context, mapping): 220 def getmin(self, context, mapping):
206 raise error.ParseError(_('date is not iterable')) 221 raise error.ParseError(_('date is not iterable'))
207 222
208 def getmax(self, context, mapping): 223 def getmax(self, context, mapping):
224 raise error.ParseError(_('date is not iterable'))
225
226 def filter(self, context, mapping, select):
209 raise error.ParseError(_('date is not iterable')) 227 raise error.ParseError(_('date is not iterable'))
210 228
211 def join(self, context, mapping, sep): 229 def join(self, context, mapping, sep):
212 raise error.ParseError(_("date is not iterable")) 230 raise error.ParseError(_("date is not iterable"))
213 231
271 if util.safehasattr(val, '_makemap'): 289 if util.safehasattr(val, '_makemap'):
272 # a nested hybrid list/dict, which has its own way of map operation 290 # a nested hybrid list/dict, which has its own way of map operation
273 return val 291 return val
274 return hybriditem(None, key, val, self._makemap) 292 return hybriditem(None, key, val, self._makemap)
275 293
294 def filter(self, context, mapping, select):
295 if util.safehasattr(self._values, 'get'):
296 values = {k: v for k, v in self._values.iteritems()
297 if select(self._wrapvalue(k, v))}
298 else:
299 values = [v for v in self._values if select(self._wrapvalue(v, v))]
300 return hybrid(None, values, self._makemap, self._joinfmt, self._keytype)
301
276 def itermaps(self, context): 302 def itermaps(self, context):
277 makemap = self._makemap 303 makemap = self._makemap
278 for x in self._values: 304 for x in self._values:
279 yield makemap(x) 305 yield makemap(x)
280 306
334 360
335 def getmax(self, context, mapping): 361 def getmax(self, context, mapping):
336 w = makewrapped(context, mapping, self._value) 362 w = makewrapped(context, mapping, self._value)
337 return w.getmax(context, mapping) 363 return w.getmax(context, mapping)
338 364
365 def filter(self, context, mapping, select):
366 w = makewrapped(context, mapping, self._value)
367 return w.filter(context, mapping, select)
368
339 def join(self, context, mapping, sep): 369 def join(self, context, mapping, sep):
340 w = makewrapped(context, mapping, self._value) 370 w = makewrapped(context, mapping, self._value)
341 return w.join(context, mapping, sep) 371 return w.join(context, mapping, sep)
342 372
343 def show(self, context, mapping): 373 def show(self, context, mapping):
381 def getmin(self, context, mapping): 411 def getmin(self, context, mapping):
382 raise error.ParseError(_('not comparable')) 412 raise error.ParseError(_('not comparable'))
383 413
384 def getmax(self, context, mapping): 414 def getmax(self, context, mapping):
385 raise error.ParseError(_('not comparable')) 415 raise error.ParseError(_('not comparable'))
416
417 def filter(self, context, mapping, select):
418 raise error.ParseError(_('not filterable without template'))
386 419
387 def join(self, context, mapping, sep): 420 def join(self, context, mapping, sep):
388 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context)) 421 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context))
389 if self._name: 422 if self._name:
390 itemiter = (context.process(self._name, m) for m in mapsiter) 423 itemiter = (context.process(self._name, m) for m in mapsiter)
469 def _getby(self, context, mapping, func): 502 def _getby(self, context, mapping, func):
470 xs = self.tovalue(context, mapping) 503 xs = self.tovalue(context, mapping)
471 if not xs: 504 if not xs:
472 raise error.ParseError(_('empty sequence')) 505 raise error.ParseError(_('empty sequence'))
473 return func(xs) 506 return func(xs)
507
508 @staticmethod
509 def _filteredgen(context, mapping, make, args, select):
510 for x in make(context, *args):
511 s = stringify(context, mapping, x)
512 if select(wrappedbytes(s)):
513 yield s
514
515 def filter(self, context, mapping, select):
516 args = (mapping, self._make, self._args, select)
517 return mappedgenerator(self._filteredgen, args)
474 518
475 def itermaps(self, context): 519 def itermaps(self, context):
476 raise error.ParseError(_('list of strings is not mappable')) 520 raise error.ParseError(_('list of strings is not mappable'))
477 521
478 def join(self, context, mapping, sep): 522 def join(self, context, mapping, sep):