maybetype module

A basic implementation of a maybe/option type in Python, as well as a Result type.

class maybetype.Err(val: E)

Indicates a failed result of type E.

class maybetype.Maybe(_val: T)

Wraps a possible value of type T.

This is a base class that is subclassed by Some and NothingType, and will raise errors.MaybeInstanceError if instanced directly

and_then(func: Callable[[T], Maybe[U]]) Maybe[U]

Returns func(val) if Some, otherwise returns Nothing.

as_list() list[T]

Returns a list containing the wrapped value if Some, otherwise returns an empty list.

as_tuple() tuple[T] | tuple[()]

Returns a tuple containing the wrapped value if Some, otherwise returns an empty tuple.

attr(name: str, default: U | None = None, _typ: type[U] | None = None) Maybe

Attempts to access an attribute name in the wrapped value, returning Some wrapping the the attribute’s value if it exists, or Nothing otherwise.

Parameters:
  • name – The name of the attribute to access.

  • default – An optional default value to use if the attribute does not exist, returning Some(default) in that case.

  • typ – Specifies the generic type of the resulting Maybe. This does not affect the value’s real type at runtime; it is only used for type checkers. This is generally unnecessary if the default parameter is given, as the type will be inferred from its value.

cast(typ: type[U]) Maybe

Returns this instance casted to Maybe[typ].

static cat(vals: Iterable[Maybe[T]]) list[T]

Takes an iterable of Maybe objects and returns a list of the unwrapped values of the Some objects.

>>> vals = [maybe(5), maybe(None), maybe(10), maybe(None)]
>>> assert vals == [Some(5), Nothing, Some(10), Nothing]
>>> assert Maybe.cat(vals) == [5, 10]
filter(predicate: Callable[[T], bool]) Maybe[T]

Returns self if it is Some and predicate(val) is True, otherwise returns Nothing.

>>> assert Some(1).filter(lambda n: n > 0).unwrap() == 1
>>> assert Some(1).filter(lambda n: n > 1) is Nothing
>>> assert Nothing.filter(lambda n: n > 1) is Nothing
flatten() Maybe[T]

Returns a new Maybe[T] from a Maybe[Maybe[T]].

Only flattens one level at a time, and will raise a TypeError if called when the wrapped value is not Maybe.

Note

It’s expected that the resulting type of this method may not be correctly inferred and will return returning Maybe[Unknown]. For now, cast() can be used to specify a type for type checkers.

Raises:

TypeError – The wrapped value is not Maybe.

get(accessor: object, _typ: type[U] | None = None, *, err: bool = False, default: U | EllipsisType = Ellipsis) Maybe

Attempts to access an item by accessor on the wrapped object if it supports __getitem__.

If it does not, or if the value does not exist (list index out of range, key does not exist on a dictionary, etc.), Nothing is returned.

Parameters:
  • typ – Specifies the generic type of the resulting Maybe. No conversion is performed; this argument is only for typing purposes.

  • err – Whether to allow IndexError and KeyError to propagate from the __getitem__ call. When False (default), these errors are ignored and Nothing is returned.

  • default – Specifies an alternate value to return a Some of instead of returning Nothing.

inspect(func: Callable[[T], Any]) Self

Calls a function with the wrapped value if Some, otherwise does nothing. Returns this instance.

map(func: Callable[[T], U]) Maybe[U]

Returns Some(func(val)) if Some, otherwise Nothing.

ok_or(err: E) Result[T, E]

Converts this Maybe[T] to a Result[T, E].

Some(val) becomes Ok(val), Nothing becomes Err(err).

ok_or_else(err: Callable[[], E]) Result[T, E]

Converts this Maybe[T] to a Result[T, E].

Some(val) becomes Ok(val), Nothing becomes Err(err()).

reduce(other: Maybe[U], func: Callable[[T, U], R], *, strict: bool = False) Maybe[T] | Maybe[U] | Maybe[R]

Reduces the values of two Maybe instances to one value returned in a new Maybe using func.

If only one of self and other is Some, that instance is returned. If neither are, Nothing is returned.

