Skip to content

ResultType

Bases: Pipeable, Protocol

This is the base Protocol defined for returning and propagating errors.

Result[T, E] is a the type union of the two possibles variants of the Protocol:

  • Ok[T, E], representing success and containing a value
  • Err[T, E], representing error and containing an error value

Functions return Result whenever errors are expected and recoverable.

For example, I/O or web requests can fail for many reasons, and using Result forces the caller to handle the possibility of failure.

This is directly inspired by Rust's Result type, and provides similar functionality for error handling in Python.

Note

Due to Python typing nature, we need to separate both the Protocol definition (ResultType), and the type union (Result), which is the public facing type that users will interact with.

This separation allows type checkers to flag exhaustive handling of both variants, in match statements notably, while avoiding duplicated docstrings and method definitions.

Warning

Do not try to instanciate this class, as it don't exist at runtime.

Result does in fact exist in the namespace, but it's an empty Rust struct,

and your type checker will warn you in any case because a type Result = ... is not supposed to be instanciable.

Example:

>>> from pyochain import Err, Ok, Result
>>>
>>> def is_positive(x: int) -> Result[str, ValueError]:
...     if x > 0:
...         return Ok(f"Value is {x}")
...     msg = f"{x} is not positive"
...     return Err(ValueError(msg))
>>>
>>> def handle_variant(x: Result[str, ValueError]) -> str:
...     match x:
...         case Ok(value):
...             return f"Success: {value}"
...         case Err(error):
...             return f"Failure: {error}"
>>>
>>> is_positive(5).map(lambda s: s.upper()).into(handle_variant)
'Success: VALUE IS 5'
>>> is_positive(-3).map(lambda s: s.upper()).into(handle_variant)
'Failure: -3 is not positive'

and_(res)

Returns res if the result is Ok, otherwise returns the Err value.

This is often used for chaining operations that might fail.

Parameters:

Name Type Description Default
res Result[U, E]

The result to return if the original result is Ok.

required

Returns:

Type Description
Result[U, E]

Result[U, E]: res if the original result is Ok, otherwise the original Err.

Example:

>>> from pyochain import Ok, Err
>>> x = Ok(2)
>>> y = Err("late error")
>>> x.and_(y)
Err('late error')
>>> x = Err("early error")
>>> y = Ok("foo")
>>> x.and_(y)
Err('early error')

>>> x = Err("not a 2")
>>> y = Err("late error")
>>> x.and_(y)
Err('not a 2')

>>> x = Ok(2)
>>> y = Ok("different result type")
>>> x.and_(y)
Ok('different result type')

and_then(fn, *args, **kwargs)

Calls a function if the result is Ok, otherwise returns the Err value.

This is often used for chaining operations that might fail.

Parameters:

Name Type Description Default
fn Callable[Concatenate[T, P], Result[R, E]]

The function to call with the Ok value.

required
*args P.args

Additional positional arguments to pass to fn.

()
**kwargs P.kwargs

Additional keyword arguments to pass to fn.

{}

Returns:

Type Description
Result[R, E]

Result[R, E]: The result of the function if Ok, otherwise the original Err.

Example:

>>> from pyochain import Ok, Err, Result
>>> def to_str(x: int) -> Result[str, str]:
...     return Ok(str(x))
>>> Ok(2).and_then(to_str)
Ok('2')
>>> Err("error").and_then(to_str)
Err('error')

and_then_star(func)

