Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and

## Unreleased

- [#995](https://github.com/pytask-dev/pytask/pull/995) documents that return values
from task generators are ignored and adds a regression test for this behavior.
- [#977](https://github.com/pytask-dev/pytask/pull/977) allows marker expressions
passed to `-m` to select tasks by marker keyword arguments.
- [#976](https://github.com/pytask-dev/pytask/pull/976) makes invalid marker and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,6 @@ content to a `.txt` file.
!!! important

The generated tasks need to be decorated with `@task` to be collected.

Task generators are only used to define other tasks. Their return values are ignored
and cannot be used to define products. Define products on the generated tasks instead.
7 changes: 5 additions & 2 deletions src/_pytask/provisional.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def _safe_load(node: PNode | PProvisionalNode, task: PTask, is_product: bool) ->


@hookimpl
def pytask_execute_task(session: Session, task: PTask) -> None:
def pytask_execute_task(session: Session, task: PTask) -> bool | None:
"""Execute task generators and collect the tasks."""
if is_task_generator(task):
kwargs = {}
Expand Down Expand Up @@ -114,9 +114,12 @@ def pytask_execute_task(session: Session, task: PTask) -> None:
)
session.execution_reports.append(exec_report)
session.should_stop = True
return
return None

recreate_dag(session, task)
return True

return None


@hookimpl
Expand Down
25 changes: 25 additions & 0 deletions tests/test_provisional.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,31 @@ def task_copy(
assert tmp_path.joinpath("b-copy.txt").exists()


def test_task_generator_return_value_is_ignored(runner, tmp_path):
source = """
from pathlib import Path
from typing import Annotated
from pytask import task

@task(is_generator=True)
def task_generator() -> Annotated[
str, Path("returned.txt")
]:
@task
def task_child(produces=Path("child.txt")):
produces.write_text("child")

return "ignored"
"""
tmp_path.joinpath("task_module.py").write_text(textwrap.dedent(source))

result = runner.invoke(cli, [tmp_path.as_posix()])

assert result.exit_code == ExitCode.OK
assert tmp_path.joinpath("child.txt").read_text() == "child"
assert not tmp_path.joinpath("returned.txt").exists()


def test_gracefully_fail_when_task_generator_raises_error(runner, tmp_path):
source = """
from typing import Annotated
Expand Down
Loading