Show More
@@ -316,16 +316,16 b' def join(context, mapping, args):' | |||
|
316 | 316 | # i18n: "join" is a keyword |
|
317 | 317 | raise error.ParseError(_("join expects one or two arguments")) |
|
318 | 318 | |
|
319 | # TODO: perhaps this should be evalfuncarg(), but it can't because hgweb | |
|
320 | # abuses generator as a keyword that returns a list of dicts. | |
|
321 | 319 | joinset = evalrawexp(context, mapping, args[0]) |
|
322 | joinset = templateutil.unwrapvalue(context, mapping, joinset) | |
|
323 | joinfmt = getattr(joinset, 'joinfmt', pycompat.identity) | |
|
324 | 320 | joiner = " " |
|
325 | 321 | if len(args) > 1: |
|
326 | 322 | joiner = evalstring(context, mapping, args[1]) |
|
327 | itemiter = (joinfmt(x) for x in pycompat.maybebytestr(joinset)) | |
|
328 | return templateutil.joinitems(itemiter, joiner) | |
|
323 | if isinstance(joinset, templateutil.wrapped): | |
|
324 | return joinset.join(context, mapping, joiner) | |
|
325 | # TODO: perhaps a generator should be stringify()-ed here, but we can't | |
|
326 | # because hgweb abuses it as a keyword that returns a list of dicts. | |
|
327 | joinset = templateutil.unwrapvalue(context, mapping, joinset) | |
|
328 | return templateutil.joinitems(pycompat.maybebytestr(joinset), joiner) | |
|
329 | 329 | |
|
330 | 330 | @templatefunc('label(label, expr)') |
|
331 | 331 | def label(context, mapping, args): |
@@ -42,6 +42,15 b' class wrapped(object):' | |||
|
42 | 42 | """Yield each template mapping""" |
|
43 | 43 | |
|
44 | 44 | @abc.abstractmethod |
|
45 | def join(self, context, mapping, sep): | |
|
46 | """Join items with the separator; Returns a bytes or (possibly nested) | |
|
47 | generator of bytes | |
|
48 | ||
|
49 | A pre-configured template may be rendered per item if this container | |
|
50 | holds unprintable items. | |
|
51 | """ | |
|
52 | ||
|
53 | @abc.abstractmethod | |
|
45 | 54 | def show(self, context, mapping): |
|
46 | 55 | """Return a bytes or (possibly nested) generator of bytes representing |
|
47 | 56 | the underlying object |
@@ -86,11 +95,15 b' class hybrid(wrapped):' | |||
|
86 | 95 | for x in self._values: |
|
87 | 96 | yield makemap(x) |
|
88 | 97 | |
|
98 | def join(self, context, mapping, sep): | |
|
99 | # TODO: switch gen to (context, mapping) API? | |
|
100 | return joinitems((self.joinfmt(x) for x in self._values), sep) | |
|
101 | ||
|
89 | 102 | def show(self, context, mapping): |
|
90 | 103 | # TODO: switch gen to (context, mapping) API? |
|
91 | 104 | gen = self._gen |
|
92 | 105 | if gen is None: |
|
93 | return joinitems((self.joinfmt(x) for x in self._values), ' ') | |
|
106 | return self.join(context, mapping, ' ') | |
|
94 | 107 | if callable(gen): |
|
95 | 108 | return gen() |
|
96 | 109 | return gen |
@@ -137,6 +150,14 b' class mappable(wrapped):' | |||
|
137 | 150 | def itermaps(self, context): |
|
138 | 151 | yield self.tomap() |
|
139 | 152 | |
|
153 | def join(self, context, mapping, sep): | |
|
154 | # TODO: just copies the old behavior where a value was a generator | |
|
155 | # yielding one item, but reconsider about it. join() over a string | |
|
156 | # has no consistent result because a string may be a bytes, or a | |
|
157 | # generator yielding an item, or a generator yielding multiple items. | |
|
158 | # Preserving all of the current behaviors wouldn't make any sense. | |
|
159 | return self.show(context, mapping) | |
|
160 | ||
|
140 | 161 | def show(self, context, mapping): |
|
141 | 162 | # TODO: switch gen to (context, mapping) API? |
|
142 | 163 | gen = self._gen |
General Comments 0
You need to be logged in to leave comments.
Login now