comparison mercurial/templateutil.py @ 38277:41ae9b3cbfb9

templater: abstract min/max away I'm not certain how many get*() functions I'll add to the wrapped types, but getmin() and getmax() will allow us to optimize a revset wrapper.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 19 Mar 2018 00:16:12 +0900
parents 688fbb758ba9
children 80f423a14c90
comparison
equal deleted inserted replaced
38276:fbb2eddea4d2 38277:41ae9b3cbfb9
45 A returned object may be either a wrapped object or a pure value 45 A returned object may be either a wrapped object or a pure value
46 depending on the self type. 46 depending on the self type.
47 """ 47 """
48 48
49 @abc.abstractmethod 49 @abc.abstractmethod
50 def getmin(self, context, mapping):
51 """Return the smallest item, which may be either a wrapped or a pure
52 value depending on the self type"""
53
54 @abc.abstractmethod
55 def getmax(self, context, mapping):
56 """Return the largest item, which may be either a wrapped or a pure
57 value depending on the self type"""
58
59 @abc.abstractmethod
50 def itermaps(self, context): 60 def itermaps(self, context):
51 """Yield each template mapping""" 61 """Yield each template mapping"""
52 62
53 @abc.abstractmethod 63 @abc.abstractmethod
54 def join(self, context, mapping, sep): 64 def join(self, context, mapping, sep):
83 93
84 def getmember(self, context, mapping, key): 94 def getmember(self, context, mapping, key):
85 raise error.ParseError(_('%r is not a dictionary') 95 raise error.ParseError(_('%r is not a dictionary')
86 % pycompat.bytestr(self._value)) 96 % pycompat.bytestr(self._value))
87 97
98 def getmin(self, context, mapping):
99 return self._getby(context, mapping, min)
100
101 def getmax(self, context, mapping):
102 return self._getby(context, mapping, max)
103
104 def _getby(self, context, mapping, func):
105 if not self._value:
106 raise error.ParseError(_('empty string'))
107 return func(pycompat.iterbytestr(self._value))
108
88 def itermaps(self, context): 109 def itermaps(self, context):
89 raise error.ParseError(_('%r is not iterable of mappings') 110 raise error.ParseError(_('%r is not iterable of mappings')
90 % pycompat.bytestr(self._value)) 111 % pycompat.bytestr(self._value))
91 112
92 def join(self, context, mapping, sep): 113 def join(self, context, mapping, sep):
104 def __init__(self, value): 125 def __init__(self, value):
105 self._value = value 126 self._value = value
106 127
107 def getmember(self, context, mapping, key): 128 def getmember(self, context, mapping, key):
108 raise error.ParseError(_('%r is not a dictionary') % self._value) 129 raise error.ParseError(_('%r is not a dictionary') % self._value)
130
131 def getmin(self, context, mapping):
132 raise error.ParseError(_("%r is not iterable") % self._value)
133
134 def getmax(self, context, mapping):
135 raise error.ParseError(_("%r is not iterable") % self._value)
109 136
110 def itermaps(self, context): 137 def itermaps(self, context):
111 raise error.ParseError(_('%r is not iterable of mappings') 138 raise error.ParseError(_('%r is not iterable of mappings')
112 % self._value) 139 % self._value)
113 140
148 # TODO: maybe split hybrid list/dict types? 175 # TODO: maybe split hybrid list/dict types?
149 if not util.safehasattr(self._values, 'get'): 176 if not util.safehasattr(self._values, 'get'):
150 raise error.ParseError(_('not a dictionary')) 177 raise error.ParseError(_('not a dictionary'))
151 key = unwrapastype(context, mapping, key, self.keytype) 178 key = unwrapastype(context, mapping, key, self.keytype)
152 return self._wrapvalue(key, self._values.get(key)) 179 return self._wrapvalue(key, self._values.get(key))
180
181 def getmin(self, context, mapping):
182 return self._getby(context, mapping, min)
183
184 def getmax(self, context, mapping):
185 return self._getby(context, mapping, max)
186
187 def _getby(self, context, mapping, func):
188 if not self._values:
189 raise error.ParseError(_('empty sequence'))
190 val = func(self._values)
191 return self._wrapvalue(val, val)
153 192
154 def _wrapvalue(self, key, val): 193 def _wrapvalue(self, key, val):
155 if val is None: 194 if val is None:
156 return 195 return
157 return wraphybridvalue(self, key, val) 196 return wraphybridvalue(self, key, val)
215 254
216 def getmember(self, context, mapping, key): 255 def getmember(self, context, mapping, key):
217 w = makewrapped(context, mapping, self._value) 256 w = makewrapped(context, mapping, self._value)
218 return w.getmember(context, mapping, key) 257 return w.getmember(context, mapping, key)
219 258
259 def getmin(self, context, mapping):
260 w = makewrapped(context, mapping, self._value)
261 return w.getmin(context, mapping)
262
263 def getmax(self, context, mapping):
264 w = makewrapped(context, mapping, self._value)
265 return w.getmax(context, mapping)
266
220 def itermaps(self, context): 267 def itermaps(self, context):
221 yield self.tomap() 268 yield self.tomap()
222 269
223 def join(self, context, mapping, sep): 270 def join(self, context, mapping, sep):
224 w = makewrapped(context, mapping, self._value) 271 w = makewrapped(context, mapping, self._value)
252 self._tmpl = tmpl 299 self._tmpl = tmpl
253 self._defaultsep = sep 300 self._defaultsep = sep
254 301
255 def getmember(self, context, mapping, key): 302 def getmember(self, context, mapping, key):
256 raise error.ParseError(_('not a dictionary')) 303 raise error.ParseError(_('not a dictionary'))
304
305 def getmin(self, context, mapping):
306 raise error.ParseError(_('not comparable'))
307
308 def getmax(self, context, mapping):
309 raise error.ParseError(_('not comparable'))
257 310
258 def join(self, context, mapping, sep): 311 def join(self, context, mapping, sep):
259 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context)) 312 mapsiter = _iteroverlaymaps(context, mapping, self.itermaps(context))
260 if self._name: 313 if self._name:
261 itemiter = (context.process(self._name, m) for m in mapsiter) 314 itemiter = (context.process(self._name, m) for m in mapsiter)
318 def _gen(self, context): 371 def _gen(self, context):
319 return self._make(context, *self._args) 372 return self._make(context, *self._args)
320 373
321 def getmember(self, context, mapping, key): 374 def getmember(self, context, mapping, key):
322 raise error.ParseError(_('not a dictionary')) 375 raise error.ParseError(_('not a dictionary'))
376
377 def getmin(self, context, mapping):
378 return self._getby(context, mapping, min)
379
380 def getmax(self, context, mapping):
381 return self._getby(context, mapping, max)
382
383 def _getby(self, context, mapping, func):
384 xs = self.tovalue(context, mapping)
385 if not xs:
386 raise error.ParseError(_('empty sequence'))
387 return func(xs)
323 388
324 def itermaps(self, context): 389 def itermaps(self, context):
325 raise error.ParseError(_('list of strings is not mappable')) 390 raise error.ParseError(_('list of strings is not mappable'))
326 391
327 def join(self, context, mapping, sep): 392 def join(self, context, mapping, sep):