summaryrefslogtreecommitdiffstats
path: root/format.py
diff options
context:
space:
mode:
authorJan Pokorný <jpokorny@redhat.com>2014-05-30 16:24:03 +0200
committerJan Pokorný <jpokorny@redhat.com>2014-05-30 16:30:43 +0200
commite7856c2e626fb27e8c27eca4c6a77deba2fca3b7 (patch)
treec4efcd789dc6279e9b13aaa8e7b29b44b751b53b /format.py
parent64dccfab85f9d583cbd32a0120f8e750b23c5290 (diff)
downloadclufter-e7856c2e626fb27e8c27eca4c6a77deba2fca3b7.tar.gz
clufter-e7856c2e626fb27e8c27eca4c6a77deba2fca3b7.tar.xz
clufter-e7856c2e626fb27e8c27eca4c6a77deba2fca3b7.zip
format: allow implicit "produce" generic->specific chaining
... which is also applied on XML's get_bytestring, i.e.,: thanks to "chained" flag in the decorator of the producing method, the responsibility is first generated upwards, to Format, if the respective implementation is able to cope with the request on this general level (like fetching string from file), the product is then the final product, otherwise (product is None), more specific implementation is used instead (like getting string from existing ElementTree object), and this goes on and forth. Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
Diffstat (limited to 'format.py')
-rw-r--r--format.py31
1 files changed, 21 insertions, 10 deletions
diff --git a/format.py b/format.py
index 7f385c4..7e4e8ae 100644
--- a/format.py
+++ b/format.py
@@ -138,20 +138,34 @@ class Format(object):
return self._representations.copy()
@staticmethod
- def producing(protocol, protect=False):
+ def producing(protocol, chained=False, protect=False):
"""Decorator for externalizing method understood by the `Format` magic
As a bonus: caching of representations."""
def deco_meth(meth):
def deco_args(self, protocol, *args, **kwargs):
+ # XXX enforce nochain for this interative processing?
protect_safe = kwargs.pop('protect_safe', False)
try:
# stored -> computed norm.: detuple if len == 1
produced = args2unwrapped(*self._representations[protocol])
except KeyError:
- produced = meth(self, protocol, *args, **kwargs)
- # computed -> stored normalization
- self._representations[protocol] = *arg2wrapped(produced)
+ produced = None
+ worklist = [type(self)]
+ this_m = self._protocols[protocol]
+ while worklist:
+ t = worklist.pop()
+ that_m = t._protocols[protocol]
+ if that_m is this_m and chained:
+ worklist.extend(b for b in t.__bases__ if formats is
+ getattr(b, '__metaclass__', None))
+ continue
+ if that_m is not this_m:
+ produced = that_m(self, protocol, *args, **kwargs)
+ if produced is None:
+ produced = meth(self, protocol, *args, **kwargs)
+ # computed -> stored normalization
+ self.swallow(protocol, *arg2wrapped(produced))
if protect and not protect_safe and not mutable(produced):
log.debug("{0}:{1}:Forced deepcopy of `{2}' instance"
@@ -420,13 +434,10 @@ class XML(SimpleFormat):
native_protocol = 'etree'
- @SimpleFormat.producing('bytestring')
- def get_bytestring(self, protocol):
- ret = super(XML, self).get_bytestring(self)
- if ret is not None:
- return ret
- # fallback
+ @SimpleFormat.producing('bytestring', chained=True)
+ def get_bytestring(self, protocol):
+ # chained fallback
return etree.tostring(self('etree', protect_safe=True),
pretty_print=True)