How can I elide a function wrapper from the traceback in Python-3?
The simple answer is that you shouldn't do that. Hiding things from the traceback is dangerous. You may think you don't want to show that line because it's trivial or "just a wrapper", but in general you wouldn't write the wrapper function if it didn't do something. Next thing you know there is a bug in the wrapper function which is now unfindable because the wrapper function has erased itself from the traceback.
Just deal with the extra lines in the traceback, or, if you really want, override sys.excepthook
and filter them out at the top level. If you're worried about someone else overriding sys.excepthook
too, then wrap all your code in a top-level function that does the exception printing itself. It isn't and shouldn't be easy to hide levels from the traceback.
The internal _testcapi
module contains a binding for the PyErr_SetExcInfo
function, which makes this fairly easy to implement. Only tested on cpython 3.9; there's no guarantee that it'll continue working in the future.
import functoolsimport typing as TA_Callable = T.TypeVar("A_Callable", bound=T.Callable[..., T.Any])try: from sys import exc_info from _testcapi import set_exc_info def silent_wrapper(f: A_Callable) -> A_Callable: @functools.wraps(f) def wrapper(*args: T.Any, **kwargs: T.Any) -> T.Any: try: return f(*args, **kwargs) except: tp, exc, tb = exc_info() # Drop two frames, one for silent_wrapper itself and one for the # wrapped function set_exc_info(tp, exc, tb.tb_next.tb_next) # type: ignore[union-attr] del tp, exc, tb raise return T.cast(A_Callable, wrapper)except ImportError: def silent_wrapper(f: A_Callable) -> A_Callable: return f