and_then_star(
    func: Callable[[Any], Result[R, E]],
) -> Result[R, E]
and_then_star(
    func: Callable[[T1, T2], Result[R, E]],
) -> Result[R, E]
and_then_star(
    func: Callable[[T1, T2, T3], Result[R, E]],
) -> Result[R, E]
and_then_star(
    func: Callable[[T1, T2, T3, T4], Result[R, E]],
) -> Result[R, E]
and_then_star(
    func: Callable[[T1, T2, T3, T4, T5], Result[R, E]],
) -> Result[R, E]
and_then_star(
    func: Callable[[T1, T2, T3, T4, T5, T6], Result[R, E]],
) -> Result[R, E]
and_then_star(
    func: Callable[
        [T1, T2, T3, T4, T5, T6, T7], Result[R, E]
    ],
) -> Result[R, E]
and_then_star(
    func: Callable[
        [T1, T2, T3, T4, T5, T6, T7, T8], Result[R, E]
    ],
) -> Result[R, E]
and_then_star(
    func: Callable[
        [T1, T2, T3, T4, T5, T6, T7, T8, T9], Result[R, E]
    ],
) -> Result[R, E]
and_then_star(
    func: Callable[
        [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10],
        Result[R, E],
    ],
) -> Result[R, E]

Calls a function if the result is Ok, unpacking the tuple.

Done by applying a function to a contained Ok value (which is expected to be a tuple).

Parameters:

Name Type Description Default
func Callable[..., Result[R, E]]

The function to call with the unpacked Ok value.

required

Returns:

Type Description
Result[R, E]

Result[R, E]: The result of the function if Ok, otherwise the original Err.

Example:

>>> from pyochain import Ok, Err, Result
>>> def to_str(x: int, y: int) -> Result[str, str]:
...     return Ok(f"{x},{y}")
>>> Ok((2, 3)).and_then_star(to_str)
Ok('2,3')
>>> Err("error").and_then_star(to_str)
Err('error')

err()

Converts from Result[T, E] to Option[E].

Err(e) becomes Some(e), and Ok(v) becomes None.

Returns:

Type Description
Option[E]

Option[E]: An Option containing the Err value, or None if the result is Ok.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).err()
NONE
>>> Err("error").err()
Some('error')

expect(msg)

Returns the contained Ok value.

Raises an exception with a provided message if the value is an Err.

Parameters:

Name Type Description Default
msg str

The message to include in the exception if the result is Err.

required

Returns:

Name Type Description
T T

The contained Ok value.

Raises:

Type Description
ResultUnwrapError

If the result is Err.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).expect("No error")
2
>>> Err("emergency failure").expect("Testing expect")
Traceback (most recent call last):
...
ResultUnwrapError: Testing expect: 'emergency failure'

expect_err(msg)

Returns the contained Err value.

Raises an exception with a provided message if the value is an Ok.

Parameters:

Name Type Description Default
msg str

The message to include in the exception if the result is Ok.

required

Returns:

Name Type Description
E E

The contained Err value.

Raises:

Type Description
ResultUnwrapError

If the result is Ok.

Example:

>>> from pyochain import Err, Ok
>>> Err("emergency failure").expect_err("Testing expect_err")
'emergency failure'
>>> Ok(10).expect_err("Testing expect_err")
Traceback (most recent call last):
...
ResultUnwrapError: Testing expect_err: expected Err, got Ok(10)

flatten()

Flattens a nested Result.

Converts from Result[Result[T, E], E] to Result[T, E].

Equivalent to calling Result.and_then(lambda x: x), but more convenient when there's no need to process the inner Ok value.

Returns:

Type Description
Result[T1, E1]

Result[T, E]: The flattened result.

Example:

>>> from pyochain import Result, Ok, Err
>>> nested_ok: Result[Result[int, str], str] = Ok(Ok(2))
>>> nested_ok.flatten()
Ok(2)
>>> nested_err: Result[Result[int, str], str] = Ok(Err("inner error"))
>>> nested_err.flatten()
Err('inner error')

inspect(fn, *args, **kwargs)

Applies a function to the contained Ok value, returning the original Result.

This is primarily useful for debugging or logging, allowing side effects to be performed on the Ok value without changing the result.

Parameters:

Name Type Description Default
fn Callable[Concatenate[T, P], object]

Function to apply to the Ok value.

required
*args P.args

Additional positional arguments to pass to fn.

()
**kwargs P.kwargs

Additional keyword arguments to pass to fn.

{}

Returns:

Type Description
Result[T, E]

Result[T, E]: The original result, unchanged.

Example:

