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 valueErr[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 |
required |
Returns:
| Type | Description |
|---|---|
Result[U, E]
|
Result[U, E]: |
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 |
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 |
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 |
required |
Returns:
| Type | Description |
|---|---|
Result[R, E]
|
Result[R, E]: The result of the function if |
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 |
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 |
required |
Returns:
| Name | Type | Description |
|---|---|---|
T |
T
|
The contained |
Raises:
| Type | Description |
|---|---|
ResultUnwrapError
|
If the result is |
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 |
required |
Returns:
| Name | Type | Description |
|---|---|---|
E |
E
|
The contained |
Raises:
| Type | Description |
|---|---|
ResultUnwrapError
|
If the result is |
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 |
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 |
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
|
|
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
|
|
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
required |
err
|
Callable[[E], U]
|
The function to apply to the |
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 |
required |
Returns:
| Type | Description |
|---|---|
Result[R, E]
|
Result[R, E]: A new |
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 |
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 |
required |
Returns:
| Type | Description |
|---|---|
Result[T, F]
|
Result[T, F]: The original |
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 |
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 |
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))becomesSome(Ok(v))Ok(NONE)becomesNONEErr(e)becomesSome(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 |
Raises:
| Type | Description |
|---|---|
ResultUnwrapError
|
If the result is |
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 |
Raises:
| Type | Description |
|---|---|
ResultUnwrapError
|
If the result is |
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 |
required |
Returns:
| Name | Type | Description |
|---|---|---|
T |
T
|
The contained |
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 |
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 |
Example:
>>> from pyochain import Ok, Err
>>> Ok(2).unwrap_or_else(len)
2
>>> Err("foo").unwrap_or_else(len)
3