Skip to content

Commit

Permalink
otk: add file to variable substitution errors too
Browse files Browse the repository at this point in the history
This commit adds file context for errors from variable substitution
too.
  • Loading branch information
mvo5 committed Oct 2, 2024
1 parent 6191cff commit 38a000c
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 8 deletions.
8 changes: 6 additions & 2 deletions src/otk/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .constant import NAME_VERSION, PREFIX, PREFIX_DEFINE, PREFIX_INCLUDE, PREFIX_OP, PREFIX_TARGET
from .context import Context, validate_var_name
from .error import (
IncludeNotFoundError,
IncludeNotFoundError, OTKError,
ParseError, ParseTypeError, ParseValueError, ParseDuplicatedYamlKeyError,
TransformDirectiveTypeError, TransformDirectiveUnknownError,
)
Expand Down Expand Up @@ -287,7 +287,11 @@ def substitute_vars(ctx: Context, state: State, data: str) -> Any:
# return its value directly.
if m := re.fullmatch(pattern, data):
validate_var_name(m.group("name"))
return ctx.variable(m.group("name"))
try:
var = ctx.variable(m.group("name"))
except OTKError as exc:
raise exc.__class__(str(exc), state)
return var

if matches := re.finditer(pattern, data):
for m in matches:
Expand Down
3 changes: 2 additions & 1 deletion src/otk/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def wrapper(*args, **kwargs):
if not isinstance(args[2], kind):
# XXX: this needs state to give proper errors
raise TransformDirectiveTypeError(
f"otk.define expects a {kind!r} as its argument but received a `{type(args[2])}`: `{args[2]!r}`")
f"otk.define expects a {kind!r} as its argument but "
f"received a `{type(args[2])}`: `{args[2]!r}`", args[1])
return function(*args, **kwargs)

return wrapper
Expand Down
15 changes: 10 additions & 5 deletions test/test_substitute_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_sub_var_multiple():


def test_sub_var_missing_var_in_context():
state = State("")
state = State("foo.yaml")
context = CommonContext()
# toplevel
expected_err = r"could not resolve 'a' as 'a' is not defined"
Expand All @@ -60,7 +60,8 @@ def test_sub_var_missing_var_in_context():
substitute_vars(context, state, "${a.b}")
# no subtree
context.define("a", "foo")
expected_err = r"tried to look up 'a.b', but the value of prefix 'a' is not a dictionary but <class 'str'>"
expected_err = r"foo.yaml: tried to look up 'a.b', but the value of " \
"prefix 'a' is not a dictionary but <class 'str'>"
with pytest.raises(TransformVariableTypeError, match=expected_err):
substitute_vars(context, state, "${a.b}")

Expand Down Expand Up @@ -127,12 +128,16 @@ def test_substitute_vars():


def test_substitute_vars_unhappy():
state = State("")
state = State("foo.yaml")
ctx = CommonContext()
ctx.define("dict", {})

with pytest.raises(TransformDirectiveTypeError):
with pytest.raises(TransformDirectiveTypeError) as exc:
substitute_vars(ctx, state, 1)
assert "foo.yaml: otk.define expects a <class 'str'> as its argument but received a `<class 'int'>" in str(
exc.value)

with pytest.raises(TransformDirectiveTypeError):
with pytest.raises(TransformDirectiveTypeError) as exc:
substitute_vars(ctx, state, "a${dict}b")
assert "foo.yaml: string 'a${dict}b' resolves to an incorrect type, " \
"expected int, float, or str but got dict" in str(exc.value)

0 comments on commit 38a000c

Please sign in to comment.