>>> from pyochain import Ok, Vec
>>> seen = Vec[int](())
>>> Ok(2).inspect(lambda x: seen.append(x))
Ok(2)
>>> seen
Vec(2)

inspect_err(fn, *args, **kwargs)

Applies a function to the contained Err value, returning the original Result.

This mirrors :meth:inspect but operates on the error value. It is useful for logging or debugging error paths while keeping the Result unchanged.

Parameters:

Name Type Description Default
fn Callable[Concatenate[E, P], object]

Function to apply to the Err value.

required
*args P.args

Additional positional arguments to pass to fn.

()
**kwargs P.kwargs

Additional keyword arguments to pass to fn.

{}

Returns:

Type Description
Result[T, E]

Result[T, E]: The original result, unchanged.

Example:

>>> from pyochain import Err, Vec
>>> seen = Vec[str](())
>>> Err("oops").inspect_err(lambda e: seen.append(e))
Err('oops')
>>> seen
Vec('oops')

is_err()

Returns True if the result is Err.

Returns:

Name Type Description
bool bool

True if the result is an Err variant, False otherwise.

Example:

>>> from pyochain import Ok, Err, Result
>>> x: Result[int, str] = Ok(2)
>>> x.is_err()
False
>>> y: Result[int, str] = Err("Some error message")
>>> y.is_err()
True

is_err_and(pred, *args, **kwargs)

Returns True if the result is Err and the predicate is true for the error value.

Parameters:

Name Type Description Default
pred Callable[Concatenate[E, P], bool]

Predicate function to apply to the Err value.

required
*args P.args

Additional positional arguments to pass to pred.

()
**kwargs P.kwargs

Additional keyword arguments to pass to pred.

{}

Returns:

Name Type Description
bool bool

True if Err and pred(error) is true, False otherwise.

Example:

>>> from pyochain import Err, Ok
>>> Err("foo").is_err_and(lambda e: len(e) == 3)
True
>>> Err("bar").is_err_and(lambda e: e == "baz")
False
>>> Ok(2).is_err_and(lambda e: True)
False

is_ok()

Returns True if the result is Ok.

Returns:

Name Type Description
bool bool

True if the result is an Ok variant, False otherwise.

Example:

>>> from pyochain import Ok, Err, Result
>>> x: Result[int, str] = Ok(2)
>>> x.is_ok()
True
>>> y: Result[int, str] = Err("Some error message")
>>> y.is_ok()
False

is_ok_and(pred, *args, **kwargs)

Returns True if the result is Ok and the predicate is true for the contained value.

Parameters:

Name Type Description Default
pred Callable[Concatenate[T, P], bool]

Predicate function to apply to the Ok value.

required
*args P.args

Additional positional arguments to pass to pred.

()
**kwargs P.kwargs

Additional keyword arguments to pass to pred.

{}

Returns:

Name Type Description
bool bool

True if Ok and pred(value) is true, False otherwise.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).is_ok_and(lambda x: x > 1)
True
>>> Ok(0).is_ok_and(lambda x: x > 1)
False
>>> Err("err").is_ok_and(lambda x: x > 1)
False

iter()

Returns a Iter[T] over the possibly contained value.

The iterator yields one value if the result is Ok, otherwise none.

Returns:

Type Description
Iter[T]

Iter[T]: An iterator over the Ok value, or empty if Err.

Example:

>>> from pyochain import Ok, Err
>>> Ok(7).iter().next()
Some(7)
>>> Err("nothing!").iter().next()
NONE

map(fn, *args, **kwargs)

Maps a Result[T, E] to Result[U, E].

Done by applying a function to a contained Ok value, leaving an Err value untouched.

Parameters:

Name Type Description Default
fn Callable[Concatenate[T, P], R]

The function to apply to the Ok value.

required
*args P.args

Additional positional arguments to pass to fn.

()
**kwargs P.kwargs

Additional keyword arguments to pass to fn.

{}

Returns:

Type Description
Result[R, E]

Result[R, E]: A new Result with the mapped value if Ok, otherwise the original Err.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).map(lambda x: x * 2)
Ok(4)
>>> Err("error").map(lambda x: x * 2)
Err('error')

