Add decorator to make plain functions return a Result
See original GitHub issueIdea
While using the library, I came up with the idea to implement a simple decorator that wraps any plain function into try-except
and returns an Err
if an exception occurred. This makes it very easy to wrap existing “unsafe” functions and thus prevent runtime errors.
Example:
@safe_wrap
def i_will_fail():
raise Exception
@safe_wrap
def i_will_succeed():
return 42
output = i_will_fail()
assert(output.is_err())
output = i_will_succeed()
assert(output.is_ok())
Existing implementation
Just to give you an idea, here is my naive first implementation (shortened):
@singledispatch
def safe_wrap(f: Callable[[Any], Any], O]) -> Callable[[Any, Any], Result[O, Exception]]:
@wraps(f)
def wrapper(*args: Any, **kwargs: Any) -> Result[O, Exception]:
try:
return Ok(f(args, kwargs))
except Exception as err:
return Err(err)
return wrapper
# and now we register calls with no args and args only and kwargs only
@safe_wrap.register
def _(f: Callable[[Optional[Any]], O]) -> Callable[[Any, Any], Result[O, Exception]]:
[...]
Downsides
Typing arbitrary *args
and **kwargs
is not trivial, as described in https://github.com/python/mypy/issues/5876. In my current implementation, I work around this with using Any
and a generic dispatch. Nevertheless, this may not comply with the excessive typing that the rest of result
-module aims for.
Question(s)
What do you think about the concept and do you want something like this in the library? If so, I could provide a PR with a more elaborated version of the code shown above.
Issue Analytics
- State:
- Created 3 years ago
- Comments:13 (7 by maintainers)
good news everybody,
as_result()
is now merged #71see the readme for example usage!
@wbolster if I remember correctly, I did that to enable generic calls with
args
and/orkwargs
using the same decorator. But don‘t rely on that piece of code - I‘m not that into Python generics/typing.Mentioning that, I would really like you for investing time on this topic 👍🏼