aboutsummaryrefslogtreecommitdiffstats
path: root/subv.py
diff options
context:
space:
mode:
Diffstat (limited to 'subv.py')
-rw-r--r--subv.py42
1 files changed, 42 insertions, 0 deletions
diff --git a/subv.py b/subv.py
index 0615159..a280e77 100644
--- a/subv.py
+++ b/subv.py
@@ -288,3 +288,45 @@ def dump(line):
def join_all(gen):
res = '\n'.join(gen)
return res
+
+
+class SubVException(Exception):
+ pass
+
+class LineIterator(object):
+ def __init__(self, stream):
+ self.stream = stream
+ self.iter = enumerate(self.stream, start=1)
+ self.i, self.raw_line, self.line = 0, None, None
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ self.i, self.raw_line = next(self.iter)
+ self.line = None
+ try:
+ self.line = parse(self.raw_line)
+ except Exception as e:
+ raise self.exception("failed to parse line") from e
+ return self.line
+
+ def exception(self, msg):
+ if self.line:
+ msg = msg + "\n{}:{}: {}".format(self.stream.name, self.i, format(self.line))
+ msg = msg + "\nparsed as {}".format(dump(self.line))
+ elif self.raw_line:
+ msg = msg + "\n{}:{}: {}".format(self.stream.name, self.i, self.raw_line.strip())
+ return SubVException(msg)
+
+def with_parsed_lines(process_fn):
+ def _wrapped(iter):
+ iterator = LineIterator(iter)
+ try:
+ yield from process_fn(iterator)
+ except SubVException:
+ raise
+ except Exception as e:
+ raise iterator.exception("failed to {} line".format(process_fn.__name__)) from e
+
+ return _wrapped