danom package¶
Module contents¶
- class danom.AsyncStream(seq: tuple, ops: tuple = ())¶
Bases:
_BaseAsyncStream,GenericA stream that applies async functions to its values.
Version changes¶
0.16.0: AddedAsyncStream- async collect(*, workers: int = 4, use_threads: bool = False) tuple[U, ...]¶
Materialise the
AsyncStreaminto a tuple.values = await stream.collect()
- filter(fn: ~collections.abc.Callable[[~P], ~collections.abc.Awaitable[bool]], *args: ~typing.~P, **kwargs: ~typing.~P) AsyncStream[T]¶
Filter the
AsyncStreamwith an async predicate.await stream.filter(is_even).collect()
- async fold(initial: T, fn: Callable[[T, U], T], *, workers: int = 1, use_threads: bool = False) T¶
Reduce the collected values into one value.
total = await stream.fold(0, add)
- classmethod from_iterable(it: Iterable) Self¶
Create an
AsyncStreamfrom an iterable.from danom import AsyncStream stream = AsyncStream.from_iterable([1, 2, 3])
- map(fn: ~collections.abc.Callable[[~P], ~collections.abc.Awaitable[~danom._stream._base.U]], *args: ~typing.~P, **kwargs: ~typing.~P) AsyncStream[T]¶
Map an async function to the values in the
AsyncStream.await stream.map(add_one).collect()
- async partition(fn: Callable[[P], Awaitable[bool]], *, workers: int = 1, use_threads: bool = False) tuple[AsyncStream[T], AsyncStream[U]]¶
Split the
AsyncStreaminto values accepted and rejected by a predicate.accepted, rejected = await stream.partition(is_valid)
- async sequence(*, workers: int = 1, use_threads: bool = False) Result[Self, E] | Either[Self, E]¶
Convert a stream of
ResultorEithervalues into one monad of stream.result = await stream.sequence()
- tap(fn: ~collections.abc.Callable[[~P], ~collections.abc.Awaitable[None]], *args: ~typing.~P, **kwargs: ~typing.~P) AsyncStream[T]¶
Apply an async function to a copy of each value.
The original values remain in the
AsyncStream.await stream.tap(log_value).collect()
- class danom.Either(inner: Any = None)¶
Bases:
ABC,GenericEithermonad. Consists ofRightandLeftfor successful and failed operations respectively. Each monad is a frozen instance to prevent further mutation.- abstractmethod and_then(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.Either[~danom._monads._either.U_co, ~danom._monads._either.E_co]], *args: ~typing.~P, **kwargs: ~typing.~P) Either[U_co, E_co]¶
Pipe another function that returns a monad. For
Leftwill return original inner.
- static either_is_ok(result: Either[T_co, E_co]) bool¶
Check whether the monad is ok. Allows for
filterorpartitionin aStreamwithout needing a lambda or custom function.
- static either_unwrap(result: Either[T_co, E_co]) T_co¶
Unwrap the Right or
Leftmonad to get the inner value.
- flatten() Either[T_co, E_co]¶
Flatten the monad. Will return the first
Leftor the lowestRightinstance.Papertrail examples:
>>> Right(inner=Right(inner=None)).flatten() == Right(inner=None) True
>>> Right(inner=Left(inner=None)).flatten() == Left(inner=None) True
>>> Left(inner=Right(inner=None)).flatten() == Right(inner=None) True
>>> Left(inner=Left(inner=None)).flatten() == Left(inner=None) True
- inner: Any¶
- abstractmethod is_ok() bool¶
Returns
Trueif the result type isRight. ReturnsFalseif the result type isLeft.Papertrail examples:
>>> Right(inner=None).is_ok() == True True
>>> Left(inner=None).is_ok() == False True
- abstractmethod map(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.U_co], *args: ~typing.~P, **kwargs: ~typing.~P) Either[U_co, E_co]¶
Pipe a pure function and wrap the return value with
Right. Given anLeftwill returnself.Papertrail examples:
>>> Right(inner=0).map(add_one) == Right(inner=1) True
>>> Left(inner=None).map(add_one) == Left(inner=None) True
- abstractmethod map_err(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.U_co], *args: ~typing.~P, **kwargs: ~typing.~P) Either[U_co, E_co]¶
Pipe a pure function and wrap the return value with
Left. Given anRightwill returnself.Papertrail examples:
>>> Right(inner=0).map_err(add_one) == Right(inner=0) True
>>> Left(inner=0).map_err(add_one) == Left(inner=1) True
- abstractmethod or_else(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.Either[~danom._monads._either.U_co, ~danom._monads._either.E_co]], *args: ~typing.~P, **kwargs: ~typing.~P) Either[U_co, E_co]¶
Pipe a function that returns a monad to recover from an
Left. ForRightwill return originalEither.
- abstractmethod unwrap() T_co¶
Unwrap the Right or
Leftmonad to get the inner value.
- class danom.Err(error: E = None, input_args: tuple[()] | SafeArgs | SafeMethodArgs = (), traceback: str = '')¶
Bases:
Result[Never,E],Generic- and_(res: Result[U, F]) Result[U, F]¶
Papertrail examples:
If you call
and_on anOkwith anErras the arg then theErrtakes precedence over theOk.>>> Ok(inner=2).and_(Err(error="late error")) == Err(error="late error") True
If you call
and_on anErrwith anOkas the arg then theErrstill takes precedence over theOk.>>> Err(error="early error").and_(Ok(inner="foo")) == Err(error="early error") True
If you call
and_on anErrwith anErras the arg then the firstErris returned and the second is discarded.>>> Err(error="not a 2").and_(Err(error="late error")) == Err(error="not a 2") True
Whereas, calling
and_on anOkwith anotherOkas the arg then the firstOkis discarded and the second is returned.>>> Ok(inner=2).and_(Ok(inner="different result type")) == Ok(inner="different result type") True
- and_then(fn: Callable[Concatenate[Never, P], Result[U, F]], *args: P.args, **kwargs: P.kwargs) Result[U, F]¶
Papertrail examples:
An
Okpassed toand_thenreturns theOkproduced by the function.>>> Ok(inner=2).and_then(must_be_less_than_10) == Ok(inner=2) True
When the function passed to
and_thenproduces anErr, thatErrbecomes the result.>>> Ok(inner=20).and_then(must_be_less_than_10) == Err(error="too high") True
An existing
Errpasses throughand_thenunchanged, without calling the function.>>> Err(error="not a number").and_then(must_be_less_than_10) == Err(error="not a number") True
- err() Option[E]¶
Papertrail examples:
An
Okhas no error, soerrreturnsNull.>>> Ok(inner=2).err() == Null() True
If you call
erron anErrthenSomewith the wrapped error is returned.>>> Err(error="Nothing here").err() == Some(inner="Nothing here") True
- error: E¶
- expect(msg: str) Never¶
Papertrail examples:
expectextracts the value from anOk.>>> Ok(inner=2).expect("must be positive") == 2 True
- expect_err(msg: str) E¶
Papertrail examples:
expect_errextracts the error from anErr.>>> Err(error=2).expect_err("must be err") == 2 True
- flatten() Result[Never, E]¶
Papertrail examples:
If you call
flattenon three nestedOkvalues then two nestedOkvalues are returned. Only the outer monad is removed>>> Ok(inner=Ok(inner=Ok(inner=2))).flatten() == Ok(inner=Ok(inner=2)) True
This is made obvious calling
flattenon a doubly wrapped value returning just the inner monad.>>> Ok(inner=Ok(inner=2)).flatten() == Ok(inner=2) True
Calling
flattenif the inner is not a monad of the same type is a no-op.>>> Ok(inner=2).flatten() == Ok(inner=2) True
An
Errpasses throughflattenunchanged.>>> Err(error=None).flatten() == Err(error=None) True
- input_args: tuple[()] | SafeArgs | SafeMethodArgs¶
- inspect(fn: Callable[[Never], None]) Result[Never, E]¶
Papertrail examples:
If you call
inspecton anOkthen the originalOkis returned after the function is called, this is used for logging or side outputs that shouldn’t disrupt the existing flow.>>> Ok(inner=[1]).inspect(append_to_list) == Ok(inner=[1]) True
If you call
inspecton anErrthen theErris returned and the function is not called.>>> Err(error="un-appendable").inspect(append_to_list) == Err(error="un-appendable") True
- inspect_err(fn: Callable[[E], None]) Result[Never, E]¶
Papertrail examples:
If you call
inspect_erron anErrthen the originalErris returned after the function is called, it’s essentially the inverse ofinspect.>>> Err(error=[1]).inspect_err(append_to_list) == Err(error=[1]) True
Similarly to calling
inspecton anErr, if you callinspect_erron anOkthen theOkis returned and the function is not called.>>> Ok(inner="un-appendable").inspect_err(append_to_list) == Ok(inner="un-appendable") True
- is_err() bool¶
Papertrail examples:
is_errreportsFalsefor anOk.>>> Ok(inner=2).is_err() == False True
For an
Err,is_errreportsTrue.>>> Err(error=2).is_err() == True True
- is_err_and(fn: Callable[[E], bool]) bool¶
Papertrail examples:
is_err_andrequires both the monad to be anErrand the returned value of the passed in callable to beTrue, for example, if you calledis_err_andwith a function that checks for evenness on anErr(1)then the result isFalse.>>> Err(error=1).is_err_and(is_even) == False True
Therefore, if you call
is_err_andon anErrwith a function that returnsTruethenTrueis returned.>>> Err(error=2).is_err_and(is_even) == True True
Whereas, if you call
is_err_andon anOkwith a function thenFalseis returned and the function is not called.>>> Ok(inner=2).is_err_and(is_even) == False True
- is_ok() bool¶
Papertrail examples:
is_okreportsTruefor anOk.>>> Ok(inner=2).is_ok() == True True
For an
Err,is_okreportsFalse.>>> Err(error=2).is_ok() == False True
- is_ok_and(fn: Callable[[Never], bool]) bool¶
Papertrail examples:
When the predicate rejects an
Ok,is_ok_andreportsFalse.>>> Ok(inner=1).is_ok_and(is_even) == False True
When the predicate accepts an
Ok,is_ok_andreportsTrue.>>> Ok(inner=2).is_ok_and(is_even) == True True
An
Errmakesis_ok_andreportFalsewithout calling the predicate.>>> Err(error=2).is_ok_and(is_even) == False True
- map(fn: Callable[Concatenate[Never, P], U], *args: P.args, **kwargs: P.kwargs) Result[U, E]¶
Papertrail examples:
Mapping an
Okapplies the function and wraps its result in a newOk.>>> Ok(inner=1).map(add_one) == Ok(inner=2) True
Mapping an
Errleaves it unchanged and skips the function.>>> Err(error=1).map(add_one) == Err(error=1) True
- map_err(fn: Callable[Concatenate[E, P], F], *args: P.args, **kwargs: P.kwargs) Result[Never, F]¶
Papertrail examples:
Mapping an
Errapplies the function and wraps its result in a newErr.>>> Err(error=1).map_err(add_one) == Err(error=2) True
Mapping an
Okleaves it unchanged and skips the function.>>> Ok(inner=1).map_err(add_one) == Ok(inner=1) True
- map_or(default: U, fn: Callable[Concatenate[Never, P], U], *args: P.args, **kwargs: P.kwargs) U¶
Papertrail examples:
For an
Ok,map_oruses the function result instead of the default.>>> Ok(inner="foo").map_or(42, len) == 3 True
For an
Err,map_orreturns the supplied default.>>> Err(error=None).map_or(42, len) == 42 True
- map_or_else(default: Callable[P, U], fn: Callable[Concatenate[Never, P], U], *args: P.args, **kwargs: P.kwargs) U¶
Papertrail examples:
An
Okmakesmap_or_elseuse the mapping function.>>> Ok(inner="foo").map_or_else(get_42, len) == 3 True
An
Errmakesmap_or_elseuse the default function.>>> Err(error=None).map_or_else(get_42, len) == 42 True
- ok() Option[Never]¶
Papertrail examples:
An
Okconverts toSomethroughok.>>> Ok(inner=2).ok() == Some(inner=2) True
An
Errconverts toNullthroughok.>>> Err(error=2).ok() == Null() True
- or_(res: Result[Never, F]) Result[Never, F]¶
Papertrail examples:
An
Okkeeps its value whenor_receives anErr.>>> Ok(inner=2).or_(Err(error="foo")) == Ok(inner=2) True
An
Errgives way to anOkpassed toor_.>>> Err(error="foo").or_(Ok(inner=100)) == Ok(inner=100) True
When both values are
Ok,or_keeps the first one.>>> Ok(inner=2).or_(Ok(inner=100)) == Ok(inner=2) True
When both values are
Err,or_keeps the first error.>>> Err(error="foo").or_(Err(error="foo")) == Err(error="foo") True
- or_else(fn: Callable[Concatenate[E, P], F], *args: P.args, **kwargs: P.kwargs) Result[Never, F]¶
Papertrail examples:
An
Okpasses throughor_elsewithout calling the function.>>> Ok(inner="barbarians").or_else(get_ok_vikings) == Ok(inner="barbarians") True
For an
Err,or_elsereturns theOkproduced by the function.>>> Err(error="foo").or_else(get_ok_vikings) == Ok(inner="vikings") True
If the fallback also produces an
Err,or_elsekeeps the original error.>>> Err(error="foo").or_else(Err) == Err(error="foo") True
- traceback: str¶
- transpose() Option[Result[Never, E]]¶
Papertrail examples:
Transposing
Ok(Some(value))producesSome(Ok(value)).>>> Ok(inner=Some(inner=5)).transpose() == Some(inner=Ok(inner=5)) True
Transposing
Ok(Null())producesNull.>>> Ok(inner=Null()).transpose() == Null() True
Transposing an
Errwraps it inSome.>>> Err(error=None).transpose() == Some(inner=Err(error=None)) True
- unwrap() Never¶
Papertrail examples:
unwrapextracts the value from anOk.>>> Ok(inner=2).unwrap() == 2 True
- unwrap_err() E¶
Papertrail examples:
unwrap_errextracts the error from anErr.>>> Err(error="failed").unwrap_err() == "failed" True
- unwrap_or(default: U) U¶
Papertrail examples:
With an
Ok,unwrap_orreturns the value and ignores the default.>>> Ok(inner="car").unwrap_or("bike") == "car" True
With an
Err,unwrap_orreturns the default.>>> Err(error=None).unwrap_or("bike") == "bike" True
- unwrap_or_else(fn: Callable[[E], U]) U¶
Papertrail examples:
An
Okmakesunwrap_or_elsereturn its value without calling the function.>>> Ok(inner=4).unwrap_or_else(get_42) == 4 True
An
Errmakesunwrap_or_elsereturn the function result.>>> Err(error=None).unwrap_or_else(get_42) == 42 True
- class danom.Left(inner: Any = None)¶
Bases:
Either[Never,E_co]- and_then(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.Either[~danom._monads._either.U_co, ~danom._monads._either.E_co]], *args: ~typing.~P, **kwargs: ~typing.~P) Self¶
Pipe another function that returns a monad. For
Leftwill return original inner.
- is_ok() Literal[False]¶
Papertrail examples:
>>> Right(inner=None).is_ok() == True True
>>> Left(inner=None).is_ok() == False True
- map(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.U_co], *args: ~typing.~P, **kwargs: ~typing.~P) Self¶
Papertrail examples:
>>> Right(inner=0).map(add_one) == Right(inner=1) True
>>> Left(inner=None).map(add_one) == Left(inner=None) True
- map_err(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.U_co], *args: ~typing.~P, **kwargs: ~typing.~P) Left[F_co]¶
Papertrail examples:
>>> Right(inner=0).map_err(add_one) == Right(inner=0) True
>>> Left(inner=0).map_err(add_one) == Left(inner=1) True
- or_else(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.Either[~danom._monads._either.U_co, ~danom._monads._either.E_co]], *args: ~typing.~P, **kwargs: ~typing.~P) Either[U_co, E_co]¶
Pipe a function that returns a monad to recover from an
Left. ForRightwill return originalEither.
- unwrap() T_co¶
Unwrap the Right or
Leftmonad to get the inner value.
- class danom.Null¶
Bases:
Option,Generic- and_(opt_b: Option[T]) Option[T]¶
Papertrail examples:
A
Somecombined withNullthroughand_producesNull.>>> Some(inner=2).and_(Null()) == Null() True
A
Nullcombined with anSomethroughand_remainsNull.>>> Null().and_(Some(inner="foo")) == Null() True
When both options contain values,
and_keeps the secondSome.>>> Some(inner=2).and_(Some(inner="foo")) == Some(inner="foo") True
Combining two
Nullvalues withand_producesNull.>>> Null().and_(Null()) == Null() True
- and_then(fn: Callable[[T], Option[U]]) Option[U]¶
Papertrail examples:
A successful function passed to
and_thenreturns itsSomeresult.>>> Some(inner=2).and_then(must_be_less_than_10) == Some(inner=2) True
When the function returns
Null,and_thenpasses thatNullthrough.>>> Some(inner=20).and_then(must_be_less_than_10) == Null() True
An existing
Nullskips the function passed toand_then.>>> Null().and_then(must_be_less_than_10) == Null() True
- as_list() list[T]¶
Papertrail examples:
A
Somebecomes a one-item list throughas_list.>>> Some(inner=2).as_list() == [2] True
as_listrepresentsNullas an empty list.>>> Null().as_list() == [] True
- as_tuple() tuple[T, ...]¶
Papertrail examples:
A
Somebecomes a one-item tuple throughas_tuple.>>> Some(inner=2).as_tuple() == (2,) True
as_tuplerepresentsNullas an empty tuple.>>> Null().as_tuple() == () True
- expect(msg: str) T¶
Papertrail examples:
expectextracts the value from aSome.>>> Some(inner=2).expect("must be positive") == 2 True
- filter_(predicate: Callable[[T], bool]) Option[T]¶
Papertrail examples:
A
Somethat fails the predicate becomesNullthroughfilter_.>>> Some(inner=3).filter_(is_even) == Null() True
A
Somethat passes the predicate remains unchanged.>>> Some(inner=4).filter_(is_even) == Some(inner=4) True
filter_leavesNullunchanged without calling the predicate.>>> Null().filter_(is_even) == Null() True
- flatten() Option[T]¶
Papertrail examples:
Flattening three nested
Somevalues removes only the outer option.>>> Some(inner=Some(inner=Some(inner=2))).flatten() == Some(inner=Some(inner=2)) True
Flattening a doubly wrapped value returns the inner
Some.>>> Some(inner=Some(inner=2)).flatten() == Some(inner=2) True
Flattening a
Somewith a non-option value does nothing.>>> Some(inner=2).flatten() == Some(inner=2) True
A
Nullpasses throughflattenunchanged.>>> Null().flatten() == Null() True
- inspect(fn: Callable[[T], None]) Option[T]¶
Papertrail examples:
Inspecting a
Somecalls the function and returns the original option.>>> Some(inner=[1]).inspect(append_to_list) == Some(inner=[1]) True
Inspecting
NullreturnsNullwithout calling the function.>>> Null().inspect(append_to_list) == Null() True
- is_none() bool¶
Papertrail examples:
is_nonereportsFalsefor aSome.>>> Some(inner=2).is_none() == False True
For
Null,is_nonereportsTrue.>>> Null().is_none() == True True
- is_none_or(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects a
Some,is_none_orreportsFalse.>>> Some(inner=1).is_none_or(is_even) == False True
When the predicate accepts a
Some,is_none_orreportsTrue.>>> Some(inner=2).is_none_or(is_even) == True True
Nullmakesis_none_orreportTruewithout calling the predicate.>>> Null().is_none_or(is_even) == True True
- is_some() bool¶
Papertrail examples:
is_somereportsTruefor aSome.>>> Some(inner=2).is_some() == True True
For
Null,is_somereportsFalse.>>> Null().is_some() == False True
- is_some_and(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects a
Some,is_some_andreportsFalse.>>> Some(inner=1).is_some_and(is_even) == False True
When the predicate accepts a
Some,is_some_andreportsTrue.>>> Some(inner=2).is_some_and(is_even) == True True
A
Nullmakesis_some_andreportFalsewithout calling the predicate.>>> Null().is_some_and(is_even) == False True
- map(fn: Callable[[T], U]) Option[U]¶
Papertrail examples:
Mapping a
Someapplies the function and wraps its result in a newSome.>>> Some(inner=1).map(add_one) == Some(inner=2) True
Mapping
Nullleaves it unchanged and skips the function.>>> Null().map(add_one) == Null() True
- map_or(default: U, fn: Callable[[T], U]) U¶
Papertrail examples:
For a
Some,map_oruses the function result instead of the default.>>> Some(inner="foo").map_or(42, len) == 3 True
For
Null,map_orreturns the supplied default.>>> Null().map_or(42, len) == 42 True
- map_or_else(default: Callable[..., U], fn: Callable[[T], U]) U¶
Papertrail examples:
A
Somemakesmap_or_elseuse the mapping function.>>> Some(inner="foo").map_or_else(get_42, len) == 3 True
A
Nullmakesmap_or_elseuse the default function.>>> Null().map_or_else(get_42, len) == 42 True
- ok_or(err: E) Result[T, E]¶
Papertrail examples:
A
Someconverts toOkthroughok_or.>>> Some(inner="foo").ok_or(0) == Ok(inner="foo") True
A
Nullconverts toErrthroughok_or.>>> Null().ok_or(0) == Err(error=0) True
- ok_or_else(err: Callable[[], E]) Result[T, E]¶
Papertrail examples:
A
Someconverts toOkwithout calling the error function.>>> Some(inner="foo").ok_or_else(get_42) == Ok(inner="foo") True
A
Nullconverts toErrusing the error function result.>>> Null().ok_or_else(get_42) == Err(error=42) True
- or_(opt_b: Option[T]) Option[T]¶
Papertrail examples:
A
Somekeeps its value whenor_receivesNull.>>> Some(inner=2).or_(Null()) == Some(inner=2) True
A
Nullgives way to aSomepassed toor_.>>> Null().or_(Some(inner=100)) == Some(inner=100) True
When both options contain values,
or_keeps the firstSome.>>> Some(inner=2).or_(Some(inner=100)) == Some(inner=2) True
When both options are
Null,or_returnsNull.>>> Null().or_(Null()) == Null() True
- or_else(opt_b: Callable[[], Option[T]]) Option[T]¶
Papertrail examples:
A
Somepasses throughor_elsewithout calling the function.>>> Some(inner="barbarians").or_else(get_some_vikings) == Some(inner="barbarians") True
For
Null,or_elsereturns theSomeproduced by the function.>>> Null().or_else(get_some_vikings) == Some(inner="vikings") True
If the fallback also produces
Null,or_elsereturnsNull.>>> Null().or_else(Null) == Null() True
- replace(value: T) Option[T]¶
Papertrail examples:
Replacing a
Somereturns a newSomewith the replacement value.>>> Some(inner=2).replace(5) == Some(inner=5) True
Replacing
Nullleaves it asNull.>>> Null().replace(3) == Null() True
- transpose() Result[Option[T], E]¶
Papertrail examples:
Transposing
Some(Ok(value))producesOk(Some(value)).>>> Some(inner=Ok(inner=2)).transpose() == Ok(inner=Some(inner=2)) True
Transposing
Some(Err(error))producesErr(Some(error)).>>> Some(inner=Err(error=2)).transpose() == Err(error=Some(inner=2)) True
Transposing
NullproducesOk(Null()).>>> Null().transpose() == Ok(inner=Null()) True
- unwrap() T¶
Papertrail examples:
unwrapextracts the value from aSome.>>> Some(inner=2).unwrap() == 2 True
- unwrap_or(default: T) T¶
Papertrail examples:
With a
Some,unwrap_orreturns the value and ignores the default.>>> Some(inner="car").unwrap_or("bike") == "car" True
With
Null,unwrap_orreturns the default.>>> Null().unwrap_or("bike") == "bike" True
- unwrap_or_else(fn: Callable[[], T]) T¶
Papertrail examples:
A
Somemakesunwrap_or_elsereturn its value without calling the function.>>> Some(inner=4).unwrap_or_else(get_42) == 4 True
A
Nullmakesunwrap_or_elsereturn the function result.>>> Null().unwrap_or_else(get_42) == 42 True
- unzip() tuple[Option[T], Option[U]]¶
Papertrail examples:
Unzipping a
Somepair produces twoSomevalues.>>> Some(inner=(2, 2)).unzip() == (Some(inner=2), Some(inner=2)) True
Unzipping a
Somewith a non-pair value produces twoNullvalues.>>> Some(inner=4).unzip() == (Null(), Null()) True
Unzipping
Nullproduces twoNullvalues.>>> Null().unzip() == (Null(), Null()) True
- zip(other: Option[U]) Option[tuple[T, U]]¶
Papertrail examples:
Zipping two
Somevalues produces aSomecontaining both values.>>> Some(inner=1).zip(Some(inner="hi")) == Some(inner=(1, "hi")) True
Zipping a
SomewithNullproducesNull.>>> Some(inner=1).zip(Null()) == Null() True
Zipping
Nullwith aSomeproducesNull.>>> Null().zip(Some(inner=1)) == Null() True
- class danom.Ok(inner: T = None)¶
Bases:
Result[T,Never],Generic- and_(res: Result[U, E]) Result[U, E]¶
Papertrail examples:
If you call
and_on anOkwith anErras the arg then theErrtakes precedence over theOk.>>> Ok(inner=2).and_(Err(error="late error")) == Err(error="late error") True
If you call
and_on anErrwith anOkas the arg then theErrstill takes precedence over theOk.>>> Err(error="early error").and_(Ok(inner="foo")) == Err(error="early error") True
If you call
and_on anErrwith anErras the arg then the firstErris returned and the second is discarded.>>> Err(error="not a 2").and_(Err(error="late error")) == Err(error="not a 2") True
Whereas, calling
and_on anOkwith anotherOkas the arg then the firstOkis discarded and the second is returned.>>> Ok(inner=2).and_(Ok(inner="different result type")) == Ok(inner="different result type") True
- and_then(fn: Callable[Concatenate[T, P], Result[U, E]], *args: P.args, **kwargs: P.kwargs) Result[U, E]¶
Papertrail examples:
An
Okpassed toand_thenreturns theOkproduced by the function.>>> Ok(inner=2).and_then(must_be_less_than_10) == Ok(inner=2) True
When the function passed to
and_thenproduces anErr, thatErrbecomes the result.>>> Ok(inner=20).and_then(must_be_less_than_10) == Err(error="too high") True
An existing
Errpasses throughand_thenunchanged, without calling the function.>>> Err(error="not a number").and_then(must_be_less_than_10) == Err(error="not a number") True
- err() Option[E]¶
Papertrail examples:
An
Okhas no error, soerrreturnsNull.>>> Ok(inner=2).err() == Null() True
If you call
erron anErrthenSomewith the wrapped error is returned.>>> Err(error="Nothing here").err() == Some(inner="Nothing here") True
- expect(msg: str) T¶
Papertrail examples:
expectextracts the value from anOk.>>> Ok(inner=2).expect("must be positive") == 2 True
- expect_err(msg: str) Never¶
Papertrail examples:
expect_errextracts the error from anErr.>>> Err(error=2).expect_err("must be err") == 2 True
- flatten() Result[T, Never]¶
Papertrail examples:
If you call
flattenon three nestedOkvalues then two nestedOkvalues are returned. Only the outer monad is removed>>> Ok(inner=Ok(inner=Ok(inner=2))).flatten() == Ok(inner=Ok(inner=2)) True
This is made obvious calling
flattenon a doubly wrapped value returning just the inner monad.>>> Ok(inner=Ok(inner=2)).flatten() == Ok(inner=2) True
Calling
flattenif the inner is not a monad of the same type is a no-op.>>> Ok(inner=2).flatten() == Ok(inner=2) True
An
Errpasses throughflattenunchanged.>>> Err(error=None).flatten() == Err(error=None) True
- inner: T¶
- inspect(fn: Callable[[T], None]) Result[T, Never]¶
Papertrail examples:
If you call
inspecton anOkthen the originalOkis returned after the function is called, this is used for logging or side outputs that shouldn’t disrupt the existing flow.>>> Ok(inner=[1]).inspect(append_to_list) == Ok(inner=[1]) True
If you call
inspecton anErrthen theErris returned and the function is not called.>>> Err(error="un-appendable").inspect(append_to_list) == Err(error="un-appendable") True
- inspect_err(fn: Callable[[Never], None]) Result[T, Never]¶
Papertrail examples:
If you call
inspect_erron anErrthen the originalErris returned after the function is called, it’s essentially the inverse ofinspect.>>> Err(error=[1]).inspect_err(append_to_list) == Err(error=[1]) True
Similarly to calling
inspecton anErr, if you callinspect_erron anOkthen theOkis returned and the function is not called.>>> Ok(inner="un-appendable").inspect_err(append_to_list) == Ok(inner="un-appendable") True
- is_err() bool¶
Papertrail examples:
is_errreportsFalsefor anOk.>>> Ok(inner=2).is_err() == False True
For an
Err,is_errreportsTrue.>>> Err(error=2).is_err() == True True
- is_err_and(fn: Callable[[Never], bool]) bool¶
Papertrail examples:
is_err_andrequires both the monad to be anErrand the returned value of the passed in callable to beTrue, for example, if you calledis_err_andwith a function that checks for evenness on anErr(1)then the result isFalse.>>> Err(error=1).is_err_and(is_even) == False True
Therefore, if you call
is_err_andon anErrwith a function that returnsTruethenTrueis returned.>>> Err(error=2).is_err_and(is_even) == True True
Whereas, if you call
is_err_andon anOkwith a function thenFalseis returned and the function is not called.>>> Ok(inner=2).is_err_and(is_even) == False True
- is_ok() bool¶
Papertrail examples:
is_okreportsTruefor anOk.>>> Ok(inner=2).is_ok() == True True
For an
Err,is_okreportsFalse.>>> Err(error=2).is_ok() == False True
- is_ok_and(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects an
Ok,is_ok_andreportsFalse.>>> Ok(inner=1).is_ok_and(is_even) == False True
When the predicate accepts an
Ok,is_ok_andreportsTrue.>>> Ok(inner=2).is_ok_and(is_even) == True True
An
Errmakesis_ok_andreportFalsewithout calling the predicate.>>> Err(error=2).is_ok_and(is_even) == False True
- map(fn: Callable[Concatenate[T, P], U], *args: P.args, **kwargs: P.kwargs) Result[U, Never]¶
Papertrail examples:
Mapping an
Okapplies the function and wraps its result in a newOk.>>> Ok(inner=1).map(add_one) == Ok(inner=2) True
Mapping an
Errleaves it unchanged and skips the function.>>> Err(error=1).map(add_one) == Err(error=1) True
- map_err(fn: Callable[Concatenate[Never, P], F], *args: P.args, **kwargs: P.kwargs) Result[T, F]¶
Papertrail examples:
Mapping an
Errapplies the function and wraps its result in a newErr.>>> Err(error=1).map_err(add_one) == Err(error=2) True
Mapping an
Okleaves it unchanged and skips the function.>>> Ok(inner=1).map_err(add_one) == Ok(inner=1) True
- map_or(default: U, fn: Callable[Concatenate[T, P], U], *args: P.args, **kwargs: P.kwargs) U¶
Papertrail examples:
For an
Ok,map_oruses the function result instead of the default.>>> Ok(inner="foo").map_or(42, len) == 3 True
For an
Err,map_orreturns the supplied default.>>> Err(error=None).map_or(42, len) == 42 True
- map_or_else(default: Callable[P, U], fn: Callable[Concatenate[T, P], U], *args: P.args, **kwargs: P.kwargs) U¶
Papertrail examples:
An
Okmakesmap_or_elseuse the mapping function.>>> Ok(inner="foo").map_or_else(get_42, len) == 3 True
An
Errmakesmap_or_elseuse the default function.>>> Err(error=None).map_or_else(get_42, len) == 42 True
- ok() Option[T]¶
Papertrail examples:
An
Okconverts toSomethroughok.>>> Ok(inner=2).ok() == Some(inner=2) True
An
Errconverts toNullthroughok.>>> Err(error=2).ok() == Null() True
- or_(res: Result[T, F]) Result[T, F]¶
Papertrail examples:
An
Okkeeps its value whenor_receives anErr.>>> Ok(inner=2).or_(Err(error="foo")) == Ok(inner=2) True
An
Errgives way to anOkpassed toor_.>>> Err(error="foo").or_(Ok(inner=100)) == Ok(inner=100) True
When both values are
Ok,or_keeps the first one.>>> Ok(inner=2).or_(Ok(inner=100)) == Ok(inner=2) True
When both values are
Err,or_keeps the first error.>>> Err(error="foo").or_(Err(error="foo")) == Err(error="foo") True
- or_else(fn: Callable[Concatenate[Never, P], F], *args: P.args, **kwargs: P.kwargs) Result[T, F]¶
Papertrail examples:
An
Okpasses throughor_elsewithout calling the function.>>> Ok(inner="barbarians").or_else(get_ok_vikings) == Ok(inner="barbarians") True
For an
Err,or_elsereturns theOkproduced by the function.>>> Err(error="foo").or_else(get_ok_vikings) == Ok(inner="vikings") True
If the fallback also produces an
Err,or_elsekeeps the original error.>>> Err(error="foo").or_else(Err) == Err(error="foo") True
- transpose() Option[Result[T, Never]]¶
Papertrail examples:
Transposing
Ok(Some(value))producesSome(Ok(value)).>>> Ok(inner=Some(inner=5)).transpose() == Some(inner=Ok(inner=5)) True
Transposing
Ok(Null())producesNull.>>> Ok(inner=Null()).transpose() == Null() True
Transposing an
Errwraps it inSome.>>> Err(error=None).transpose() == Some(inner=Err(error=None)) True
- unwrap() T¶
Papertrail examples:
unwrapextracts the value from anOk.>>> Ok(inner=2).unwrap() == 2 True
- unwrap_err() Never¶
Papertrail examples:
unwrap_errextracts the error from anErr.>>> Err(error="failed").unwrap_err() == "failed" True
- unwrap_or(default: T) T¶
Papertrail examples:
With an
Ok,unwrap_orreturns the value and ignores the default.>>> Ok(inner="car").unwrap_or("bike") == "car" True
With an
Err,unwrap_orreturns the default.>>> Err(error=None).unwrap_or("bike") == "bike" True
- unwrap_or_else(fn: Callable[[Never], T]) T¶
Papertrail examples:
An
Okmakesunwrap_or_elsereturn its value without calling the function.>>> Ok(inner=4).unwrap_or_else(get_42) == 4 True
An
Errmakesunwrap_or_elsereturn the function result.>>> Err(error=None).unwrap_or_else(get_42) == 42 True
- class danom.Option¶
Bases:
ABC,GenericA monad to represent optional values.
Version changes¶
0.17.0: AddedOption,Some,Null- abstractmethod and_(opt_b: Option[T]) Option[T]¶
Papertrail examples:
A
Somecombined withNullthroughand_producesNull.>>> Some(inner=2).and_(Null()) == Null() True
A
Nullcombined with anSomethroughand_remainsNull.>>> Null().and_(Some(inner="foo")) == Null() True
When both options contain values,
and_keeps the secondSome.>>> Some(inner=2).and_(Some(inner="foo")) == Some(inner="foo") True
Combining two
Nullvalues withand_producesNull.>>> Null().and_(Null()) == Null() True
- abstractmethod and_then(fn: Callable[[T], Option[U]]) Option[T]¶
Papertrail examples:
A successful function passed to
and_thenreturns itsSomeresult.>>> Some(inner=2).and_then(must_be_less_than_10) == Some(inner=2) True
When the function returns
Null,and_thenpasses thatNullthrough.>>> Some(inner=20).and_then(must_be_less_than_10) == Null() True
An existing
Nullskips the function passed toand_then.>>> Null().and_then(must_be_less_than_10) == Null() True
- abstractmethod as_list() list[T]¶
Papertrail examples:
A
Somebecomes a one-item list throughas_list.>>> Some(inner=2).as_list() == [2] True
as_listrepresentsNullas an empty list.>>> Null().as_list() == [] True
- abstractmethod as_tuple() tuple[T, ...]¶
Papertrail examples:
A
Somebecomes a one-item tuple throughas_tuple.>>> Some(inner=2).as_tuple() == (2,) True
as_tuplerepresentsNullas an empty tuple.>>> Null().as_tuple() == () True
- cloned() Option[T]¶
Papertrail examples:
Cloning a
Somecreates a separate option with the same value.>>> Some(inner=2).cloned() == Some(inner=2) True
Cloning
Nullcreates a separateNull.>>> Null().cloned() == Null() True
- abstractmethod expect(msg: str) T¶
Papertrail examples:
expectextracts the value from aSome.>>> Some(inner=2).expect("must be positive") == 2 True
- abstractmethod filter_(predicate: Callable[[T], bool]) Option[T]¶
Papertrail examples:
A
Somethat fails the predicate becomesNullthroughfilter_.>>> Some(inner=3).filter_(is_even) == Null() True
A
Somethat passes the predicate remains unchanged.>>> Some(inner=4).filter_(is_even) == Some(inner=4) True
filter_leavesNullunchanged without calling the predicate.>>> Null().filter_(is_even) == Null() True
- abstractmethod flatten() Option[T]¶
Papertrail examples:
Flattening three nested
Somevalues removes only the outer option.>>> Some(inner=Some(inner=Some(inner=2))).flatten() == Some(inner=Some(inner=2)) True
Flattening a doubly wrapped value returns the inner
Some.>>> Some(inner=Some(inner=2)).flatten() == Some(inner=2) True
Flattening a
Somewith a non-option value does nothing.>>> Some(inner=2).flatten() == Some(inner=2) True
A
Nullpasses throughflattenunchanged.>>> Null().flatten() == Null() True
- abstractmethod inspect(fn: Callable[[T], None]) Option[T]¶
Papertrail examples:
Inspecting a
Somecalls the function and returns the original option.>>> Some(inner=[1]).inspect(append_to_list) == Some(inner=[1]) True
Inspecting
NullreturnsNullwithout calling the function.>>> Null().inspect(append_to_list) == Null() True
- abstractmethod is_none() bool¶
Papertrail examples:
is_nonereportsFalsefor aSome.>>> Some(inner=2).is_none() == False True
For
Null,is_nonereportsTrue.>>> Null().is_none() == True True
- abstractmethod is_none_or(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects a
Some,is_none_orreportsFalse.>>> Some(inner=1).is_none_or(is_even) == False True
When the predicate accepts a
Some,is_none_orreportsTrue.>>> Some(inner=2).is_none_or(is_even) == True True
Nullmakesis_none_orreportTruewithout calling the predicate.>>> Null().is_none_or(is_even) == True True
- abstractmethod is_some() bool¶
Papertrail examples:
is_somereportsTruefor aSome.>>> Some(inner=2).is_some() == True True
For
Null,is_somereportsFalse.>>> Null().is_some() == False True
- abstractmethod is_some_and(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects a
Some,is_some_andreportsFalse.>>> Some(inner=1).is_some_and(is_even) == False True
When the predicate accepts a
Some,is_some_andreportsTrue.>>> Some(inner=2).is_some_and(is_even) == True True
A
Nullmakesis_some_andreportFalsewithout calling the predicate.>>> Null().is_some_and(is_even) == False True
- abstractmethod map(fn: Callable[[T], U]) Option[U]¶
Papertrail examples:
Mapping a
Someapplies the function and wraps its result in a newSome.>>> Some(inner=1).map(add_one) == Some(inner=2) True
Mapping
Nullleaves it unchanged and skips the function.>>> Null().map(add_one) == Null() True
- abstractmethod map_or(default: U, fn: Callable[[T], U]) U¶
Papertrail examples:
For a
Some,map_oruses the function result instead of the default.>>> Some(inner="foo").map_or(42, len) == 3 True
For
Null,map_orreturns the supplied default.>>> Null().map_or(42, len) == 42 True
- abstractmethod map_or_else(default: Callable[..., U], fn: Callable[[T], U]) U¶
Papertrail examples:
A
Somemakesmap_or_elseuse the mapping function.>>> Some(inner="foo").map_or_else(get_42, len) == 3 True
A
Nullmakesmap_or_elseuse the default function.>>> Null().map_or_else(get_42, len) == 42 True
- abstractmethod ok_or(err: E) Result[T, E]¶
Papertrail examples:
A
Someconverts toOkthroughok_or.>>> Some(inner="foo").ok_or(0) == Ok(inner="foo") True
A
Nullconverts toErrthroughok_or.>>> Null().ok_or(0) == Err(error=0) True
- abstractmethod ok_or_else(err: Callable[..., E]) Result[T, E]¶
Papertrail examples:
A
Someconverts toOkwithout calling the error function.>>> Some(inner="foo").ok_or_else(get_42) == Ok(inner="foo") True
A
Nullconverts toErrusing the error function result.>>> Null().ok_or_else(get_42) == Err(error=42) True
- abstractmethod or_(opt_b: Option[T]) Option[T]¶
Papertrail examples:
A
Somekeeps its value whenor_receivesNull.>>> Some(inner=2).or_(Null()) == Some(inner=2) True
A
Nullgives way to aSomepassed toor_.>>> Null().or_(Some(inner=100)) == Some(inner=100) True
When both options contain values,
or_keeps the firstSome.>>> Some(inner=2).or_(Some(inner=100)) == Some(inner=2) True
When both options are
Null,or_returnsNull.>>> Null().or_(Null()) == Null() True
- abstractmethod or_else(opt_b: Callable[..., Option[T]]) Option[T]¶
Papertrail examples:
A
Somepasses throughor_elsewithout calling the function.>>> Some(inner="barbarians").or_else(get_some_vikings) == Some(inner="barbarians") True
For
Null,or_elsereturns theSomeproduced by the function.>>> Null().or_else(get_some_vikings) == Some(inner="vikings") True
If the fallback also produces
Null,or_elsereturnsNull.>>> Null().or_else(Null) == Null() True
- abstractmethod replace(value: T) Option[T]¶
Papertrail examples:
Replacing a
Somereturns a newSomewith the replacement value.>>> Some(inner=2).replace(5) == Some(inner=5) True
Replacing
Nullleaves it asNull.>>> Null().replace(3) == Null() True
- abstractmethod transpose() Result[Option[T], E]¶
Papertrail examples:
Transposing
Some(Ok(value))producesOk(Some(value)).>>> Some(inner=Ok(inner=2)).transpose() == Ok(inner=Some(inner=2)) True
Transposing
Some(Err(error))producesErr(Some(error)).>>> Some(inner=Err(error=2)).transpose() == Err(error=Some(inner=2)) True
Transposing
NullproducesOk(Null()).>>> Null().transpose() == Ok(inner=Null()) True
- abstractmethod unwrap() T¶
Papertrail examples:
unwrapextracts the value from aSome.>>> Some(inner=2).unwrap() == 2 True
- abstractmethod unwrap_or(default: T) T¶
Papertrail examples:
With a
Some,unwrap_orreturns the value and ignores the default.>>> Some(inner="car").unwrap_or("bike") == "car" True
With
Null,unwrap_orreturns the default.>>> Null().unwrap_or("bike") == "bike" True
- abstractmethod unwrap_or_else(fn: Callable[..., T]) T¶
Papertrail examples:
A
Somemakesunwrap_or_elsereturn its value without calling the function.>>> Some(inner=4).unwrap_or_else(get_42) == 4 True
A
Nullmakesunwrap_or_elsereturn the function result.>>> Null().unwrap_or_else(get_42) == 42 True
- abstractmethod unzip() tuple[Option[T], Option[U]]¶
Papertrail examples:
Unzipping a
Somepair produces twoSomevalues.>>> Some(inner=(2, 2)).unzip() == (Some(inner=2), Some(inner=2)) True
Unzipping a
Somewith a non-pair value produces twoNullvalues.>>> Some(inner=4).unzip() == (Null(), Null()) True
Unzipping
Nullproduces twoNullvalues.>>> Null().unzip() == (Null(), Null()) True
- abstractmethod zip(other: Option[U]) Option[tuple[T, U]]¶
Papertrail examples:
Zipping two
Somevalues produces aSomecontaining both values.>>> Some(inner=1).zip(Some(inner="hi")) == Some(inner=(1, "hi")) True
Zipping a
SomewithNullproducesNull.>>> Some(inner=1).zip(Null()) == Null() True
Zipping
Nullwith aSomeproducesNull.>>> Null().zip(Some(inner=1)) == Null() True
- class danom.ParStream(seq: tuple, ops: tuple = ())¶
Bases:
_BaseSyncStream,GenericA stream that applies its operations with a thread or process pool.
Version changes¶
0.16.0: AddedParStream- collect(*, workers: int = 4, use_threads: bool = False) tuple[U, ...]¶
Materialise the
ParStreamwith the configured workers.workers=-1uses one worker for each available CPU, except one. Setuse_threadstoTrueto use threads instead of processes.from danom import ParStream ParStream.from_iterable([1, 2, 3]).map(add_one).collect(workers=2)
- to_par() Self¶
Return the
ParStreamunchanged.
- class danom.Result¶
Bases:
ABC,GenericA monad to represent failable values.
Version changes¶
0.17.0: UpdatedResult,Ok,Err. Added majority of methods that are used in theResultenum in Rust. There is a breaking change with howflattenworks.- abstractmethod and_(res: Result[U, F]) Result[U, F]¶
Papertrail examples:
If you call
and_on anOkwith anErras the arg then theErrtakes precedence over theOk.>>> Ok(inner=2).and_(Err(error="late error")) == Err(error="late error") True
If you call
and_on anErrwith anOkas the arg then theErrstill takes precedence over theOk.>>> Err(error="early error").and_(Ok(inner="foo")) == Err(error="early error") True
If you call
and_on anErrwith anErras the arg then the firstErris returned and the second is discarded.>>> Err(error="not a 2").and_(Err(error="late error")) == Err(error="not a 2") True
Whereas, calling
and_on anOkwith anotherOkas the arg then the firstOkis discarded and the second is returned.>>> Ok(inner=2).and_(Ok(inner="different result type")) == Ok(inner="different result type") True
- abstractmethod and_then(fn: Callable[Concatenate[T, P], Result[U, F]], *args: P.args, **kwargs: P.kwargs) Result[U, F]¶
Papertrail examples:
An
Okpassed toand_thenreturns theOkproduced by the function.>>> Ok(inner=2).and_then(must_be_less_than_10) == Ok(inner=2) True
When the function passed to
and_thenproduces anErr, thatErrbecomes the result.>>> Ok(inner=20).and_then(must_be_less_than_10) == Err(error="too high") True
An existing
Errpasses throughand_thenunchanged, without calling the function.>>> Err(error="not a number").and_then(must_be_less_than_10) == Err(error="not a number") True
- cloned() Result[T, E]¶
Papertrail examples:
Cloning an
Okcreates a separateOkwith the same value.>>> Ok(inner=2).cloned() == Ok(inner=2) True
Cloning an
Errcreates a separateErrwith the same value.>>> Err(error=2).cloned() == Err(error=2) True
- abstractmethod err() Option[E]¶
Papertrail examples:
An
Okhas no error, soerrreturnsNull.>>> Ok(inner=2).err() == Null() True
If you call
erron anErrthenSomewith the wrapped error is returned.>>> Err(error="Nothing here").err() == Some(inner="Nothing here") True
- abstractmethod expect(msg: str) T¶
Papertrail examples:
expectextracts the value from anOk.>>> Ok(inner=2).expect("must be positive") == 2 True
- abstractmethod expect_err(msg: str) E¶
Papertrail examples:
expect_errextracts the error from anErr.>>> Err(error=2).expect_err("must be err") == 2 True
- abstractmethod flatten() Result[T, E]¶
Papertrail examples:
If you call
flattenon three nestedOkvalues then two nestedOkvalues are returned. Only the outer monad is removed>>> Ok(inner=Ok(inner=Ok(inner=2))).flatten() == Ok(inner=Ok(inner=2)) True
This is made obvious calling
flattenon a doubly wrapped value returning just the inner monad.>>> Ok(inner=Ok(inner=2)).flatten() == Ok(inner=2) True
Calling
flattenif the inner is not a monad of the same type is a no-op.>>> Ok(inner=2).flatten() == Ok(inner=2) True
An
Errpasses throughflattenunchanged.>>> Err(error=None).flatten() == Err(error=None) True
- abstractmethod inspect(fn: Callable[[T], None]) Result[T, E]¶
Papertrail examples:
If you call
inspecton anOkthen the originalOkis returned after the function is called, this is used for logging or side outputs that shouldn’t disrupt the existing flow.>>> Ok(inner=[1]).inspect(append_to_list) == Ok(inner=[1]) True
If you call
inspecton anErrthen theErris returned and the function is not called.>>> Err(error="un-appendable").inspect(append_to_list) == Err(error="un-appendable") True
- abstractmethod inspect_err(fn: Callable[[E], None]) Result[T, E]¶
Papertrail examples:
If you call
inspect_erron anErrthen the originalErris returned after the function is called, it’s essentially the inverse ofinspect.>>> Err(error=[1]).inspect_err(append_to_list) == Err(error=[1]) True
Similarly to calling
inspecton anErr, if you callinspect_erron anOkthen theOkis returned and the function is not called.>>> Ok(inner="un-appendable").inspect_err(append_to_list) == Ok(inner="un-appendable") True
- abstractmethod is_err() bool¶
Papertrail examples:
is_errreportsFalsefor anOk.>>> Ok(inner=2).is_err() == False True
For an
Err,is_errreportsTrue.>>> Err(error=2).is_err() == True True
- abstractmethod is_err_and(fn: Callable[[E], bool]) bool¶
Papertrail examples:
is_err_andrequires both the monad to be anErrand the returned value of the passed in callable to beTrue, for example, if you calledis_err_andwith a function that checks for evenness on anErr(1)then the result isFalse.>>> Err(error=1).is_err_and(is_even) == False True
Therefore, if you call
is_err_andon anErrwith a function that returnsTruethenTrueis returned.>>> Err(error=2).is_err_and(is_even) == True True
Whereas, if you call
is_err_andon anOkwith a function thenFalseis returned and the function is not called.>>> Ok(inner=2).is_err_and(is_even) == False True
- abstractmethod is_ok() bool¶
Papertrail examples:
is_okreportsTruefor anOk.>>> Ok(inner=2).is_ok() == True True
For an
Err,is_okreportsFalse.>>> Err(error=2).is_ok() == False True
- abstractmethod is_ok_and(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects an
Ok,is_ok_andreportsFalse.>>> Ok(inner=1).is_ok_and(is_even) == False True
When the predicate accepts an
Ok,is_ok_andreportsTrue.>>> Ok(inner=2).is_ok_and(is_even) == True True
An
Errmakesis_ok_andreportFalsewithout calling the predicate.>>> Err(error=2).is_ok_and(is_even) == False True
- abstractmethod map(fn: Callable[Concatenate[T, P], U], *args: P.args, **kwargs: P.kwargs) Result[U, E]¶
Papertrail examples:
Mapping an
Okapplies the function and wraps its result in a newOk.>>> Ok(inner=1).map(add_one) == Ok(inner=2) True
Mapping an
Errleaves it unchanged and skips the function.>>> Err(error=1).map(add_one) == Err(error=1) True
- abstractmethod map_err(fn: Callable[Concatenate[E, P], F], *args: P.args, **kwargs: P.kwargs) Result[T, F]¶
Papertrail examples:
Mapping an
Errapplies the function and wraps its result in a newErr.>>> Err(error=1).map_err(add_one) == Err(error=2) True
Mapping an
Okleaves it unchanged and skips the function.>>> Ok(inner=1).map_err(add_one) == Ok(inner=1) True
- abstractmethod map_or(default: U, fn: Callable[Concatenate[T, P], U], *args: P.args, **kwargs: P.kwargs) U¶
Papertrail examples:
For an
Ok,map_oruses the function result instead of the default.>>> Ok(inner="foo").map_or(42, len) == 3 True
For an
Err,map_orreturns the supplied default.>>> Err(error=None).map_or(42, len) == 42 True
- abstractmethod map_or_else(default: Callable[P, U], fn: Callable[Concatenate[T, P], U], *args: P.args, **kwargs: P.kwargs) U¶
Papertrail examples:
An
Okmakesmap_or_elseuse the mapping function.>>> Ok(inner="foo").map_or_else(get_42, len) == 3 True
An
Errmakesmap_or_elseuse the default function.>>> Err(error=None).map_or_else(get_42, len) == 42 True
- abstractmethod ok() Option[T]¶
Papertrail examples:
An
Okconverts toSomethroughok.>>> Ok(inner=2).ok() == Some(inner=2) True
An
Errconverts toNullthroughok.>>> Err(error=2).ok() == Null() True
- abstractmethod or_(res: Result[T, F]) Result[T, F]¶
Papertrail examples:
An
Okkeeps its value whenor_receives anErr.>>> Ok(inner=2).or_(Err(error="foo")) == Ok(inner=2) True
An
Errgives way to anOkpassed toor_.>>> Err(error="foo").or_(Ok(inner=100)) == Ok(inner=100) True
When both values are
Ok,or_keeps the first one.>>> Ok(inner=2).or_(Ok(inner=100)) == Ok(inner=2) True
When both values are
Err,or_keeps the first error.>>> Err(error="foo").or_(Err(error="foo")) == Err(error="foo") True
- abstractmethod or_else(fn: Callable[Concatenate[E, P], F], *args: P.args, **kwargs: P.kwargs) Result[T, F]¶
Papertrail examples:
An
Okpasses throughor_elsewithout calling the function.>>> Ok(inner="barbarians").or_else(get_ok_vikings) == Ok(inner="barbarians") True
For an
Err,or_elsereturns theOkproduced by the function.>>> Err(error="foo").or_else(get_ok_vikings) == Ok(inner="vikings") True
If the fallback also produces an
Err,or_elsekeeps the original error.>>> Err(error="foo").or_else(Err) == Err(error="foo") True
- static result_is_ok(result: Result[T, E]) bool¶
Check whether the monad is ok. Allows for
filterorpartitionin aStreamwithout needing a lambda or custom function.from danom import Stream, Result Stream.from_iterable([Ok(), Ok(), Err()]).filter(Result.result_is_ok).collect() == (Ok(), Ok())
- static result_unwrap(result: Result[T, E]) T¶
Unwrap the
Okmonad and get the inner value. Unwrap theErrmonad will raise the inner error.from danom import Err, Ok, Stream, Result oks, errs = Stream.from_iterable([Ok(1), Ok(2), Err()]).partition(Result.result_is_ok) oks.map(Result.result_unwrap).collect == (1, 2)
- abstractmethod transpose() Option[Result[T, E]]¶
Papertrail examples:
Transposing
Ok(Some(value))producesSome(Ok(value)).>>> Ok(inner=Some(inner=5)).transpose() == Some(inner=Ok(inner=5)) True
Transposing
Ok(Null())producesNull.>>> Ok(inner=Null()).transpose() == Null() True
Transposing an
Errwraps it inSome.>>> Err(error=None).transpose() == Some(inner=Err(error=None)) True
- classmethod unit(inner: T) Result[T, E]¶
Unit method. Given an item of type
TreturnOk(T)>>> from danom import Err, Ok, Result >>> Result.unit(0) == Ok(0) True >>> Ok.unit(0) == Ok(0) True >>> Err.unit(0) == Ok(0) True
- abstractmethod unwrap() T¶
Papertrail examples:
unwrapextracts the value from anOk.>>> Ok(inner=2).unwrap() == 2 True
- abstractmethod unwrap_err() E¶
Papertrail examples:
unwrap_errextracts the error from anErr.>>> Err(error="failed").unwrap_err() == "failed" True
- abstractmethod unwrap_or(default: T) T¶
Papertrail examples:
With an
Ok,unwrap_orreturns the value and ignores the default.>>> Ok(inner="car").unwrap_or("bike") == "car" True
With an
Err,unwrap_orreturns the default.>>> Err(error=None).unwrap_or("bike") == "bike" True
- abstractmethod unwrap_or_else(fn: Callable[[E], T]) T¶
Papertrail examples:
An
Okmakesunwrap_or_elsereturn its value without calling the function.>>> Ok(inner=4).unwrap_or_else(get_42) == 4 True
An
Errmakesunwrap_or_elsereturn the function result.>>> Err(error=None).unwrap_or_else(get_42) == 42 True
- class danom.Right(inner: Any = None)¶
Bases:
Either[T_co,Never]- and_then(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.Either[~danom._monads._either.U_co, ~danom._monads._either.E_co]], *args: ~typing.~P, **kwargs: ~typing.~P) Either[U_co, E_co]¶
Pipe another function that returns a monad. For
Leftwill return original inner.
- is_ok() Literal[True]¶
Papertrail examples:
>>> Right(inner=None).is_ok() == True True
>>> Left(inner=None).is_ok() == False True
- map(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.U_co], *args: ~typing.~P, **kwargs: ~typing.~P) Right[U_co]¶
Papertrail examples:
>>> Right(inner=0).map(add_one) == Right(inner=1) True
>>> Left(inner=None).map(add_one) == Left(inner=None) True
- map_err(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.U_co], *args: ~typing.~P, **kwargs: ~typing.~P) Self¶
Papertrail examples:
>>> Right(inner=0).map_err(add_one) == Right(inner=0) True
>>> Left(inner=0).map_err(add_one) == Left(inner=1) True
- or_else(func: ~collections.abc.Callable[[~typing.Concatenate[~danom._monads._either.T_co, ~P]], ~danom._monads._either.Either[~danom._monads._either.U_co, ~danom._monads._either.E_co]], *args: ~typing.~P, **kwargs: ~typing.~P) Self¶
Pipe a function that returns a monad to recover from an
Left. ForRightwill return originalEither.
- unwrap() T_co¶
Unwrap the Right or
Leftmonad to get the inner value.
- class danom.Some(inner: T)¶
Bases:
Option,Generic- and_(opt_b: Option[T]) Option[T]¶
Papertrail examples:
A
Somecombined withNullthroughand_producesNull.>>> Some(inner=2).and_(Null()) == Null() True
A
Nullcombined with anSomethroughand_remainsNull.>>> Null().and_(Some(inner="foo")) == Null() True
When both options contain values,
and_keeps the secondSome.>>> Some(inner=2).and_(Some(inner="foo")) == Some(inner="foo") True
Combining two
Nullvalues withand_producesNull.>>> Null().and_(Null()) == Null() True
- and_then(fn: Callable[[T], Option[U]]) Option[U]¶
Papertrail examples:
A successful function passed to
and_thenreturns itsSomeresult.>>> Some(inner=2).and_then(must_be_less_than_10) == Some(inner=2) True
When the function returns
Null,and_thenpasses thatNullthrough.>>> Some(inner=20).and_then(must_be_less_than_10) == Null() True
An existing
Nullskips the function passed toand_then.>>> Null().and_then(must_be_less_than_10) == Null() True
- as_list() list[T]¶
Papertrail examples:
A
Somebecomes a one-item list throughas_list.>>> Some(inner=2).as_list() == [2] True
as_listrepresentsNullas an empty list.>>> Null().as_list() == [] True
- as_tuple() tuple[T, ...]¶
Papertrail examples:
A
Somebecomes a one-item tuple throughas_tuple.>>> Some(inner=2).as_tuple() == (2,) True
as_tuplerepresentsNullas an empty tuple.>>> Null().as_tuple() == () True
- expect(msg: str) T¶
Papertrail examples:
expectextracts the value from aSome.>>> Some(inner=2).expect("must be positive") == 2 True
- filter_(predicate: Callable[[T], bool]) Option[T]¶
Papertrail examples:
A
Somethat fails the predicate becomesNullthroughfilter_.>>> Some(inner=3).filter_(is_even) == Null() True
A
Somethat passes the predicate remains unchanged.>>> Some(inner=4).filter_(is_even) == Some(inner=4) True
filter_leavesNullunchanged without calling the predicate.>>> Null().filter_(is_even) == Null() True
- flatten() Option[T]¶
Papertrail examples:
Flattening three nested
Somevalues removes only the outer option.>>> Some(inner=Some(inner=Some(inner=2))).flatten() == Some(inner=Some(inner=2)) True
Flattening a doubly wrapped value returns the inner
Some.>>> Some(inner=Some(inner=2)).flatten() == Some(inner=2) True
Flattening a
Somewith a non-option value does nothing.>>> Some(inner=2).flatten() == Some(inner=2) True
A
Nullpasses throughflattenunchanged.>>> Null().flatten() == Null() True
- inner: T¶
- inspect(fn: Callable[[T], None]) Option[T]¶
Papertrail examples:
Inspecting a
Somecalls the function and returns the original option.>>> Some(inner=[1]).inspect(append_to_list) == Some(inner=[1]) True
Inspecting
NullreturnsNullwithout calling the function.>>> Null().inspect(append_to_list) == Null() True
- is_none() bool¶
Papertrail examples:
is_nonereportsFalsefor aSome.>>> Some(inner=2).is_none() == False True
For
Null,is_nonereportsTrue.>>> Null().is_none() == True True
- is_none_or(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects a
Some,is_none_orreportsFalse.>>> Some(inner=1).is_none_or(is_even) == False True
When the predicate accepts a
Some,is_none_orreportsTrue.>>> Some(inner=2).is_none_or(is_even) == True True
Nullmakesis_none_orreportTruewithout calling the predicate.>>> Null().is_none_or(is_even) == True True
- is_some() bool¶
Papertrail examples:
is_somereportsTruefor aSome.>>> Some(inner=2).is_some() == True True
For
Null,is_somereportsFalse.>>> Null().is_some() == False True
- is_some_and(fn: Callable[[T], bool]) bool¶
Papertrail examples:
When the predicate rejects a
Some,is_some_andreportsFalse.>>> Some(inner=1).is_some_and(is_even) == False True
When the predicate accepts a
Some,is_some_andreportsTrue.>>> Some(inner=2).is_some_and(is_even) == True True
A
Nullmakesis_some_andreportFalsewithout calling the predicate.>>> Null().is_some_and(is_even) == False True
- map(fn: Callable[[T], U]) Option[U]¶
Papertrail examples:
Mapping a
Someapplies the function and wraps its result in a newSome.>>> Some(inner=1).map(add_one) == Some(inner=2) True
Mapping
Nullleaves it unchanged and skips the function.>>> Null().map(add_one) == Null() True
- map_or(default: U, fn: Callable[[T], U]) U¶
Papertrail examples:
For a
Some,map_oruses the function result instead of the default.>>> Some(inner="foo").map_or(42, len) == 3 True
For
Null,map_orreturns the supplied default.>>> Null().map_or(42, len) == 42 True
- map_or_else(default: Callable[[], U], fn: Callable[[T], U]) U¶
Papertrail examples:
A
Somemakesmap_or_elseuse the mapping function.>>> Some(inner="foo").map_or_else(get_42, len) == 3 True
A
Nullmakesmap_or_elseuse the default function.>>> Null().map_or_else(get_42, len) == 42 True
- ok_or(err: E) Result[T, E]¶
Papertrail examples:
A
Someconverts toOkthroughok_or.>>> Some(inner="foo").ok_or(0) == Ok(inner="foo") True
A
Nullconverts toErrthroughok_or.>>> Null().ok_or(0) == Err(error=0) True
- ok_or_else(err: Callable[[], E]) Result[T, E]¶
Papertrail examples:
A
Someconverts toOkwithout calling the error function.>>> Some(inner="foo").ok_or_else(get_42) == Ok(inner="foo") True
A
Nullconverts toErrusing the error function result.>>> Null().ok_or_else(get_42) == Err(error=42) True
- or_(opt_b: Option[T]) Option[T]¶
Papertrail examples:
A
Somekeeps its value whenor_receivesNull.>>> Some(inner=2).or_(Null()) == Some(inner=2) True
A
Nullgives way to aSomepassed toor_.>>> Null().or_(Some(inner=100)) == Some(inner=100) True
When both options contain values,
or_keeps the firstSome.>>> Some(inner=2).or_(Some(inner=100)) == Some(inner=2) True
When both options are
Null,or_returnsNull.>>> Null().or_(Null()) == Null() True
- or_else(opt_b: Callable[[], Option[T]]) Option[T]¶
Papertrail examples:
A
Somepasses throughor_elsewithout calling the function.>>> Some(inner="barbarians").or_else(get_some_vikings) == Some(inner="barbarians") True
For
Null,or_elsereturns theSomeproduced by the function.>>> Null().or_else(get_some_vikings) == Some(inner="vikings") True
If the fallback also produces
Null,or_elsereturnsNull.>>> Null().or_else(Null) == Null() True
- replace(value: T) Option[T]¶
Papertrail examples:
Replacing a
Somereturns a newSomewith the replacement value.>>> Some(inner=2).replace(5) == Some(inner=5) True
Replacing
Nullleaves it asNull.>>> Null().replace(3) == Null() True
- transpose() Result[Option[T], Option[T]]¶
Papertrail examples:
Transposing
Some(Ok(value))producesOk(Some(value)).>>> Some(inner=Ok(inner=2)).transpose() == Ok(inner=Some(inner=2)) True
Transposing
Some(Err(error))producesErr(Some(error)).>>> Some(inner=Err(error=2)).transpose() == Err(error=Some(inner=2)) True
Transposing
NullproducesOk(Null()).>>> Null().transpose() == Ok(inner=Null()) True
- unwrap() T¶
Papertrail examples:
unwrapextracts the value from aSome.>>> Some(inner=2).unwrap() == 2 True
- unwrap_or(default: T) T¶
Papertrail examples:
With a
Some,unwrap_orreturns the value and ignores the default.>>> Some(inner="car").unwrap_or("bike") == "car" True
With
Null,unwrap_orreturns the default.>>> Null().unwrap_or("bike") == "bike" True
- unwrap_or_else(fn: Callable[[], T]) T¶
Papertrail examples:
A
Somemakesunwrap_or_elsereturn its value without calling the function.>>> Some(inner=4).unwrap_or_else(get_42) == 4 True
A
Nullmakesunwrap_or_elsereturn the function result.>>> Null().unwrap_or_else(get_42) == 42 True
- unzip() tuple[Option[T], Option[U]]¶
Papertrail examples:
Unzipping a
Somepair produces twoSomevalues.>>> Some(inner=(2, 2)).unzip() == (Some(inner=2), Some(inner=2)) True
Unzipping a
Somewith a non-pair value produces twoNullvalues.>>> Some(inner=4).unzip() == (Null(), Null()) True
Unzipping
Nullproduces twoNullvalues.>>> Null().unzip() == (Null(), Null()) True
- zip(other: Option[U]) Option[tuple[T, U]]¶
Papertrail examples:
Zipping two
Somevalues produces aSomecontaining both values.>>> Some(inner=1).zip(Some(inner="hi")) == Some(inner=(1, "hi")) True
Zipping a
SomewithNullproducesNull.>>> Some(inner=1).zip(Null()) == Null() True
Zipping
Nullwith aSomeproducesNull.>>> Null().zip(Some(inner=1)) == Null() True
- class danom.Stream(seq: tuple, ops: tuple = ())¶
Bases:
_BaseSyncStream,GenericA lazy iterator with functional operations.
Why bother?¶
Readability counts, abstracting common operations helps reduce cognitive complexity when reading code.
Comparison¶
Take this imperative pipeline of operations, it iterates once over the data, skipping the value if it fails one of the filter checks:
res = [] for x in range(1_000_000): item = triple(x) if not is_gt_ten(item): continue item = min_two(item) if not is_even_num(item): continue item = square(item) if not is_lt_400(item): continue res.append(item) [100, 256]
number of tokens: 90
number of keywords: 11
keyword breakdown: {‘for’: 1, ‘in’: 1, ‘if’: 3, ‘not’: 3, ‘continue’: 3}
After a bit of experience with python you might use list comprehensions, however this is arguably _less_ clear and iterates multiple times over the same data
mul_three = [triple(x) for x in range(1_000_000)] gt_ten = [x for x in mul_three if is_gt_ten(x)] sub_two = [min_two(x) for x in gt_ten] is_even = [x for x in sub_two if is_even_num(x)] squared = [square(x) for x in is_even] lt_400 = [x for x in squared if is_lt_400(x)] [100, 256]
number of tokens: 92
number of keywords: 15
keyword breakdown: {‘for’: 6, ‘in’: 6, ‘if’: 3}
This still has a lot of tokens that the developer has to read to understand the code. The extra keywords add noise that cloud the actual transformations.
Using a
Streamresults in this:from danom import Stream ( Stream.from_iterable(range(1_000_000)) .map(triple) .filter(is_gt_ten) .map(min_two) .filter(is_even_num) .map(square) .filter(is_lt_400) .collect() ) (100, 256)
number of tokens: 60
number of keywords: 0
keyword breakdown: {}
The business logic is arguably much clearer like this.
Version changes¶
0.13.0:Stream.map,Stream.filterandStream.tapnow take kwargs andpartialthem into the passed in function.- collect(*, workers: int = 4, use_threads: bool = False) tuple[U, ...]¶
Materialise the sequence from the
Stream.from danom import Stream stream = Stream.from_iterable([0, 1, 2, 3]).map(add_one) stream.collect() == (1, 2, 3, 4)
- danom.all_of(*fns: Callable[[T_co], bool]) Callable[[T_co], bool]¶
Trueif all of the given functions returnTrue.from danom import all_of is_valid_user = all_of(is_subscribed, is_active, has_2fa) is_valid_user(user) == True
- danom.any_of(*fns: Callable[[T_co], bool]) Callable[[T_co], bool]¶
Trueif any of the given functions returnTrue.from danom import any_of is_eligible = any_of(has_coupon, is_vip, is_staff) is_eligible(user) == True
- danom.compose(*fns: Callable[[T_co], T_co | U_co]) Callable[[T_co], T_co | U_co]¶
Compose multiple functions into one.
The functions will be called in sequence with the result of one being used as the input for the next.
from danom import compose add_two = compose(add_one, add_one) add_two(0) == 2 add_two_is_even = compose(add_one, add_one, is_even) add_two_is_even(0) == True
- danom.identity(x: T_co) T_co¶
Basic identity function.
from danom import identity identity("abc") == "abc" identity(1) == 1 identity(ComplexDataType(a=1, b=2, c=3)) == ComplexDataType(a=1, b=2, c=3)
Papertrail examples:
>>> identity(1) == 1 True
>>> identity("abc") == "abc" True
>>> identity([0, 1, 2]) == [0, 1, 2] True
>>> identity(Ok(inner=1)) == Ok(inner=1) True
- danom.invert(func: Callable[[T_co], bool]) Callable[[T_co], bool]¶
Invert a boolean function so it returns
Falsewhere it would’ve returnedTrue.from danom import invert invert(has_len)("abc") == False invert(has_len)("") == True
- danom.new_type(name: str, base_type: type, validators: Callable | Sequence[Callable] | None = None, converters: Callable | Sequence[Callable] | None = None, *, frozen: bool = True)¶
Create a NewType based on another type.
>>> from danom import new_type >>> def is_positive[T](value: T) -> bool: ... return value >= 0 >>> ValidBalance = new_type("ValidBalance", float, validators=[is_positive]) >>> ValidBalance(20.0) == ValidBalance(inner=20.0) True
Unlike an inherited class, the type will not return
Truefor an isinstance check.isinstance(ValidBalance(20.0), ValidBalance) == True isinstance(ValidBalance(20.0), float) == False
The methods of the given
base_typewill be forwarded to the specialised type. Alternatively the map method can be used to return a new type instance with the transformation.from danom import new_type def has_len(email: str) -> bool: return len(email) > 0 Email = new_type("Email", str, validators=[has_len]) Email("some_email@domain.com").upper() == "SOME_EMAIL@DOMAIN.COM" Email("some_email@domain.com").map(str.upper) == Email(inner='SOME_EMAIL@DOMAIN.COM')
- danom.none_of(*fns: Callable[[T_co], bool]) Callable[[T_co], bool]¶
Trueif none of the given functions returnTrue.from danom import none_of is_valid = none_of(is_empty, exceeds_size_limit, contains_unsupported_format) is_valid(submission) == True
- danom.safe(func: Callable[[P], U]) Callable[[P], Result[U, Exception]]¶
- danom.safe(func: None = None, *, errors: ExceptionType = Exception) Callable[[Callable[[P], U]], Callable[[P], Result[U, Exception]]]
Decorator for functions that wraps the function in a try except returns Ok on success else Err.
from danom import safe @safe def add_one(a: int) -> int: return a + 1 add_one(1) == Ok(inner=2)
Only catch a single error type or subset of error types by passing in an error type to catch.
from danom import safe @safe(errors=ZeroDivisionError) def div(a: int, b: int) -> float: return a / b div(2, 0) == Err(error=ZeroDivisionError('division by zero')) div(2, "") --------------------------------------------------------------------------- TypeError Traceback (most recent call last)
- danom.safe_method(func: Callable[[Concatenate[T, P]], U]) Callable[[Concatenate[T, P]], Result[U, Exception]]¶
The same as
safeexcept it forwards on theselfof the class instance to the wrapped function.from danom import safe_method class Adder: def __init__(self, result: int = 0) -> None: self.result = result @safe_method def add_one(self, a: int) -> int: return self.result + 1 Adder.add_one(1) == Ok(inner=1)