>>> assert Some(1).reduce(Some(2), lambda a, b: a + b) == Some(3)
>>> assert Some(1).reduce(Nothing, lambda a, b: a + b) == Some(1)
>>> assert Nothing.reduce(Some(2), lambda a, b: a + b) == Some(2)
>>> assert Nothing.reduce(Nothing, lambda a, b: a + b) is Nothing
Parameters:

strict – If True, returns Nothing if self and other are not both Some.

replace(new_val: T) Maybe[T]

Replaces the wrapped value with new_val and returns a reference to this same instance if Some.

static sequence(vals: Iterable[Maybe[T]]) Maybe[list[T]]

Returns Nothing if any of vals is Nothing, otherwise returns Some of a list of unwrapped items of vals.

>>> assert Maybe.sequence([Some(1), Some(2), Some(3)]) == Some([1, 2, 3])
>>> assert Maybe.sequence([Some(1), Nothing, Some(3)]) is Nothing
then(func: Callable[[T], U]) U | None

Returns func called with the wrapped value if Some, otherwise returns None.

Parameters:

func – A Callable which takes a type of the possible wrapped value (T) and can return any type (U).

transpose() Result[Maybe[Any], E]

Transposes a Maybe of Result to a Result of Maybe.

Some(Ok(x)) becomes Ok(Some(x)), Some(Err(x)) becomes Err(x), Nothing becomes Ok(Nothing).

>>> assert Some(Ok(1)).transpose()  == Ok(Some(1))
>>> assert Some(Err(0)).transpose() == Err(0)
>>> assert Nothing.transpose()      == Ok(Nothing)

Note

Currently the type information of the wrapped Result can’t be known and used for the return type of this method, so it will return Result[Maybe[Any], Any]. You can use the cast() method to work around this for now.

Raises:

TypeError – The wrapped value is not Result.

unwrap(exc: str | Exception | Callable[[], Never] = 'unwrapped Nothing') T

Returns the wrapped value if Some, otherwise raises ValueError or fails according to exc.

Parameters:

exc – If a string is given, ValueError is raised with the string as its argument. If an Exception instance is given, it is raised. If a Callable is given, it is called with no arguments.

unwrap_or(other: T) T

Returns the wrapped value if Some, otherwise returns other.

unwrap_or_else(func: Callable[[], T]) T

Returns the wrapped value if Some, otherwise returns the result of calling func.

unzip() tuple[Maybe[T], Maybe[U]]

Returns (Some(a), Some(b)) if the wrapped value is a tuple of two items.

If Nothing, (Nothing, Nothing) is returned.

Raises:

TypeError – The wrapped value is not a 2-tuple.

xor(other: Maybe[T]) Maybe[T]

Returns Some if exactly one of self and other is Some, otherwise returns Nothing.

zip(other: Maybe[U]) Maybe[tuple[T, U]]

Returns Some wrapping a tuple of self and other’s values if both are Some, otherwise returns Nothing.

class maybetype.NothingType(_: None = None)

Subclass of Maybe representing no value.

class maybetype.Ok(val: T)

Indicates a successful result of type T.

class maybetype.Result(_val: T | E)

A class which wraps a value of T if the instance is of the subclass Ok, or wraps E if Err.

The Result class itself should only be using for type annotations and not instancing; use the Ok and Err constructors otherwise. ResultInitError is raised if Result() is called directly.

Ok instances are always truthy, while Err instances are always falsy.

and_then(func: Callable[[T], Result[U, E]]) Result[U, E]

Returns func called with the wrapped value if Ok, otherwise returns this instance.

cast(_t: type[U], _e: type[F]) Result

Returns a reference to this instance after casting its type as Result[t_type, e_type].

err() Maybe[E]

Returns a Some with the wrapped value if Err, otherwise returns Nothing.

flatten() Result[T, E]

Returns a new Result[T, E] from a``Result[Result[T, E], E]``.

Only flattens one level at a time, and will raise a TypeError if called when the wrapped value is not Result.

Note

It’s expected that the resulting type of this method may not be correctly inferred and will return returning Result[Unknown, Unknown]. For now, cast() can be used to specify a type for type checkers.

Raises:

TypeError – The wrapped value is not Result.

