Skip to content

Commit c902136

Browse files
authored
Fix interaction with --pdb, --trace and tasks that return. (#579)
1 parent b8b7f9f commit c902136

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

docs/source/changes.md

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and
2323
- {pull}`571` removes redundant calls to `PNode.state()` which causes a high penalty for
2424
remote files.
2525
- {pull}`573` removes the `pytask_execute_create_scheduler` hook.
26+
- {pull}`579` fixes an interaction with `--pdb` and `--trace` and task that return. The
27+
debugging modes swallowed the return and `None` was returned. Closes {issue}`574`.
2628

2729
## 0.4.6 - 2024-03-13
2830

src/_pytask/debugging.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ def wrapper(*args: Any, **kwargs: Any) -> None:
332332
capman = session.config["pm"].get_plugin("capturemanager")
333333
live_manager = session.config["pm"].get_plugin("live_manager")
334334
try:
335-
task_function(*args, **kwargs)
335+
return task_function(*args, **kwargs)
336336

337337
except Exception:
338338
# Order is important! Pausing the live object before the capturemanager
@@ -413,11 +413,13 @@ def wrapper(*args: Any, **kwargs: Any) -> None:
413413
console.rule("Captured stderr", style="default")
414414
console.print(err)
415415

416-
_pdb.runcall(task_function, *args, **kwargs)
416+
out = _pdb.runcall(task_function, *args, **kwargs)
417417

418418
live_manager.resume()
419419
capman.resume()
420420

421+
return out
422+
421423
task.function = wrapper
422424

423425

tests/test_debugging.py

+43-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
IS_PEXPECT_INSTALLED = True
2121

2222

23+
def _escape_ansi(line):
24+
"""Escape ANSI sequences produced by rich."""
25+
ansi_escape = re.compile(r"(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]")
26+
return ansi_escape.sub("", line)
27+
28+
2329
@pytest.mark.unit()
2430
@pytest.mark.parametrize(
2531
("value", "expected", "expectation"),
@@ -482,7 +488,40 @@ def test_function():
482488
_flush(child)
483489

484490

485-
def _escape_ansi(line):
486-
"""Escape ANSI sequences produced by rich."""
487-
ansi_escape = re.compile(r"(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]")
488-
return ansi_escape.sub("", line)
491+
@pytest.mark.end_to_end()
492+
@pytest.mark.skipif(not IS_PEXPECT_INSTALLED, reason="pexpect is not installed.")
493+
@pytest.mark.skipif(sys.platform == "win32", reason="pexpect cannot spawn on Windows.")
494+
def test_pdb_with_task_that_returns(tmp_path, runner):
495+
source = """
496+
from typing_extensions import Annotated
497+
from pathlib import Path
498+
499+
def task_example() -> Annotated[str, Path("data.txt")]:
500+
return "1"
501+
"""
502+
tmp_path.joinpath("task_module.py").write_text(textwrap.dedent(source))
503+
504+
result = runner.invoke(cli, [tmp_path.as_posix(), "--pdb"])
505+
assert result.exit_code == ExitCode.OK
506+
assert tmp_path.joinpath("data.txt").read_text() == "1"
507+
508+
509+
@pytest.mark.end_to_end()
510+
@pytest.mark.skipif(not IS_PEXPECT_INSTALLED, reason="pexpect is not installed.")
511+
@pytest.mark.skipif(sys.platform == "win32", reason="pexpect cannot spawn on Windows.")
512+
def test_trace_with_task_that_returns(tmp_path):
513+
source = """
514+
from typing_extensions import Annotated
515+
from pathlib import Path
516+
517+
def task_example() -> Annotated[str, Path("data.txt")]:
518+
return "1"
519+
"""
520+
tmp_path.joinpath("task_module.py").write_text(textwrap.dedent(source))
521+
522+
child = pexpect.spawn(f"pytask {tmp_path.as_posix()}")
523+
child.sendline("c")
524+
rest = child.read().decode("utf8")
525+
assert "1 Succeeded" in _escape_ansi(rest)
526+
assert tmp_path.joinpath("data.txt").read_text() == "1"
527+
_flush(child)

0 commit comments

Comments
 (0)