Development tooling¶
Tracing Failures¶
Sometimes we want to trace where the Failure has occurred in our system,
returns provide a way to trace those failures.
By default tracing is disabled.
The trace is accessible by trace property
that is available for Result, IOResult containers. It’s basically a list
containing all inspect.FrameInfo objects from the call stack when the
Failure was originally created.
To enable it you can use
collect_traces.
See examples below:
You can use it as a context manager:
>>> from inspect import FrameInfo
>>> from returns.result import Failure, Result
>>> from returns.primitives.tracing import collect_traces
>>> def get_failure(argument: str) -> Result[str, str]:
... return Failure(argument)
>>> non_traced_failure = get_failure('Normal Failure')
>>> with collect_traces():
... traced_failure = get_failure('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(f"{trace_line.filename}:{trace_line.lineno} in `{trace_line.function}`")
...
/returns/returns/result.py:529 in `Failure`
/example_folder/example.py:5 in `get_failure`
/example_folder/example.py:1 in `<module>`
Or as a decorator:
>>> from inspect import FrameInfo
>>> from returns.io import IOFailure, IOResult
>>> from returns.result import Failure, Result
>>> from returns.primitives.tracing import collect_traces
>>> @collect_traces
... def traced_function(value: str) -> IOResult[str, str]:
... return IOFailure(value)
>>> non_traced_failure = Failure('Normal Failure')
>>> traced_failure = traced_function('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(f"{trace_line.filename}:{trace_line.lineno} in `{trace_line.function}`")
...
/returns/returns/result.py:525 in `Failure`
/returns/returns/io.py:852 in `IOFailure`
/example_folder/example.py:7: in `traced_function`
/usr/lib/python3.8/contextlib.py:75 in `inner`
/example_folder/example.py:1 in `<module>`
Warning
Activating trace can make your program noticeably slower if it has many points where Failure is often created.
Warning
collect_traces is not thread safe, beware to use it with threading!
Warning
Traces are meant to be used during development only.
API Reference¶
- collect_traces(function=None)[source]¶
Context Manager/Decorator to active traces collect to the Failures.
>>> 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( ... '{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>`
- Parameters:
function (
Optional[TypeVar(_FunctionType, bound=Callable)])- Return type:
Union[TypeVar(_FunctionType, bound=Callable),AbstractContextManager[None]]