map_err(fn, *args, **kwargs)

Maps a Result[T, E] to Result[T, R].

Done by applying a function to a contained Err value, leaving an Ok value untouched.

Parameters:

Name Type Description Default
fn Callable[Concatenate[E, P], R]

The function to apply to the Err value.

required
*args P.args

Additional positional arguments to pass to fn.

()
**kwargs P.kwargs

Additional keyword arguments to pass to fn.

{}

Returns:

Type Description
Result[T, R]

Result[T, R]: A new Result with the mapped error if Err, otherwise the original Ok.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).map_err(len)
Ok(2)
>>> Err("foo").map_err(len)
Err(3)

map_or(default, f, *args, **kwargs)

Applies a function to the Ok value if present, otherwise returns the default value.

Parameters:

Name Type Description Default
default R

Value to return if the result is Err.

required
f Callable[Concatenate[T, P], R]

Function to apply to the Ok value.

required
*args P.args

Additional positional arguments to pass to f.

()
**kwargs P.kwargs

Additional keyword arguments to pass to f.

{}

Returns:

Name Type Description
R R

Result of f(value) if Ok, otherwise default.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).map_or(10, lambda x: x * 2)
4
>>> Err("err").map_or(10, lambda x: x * 2)
10

map_or_else(ok, err)

Maps a Result[T, E] to U.

Done by applying a fallback function to a contained Err value, or a default function to a contained Ok value.

Parameters:

Name Type Description Default
ok Callable[[T], U]

The function to apply to the Ok value.

required
err Callable[[E], U]

The function to apply to the Err value.

required

Returns:

Name Type Description
U U

The result of applying the appropriate function.

Example:

>>> from pyochain import Ok, Err
>>> k = 21
>>> Ok("foo").map_or_else(len, lambda e: k * 2)
3
>>> Err("bar").map_or_else(len, lambda e: k * 2)
42

map_star(func)

map_star(func: Callable[[Any], R]) -> Result[R, E]
map_star(func: Callable[[T1, T2], R]) -> Result[R, E]
map_star(func: Callable[[T1, T2, T3], R]) -> Result[R, E]
map_star(
    func: Callable[[T1, T2, T3, T4], R],
) -> Result[R, E]
map_star(
    func: Callable[[T1, T2, T3, T4, T5], R],
) -> Result[R, E]
map_star(
    func: Callable[[T1, T2, T3, T4, T5, T6], R],
) -> Result[R, E]
map_star(
    func: Callable[[T1, T2, T3, T4, T5, T6, T7], R],
) -> Result[R, E]
map_star(
    func: Callable[[T1, T2, T3, T4, T5, T6, T7, T8], R],
) -> Result[R, E]
map_star(
    func: Callable[[T1, T2, T3, T4, T5, T6, T7, T8, T9], R],
) -> Result[R, E]
map_star(
    func: Callable[
        [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], R
    ],
) -> Result[R, E]

Maps a Result[tuple, E] to Result[R, E] by unpacking the tuple.

Done by applying a function to a contained Ok value (which is expected to be a tuple).

Parameters:

Name Type Description Default
func Callable[..., R]

The function to apply to the unpacked Ok value.

required

Returns:

Type Description
Result[R, E]

Result[R, E]: A new Result with the mapped value if Ok, otherwise the original Err.

Example:

>>> from pyochain import Ok, Err
>>> Ok((2, 3)).map_star(lambda x, y: x + y)
Ok(5)
>>> Err("error").map_star(lambda x, y: x + y)
Err('error')

ok()

Converts from Result[T, E] to Option[T].

Ok(v) becomes Some(v), and Err(e) becomes None.

Returns:

Type Description
Option[T]

Option[T]: An Option containing the Ok value, or None if the result is Err.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).ok()
Some(2)
>>> Err("error").ok()
NONE

or_(res)

Returns res if the result is Err, otherwise returns the Ok value of self.

Parameters:

Name Type Description Default
res Result[T, F]

