Skip to content

Commit

Permalink
Merge 796b18c into 07a91e1
Browse files Browse the repository at this point in the history
  • Loading branch information
mlin committed Jun 12, 2019
2 parents 07a91e1 + 796b18c commit 1b01ea5
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 18 deletions.
29 changes: 19 additions & 10 deletions WDL/Error.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,40 @@
import WDL.Type as T


SourcePosition = NamedTuple(
"SourcePosition",
[("filename", str), ("line", int), ("column", int), ("end_line", int), ("end_column", int)],
)
"""Source file, line, and column, attached to each AST node"""


class SyntaxError(Exception):
"""Failure to lex/parse a WDL document"""

def __init__(self, filename: str, msg: str) -> None:
super().__init__("({}) {}".format(filename, msg))
pos: SourcePosition

def __init__(self, pos: SourcePosition, msg: str) -> None:
super().__init__("({} Ln {} Col {}) {}".format(pos.filename, pos.line, pos.column, msg))
self.pos = pos


class ImportError(Exception):
"""Failure to open/retrieve an imported WDL document
The ``__cause__`` attribute may hold the inner error object."""

def __init__(self, document: str, import_uri: str, message: Optional[str] = None) -> None:
msg = "({}) Failed to import {}".format(document, import_uri)
pos: SourcePosition

def __init__(self, pos: SourcePosition, import_uri: str, message: Optional[str] = None) -> None:
msg = "({} Ln {} Col {}) Failed to import {}".format(
pos.filename, pos.line, pos.column, import_uri
)
if message:
msg = msg + ", " + message
super().__init__(msg)
self.pos = pos


SourcePosition = NamedTuple(
"SourcePosition",
[("filename", str), ("line", int), ("column", int), ("end_line", int), ("end_column", int)],
)
"""Source file, line, and column, attached to each AST node"""

TVSourceNode = TypeVar("TVSourceNode", bound="SourceNode")


Expand Down
4 changes: 2 additions & 2 deletions WDL/Tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ def load(
imp = doc.imports[i]
if import_max_depth <= 1:
raise Err.ImportError(
uri, imp.uri, "exceeded import_max_depth; circular imports?"
imp.pos, imp.uri, "exceeded import_max_depth; circular imports?"
)
try:
subpath = [os.path.dirname(fn)] + path
Expand All @@ -1034,7 +1034,7 @@ def load(
import_max_depth=(import_max_depth - 1),
)
except Exception as exn:
raise Err.ImportError(uri, imp.uri) from exn
raise Err.ImportError(imp.pos, imp.uri) from exn
doc.imports[i] = DocImport(
pos=imp.pos,
uri=imp.uri,
Expand Down
22 changes: 17 additions & 5 deletions WDL/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,7 @@ def type(self, items, meta):

def _check_keyword(pos, name):
if name in _keywords:
raise Err.SyntaxError(
pos.filename, "(Ln {}, Col {}) unexpected keyword {}".format(pos.line, pos.column, name)
)
raise Err.SyntaxError(pos, "unexpected keyword {}".format(name))


class _DocTransformer(_ExprTransformer, _TypeTransformer):
Expand Down Expand Up @@ -757,7 +755,14 @@ def parse_expr(txt: str, version: Optional[str] = None) -> E.Base:
try:
return _ExprTransformer(txt).transform(parse(txt, "expr", version))
except lark.exceptions.UnexpectedInput as exn:
raise Err.SyntaxError("(buffer)", str(exn)) from None
pos = SourcePosition(
filename="(buffer)",
line=getattr(exn, "line", "?"),
column=getattr(exn, "column", "?"),
end_line=getattr(exn, "line", "?"),
end_column=getattr(exn, "column", "?"),
)
raise Err.SyntaxError(pos, str(exn)) from None
except lark.exceptions.VisitError as exn:
raise exn.__context__

Expand Down Expand Up @@ -791,6 +796,13 @@ def parse_document(txt: str, version: Optional[str] = None, uri: str = "") -> D.
try:
return _DocTransformer(uri).transform(parse(txt, "document", version))
except lark.exceptions.UnexpectedInput as exn:
raise Err.SyntaxError(uri if uri != "" else "(buffer)", str(exn)) from None
pos = SourcePosition(
filename=(uri if uri != "" else "(buffer)"),
line=getattr(exn, "line", "?"),
column=getattr(exn, "column", "?"),
end_line=getattr(exn, "line", "?"),
end_column=getattr(exn, "column", "?"),
)
raise Err.SyntaxError(pos, str(exn)) from None
except lark.exceptions.VisitError as exn:
raise exn.__context__
30 changes: 29 additions & 1 deletion tests/test_1doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ def test_draft2_workflow_outputs(self):
with self.assertRaises(WDL.Error.MultipleDefinitions):
doc.typecheck()

with self.assertRaises(WDL.Error.SyntaxError):
try:
doc = WDL.parse_document("""
version 1.0
task sum {
Expand All @@ -1034,6 +1034,10 @@ def test_draft2_workflow_outputs(self):
}
}
""")
assert False
except WDL.Error.SyntaxError as err:
self.assertEqual(err.pos.line, 19)
self.assertEqual(err.pos.column, 30)

doc = WDL.parse_document("""
task sum {
Expand Down Expand Up @@ -2012,3 +2016,27 @@ def test_object_literal(self):
"""
doc = WDL.parse_document(doc)
doc.typecheck()

def test_keywords(self):
templ = r"""
version 1.0
struct {} {{
String {}
}}
"""
WDL.parse_document(templ.format("foo","bar")).typecheck()
for p in [
("task","bar"),
("foo","task"),
("struct","bar"),
("foo","struct"),
("Int","bar"),
("foo","Int")
]:
try:
WDL.parse_document(templ.format(*p))
assert False
except WDL.Error.SyntaxError as err:
self.assertIsInstance(err.pos.line, int)
self.assertIsInstance(err.pos.column, int)

0 comments on commit 1b01ea5

Please sign in to comment.