inspect(func: Callable[[T], Any]) Self

Calls a function with the wrapped value if Ok, otherwise does nothing. Returns this instance.

inspect_err(func: Callable[[E], Any]) Self

Calls a function with the wrapped value if Err, otherwise does nothing. Returns this instance.

map(func: Callable[[T], U]) Result[U, E]

Returns a new Result with func mapped onto an Ok value, leaving an Err unmodified.

map_err(func: Callable[[E], F]) Result[T, F]

Returns a new Result with func mapped onto an Err value, leaving an Ok unmodified.

map_or(default: U, func: Callable[[T], U]) U

Returns func mapped onto the wrapped value if Ok, otherwise returns default.

map_or_else(default: Callable[[E], U], func: Callable[[T], U]) U

Returns the result of calling func with the wrapped value if Ok, otherwise calls default.

ok() Maybe[E]

Returns a Some with the wrapped value if Ok, otherwise returns Nothing.

transpose() Maybe[Result[T, E]]

Transposes a Result of Maybe to a Maybe of Result.

Ok(Nothing) becomes Nothing, Ok(Some(x)) becomes Some(Ok(x)), and Err(x) becomes Some(Err(x)).

Raises:

TypeError – This is an Ok instance and the wrapped value is not Maybe.

unwrap(exc: str | type[Exception] | Callable[[E], Never] = <class 'maybetype.errors.ResultUnwrapError'>) T

Returns the wrapped value if Ok, otherwise raises an error according to exc.

Parameters:

exc – By default, ResultUnwrapError is raised with the wrapped value as the exception argument. If given a string, ResultUnwrapError is raised with the message format {msg}: {repr(val)}, where val is the wrapped Err value. If given an Exception type, that type of exception is raised with the wrapped value as the exception argument. If given a Callable, exc is called with the wrapped value as the passed argument.

unwrap_err(exc: str | type[Exception] | Callable[[E], Never] = <class 'maybetype.errors.ResultUnwrapError'>) E

Returns the wrapped value if Err, otherwise raises an error according to exc.

Parameters:

exc – By default, ResultUnwrapError is raised with the wrapped value as the exception argument. If given a string, ResultUnwrapError is raised with the message format {msg}: {repr(val)}, where val is the wrapped Ok value. If given an Exception type, that type of exception is raised with the wrapped value as the exception argument. If given a Callable, exc is called with the wrapped value as the passed argument.

unwrap_or(default: T) T

Returns the wrapped value if Ok, otherwise returns default.

unwrap_or_else(func: Callable[[E], T]) T

Returns the wrapped value if Ok, otherwise returns func called with the wrapped value.

class maybetype.Some(val: T)

Subclass of Maybe representing a present value of type T.

maybetype.maybe(val: None, predicate: Callable[[T], bool] = lambda v: ...) NothingType
maybetype.maybe(val: T | None, predicate: Callable[[T], bool] = lambda v: ...) Maybe[T]

Returns Nothing if val is None or not predicate(val), otherwise returns Some(val).

Parameters:
  • val – A value to wrap.

  • predicate – A function that must return True for predicate(val) in addition to val not being None in order for a Some to be returned; maybe(val, predicate) is then effectively shorthand for maybe(val).filter(predicate).

maybetype.maybe_exc(fn: Callable[[], T], *exc: type[Exception] | tuple[type[Exception], str | Pattern]) Maybe

Returns Nothing if fn() raises the specified error(s), otherwise returns Some with its result.

>>> assert maybe_exc(lambda: int('1'), ValueError) == Some(1)
>>> assert maybe_exc(lambda: int('one'), ValueError) == Nothing
>>> assert maybe_exc(lambda: int('one'), (ValueError, r'invalid literal for int\(\).*')) == Nothing
Parameters:
  • fn – A function to call which takes no arguments.

  • exc – One or more either exception types or a tuple of an exception type and regex pattern to match the raised exception’s message against, where if any of the given exceptions are raised (and if a pattern is given, str(e) where e is the raised exception must match it), Nothing is returned instead of propagating the exception. If any exceptions not listed are raised or a pattern is given for an exception and it does not match, the exception is raised normally.