diff options
-rw-r--r-- | command.py | 33 | ||||
-rw-r--r-- | utils.py | 17 |
2 files changed, 47 insertions, 3 deletions
@@ -10,8 +10,12 @@ from optparse import make_option, SUPPRESS_HELP from .error import ClufterError, \ EC +from .filter import Filter from .plugin_registry import PluginRegistry -from .utils import func_defaults_varnames, \ +from .utils import apply_aggregation_preserving_depth, \ + apply_intercalate, \ + apply_strict_zip_preserving_depth, \ + func_defaults_varnames, \ head_tail, \ hybridproperty @@ -113,9 +117,32 @@ class Command(object): ##print apply_aggregation_preserving_passing_depth( ## lambda x, d: ('\n' + d * ' ') + (' ').join(x) ##)(format_chain) + # validate format_chain vs chain + # 1. "shapes" match + check_input, check_output = head_tail( + *apply_strict_zip_preserving_depth(self.filter_chain, format_chain) + ) + checked_input = apply_aggregation_preserving_depth( + lambda i: + head_tail(*i[1])[0] not in i[0].in_format._protocols + and head_tail(*i[1])[0] or None + if len(i) == 2 and isinstance(i[0], Filter) + else i if any(i) else None + )(check_input) + checked_output = apply_aggregation_preserving_depth( + lambda i: + head_tail(*i[1])[0] not in i[0].out_format._protocols + and head_tail(*i[1])[0] or None + if len(i) == 2 and isinstance(i[0], Filter) + else i if any(i) else None + )(check_output) + for passno, checked in enumerate((checked_input, checked_output)): + for order, cmd in filter(lambda (i, x): x, + enumerate(apply_intercalate((checked,)))): + raise CommandError(self, "filter resolution at #{0} of {1}:" + " `{2}' protocol not recognized", order + 1, + ('input', 'output')[passno], cmd) # TODO - # - validate format_chain vs chain - # 1. "shapes" match # 2. I/O formats path(s) through the graph exist(s) # 3. some per-filter validations? # - could some initial steps be done earlier? @@ -45,6 +45,23 @@ apply_intercalate = apply_aggregation_preserving_depth( i, []) ) +zipped_outlier = type('zipped_outlier', (tuple, ), {}) +# NOTE: automatically shortens the longer counterpart in the pair +# to the length of the bigger one +apply_loose_zip_preserving_depth = \ + lambda a, b: \ + (type(a) if type(a) == type(b) else type(a))( + [apply_loose_zip_preserving_depth(*p) for p in zip(a, b)] + ) if isinstance(a, (tuple, list)) == isinstance(b, (tuple, list)) \ + == True else zipped_outlier([a, b]) +# as previous, but with length checking of some sort +apply_strict_zip_preserving_depth = \ + lambda a, b: \ + (type(a) if type(a) == type(b) else type(a))( + [apply_strict_zip_preserving_depth(*p) for p in zip(a, b)] + ) if isinstance(a, (tuple, list)) == isinstance(b, (tuple, list)) \ + == True and len(a) == len(b) else zipped_outlier([a, b]) + def which(name, *where): """Mimic `which' UNIX utility""" |