Skip to content

Commit 3428f00

Browse files
authored
Add --show-traceback to control whether tracebacks are displayed. (#187)
1 parent 327a0f6 commit 3428f00

File tree

5 files changed

+63
-8
lines changed

5 files changed

+63
-8
lines changed

docs/source/changes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ all releases are available on `PyPI <https://pypi.org/project/pytask>`_ and
1111
------------------
1212

1313
- :gh:`186` enhance live displays by deactivating auto-refresh among other things.
14+
- :gh:`187` allows to enable and disable showing tracebacks and potentially different
15+
styles in the future with :confval:`show_traceback=True|False`.
1416
- :gh:`188` refactors some code related to :class:`_pytask.enums.ExitCode`.
1517

1618

src/_pytask/build.py

+5
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ def main(config_from_cli: Dict[str, Any]) -> Session:
107107
default=None,
108108
help="Print errors with tracebacks as soon as the task fails.",
109109
)
110+
@click.option(
111+
"--show-traceback",
112+
type=click.Choice(["yes", "no"]),
113+
help="Choose whether tracebacks should be displayed or not. [default: yes]",
114+
)
110115
def build(**config_from_cli: Any) -> "NoReturn":
111116
"""Collect and execute tasks and report the results.
112117

src/_pytask/execute.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,18 @@ def pytask_execute_log_end(session: Session, reports: List[ExecutionReport]) ->
228228

229229
counts = count_outcomes(reports, TaskOutcome)
230230

231-
console.print()
232-
if counts[TaskOutcome.FAIL]:
233-
console.rule(
234-
Text("Failures", style=TaskOutcome.FAIL.style), style=TaskOutcome.FAIL.style
235-
)
231+
if session.config["show_traceback"] != "no":
236232
console.print()
233+
if counts[TaskOutcome.FAIL]:
234+
console.rule(
235+
Text("Failures", style=TaskOutcome.FAIL.style),
236+
style=TaskOutcome.FAIL.style,
237+
)
238+
console.print()
237239

238-
for report in reports:
239-
if report.outcome in (TaskOutcome.FAIL, TaskOutcome.SKIP_PREVIOUS_FAILED):
240-
_print_errored_task_report(session, report)
240+
for report in reports:
241+
if report.outcome in (TaskOutcome.FAIL, TaskOutcome.SKIP_PREVIOUS_FAILED):
242+
_print_errored_task_report(session, report)
241243

242244
console.rule(style="dim")
243245

src/_pytask/logging.py

+28
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import Any
66
from typing import Dict
77
from typing import List
8+
from typing import Optional
89
from typing import Tuple
910
from typing import TYPE_CHECKING
1011
from typing import Union
@@ -38,6 +39,13 @@ class _TimeUnit(TypedDict):
3839
short: str
3940
in_seconds: int
4041

42+
if sys.version_info >= (3, 8):
43+
from typing import Literal
44+
else:
45+
from typing_extensions import Literal
46+
47+
_ShowTraceback = Literal["no", "yes"]
48+
4149

4250
@hookimpl
4351
def pytask_extend_command_line_interface(cli: click.Group) -> None:
@@ -78,6 +86,26 @@ def pytask_parse_config(
7886
"See https://github.com/pytask-dev/pytask/issues/171 for more information. "
7987
"Resort to `editor_url_scheme='file'`."
8088
)
89+
config["show_traceback"] = get_first_non_none_value(
90+
config_from_cli,
91+
config_from_file,
92+
key="show_traceback",
93+
default="yes",
94+
callback=_show_traceback_callback,
95+
)
96+
97+
98+
def _show_traceback_callback(
99+
x: Optional["_ShowTraceback"],
100+
) -> Optional["_ShowTraceback"]:
101+
"""Validate the passed options for showing tracebacks."""
102+
if x in [None, "None", "none"]:
103+
x = None
104+
elif x in ["no", "yes"]:
105+
pass
106+
else:
107+
raise ValueError("'show_traceback' can only be one of ['no', 'yes'")
108+
return x
81109

82110

83111
@hookimpl

tests/test_logging.py

+18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from _pytask.logging import _format_plugin_names_and_versions
77
from _pytask.logging import _humanize_time
88
from _pytask.logging import pytask_log_session_footer
9+
from _pytask.outcomes import ExitCode
910
from _pytask.outcomes import TaskOutcome
1011
from pytask import cli
1112

@@ -127,3 +128,20 @@ def test_humanize_time(amount, unit, short_label, expectation, expected):
127128
with expectation:
128129
result = _humanize_time(amount, unit, short_label)
129130
assert result == expected
131+
132+
133+
@pytest.mark.parametrize("show_traceback", ["no", "yes"])
134+
def test_show_traceback(runner, tmp_path, show_traceback):
135+
source = "def task_raises(): raise Exception"
136+
tmp_path.joinpath("task_module.py").write_text(source)
137+
138+
result = runner.invoke(
139+
cli, [tmp_path.as_posix(), "--show-traceback", show_traceback]
140+
)
141+
142+
has_traceback = show_traceback == "yes"
143+
144+
assert result.exit_code == ExitCode.FAILED
145+
assert ("Failures" in result.output) is has_traceback
146+
assert ("Traceback" in result.output) is has_traceback
147+
assert ("raise Exception" in result.output) is has_traceback

0 commit comments

Comments
 (0)