Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes issues with super->sub-class auto-cast and handles MultiInputObj coercion #746

Merged
merged 9 commits into from
Jun 3, 2024
3 changes: 2 additions & 1 deletion pydra/engine/specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,8 @@ def __getattr__(self, name):
raise AttributeError(f"{name} hasn't been set yet")
if name not in self._field_names:
raise AttributeError(
f"Task {self._task.name} has no {self._attr_type} attribute {name}"
f"Task '{self._task.name}' has no {self._attr_type} attribute '{name}', "
"available: '" + "', '".join(self._field_names) + "'"
)
type_ = self._get_type(name)
splits = self._get_task_splits()
Expand Down
5 changes: 4 additions & 1 deletion pydra/engine/tests/test_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ def test_lazy_getvale():
lf = LazyIn(task=tn)
with pytest.raises(Exception) as excinfo:
lf.inp_c
assert str(excinfo.value) == "Task tn has no input attribute inp_c"
assert (
str(excinfo.value)
== "Task 'tn' has no input attribute 'inp_c', available: 'inp_a', 'inp_b'"
)


def test_input_file_hash_1(tmp_path):
Expand Down
18 changes: 10 additions & 8 deletions pydra/engine/tests/test_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from ..core import Workflow
from ... import mark
from ..specs import SpecInfo, BaseSpec, ShellSpec
from pydra.utils import exc_info_matches


def test_wf_no_input_spec():
Expand Down Expand Up @@ -102,13 +103,15 @@ def test_wf_dict_input_and_output_spec():
wf.inputs.a = "any-string"
wf.inputs.b = {"foo": 1, "bar": False}

with pytest.raises(TypeError, match="Cannot coerce 1.0 into <class 'str'>"):
with pytest.raises(TypeError) as exc_info:
wf.inputs.a = 1.0
with pytest.raises(
TypeError,
match=("Could not coerce object, 'bad-value', to any of the union types "),
):
assert exc_info_matches(exc_info, "Cannot coerce 1.0 into <class 'str'>")

with pytest.raises(TypeError) as exc_info:
wf.inputs.b = {"foo": 1, "bar": "bad-value"}
assert exc_info_matches(
exc_info, "Could not coerce object, 'bad-value', to any of the union types"
)

result = wf()
assert result.output.a == "any-string"
Expand Down Expand Up @@ -5002,14 +5005,13 @@ def test_wf_input_output_typing():
output_spec={"alpha": int, "beta": ty.List[int]},
)

with pytest.raises(
TypeError, match="Cannot coerce <class 'list'> into <class 'int'>"
):
with pytest.raises(TypeError) as exc_info:
list_mult_sum(
scalar=wf.lzin.y,
in_list=wf.lzin.y,
name="A",
)
exc_info_matches(exc_info, "Cannot coerce <class 'list'> into <class 'int'>")

wf.add( # Split over workflow input "x" on "scalar" input
list_mult_sum(
Expand Down
2 changes: 1 addition & 1 deletion pydra/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .misc import user_cache_dir, add_exc_note # noqa: F401
from .misc import user_cache_dir, add_exc_note, exc_info_matches # noqa: F401
12 changes: 12 additions & 0 deletions pydra/utils/misc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pathlib import Path
import re
import platformdirs
from pydra._version import __version__

Expand Down Expand Up @@ -31,3 +32,14 @@ def add_exc_note(e: Exception, note: str) -> Exception:
else:
e.args = (e.args[0] + "\n" + note,)
return e


def exc_info_matches(exc_info, match, regex=False):
if exc_info.value.__cause__ is not None:
msg = str(exc_info.value.__cause__)
else:
msg = str(exc_info.value)
if regex:
return re.match(".*" + match, msg)
else:
return match in msg
Loading
Loading