outcome: Capture the outcome of Python function calls.

Tutorial

Outcome provides a function for capturing the outcome of a Python function call, so that it can be passed around. The basic rule is:

result = outcome.capture(f, *args, **kwargs)
x = result.unwrap()

is the same as:

x = f(*args, **kwargs)

even if f raises an error.

There’s also acapture():

result = await outcome.acapture(f, *args, **kwargs)
x = result.unwrap()

which, like before, is the same as:

x = await f(*args, **kwargs)

An Outcome object can only be unwrapped once. A second attempt would raise an AlreadyUsedError.

See the API Reference for the types involved.

API Reference

outcome.capture(sync_fn: Callable[ArgsT, ResultT], *args: ArgsT.args, **kwargs: ArgsT.kwargs) Value[ResultT] | Error

Run sync_fn(*args, **kwargs) and capture the result.

Returns:

Either a Value or Error as appropriate.

await outcome.acapture(async_fn: Callable[ArgsT, Awaitable[ResultT]], *args: ArgsT.args, **kwargs: ArgsT.kwargs) Value[ResultT] | Error

Run await async_fn(*args, **kwargs) and capture the result.

Returns:

Either a Value or Error as appropriate.

class outcome.Outcome

An abstract class representing the result of a Python computation.

This class has two concrete subclasses: Value representing a value, and Error representing an exception.

In addition to the methods described below, comparison operators on Value and Error objects (==, <, etc.) check that the other object is also a Value or Error object respectively, and then compare the contained objects.

Outcome objects are hashable if the contained objects are hashable.

abstractmethod await asend(agen: AsyncGenerator[ResultT, ValueT]) ResultT

Send or throw the contained value or exception into the given async generator object.

Parameters:

agen – An async generator object supporting .asend() and .athrow() methods.

abstractmethod send(gen: Generator[ResultT, ValueT, object]) ResultT

Send or throw the contained value or exception into the given generator object.

Parameters:

gen – A generator object supporting .send() and .throw() methods.

abstractmethod unwrap() ValueT

Return or raise the contained value or exception.

These two lines of code are equivalent:

x = fn(*args)
x = outcome.capture(fn, *args).unwrap()
outcome.Maybe = Value[ResultT] | Error

A convenience alias to a union of both results. This allows type checkers to perform exhaustiveness checking when isinstance() is used with either class:

outcome: Maybe[int] = capture(some_function, 1, 2, 3)
if isinstance(outcome, Value):
    # Type checkers know it's a Value[int] here.
else:
    # It must be an Error.
class outcome.Value(value: ValueT)

Concrete Outcome subclass representing a regular value.

await asend(agen: AsyncGenerator[ResultT, ValueT]) ResultT

Send or throw the contained value or exception into the given async generator object.

Parameters:

agen – An async generator object supporting .asend() and .athrow() methods.

send(gen: Generator[ResultT, ValueT, object]) ResultT

Send or throw the contained value or exception into the given generator object.

Parameters:

gen – A generator object supporting .send() and .throw() methods.

unwrap() ValueT

Return or raise the contained value or exception.

These two lines of code are equivalent:

x = fn(*args)
x = outcome.capture(fn, *args).unwrap()
class outcome.Error(error: BaseException)

Concrete Outcome subclass representing a raised exception.

await asend(agen: AsyncGenerator[ResultT, NoReturn]) ResultT

Send or throw the contained value or exception into the given async generator object.

Parameters:

agen – An async generator object supporting .asend() and .athrow() methods.

send(gen: Generator[ResultT, NoReturn, object]) ResultT

Send or throw the contained value or exception into the given generator object.

Parameters:

gen – A generator object supporting .send() and .throw() methods.

unwrap() NoReturn

Return or raise the contained value or exception.

These two lines of code are equivalent:

x = fn(*args)
x = outcome.capture(fn, *args).unwrap()
class outcome.AlreadyUsedError

An Outcome can only be unwrapped once.

Release history

Outcome 1.3.0 (2023-10-17)

Features

Outcome 1.2.0 (2022-06-14)

Features

  • Add support for Python 3.9 and 3.10. (#32)

Deprecations and Removals

  • Drop support for Python 3.6. (#32)

Outcome 1.1.0 (2020-11-16)

Bugfixes

  • Tweaked the implementation of Error.unwrap to avoid creating a reference cycle between the exception object and the unwrap method’s frame. This shouldn’t affect most users, but it slightly reduces the amount of work that CPython’s cycle collector has to do, and may reduce GC pauses in some cases. (#29)

Deprecations and Removals

  • Drop support for Python 2.7, 3.4, and 3.5. (#27)

Outcome 1.0.1 (2019-10-16)

Upgrade to attrs 19.2.0.

Outcome 1.0.0 (2018-09-12)

Features

  • On Python 3, the exception frame generated within capture() and acapture() has been removed from the traceback. (#21)

  • Outcome is now tested using asyncio instead of trio, which outcome is a dependency of. This makes it easier for third parties to package up Outcome. (#13)

Outcome 0.1.0 (2018-07-10)

Features

  • An Outcome may only be unwrapped or sent once.

    Attempting to do so a second time will raise an AlreadyUsedError. (#7)

Indices and tables