diff mercurial/templateutil.py @ 37327:ebf139cbd4a1

templater: abstract away from joinfmt Future patches will add a wrapper for a list of template mappings, which will implement a custom join() something like {join(mappings % template)}. The original join() function is broken down as follows: if hasattr(joinset, 'joinfmt'): # hybrid.join() where values must be a list or a dict joinitems((joinfmt(x) for x in values), sep) elif isinstance(joinset, templateutil.wrapped): # mappable.join() show() else: # a plain list, a generator, or a byte string; joinfmt was identity() joinset = templateutil.unwrapvalue(context, joinset) joinitems(pycompat.maybebytestr(joinset), joiner)
author Yuya Nishihara <yuya@tcha.org>
date Sat, 17 Mar 2018 22:06:31 +0900
parents 9cd88dd3bf64
children 676664592313
line wrap: on
line diff
--- a/mercurial/templateutil.py	Tue Mar 20 23:16:28 2018 +0900
+++ b/mercurial/templateutil.py	Sat Mar 17 22:06:31 2018 +0900
@@ -42,6 +42,15 @@
         """Yield each template mapping"""
 
     @abc.abstractmethod
+    def join(self, context, mapping, sep):
+        """Join items with the separator; Returns a bytes or (possibly nested)
+        generator of bytes
+
+        A pre-configured template may be rendered per item if this container
+        holds unprintable items.
+        """
+
+    @abc.abstractmethod
     def show(self, context, mapping):
         """Return a bytes or (possibly nested) generator of bytes representing
         the underlying object
@@ -86,11 +95,15 @@
         for x in self._values:
             yield makemap(x)
 
+    def join(self, context, mapping, sep):
+        # TODO: switch gen to (context, mapping) API?
+        return joinitems((self.joinfmt(x) for x in self._values), sep)
+
     def show(self, context, mapping):
         # TODO: switch gen to (context, mapping) API?
         gen = self._gen
         if gen is None:
-            return joinitems((self.joinfmt(x) for x in self._values), ' ')
+            return self.join(context, mapping, ' ')
         if callable(gen):
             return gen()
         return gen
@@ -137,6 +150,14 @@
     def itermaps(self, context):
         yield self.tomap()
 
+    def join(self, context, mapping, sep):
+        # TODO: just copies the old behavior where a value was a generator
+        # yielding one item, but reconsider about it. join() over a string
+        # has no consistent result because a string may be a bytes, or a
+        # generator yielding an item, or a generator yielding multiple items.
+        # Preserving all of the current behaviors wouldn't make any sense.
+        return self.show(context, mapping)
+
     def show(self, context, mapping):
         # TODO: switch gen to (context, mapping) API?
         gen = self._gen