From 4a6d76c557caf7263ab57e5fe840d28aa3356621 Mon Sep 17 00:00:00 2001 From: jaseg Date: Mon, 24 Jan 2022 11:55:19 +0100 Subject: Improve error messages --- gerbonara/gerber/excellon.py | 16 +++++++++------- gerbonara/gerber/rs274x.py | 19 ++++++++++++------- gerbonara/gerber/tests/test_excellon.py | 8 ++++++++ gerbonara/gerber/tests/test_rs274x.py | 9 +++++++++ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/gerbonara/gerber/excellon.py b/gerbonara/gerber/excellon.py index b5c9221..02e63d7 100755 --- a/gerbonara/gerber/excellon.py +++ b/gerbonara/gerber/excellon.py @@ -175,7 +175,7 @@ class ExcellonFile(CamFile): @classmethod def from_string(kls, data, settings=None, filename=None, plated=None): parser = ExcellonParser(settings) - parser._do_parse(data) + parser.do_parse(data, filename=filename) return kls(objects=parser.objects, comments=parser.comments, import_settings=settings, generator_hints=parser.generator_hints, filename=filename) @@ -347,9 +347,12 @@ class ExcellonParser(object): self.comments = [] self.generator_hints = [] - def _do_parse(self, data): + def do_parse(self, data, filename=None): + # filename arg is for error messages + filename = filename or '' + leftover = None - for line in data.splitlines(): + for lineno, line in enumerate(data.splitlines(), start=1): line = line.strip() if not line: @@ -373,9 +376,8 @@ class ExcellonParser(object): try: if not self.exprs.handle(self, line): raise ValueError('Unknown excellon statement:', line) - except: - print('Original line was:', line) - raise + except Exception as e: + raise SyntaxError(f'{filename}:{lineno} "{line}": {e}') from e exprs = RegexMatcher() @@ -661,7 +663,7 @@ class ExcellonParser(object): def handle_absolute_mode(self, match): if int(match['X'] or 0) != 0 or int(match['Y'] or 0) != 0: # Siemens tooling likes to include a meaningless G93X0Y0 after its header. - raise SyntaxError('G93 zero set command is not supported.') + raise NotImplementedError('G93 zero set command is not supported.') self.generator_hints.append('siemens') @exprs.match('ICI,?(ON|OFF)') diff --git a/gerbonara/gerber/rs274x.py b/gerbonara/gerber/rs274x.py index f3ae62b..8089944 100644 --- a/gerbonara/gerber/rs274x.py +++ b/gerbonara/gerber/rs274x.py @@ -153,15 +153,17 @@ class GerberFile(CamFile): @classmethod def open(kls, filename, enable_includes=False, enable_include_dir=None): + filename = Path(filename) with open(filename, "r") as f: if enable_includes and enable_include_dir is None: - enable_include_dir = Path(filename).parent - return kls.from_string(f.read(), enable_include_dir) + enable_include_dir = filename.parent + return kls.from_string(f.read(), enable_include_dir, filename=filename.name) @classmethod - def from_string(kls, data, enable_include_dir=None): + def from_string(kls, data, enable_include_dir=None, filename=None): + # filename arg is for error messages obj = kls() - GerberParser(obj, include_dir=enable_include_dir).parse(data) + GerberParser(obj, include_dir=enable_include_dir).parse(data, filename=filename) return obj def generate_statements(self, settings, drop_comments=True): @@ -576,7 +578,10 @@ class GerberParser: yield lineno, word_command start = pos + 1 - def parse(self, data): + def parse(self, data, filename=None): + # filename arg is for error messages + filename = filename or '' + for lineno, line in self._split_commands(data): if not line.strip(): continue @@ -595,7 +600,7 @@ class GerberParser: except Exception as e: #print(f'Line {lineno}: {line}') #print(f' match: {name} / {match}') - raise SyntaxError(f'Syntax error in line {lineno} "{line}": {e}') from e + raise SyntaxError(f'{filename}:{lineno} "{line}": {e}') from e line = line[match.end(0):] break @@ -787,7 +792,7 @@ class GerberParser: self.include_stack.append(include_file) # Spec 2020-09 section 3.1: Gerber files must use UTF-8 - self._parse(f.read_text(encoding='UTF-8')) + self._parse(f.read_text(encoding='UTF-8'), filename=include_file.name) self.include_stack.pop() def _parse_image_name(self, match): diff --git a/gerbonara/gerber/tests/test_excellon.py b/gerbonara/gerber/tests/test_excellon.py index fb0ebb8..fb25d8f 100644 --- a/gerbonara/gerber/tests/test_excellon.py +++ b/gerbonara/gerber/tests/test_excellon.py @@ -94,4 +94,12 @@ def test_gerber_alignment(reference, tmpfile, print_on_error): assert matches > 10 assert matches/total > 0.5 +@filter_syntax_warnings +def test_syntax_error(): + ref = reference_path('test_syntax_error.exc') + with pytest.raises(SyntaxError) as exc_info: + ExcellonFile.open(ref) + + assert 'test_syntax_error.exc' in exc_info.value.msg + assert '12' in exc_info.value.msg # lineno diff --git a/gerbonara/gerber/tests/test_rs274x.py b/gerbonara/gerber/tests/test_rs274x.py index 7e21d62..83148a5 100644 --- a/gerbonara/gerber/tests/test_rs274x.py +++ b/gerbonara/gerber/tests/test_rs274x.py @@ -501,3 +501,12 @@ def test_bounding_box(reference, tmpfile): assert margin_px-2 <= row_prefix <= margin_px+2 assert margin_px-2 <= row_suffix <= margin_px+2 +@filter_syntax_warnings +def test_syntax_error(): + ref = reference_path('test_syntax_error.gbr') + with pytest.raises(SyntaxError) as exc_info: + GerberFile.open(ref) + + assert 'test_syntax_error.gbr' in exc_info.value.msg + assert '7' in exc_info.value.msg # lineno + -- cgit