Skip to content

Result API Reference

API documentation for the Result type and related classes.

Type Alias

Result[T, E] = Ok[T] | Err[E]

A type representing either success (Ok[T]) or failure (Err[E]).


Ok

Ok

Ok(value: T)

Bases: Generic[T]

Success variant of Result containing a value.

PARAMETER DESCRIPTION
value

The success value to wrap.

TYPE: T

Example
result = Ok(42)
result.unwrap()  # 42
result.is_ok()  # True

inspect class-attribute instance-attribute

inspect = tee

is_ok

is_ok() -> Literal[True]

Return True (this is Ok).

is_err

is_err() -> Literal[False]

Return False (this is not Err).

ok

ok() -> Some[T]

Return the Ok value wrapped in Some.

err

err() -> _NothingType

Return Nothing (no error in Ok).

map

map(fn: Callable[[T], U]) -> Ok[U]

Transform the Ok value.

map_async async

map_async(
    fn: Callable[[T], Coroutine[Any, Any, U]],
) -> Ok[U]

Transform Ok value with async function.

map_err

map_err(fn: Callable[[Any], F]) -> Ok[T]

Return self unchanged (no error to transform).

map_err_async async

map_err_async(
    fn: Callable[[Any], Coroutine[Any, Any, F]],
) -> Ok[T]

Return self (no error to transform).

and_then

and_then(
    fn: Callable[[T], Ok[U] | Err[F]],
) -> Ok[U] | Err[F]

Chain Result-returning operation.

and_then_async async

and_then_async(
    fn: Callable[
        [T], Coroutine[Any, Any, Ok[U] | Err[F]]
    ],
) -> Ok[U] | Err[F]

Chain async Result-returning operation.

or_else

or_else(fn: Callable[[Any], Ok[U] | Err[F]]) -> Ok[T]

Return self (no error to recover from).

or_else_async async

or_else_async(
    fn: Callable[
        [Any], Coroutine[Any, Any, Ok[U] | Err[F]]
    ],
) -> Ok[T]

Return self (no error to recover from).

unwrap

unwrap() -> T

Return the Ok value.

unwrap_or

unwrap_or(default: object) -> T

Return the Ok value, ignoring the default.

unwrap_or_else

unwrap_or_else(fn: Callable[[Any], U]) -> T

Return the Ok value, ignoring the function.

unwrap_or_raise

unwrap_or_raise(fn: Callable[[Any], BaseException]) -> T

Return the Ok value, ignoring the exception factory.

unwrap_err

unwrap_err() -> NoReturn

Raise UnwrapError (cannot get error from Ok).

expect

expect(msg: str) -> T

Return the Ok value.

tee

tee(fn: Callable[[T], Any]) -> Ok[T]

Execute fn for side effects, return self.

inspect_err

inspect_err(fn: Callable[[Any], Any]) -> Ok[T]

Return self (no error to inspect).

flatten

flatten() -> Ok[U] | Err[F]

Flatten nested Result.

split

split() -> tuple[T, None]

Split into (value, None) tuple.

filter

filter(
    predicate: Callable[[T], bool], error: F
) -> Ok[T] | Err[F]

Return self if predicate passes, otherwise Err with given error.

zip

zip(other: Ok[U] | Err[F]) -> Ok[tuple[T, U]] | Err[F]

Combine with another Result into a tuple.

zip_with

zip_with(
    other: Ok[U] | Err[F], fn: Callable[[T, U], Any]
) -> Ok[Any] | Err[F]

Combine with another Result using a function.

context

context(msg: str) -> Ok[T]

Return self unchanged (no error to add context to).


Err

Err

Err(error: E)

Bases: Generic[E]

Error variant of Result containing an error value.

PARAMETER DESCRIPTION
error

The error value to wrap.

TYPE: E

Example
result = Err("something went wrong")
result.unwrap_err()  # 'something went wrong'
result.is_err()  # True

inspect class-attribute instance-attribute

inspect = tee

is_ok

is_ok() -> Literal[False]

Return False (this is not Ok).

is_err

is_err() -> Literal[True]

Return True (this is Err).

ok

ok() -> _NothingType

Return Nothing (no value in Err).

err

err() -> Some[E]

Return the Err value wrapped in Some.

map

map(fn: Callable[[Any], U]) -> Err[E]

Return self unchanged (no value to transform).

map_async async

map_async(
    fn: Callable[[Any], Coroutine[Any, Any, U]],
) -> Err[E]

Return self (no value to transform).

map_err

map_err(fn: Callable[[E], F]) -> Err[F]

Transform the Err value.

map_err_async async

map_err_async(
    fn: Callable[[E], Coroutine[Any, Any, F]],
) -> Err[F]

