Mercurial > public > mercurial-scm > hg-stable
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): |