[PATCH 2 of 8 V2] templater: define interface for objects requiring unwraphybrid()
Yuya Nishihara
yuya at tcha.org
Tue Apr 3 11:40:04 EDT 2018
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1521287570 -32400
# Sat Mar 17 20:52:50 2018 +0900
# Node ID b02b53e4cc2049324d69e3c4a16357f79400a5e4
# Parent 164e39f1fc56cebdaa441458dfa6436939c97267
templater: define interface for objects requiring unwraphybrid()
Prepares for introducing another hybrid-like data type. show() takes context
as an argument so a wrapper class may render its items by pre-configured
template:
def show(self, context, mapping):
return (context.expand(self._tmpl, mapping + lm) for lm in self._mappings)
diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -7,6 +7,7 @@
from __future__ import absolute_import
+import abc
import types
from .i18n import _
@@ -26,12 +27,27 @@ class ResourceUnavailable(error.Abort):
class TemplateNotFound(error.Abort):
pass
+class wrapped(object):
+ """Object requiring extra conversion prior to displaying or processing
+ as value"""
+
+ __metaclass__ = abc.ABCMeta
+
+ @abc.abstractmethod
+ def show(self, context, mapping):
+ """Return a bytes or (possibly nested) generator of bytes representing
+ the underlying object
+
+ A pre-configured template may be rendered if the underlying object is
+ not printable.
+ """
+
# stub for representing a date type; may be a real date type that can
# provide a readable string value
class date(object):
pass
-class hybrid(object):
+class hybrid(wrapped):
"""Wrapper for list or dict to support legacy template
This class allows us to handle both:
@@ -60,6 +76,14 @@ class hybrid(object):
makemap = self._makemap
for x in self._values:
yield makemap(x)
+
+ def show(self, context, mapping):
+ # TODO: switch gen to (context, mapping) API?
+ gen = self.gen
+ if callable(gen):
+ return gen()
+ return gen
+
def __contains__(self, x):
return x in self._values
def __getitem__(self, key):
@@ -74,7 +98,7 @@ class hybrid(object):
raise AttributeError(name)
return getattr(self._values, name)
-class mappable(object):
+class mappable(wrapped):
"""Wrapper for non-list/dict object to support map operation
This class allows us to handle both:
@@ -103,6 +127,13 @@ class mappable(object):
def itermaps(self):
yield self.tomap()
+ def show(self, context, mapping):
+ # TODO: switch gen to (context, mapping) API?
+ gen = self.gen
+ if callable(gen):
+ return gen()
+ return gen
+
def hybriddict(data, key='key', value='value', fmt=None, gen=None):
"""Wrap data to support both dict-like and string-like operations"""
prefmt = pycompat.identity
@@ -123,12 +154,9 @@ def hybridlist(data, name, fmt=None, gen
def unwraphybrid(context, mapping, thing):
"""Return an object which can be stringified possibly by using a legacy
template"""
- gen = getattr(thing, 'gen', None)
- if gen is None:
+ if not isinstance(thing, wrapped):
return thing
- if callable(gen):
- return gen()
- return gen
+ return thing.show(context, mapping)
def unwrapvalue(thing):
"""Move the inner value object out of the wrapper"""
More information about the Mercurial-devel
mailing list