Transform Err value with async function.

and_then

and_then(fn: Callable[[Any], Ok[U] | Err[F]]) -> Err[E]

Return self (no value to chain).

and_then_async async

and_then_async(
    fn: Callable[
        [Any], Coroutine[Any, Any, Ok[U] | Err[F]]
    ],
) -> Err[E]

Return self (no value to chain).

or_else

or_else(
    fn: Callable[[E], Ok[U] | Err[F]],
) -> Ok[U] | Err[F]

Recover from error by calling fn.

or_else_async async

or_else_async(
    fn: Callable[
        [E], Coroutine[Any, Any, Ok[U] | Err[F]]
    ],
) -> Ok[U] | Err[F]

Recover from error with async function.

unwrap

unwrap() -> NoReturn

Raise UnwrapError (cannot get value from Err).

unwrap_or

unwrap_or(default: U) -> U

Return the default value.

unwrap_or_else

unwrap_or_else(fn: Callable[[E], U]) -> U

Compute and return value from error.

unwrap_or_raise

unwrap_or_raise(
    fn: Callable[[E], BaseException],
) -> NoReturn

Raise exception created by fn(error).

unwrap_err

unwrap_err() -> E

Return the Err value.

expect

expect(msg: str) -> NoReturn

Raise UnwrapError with custom message.

tee

tee(fn: Callable[[Any], Any]) -> Err[E]

Return self (no value to inspect).

inspect_err

inspect_err(fn: Callable[[E], Any]) -> Err[E]

Execute fn for side effects, return self.

flatten

flatten() -> Err[E]

Return self (already flat).

split

split() -> tuple[None, E]

Split into (None, error) tuple.

filter

filter(
    predicate: Callable[[Any], bool], error: Any
) -> Err[E]

Return self unchanged (already an error).

zip

zip(other: Ok[U] | Err[Any]) -> Err[E]

Return self (first error wins).

zip_with

zip_with(
    other: Ok[U] | Err[Any], fn: Callable[[Any, U], Any]
) -> Err[E]

Return self (first error wins).

context

context(msg: str) -> Err[ChainedError]

Wrap the error with additional context.


LazyResult

LazyResult

LazyResult(
    source: Awaitable[Ok[T] | Err[E]] | Ok[T] | Err[E],
    operations: tuple[ResultOperation, ...] = (),
)

Bases: Generic[T, E]

Lazy Result with deferred execution for clean async chaining.

LazyResult builds a pipeline of operations that execute only when .collect() is called. All methods accept both sync and async functions transparently, avoiding nested await chains.

This pattern is inspired by Polars' lazy evaluation - build the computation graph, then execute it all at once.

Example
async def fetch_user(id: int) -> Result[User, str]: ...
async def fetch_profile(user: User) -> Result[Profile, str]: ...

result = await (
    LazyResult.from_awaitable(fetch_user(42))
    .and_then(fetch_profile)   # Async function
    .map(lambda p: p.name)     # Sync function
    .tee(print)                # Side effect
    .collect()
)
From an existing Result
result = await Ok(5).lazy().map(lambda x: x * 2).collect()
result  # Ok(10)
Note

Operations are stored as frozen dataclasses and executed sequentially. Short-circuiting occurs on Err values.

inspect class-attribute instance-attribute

inspect = tee

from_result classmethod

from_result(result: Ok[T] | Err[E]) -> LazyResult[T, E]

Create LazyResult from an existing Result.

from_awaitable classmethod

from_awaitable(
    awaitable: Awaitable[Ok[T] | Err[E]],
) -> LazyResult[T, E]

Create LazyResult from a coroutine/awaitable that returns Result.

ok classmethod

ok(value: U) -> LazyResult[U, Any]

Create LazyResult from a success value.

err classmethod

err(error: U) -> LazyResult[Any, U]

Create LazyResult from an error value.

map

map(
    fn: Callable[[T], U | Awaitable[U]],
) -> LazyResult[U, E]

Transform Ok value. fn can be sync or async.

map_err

map_err(
    fn: Callable[[E], F | Awaitable[F]],
) -> LazyResult[T, F]

Transform Err value. fn can be sync or async.

and_then

and_then(
    fn: Callable[
        [T], Ok[U] | Err[E] | Awaitable[Ok[U] | Err[E]]
    ],
) -> LazyResult[U, E]

Chain Result-returning function. fn can be sync or async.

or_else

or_else(
    fn: Callable[
        [E], Ok[T] | Err[F] | Awaitable[Ok[T] | Err[F]]
    ],
) -> LazyResult[T, F]

Recover from Err. fn can be sync or async.

tee

tee(fn: Callable[[T], Any]) -> LazyResult[T, E]

