importtypesfromcollections.abcimportCallable,IteratorfromcontextlibimportcontextmanagerfrominspectimportFrameInfo,stackfromtypingimportContextManager,TypeVar,overloadfromreturns.resultimportFailure_FunctionType=TypeVar('_FunctionType',bound=Callable)@overloaddefcollect_traces()->ContextManager[None]:"""Context Manager to active traces collect to the Failures."""@overloaddefcollect_traces(function:_FunctionType)->_FunctionType:"""Decorator to active traces collect to the Failures."""
[docs]defcollect_traces(function:_FunctionType|None=None,)->_FunctionType|ContextManager[None]:# noqa: DAR101, DAR201, DAR301""" Context Manager/Decorator to active traces collect to the Failures. .. code:: python >>> from inspect import FrameInfo >>> from returns.io import IOResult >>> from returns.result import Result >>> from returns.primitives.tracing import collect_traces >>> with collect_traces(): ... traced_failure = Result.from_failure('Traced Failure') >>> non_traced_failure = IOResult.from_failure('Non Traced Failure') >>> assert non_traced_failure.trace is None >>> assert isinstance(traced_failure.trace, list) >>> assert all(isinstance(trace_line, FrameInfo) for trace_line in traced_failure.trace) >>> for trace_line in traced_failure.trace: ... print( # doctest: +SKIP ... '{0}:{1} in `{2}`'.format( ... trace_line.filename, ... trace_line.lineno, ... trace_line.function, ... ), ... ) ... /returns/returns/result.py:525 in `Failure` /returns/returns/result.py:322 in `from_failure` /example_folder/example.py:1 in `<module>` # doctest: # noqa: DAR301, E501 """@contextmanagerdeffactory()->Iterator[None]:unpatched_get_trace=getattr(Failure,'_get_trace')# noqa: B009substitute_get_trace=types.MethodType(_get_trace,Failure)setattr(Failure,'_get_trace',substitute_get_trace)# noqa: B010try:# noqa: WPS501yieldfinally:setattr(Failure,'_get_trace',unpatched_get_trace)# noqa: B010returnfactory()(function)iffunctionelsefactory()
def_get_trace(_self:Failure)->list[FrameInfo]|None:""" Function to be used on Monkey Patching. This function is the substitute for '_get_trace' method from ``Failure`` class on Monkey Patching promoted by :func:`returns.primitives.tracing.collect_traces` function. We get all the call stack from the current call and return it from the third position, to avoid two useless calls on the call stack. Those useless calls are a call to this function and a call to `__init__` method from ``Failure`` class. We're just interested in the call stack ending on ``Failure`` function call! See also: - https://github.com/dry-python/returns/issues/409 """current_stack=stack()returncurrent_stack[2:]