Skip to content

Commit

Permalink
Add returns_result and unwrap_or_return to emulate question mark oper…
Browse files Browse the repository at this point in the history
…ator
  • Loading branch information
olekli committed Sep 4, 2024
1 parent 0b855e1 commit 4bd2902
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/result/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
UnwrapError,
as_async_result,
as_result,
returns_result,
is_ok,
is_err,
do,
Expand All @@ -20,6 +21,7 @@
"UnwrapError",
"as_async_result",
"as_result",
"returns_result",
"is_ok",
"is_err",
"do",
Expand Down
30 changes: 30 additions & 0 deletions src/result/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ def unwrap_or_raise(self, e: object) -> T:
"""
return self._value

def unwrap_or_return(self) -> T:
"""
Return the value.
"""
return self._value

def map(self, op: Callable[[T], U]) -> Ok[U]:
"""
The contained result is `Ok`, so return `Ok` with original value mapped to
Expand Down Expand Up @@ -358,6 +364,12 @@ def unwrap_or_raise(self, e: Type[TBE]) -> NoReturn:
"""
raise e(self._value)

def unwrap_or_return(self) -> NoReturn:
"""
The contained result is ``Err``, raise DoException with self.
"""
raise DoException(self)

def map(self, op: object) -> Err[E]:
"""
Return `Err` with the same value
Expand Down Expand Up @@ -464,6 +476,24 @@ def result(self) -> Result[Any, Any]:
return self._result


def returns_result() -> Callable[[Callable[P, Result[R, E]]], Callable[P, Result[R, E]]]:
"""
Make a decorator to turn a function into one that allows using unwrap_or_return.
"""
def decorator(f: Callable[P, Result[R, E]]) -> Callable[P, Result[R, E]]:
@functools.wraps(f)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> Result[R, E]:
try:
return f(*args, **kwargs)
except DoException as e:
out: Err[E] = e.err # type: ignore
return out

return wrapper

return decorator


def as_result(
*exceptions: Type[TBE],
) -> Callable[[Callable[P, R]], Callable[P, Result[R, TBE]]]:
Expand Down
18 changes: 17 additions & 1 deletion tests/test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from result import Err, Ok, OkErr, Result, UnwrapError, as_async_result, as_result
from result import Err, Ok, OkErr, Result, UnwrapError, as_async_result, as_result, returns_result


def test_ok_factories() -> None:
Expand Down Expand Up @@ -158,6 +158,22 @@ def test_unwrap_or_raise() -> None:
assert exc_info.value.args == ('nay',)


def test_unwrap_or_return() -> None:
@returns_result()
def func(yay):
if yay:
o = Ok('yay')
value = o.unwrap_or_return()
return Ok(value)
else:
n = Err('nay')
value = n.unwrap_or_return()
assert False

assert func(True).ok() == 'yay'
assert func(False).err() == 'nay'


def test_map() -> None:
o = Ok('yay')
n = Err('nay')
Expand Down

0 comments on commit 4bd2902

Please sign in to comment.