Side effect on Ok value. fn can be sync or async.

inspect_err

inspect_err(fn: Callable[[E], Any]) -> LazyResult[T, E]

Side effect on Err value. fn can be sync or async.

flatten

flatten() -> LazyResult[U, E]

Flatten nested LazyResult[Result[U, E], E] to LazyResult[U, E].

collect async

collect() -> Ok[T] | Err[E]

Execute the lazy chain and return the final Result.


Type Guards

is_ok

is_ok

is_ok(result: Ok[T] | Err[E]) -> TypeIs[Ok[T]]

Type guard to check if a result is Ok.

Unlike the .is_ok() method, this standalone function enables proper type narrowing in conditional branches. This is necessary because Python's type system doesn't support narrowing based on method return types.

This pattern is also used by rustedpy/result.

PARAMETER DESCRIPTION
result

The Result to check.

TYPE: Ok[T] | Err[E]

RETURNS DESCRIPTION
TypeIs[Ok[T]]

True if result is Ok, with the type narrowed to Ok[T].

Example
from unwrappy import Result, Ok, Err, is_ok

def get_value(r: Result[int, str]) -> int:
    if is_ok(r):
        return r.unwrap()  # Type checker knows r is Ok[int]
    return 0

is_err

is_err

is_err(result: Ok[T] | Err[E]) -> TypeIs[Err[E]]

Type guard to check if a result is Err.

Unlike the .is_err() method, this standalone function enables proper type narrowing in conditional branches. This is necessary because Python's type system doesn't support narrowing based on method return types.

This pattern is also used by rustedpy/result.

PARAMETER DESCRIPTION
result

The Result to check.

TYPE: Ok[T] | Err[E]

RETURNS DESCRIPTION
TypeIs[Err[E]]

True if result is Err, with the type narrowed to Err[E].

Example
from unwrappy import Result, Ok, Err, is_err

def handle_error(r: Result[int, str]) -> str:
    if is_err(r):
        return r.unwrap_err()  # Type checker knows r is Err[str]
    return "success"

Utility Functions

sequence_results

sequence_results

sequence_results(
    results: Iterable[Ok[T] | Err[E]],
) -> Ok[list[T]] | Err[E]

Collect an iterable of Results into a Result of list.

Fails fast on the first Err encountered, returning that error. If all Results are Ok, returns Ok containing a list of all values.

PARAMETER DESCRIPTION
results

Iterable of Result values to collect.

TYPE: Iterable[Ok[T] | Err[E]]

RETURNS DESCRIPTION
Ok[list[T]] | Err[E]

Ok(list) if all are Ok, otherwise the first Err.

Example
sequence_results([Ok(1), Ok(2), Ok(3)])  # Ok([1, 2, 3])
sequence_results([Ok(1), Err("fail"), Ok(3)])  # Err('fail')
sequence_results([])  # Ok([])

traverse_results

traverse_results

traverse_results(
    items: Iterable[U],
    fn: Callable[[U], Ok[T] | Err[E]],
) -> Ok[list[T]] | Err[E]

Map a function over items and collect Results.

Equivalent to sequence_results(map(fn, items)) but more efficient. Fails fast on the first Err encountered.

PARAMETER DESCRIPTION
items

Iterable of items to process.

TYPE: Iterable[U]

fn

Function returning Result for each item.

TYPE: Callable[[U], Ok[T] | Err[E]]

RETURNS DESCRIPTION
Ok[list[T]] | Err[E]

Ok(list) if all succeed, otherwise the first Err.

Example
def parse_int(s: str) -> Result[int, str]:
    try:
        return Ok(int(s))
    except ValueError:
        return Err(f"invalid: {s}")

traverse_results(["1", "2", "3"], parse_int)  # Ok([1, 2, 3])
traverse_results(["1", "x", "3"], parse_int)  # Err('invalid: x')

Exceptions

UnwrapError

UnwrapError

UnwrapError(message: str, value: object)

Bases: Exception

Raised when unwrap() is called on an Err, or unwrap_err() on an Ok.

ChainedError

ChainedError

ChainedError(error: object, context: str)

Error with context chain for tracing error propagation.

Wraps an original error with additional context about where/why the error occurred. Multiple contexts can be chained.

PARAMETER DESCRIPTION
error

The original error or a previous ChainedError.

TYPE: object

context

Description of the context where the error occurred.

TYPE: str

Example

err = ChainedError("invalid json", "parsing config") str(err) 'parsing config: invalid json' err2 = ChainedError(err, "loading user settings") str(err2) 'loading user settings: parsing config: invalid json'

root_cause

root_cause() -> object

Get the original error at the bottom of the chain.

chain

chain() -> list[str]

Get the full context chain as a list, from outermost to innermost.