Skip to content

Commit

Permalink
Merge pull request #746 from nipype/typing-bugfixes
Browse files Browse the repository at this point in the history
fixes issues with super->sub-class auto-cast and handles MultiInputObj coercion
  • Loading branch information
tclose authored Jun 3, 2024
2 parents ad47c1e + ad28ae5 commit d674840
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 207 deletions.
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

0 comments on commit d674840

Please sign in to comment.