Skip to content

Commit 7fa5e9a

Browse files
authored
Fix issue with @task(after=...) in notebooks and terminals. (#557)
1 parent 8b9fae3 commit 7fa5e9a

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

docs/source/changes.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and
1616
passed via the command line are relative to CWD and paths in the configuration
1717
relative to the config file.
1818
- {pull}`555` uses new-style hook wrappers and requires pluggy 1.3 for typing.
19+
- {pull}`557` fixes an issue with `@task(after=...)` in notebooks and terminals.
1920

2021
## 0.4.5 - 2024-01-09
2122

src/_pytask/task_utils.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,16 @@ def _parse_after(
171171
if isinstance(after, str):
172172
return after
173173
if callable(after):
174-
if not hasattr(after, "pytask_meta"):
175-
after.pytask_meta = CollectionMetadata() # type: ignore[attr-defined]
176-
return [after.pytask_meta._id] # type: ignore[attr-defined]
174+
after = [after]
177175
if isinstance(after, list):
178176
new_after = []
179177
for func in after:
180178
if not hasattr(func, "pytask_meta"):
181-
func.pytask_meta = CollectionMetadata() # type: ignore[attr-defined]
182-
new_after.append(func.pytask_meta._id) # type: ignore[attr-defined]
179+
func = task()(func) # noqa: PLW2901
180+
new_after.append(func.pytask_meta._id)
181+
return new_after
183182
msg = (
184-
"'after' should be an expression string, a task, or a list of class. Got "
183+
"'after' should be an expression string, a task, or a list of tasks. Got "
185184
f"{after}, instead."
186185
)
187186
raise TypeError(msg)

tests/test_task.py

+36-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import subprocess
34
import textwrap
45

56
import pytest
@@ -637,12 +638,17 @@ def task_first() -> Annotated[str, Path("out.txt")]:
637638
assert "1 Skipped because unchanged" in result.output
638639

639640

640-
def test_task_will_be_executed_after_another_one_with_function(tmp_path):
641-
source = """
641+
@pytest.mark.end_to_end()
642+
@pytest.mark.parametrize("decorator", ["", "@task"])
643+
def test_task_will_be_executed_after_another_one_with_function(
644+
runner, tmp_path, decorator
645+
):
646+
source = f"""
642647
from pytask import task
643648
from pathlib import Path
644649
from typing_extensions import Annotated
645650
651+
{decorator}
646652
def task_first() -> Annotated[str, Path("out.txt")]:
647653
return "Hello, World!"
648654
@@ -652,8 +658,35 @@ def task_second():
652658
"""
653659
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
654660

655-
session = build(paths=tmp_path)
661+
result = runner.invoke(cli, [tmp_path.as_posix()])
662+
assert result.exit_code == ExitCode.OK
663+
664+
665+
@pytest.mark.end_to_end()
666+
@pytest.mark.parametrize("decorator", ["", "@task"])
667+
def test_task_will_be_executed_after_another_one_with_function_session(
668+
tmp_path, decorator
669+
):
670+
source = f"""
671+
from pytask import task, ExitCode, build
672+
from pathlib import Path
673+
from typing_extensions import Annotated
674+
675+
{decorator}
676+
def task_first() -> Annotated[str, Path("out.txt")]:
677+
return "Hello, World!"
678+
679+
@task(after=task_first)
680+
def task_second():
681+
assert Path(__file__).parent.joinpath("out.txt").exists()
682+
683+
session = build(tasks=[task_first, task_second])
656684
assert session.exit_code == ExitCode.OK
685+
"""
686+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
687+
688+
result = subprocess.run(("pytask",), cwd=tmp_path, capture_output=True, check=False)
689+
assert result.returncode == ExitCode.OK
657690

658691

659692
def test_raise_error_for_wrong_after_expression(runner, tmp_path):

0 commit comments

Comments
 (0)