From 6eb606bb61b46be4745e2c79904fdc212365449d Mon Sep 17 00:00:00 2001 From: Jan Pokorný Date: May 25 2017 17:00:01 +0000 Subject: command: factor "common_protocols" out as a class method of Format Signed-off-by: Jan Pokorný --- diff --git a/command.py b/command.py index d1048d1..1330bef 100644 --- a/command.py +++ b/command.py @@ -6,7 +6,6 @@ __author__ = "Jan Pokorný " from collections import MutableMapping -from functools import reduce try: from itertools import zip_longest except ImportError: # PY2 backward compatibility @@ -205,26 +204,17 @@ class _Command(object): "filter `{0}' is feeded by `{1}' more than once", i.__class__.__name__, pass_through.__class__.__name__ ) - common_protocols = None # for when CompositeFormat involved + com = None # for when CompositeFormat involved if (hasattr(pass_through.out_format, '_protocols') - and hasattr(i.in_format, '_protocols')): - common_protocols = sorted( - reduce( - set.intersection, - map(set, (pass_through.out_format._protocols, - i.in_format._protocols)) - ), - key=lambda x: - int(x == pass_through.out_format.native_protocol) - + int(x == i.in_format.native_protocol) - ) - if not common_protocols: + and hasattr(i.in_format, '_protocols')): + com = pass_through.out_format.common_protocols(i.in_format) + if not com: raise CommandError(me, "filter `{0}' and its feeder `{1}' have no protocol" " in common", i.__class__.__name__, pass_through.__class__.__name__ ) - bt[pass_through] = common_protocols + bt[pass_through] = com if i_tail: # PASSDOWN # this uses a dirty trick of exploiting the end of the list diff --git a/format.py b/format.py index 2198244..55e1846 100644 --- a/format.py +++ b/format.py @@ -245,6 +245,23 @@ class _Format(object): setattr(self, attr, get_protocol_proxy(getattr(self, attr))) self._swallow(protocol, *args) + @MimicMeta.passdeco(classmethod) + def common_protocols(cls, foreign): + """Get common local vs. foreign protocols, native ones prioritized""" + # XXX composite format + if not hasattr(foreign, '_protocols'): + raise FormatError(cls, "cannot check common protocols for `{0}'", + repr(foreign)) + return sorted( + reduce( + set.intersection, + map(set, (cls._protocols, foreign._protocols)) + ), + key=lambda x: + int(x == cls.native_protocol) * 2 + + int(x == foreign.native_protocol) + ) + @MimicMeta.classmethod def as_instance(cls, *decl_or_instance, **kwargs): """Create an instance or verify and return existing one"""