Skip to content

Checkable

Bases: Protocol


              flowchart TD
              pyochain.rs.Checkable[Checkable]

              

              click pyochain.rs.Checkable href "" "pyochain.rs.Checkable"
            

Mixin class providing conditional chaining methods based on truthiness.

This class provides methods inspired by Rust's bool type for conditional execution and wrapping in Option or Result types.

All methods evaluate the instance's truthiness to determine their behavior.

Truthiness being determined by:

  • __bool__() if defined
  • otherwise by __len__() if defined (returning False if length is 0)
  • otherwise all instances are truthy (Python's default behavior).

This can be very handy to cover the common pattern of checking if a collection is empty or not.

You can then explicitly handle each situation with Option or Result types, without breaking the fluent method chaining.

Tip

This class is compiled in Rust with Pyo3 bindings.

This means that even pure Python classes inheriting from Checkable can call these methods with builtin-like performance.

Example

Pyochain collections can efficiently check for emptiness and execute code conditionally natively.

>>> from pyochain import Seq
>>> Seq((1, 2, 3)).then(sum)
Some(6)
>>> Seq(()).then(sum)
NONE
This can also be extended to any type, not just collections.
>>> from pyochain.abc import Checkable
>>> class MyString(str, Checkable):
...     pass
>>> MyString("hello").then(lambda s: s.upper())
Some('HELLO')
>>> MyString("").then(lambda s: s.upper())
NONE
This means that you can handle complex business logic in the same way.
>>> from dataclasses import dataclass
>>> @dataclass(slots=True)
... class User(Checkable):
...     name: str
...     is_active: bool
...     age: int
...     def __bool__(self) -> bool:
...         return self.is_active and self.age >= 18
...
...     def describe(self) -> str:
...         return f"{self.name} is an active adult"
>>>
>>> alice = User("Alice", is_active=True, age=30).then(User.describe)
>>> bob = (
...     User("Bob", is_active=False, age=24)
...     .then(User.describe)
...     .ok_or("Expected an active adult user")
...     .map_err(ValueError)
... )
>>> alice
Some('Alice is an active adult')
>>> bob
Err(ValueError('Expected an active adult user'))

err_or(ok)

Wrap Self in a Result[T, Self] based on its truthiness.

This method is the inverse of ok_or.

Parameters:

Name Type Description Default
ok T

The ok value to wrap in Ok if self is falsy.

required

Returns:

Type Description
Result[T, Self]

Result[T, Self]: Ok(ok) if self is truthy, Err(self) otherwise.

Example
>>> from pyochain import Seq
>>> Seq((1, 2, 3)).err_or("should be empty")
Err(Seq(1, 2, 3))
>>> Seq(()).err_or("should be empty")
Ok('should be empty')

err_or_else(func, *args, **kwargs)

Wrap Self in a Result[Self, E] based on its truthiness.

E being the return type of func.

The function is only called if self evaluates to False.

Parameters:

Name Type Description Default
func Callable[Concatenate[Self, P], E]

A callable that returns the error value to wrap in Err.

required
*args P.args

Positional arguments to pass to the function.

()
**kwargs P.kwargs

Keyword arguments to pass to the function.

{}

Returns:

Type Description
Result[T, Self]

Result[Self, E]: Ok(self) if self is truthy, Err(f(...)) otherwise.

Example
>>> from pyochain import Seq
>>> Seq((1, 2, 3)).err_or_else(lambda s: "should be empty")
Err(Seq(1, 2, 3))
>>> Seq(()).err_or_else(lambda s: "should be empty")
Ok('should be empty')

ok_or(err)

Wrap Self in a Result[Self, E] based on its truthiness.

This method is the inverse of err_or.

Parameters:

Name Type Description Default
err E

The error value to wrap in Err if self is falsy.

required

Returns:

Type Description
Result[Self, E]

Result[Self, E]: Ok(self) if self is truthy, Err(err) otherwise.

Example
>>> from pyochain import Seq
>>> Seq((1, 2, 3)).ok_or("empty")
Ok(Seq(1, 2, 3))
>>> Seq(()).ok_or("empty")
Err('empty')

ok_or_else(func, *args, **kwargs)

Wrap Self in a Result[Self, E] based on its truthiness.

E being the return type of func.

The function is only called if self evaluates to False.

Parameters:

Name Type Description Default
func Callable[Concatenate[Self, P], E]

A callable that returns the error value to wrap in Err.

required
*args P.args

Positional arguments to pass to the function.

()
**kwargs P.kwargs

Keyword arguments to pass to the function.

{}

Returns:

Type Description
Result[Self, E]

Result[Self, E]: Ok(self) if self is truthy, Err(f(...)) otherwise.

Example
>>> from pyochain import Seq
>>> Seq((1, 2, 3)).ok_or_else(lambda s: f"empty seq")
Ok(Seq(1, 2, 3))
>>> Seq(()).ok_or_else(lambda s: f"empty seq")
Err('empty seq')

then(func, *args, **kwargs)

Wrap Self in an Option[R] based on its truthiness.

R being the return type of func.

The function is only called if Self evaluates to True (lazy evaluation).

Parameters:

Name Type Description Default
func Callable[Concatenate[Self, P], R]

A callable that returns the value to wrap in Some.

required
*args P.args

Positional arguments to pass to func.

()
**kwargs P.kwargs

Keyword arguments to pass to func.

{}

Returns:

Type Description
Option[R]

Option[R]: Some(R) if self is truthy, NONE otherwise.

Example
>>> from pyochain import Seq
>>> Seq((1, 2, 3)).then(lambda s: s.iter().sum())
Some(6)
>>> Seq(()).then(lambda s: s.iter().sum())
NONE

then_some()

Wraps Self in an Option[Self] based on its truthiness.

Returns:

Type Description
Option[Self]

Option[Self]: Some(self) if self is truthy, NONE otherwise.

Example
>>> from pyochain import Seq
>>> Seq((1, 2, 3)).then_some()
Some(Seq(1, 2, 3))
>>> Seq(()).then_some()
NONE