hera icon indicating copy to clipboard operation
hera copied to clipboard

Support Optional/Union types in script runner

Open elliotgunton opened this issue 1 year ago • 0 comments

Pre-bug-report checklist

1. This bug can be reproduced using pure Argo YAML

If yes, it is more likely to be an Argo bug unrelated to Hera. Please double check before submitting an issue to Hera.

2. This bug occurs in Hera when...

  • [ ] exporting to YAML
  • [ ] submitting to Argo
  • [x] running on Argo with the Hera runner
  • [ ] other:

Bug report

Describe the bug A clear and concise description of what the bug is:

Using a function with an optional (string, but I think could be any type) argument in the runner results in the following stack trace:

Error log if applicable:

  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/runner.py", line 6, in <module>
    _run()
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/_runner/util.py", line 254, in _run
    result = _runner(args.entrypoint, kwargs_list)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/_runner/util.py", line 225, in _runner
    raise e
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/_runner/util.py", line 222, in _runner
    output = _save_annotated_return_outputs(function(**kwargs), output_annotations)
                                            ^^^^^^^^^^^^^^^^^^
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/_runner/util.py", line 58, in inner
    filtered_kwargs = {key: _parse(value, key, f) for key, value in kwargs.items() if _is_kwarg_of(key, f)}
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/_runner/util.py", line 58, in <dictcomp>
    filtered_kwargs = {key: _parse(value, key, f) for key, value in kwargs.items() if _is_kwarg_of(key, f)}
                            ^^^^^^^^^^^^^^^^^^^^^
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/_runner/util.py", line 89, in _parse
    if _is_str_kwarg_of(key, f) or _is_artifact_loaded(key, f) or _is_output_kwarg(key, f):
       ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/.../requirements/lib/python3.11/site-packages/hera/workflows/_runner/util.py", line 142, in _is_str_kwarg_of
    return issubclass(type_, str)
           ^^^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 1 must be a class

To Reproduce Full Hera code to reproduce the bug:

from hera.workflows import Workflow, script

@script(constructor="runner", image="my-image")
def optional_str(my_str: Optional[str], another_str: str | None):  # note the old/new ways to specify optional
    print(my_str)
    print(another_str)

with Workflow(name="my-workflow", entrypoint="optional-str") as w:
    optional_str()

Expected behavior A clear and concise description of what you expected to happen: No error trace.

Environment

  • Hera Version: 5.14.3
  • Python Version: 3.11
  • Argo Version: 3.4.16

Additional context Add any other context about the problem here. We can currently work around this by using an empty string as the default.

@script(constructor="runner", image="my-image")
def optional_str(my_str: str = "", another_str: str = ""):
    print(my_str)
    print(another_str)

elliotgunton avatar Mar 27 '24 16:03 elliotgunton