diff --git a/docs/source/changes.md b/docs/source/changes.md index cc24b331..db0ec4ac 100644 --- a/docs/source/changes.md +++ b/docs/source/changes.md @@ -25,6 +25,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and - {pull}`473` adds signatures to nodes which decouples an identifier from a name. - {pull}`477` updates the PyPI action. - {pull}`478` replaces black with ruff-format. +- {pull}`479` gives skips a higher precedence as an outcome than ancestor failed. ## 0.4.1 - 2023-10-11 diff --git a/src/_pytask/skipping.py b/src/_pytask/skipping.py index 2c9b3295..e86d3d72 100644 --- a/src/_pytask/skipping.py +++ b/src/_pytask/skipping.py @@ -54,14 +54,6 @@ def pytask_execute_task_setup(session: Session, task: PTask) -> None: if is_unchanged and not session.config["force"]: raise SkippedUnchanged - ancestor_failed_marks = get_marks(task, "skip_ancestor_failed") - if ancestor_failed_marks: - message = "\n".join( - skip_ancestor_failed(*mark.args, **mark.kwargs) - for mark in ancestor_failed_marks - ) - raise SkippedAncestorFailed(message) - is_skipped = has_mark(task, "skip") if is_skipped: raise Skipped @@ -74,6 +66,14 @@ def pytask_execute_task_setup(session: Session, task: PTask) -> None: if should_skip: raise Skipped(message) + ancestor_failed_marks = get_marks(task, "skip_ancestor_failed") + if ancestor_failed_marks: + message = "\n".join( + skip_ancestor_failed(*mark.args, **mark.kwargs) + for mark in ancestor_failed_marks + ) + raise SkippedAncestorFailed(message) + @hookimpl def pytask_execute_task_process_report( diff --git a/tests/test_skipping.py b/tests/test_skipping.py index 468f5e13..c100f4d7 100644 --- a/tests/test_skipping.py +++ b/tests/test_skipping.py @@ -270,3 +270,37 @@ def test_pytask_execute_task_setup(marker_name, force, expectation): with expectation: pytask_execute_task_setup(session=session, task=task) + + +def test_skip_has_precendence_over_ancestor_failed(runner, tmp_path): + source = """ + from pathlib import Path + + def task_example(produces=Path("file.txt")): + raise Exception + + def task_example_2(path=Path("file.txt")): ... + """ + tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source)) + result = runner.invoke(cli, [tmp_path.as_posix()]) + assert result.exit_code == ExitCode.FAILED + assert "1 Failed" in result.output + assert "1 Skipped" in result.output + + +def test_skipif_has_precendence_over_ancestor_failed(runner, tmp_path): + source = """ + from pathlib import Path + import pytask + + def task_example(produces=Path("file.txt")): + raise Exception + + @pytask.mark.skipif(True, reason="God knows.") + def task_example_2(path=Path("file.txt")): ... + """ + tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source)) + result = runner.invoke(cli, [tmp_path.as_posix()]) + assert result.exit_code == ExitCode.FAILED + assert "1 Failed" in result.output + assert "1 Skipped" in result.output