diff options
Diffstat (limited to 'subv.py')
| -rw-r--r-- | subv.py | 42 |
1 files changed, 42 insertions, 0 deletions
@@ -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 |