The result to return if the original result is Err.

required

Returns:

Type Description
Result[T, F]

Result[T, F]: The original Ok value, or res if the original result is Err.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).or_(Err("late error"))
Ok(2)
>>> Err("early error").or_(Ok(2))
Ok(2)
>>> Err("not a 2").or_(Err("late error"))
Err('late error')
>>> Ok(2).or_(Ok(100))
Ok(2)

or_else(fn, *args, **kwargs)

Calls a function if the result is Err, otherwise returns the Ok value.

This is often used for handling errors by trying an alternative operation.

Parameters:

Name Type Description Default
fn Callable[Concatenate[E, P], Result[T, E]]

The function to call with the Err value.

required
*args P.args

Additional positional arguments to pass to fn.

()
**kwargs P.kwargs

Additional keyword arguments to pass to fn.

{}

Returns:

Type Description
Result[T, E]

Result[T, E]: The original Ok value, or the result of the function if Err.

Example:

>>> from pyochain import Ok, Err, Result
>>> def fallback(e: str) -> Result[int, str]:
...     return Ok(len(e))
>>> Ok(2).or_else(fallback)
Ok(2)
>>> Err("foo").or_else(fallback)
Ok(3)

swap()

Swaps the Ok and Err variants.

Converts an Ok[T] into an Err[T] and an Err[E] into an Ok[E].

Returns:

Type Description
Result[E, T]

Result[E, T]: The swapped result.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).swap()
Err(2)
>>> Err("error").swap()
Ok('error')

transpose()

Transposes a Result containing an Option into an Option containing a Result.

Can only be called if the inner type is Option[T, E].

The mapping is as follows:

  • Ok(Some(v)) becomes Some(Ok(v))
  • Ok(NONE) becomes NONE
  • Err(e) becomes Some(Err(e))

Returns:

Type Description
Option[Result[T, E]]

Option[Result[T, E]]: Option containing a Result or NONE.

Example:

>>> from pyochain import Ok, Err, Some, NONE
>>> Ok(Some(2)).transpose()
Some(Ok(2))
>>> Ok(NONE).transpose()
NONE
>>> Err("err").transpose()
Some(Err('err'))

unwrap()

Returns the contained Ok value.

Returns:

Name Type Description
T T

The contained Ok value.

Raises:

Type Description
ResultUnwrapError

If the result is Err.

Example:

>>> from pyochain import Ok
>>> Ok(2).unwrap()
2
>>> from pyochain import Err
>>> Err("emergency failure").unwrap()
Traceback (most recent call last):
...
ResultUnwrapError: called `unwrap` on an `Err`: 'emergency failure'

unwrap_err()

Returns the contained Err value.

Returns:

Name Type Description
E E

The contained Err value.

Raises:

Type Description
ResultUnwrapError

If the result is Ok.

Example:

>>> from pyochain import Err
>>> Err("emergency failure").unwrap_err()
'emergency failure'
>>> from pyochain import Ok
>>> Ok(2).unwrap_err()
Traceback (most recent call last):
...
ResultUnwrapError: called `unwrap_err` on Ok

unwrap_or(default)

Returns the contained Ok value or a provided default.

Parameters:

Name Type Description Default
default T

The value to return if the result is Err.

required

Returns:

Name Type Description
T T

The contained Ok value or the provided default.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).unwrap_or(10)
2
>>> Err("error").unwrap_or(10)
10

unwrap_or_else(fn, *args, **kwargs)

Returns the contained Ok value or computes it from a function.

Parameters:

Name Type Description Default
fn Callable[Concatenate[E, P], T]

A function that takes the Err value and returns a default value.

required
*args P.args

Additional positional arguments to pass to fn.

()
**kwargs P.kwargs

Additional keyword arguments to pass to fn.

{}

Returns:

Name Type Description
T T

The contained Ok value or the result of the function.

Example:

>>> from pyochain import Ok, Err
>>> Ok(2).unwrap_or_else(len)
2
>>> Err("foo").unwrap_or_else(len)
3