Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide traceback frames with __tracebackhide__ = True. #129

Merged
merged 6 commits into from
Jul 18, 2021
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
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ repos:
- id: rst-inline-touching-normal
- id: text-unicode-replacement-char
- repo: https://github.com/asottile/pyupgrade
rev: v2.21.0
rev: v2.21.2
hooks:
- id: pyupgrade
args: [--py36-plus]
Expand All @@ -45,7 +45,7 @@ repos:
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/psf/black
rev: 21.6b0
rev: 21.7b0
hooks:
- id: black
- repo: https://github.com/asottile/blacken-docs
Expand Down
2 changes: 2 additions & 0 deletions docs/source/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ all releases are available on `PyPI <https://pypi.org/project/pytask>`_ and
- :gh:`121` add skipped and persisted tasks to the execution footer.
- :gh:`127` make the table during execution the default. Silence pytask with negative
verbose mode integers and increase verbosity with positive ones.
- :gh:`129` allows to hide frames from the traceback by using ``__tracebackhide__ =
True``.


0.0.16 - 2021-06-25
Expand Down
13 changes: 9 additions & 4 deletions src/_pytask/traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ def remove_internal_traceback_frames_from_exc_info(exc_info):
return exc_info


def _is_internal_traceback_frame(frame):
"""Returns ``True`` if traceback frame belongs to internal packages.
def _is_internal_or_hidden_traceback_frame(frame):
"""Returns ``True`` if traceback frame belongs to internal packages or is hidden.

Internal packages are ``_pytask`` and ``pluggy``.
Internal packages are ``_pytask`` and ``pluggy``. A hidden frame is indicated by a
local variable called ``__tracebackhide__ = True``.

"""
is_hidden = frame.tb_frame.f_locals.get("__tracebackhide__", False)
if is_hidden:
return True

path = Path(frame.tb_frame.f_code.co_filename)
return any(root in path.parents for root in [_PLUGGY_DIRECTORY, _PYTASK_DIRECTORY])

Expand All @@ -44,7 +49,7 @@ def _filter_internal_traceback_frames(frame):

"""
for frame in _yield_traceback_frames(frame):
if frame is None or not _is_internal_traceback_frame(frame):
if frame is None or not _is_internal_or_hidden_traceback_frame(frame):
break
return frame

Expand Down
26 changes: 26 additions & 0 deletions tests/test_traceback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import textwrap

import pytest
from pytask import cli


@pytest.mark.parametrize("is_hidden", [True, False])
def test_hide_traceback_from_error_report(runner, tmp_path, is_hidden):
source = f"""
def task_main():
a = "This variable should not be shown."
__tracebackhide__ = {is_hidden}


helper()


def helper():
raise Exception
"""
tmp_path.joinpath("task_main.py").write_text(textwrap.dedent(source))

result = runner.invoke(cli, [tmp_path.as_posix(), "--show-locals"])

assert result.exit_code == 1
assert ("This variable should not be shown." in result.output) is not is_hidden
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ ignore =
max-line-length = 88
per-file-ignores =
src/_pytask/hookspecs.py: U100
src/_pytask/outcomes.py: N818
tests/test_capture.py: T000, T001, N802, PT011
pytest-mark-no-parentheses = true
warn-symbols =
Expand Down