summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Pokorný <jpokorny@redhat.com>2014-01-27 23:04:12 +0100
committerJan Pokorný <jpokorny@redhat.com>2014-01-27 23:17:41 +0100
commitc33694ac035fe2915c3aa4d39f430ad7d0de753b (patch)
treea3004a0eef0acff456d6b8a402a79adbb62386ce
parentabfb91d87a57970315504508dd094b9f5cdba489 (diff)
downloadclufter-c33694ac035fe2915c3aa4d39f430ad7d0de753b.tar.gz
clufter-c33694ac035fe2915c3aa4d39f430ad7d0de753b.tar.xz
clufter-c33694ac035fe2915c3aa4d39f430ad7d0de753b.zip
command: implement "shapes" match for filter/format chain
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
-rw-r--r--command.py33
-rw-r--r--utils.py17
2 files changed, 47 insertions, 3 deletions
diff --git a/command.py b/command.py
index fc890ba..16e45c6 100644
--- a/command.py
+++ b/command.py
@@ -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?
diff --git a/utils.py b/utils.py
index 785bdad..c457bc1 100644
--- a/utils.py
+++ b/utils.py
@@ -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"""