Skip to content

Commit

Permalink
feat: Perform dynamic import such that local relative imports functio… (
Browse files Browse the repository at this point in the history
#906)

…n correctly.

**Pull Request Checklist**
- [ ] Fixes #<!--issue number goes here-->
- [x] Tests added
- [ ] Documentation/examples added
- [x] [Good commit messages](https://cbea.ms/git-commit/) and/or PR
title

**Description of PR**

Given a folder structure like:

```python
folder/
  foo.py
  bar.py
```

Currently, files containing workflows cannot reference other python
modules, local to the point of import.

i.e. `from .foo import ...` from inside `bar.py`.

This PR updates the way the dynamic import occurs such that local
imports **do** function correctly.

What does **not** yet appear to work correctly is if the referenced code
can be imported where absolute imports to a root package would function
correctly. I suspect that for that to work, the FROM argument would need
to reference a source `module.path` rather than a path to a file.

Signed-off-by: DanCardin <[email protected]>
  • Loading branch information
DanCardin authored Jan 4, 2024
1 parent ab3b4ab commit 81ee7f5
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/hera/_cli/generate/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,12 @@ def load_workflows_from_module(path: Path) -> list[Workflow]:
Returns:
A list containing all `Workflow` objects defined within that module.
"""
spec = importlib.util.spec_from_file_location(path.stem, path)
module_name = path.stem
spec = importlib.util.spec_from_file_location(module_name, path, submodule_search_locations=[str(path.parent)])
assert spec

module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module

assert spec.loader
spec.loader.exec_module(module)
Expand Down
3 changes: 3 additions & 0 deletions tests/cli/examples/relative_imports/file1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from hera.workflows import Container

on_exit = Container(image="image")
6 changes: 6 additions & 0 deletions tests/cli/examples/relative_imports/file2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from hera.workflows import Workflow

from .file1 import on_exit

with Workflow(name="relative_import", on_exit=on_exit) as workflow:
workflow._add_sub(on_exit)
23 changes: 23 additions & 0 deletions tests/cli/test_generate_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import cappa
import pytest
from cappa.testing import CommandRunner

from hera._cli.base import Hera

Expand Down Expand Up @@ -76,6 +77,9 @@ def patch_open():
)


runner = CommandRunner(Hera, base_args=["generate", "yaml"])


@pytest.mark.cli
def test_no_output(capsys):
cappa.invoke(Hera, argv=["generate", "yaml", "tests/cli/test_generate_yaml.py"])
Expand Down Expand Up @@ -244,3 +248,22 @@ def test_source_folder_output_folder():

content2 = open_patch.new.return_value.write.mock_calls[2][1][0]
assert content2 == single_workflow_output


@pytest.mark.cli
def test_relative_imports(capsys):
runner.invoke("tests/cli/examples/relative_imports")

output = get_stdout(capsys)
assert output == dedent(
"""\
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
name: relative_import
spec:
templates:
- container:
image: image
"""
)

0 comments on commit 81ee7f5

Please sign in to comment.