Skip to content

Commit 9bab583

Browse files
committed
Drop check_shapes from except tracebacks.
1 parent d59799f commit 9bab583

File tree

21 files changed

+5762
-5253
lines changed

21 files changed

+5762
-5253
lines changed

check_shapes/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
DocstringFormat,
2323
ShapeCheckingState,
2424
disable_check_shapes,
25+
get_drop_frames,
2526
get_enable_check_shapes,
2627
get_enable_function_call_precompute,
2728
get_rewrite_docstrings,
29+
set_drop_frames,
2830
set_enable_check_shapes,
2931
set_enable_function_call_precompute,
3032
set_rewrite_docstrings,
@@ -64,6 +66,7 @@
6466
"error_contexts",
6567
"exceptions",
6668
"get_check_shapes",
69+
"get_drop_frames",
6770
"get_enable_check_shapes",
6871
"get_enable_function_call_precompute",
6972
"get_rewrite_docstrings",
@@ -73,6 +76,7 @@
7376
"inheritance",
7477
"parser",
7578
"register_get_shape",
79+
"set_drop_frames",
7680
"set_enable_check_shapes",
7781
"set_enable_function_call_precompute",
7882
"set_rewrite_docstrings",

check_shapes/config.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,11 @@
1616
"""
1717
from contextlib import contextmanager
1818
from enum import Enum
19-
from typing import Callable, Iterator, List, Union
19+
from typing import Callable, ContextManager, Iterator, List, Union
2020

21-
IsCompiledMode = Callable[[], bool]
22-
23-
24-
_is_compiled_mode: List[IsCompiledMode] = []
25-
26-
27-
def add_is_compiled_mode(is_compiled_mode: IsCompiledMode) -> None:
28-
"""
29-
Add a function for determining whether we are currently executing "compiled mode".
21+
from dropstackframe import get_enable_drop_stack_frame, set_enable_drop_stack_frame
3022

31-
Used when func:`set_enable_check_shapes` is set to ``EAGER_MODE_ONLY``.
32-
"""
33-
_is_compiled_mode.append(is_compiled_mode)
23+
IsCompiledMode = Callable[[], bool]
3424

3525

3626
class ShapeCheckingState(Enum):
@@ -67,9 +57,6 @@ def __bool__(self) -> bool:
6757
return False
6858

6959

70-
_enabled = ShapeCheckingState.EAGER_MODE_ONLY
71-
72-
7360
class DocstringFormat(Enum):
7461
"""
7562
Enumeration of supported formats of docstrings.
@@ -86,11 +73,21 @@ class DocstringFormat(Enum):
8673
"""
8774

8875

76+
_is_compiled_mode: List[IsCompiledMode] = []
77+
_enabled = ShapeCheckingState.EAGER_MODE_ONLY
8978
_docstring_format = DocstringFormat.SPHINX
90-
9179
_function_call_precompute_enabled = False
9280

9381

82+
def add_is_compiled_mode(is_compiled_mode: IsCompiledMode) -> None:
83+
"""
84+
Add a function for determining whether we are currently executing "compiled mode".
85+
86+
Used when func:`set_enable_check_shapes` is set to ``EAGER_MODE_ONLY``.
87+
"""
88+
_is_compiled_mode.append(is_compiled_mode)
89+
90+
9491
def set_enable_check_shapes(enabled: Union[ShapeCheckingState, str, bool]) -> None:
9592
"""
9693
Set whether to enable :mod:`check_shapes`.
@@ -192,3 +189,17 @@ def get_enable_function_call_precompute() -> bool:
192189
Get whether to precompute function call path and line numbers for debugging.
193190
"""
194191
return _function_call_precompute_enabled
192+
193+
194+
def set_drop_frames(drop_frames: bool) -> ContextManager[None]:
195+
"""
196+
Set whether :mod:`check_shapes` should hide itself from exception stack traces.
197+
"""
198+
return set_enable_drop_stack_frame(drop_frames)
199+
200+
201+
def get_drop_frames() -> bool:
202+
"""
203+
Get whether :mod:`check_shapes` should hide itself from exception stack traces.
204+
"""
205+
return get_enable_drop_stack_frame()

check_shapes/decorator.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from functools import update_wrapper
2020
from typing import Any, Callable, Sequence, cast
2121

22+
from dropstackframe import drop_stack_frame
23+
2224
from .accessors import set_check_shapes
2325
from .argument_ref import RESULT_TOKEN
2426
from .base_types import C
@@ -117,7 +119,11 @@ def _check_shapes(func: C) -> C:
117119

118120
def wrapped_function(*args: Any, **kwargs: Any) -> Any:
119121
if not get_enable_check_shapes():
120-
return func(*args, **kwargs)
122+
try:
123+
return func(*args, **kwargs)
124+
except Exception:
125+
drop_stack_frame()
126+
raise
121127

122128
try:
123129
bound_arguments = signature.bind(*args, **kwargs)
@@ -182,7 +188,11 @@ def _check_specs(specs: Sequence[ParsedArgumentSpec]) -> None:
182188
_check_specs(pre_specs)
183189

184190
with set_shape_checker(checker):
185-
result = func(*args, **kwargs)
191+
try:
192+
result = func(*args, **kwargs)
193+
except Exception:
194+
drop_stack_frame()
195+
raise
186196
arg_map[RESULT_TOKEN] = result
187197

188198
_check_specs(post_specs)

docs/index.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,3 +495,19 @@ your type:
495495
:start-after: [custom_type]
496496
:end-before: [custom_type]
497497
:dedent:
498+
499+
500+
`check_shapes` in stack traces
501+
++++++++++++++++++++++++++++++
502+
503+
If you use :mod:`check_shapes` consistently you will have a lot of functions wrapped in
504+
:func:`check_shapes`. This means that if you have an error many of the stack frames in the trace
505+
back would belong to :mod:`check_shapes`. For the sake of more readable error messages
506+
:mod:`check_shapes` has code to hide itself from trace backs. If you do not like this you can
507+
disable this behaviour with :func:`set_drop_frames`:
508+
509+
510+
.. literalinclude:: /examples/test_check_shapes_examples.py
511+
:start-after: [disable_drop_frames]
512+
:end-before: [disable_drop_frames]
513+
:dedent:

0 commit comments

Comments
 (0)