diff --git a/docs/result.md b/docs/result.md index 639f918..def1d59 100644 --- a/docs/result.md +++ b/docs/result.md @@ -55,15 +55,22 @@ is_ok(result: 'Result[T, E]') → TypeGuard[Ok[T]] A typeguard to check if a result is an Ok -Usage: ``` r: Result[int, str] = get_a_result()``` -``` if is_ok(r):``` ``` r # r is of type Ok[int]``` -``` elif is_err(r):``` ``` r # r is of type Err[str]``` +Usage: +```python + +r: Result[int, str] = get_a_result() +if is_ok(r): + r # r is of type Ok[int] +elif is_err(r): + r # r is of type Err[str] + +``` --- - + ## function `is_err` @@ -73,15 +80,22 @@ is_err(result: 'Result[T, E]') → TypeGuard[Err[E]] A typeguard to check if a result is an Err -Usage: ``` r: Result[int, str] = get_a_result()``` -``` if is_ok(r):``` ``` r # r is of type Ok[int]``` -``` elif is_err(r):``` ``` r # r is of type Err[str]``` +Usage: +```python + +r: Result[int, str] = get_a_result() +if is_ok(r): + r # r is of type Ok[int] +elif is_err(r): + r # r is of type Err[str] + +``` --- - + ## function `do` @@ -93,7 +107,11 @@ Do notation for Result (syntactic sugar for sequence of `and_then()` calls). -Usage: ``` # This is similar to``` +Usage: + +``` rust + +// This is similar to use do_notation::m; let final_result = m! { x <- Ok("hello"); @@ -101,14 +119,24 @@ let final_result = m! { Ok(len(x) + int(y) + 0.5) }; -``` final_result: Result[float, int] = do(``` Ok(len(x) + int(y) + 0.5) for x in Ok("hello") for y in Ok(True) ) +``` + +``` rust + +final_result: Result[float, int] = do( + Ok(len(x) + int(y) + 0.5) + for x in Ok("hello") + for y in Ok(True) + ) + +``` NOTE: If you exclude the type annotation e.g. `Result[float, int]` your type checker might be unable to infer the return type. To avoid an error, you might need to help it with the type hint. --- - + ## function `do_async` @@ -118,28 +146,26 @@ do_async( ) → Result[T, E] ``` -Async version of do. Example: +Async version of do. Example: ``` +``` python -``` final_result: Result[float, int] = await do_async(``` - Ok(len(x) + int(y) + z) - for x in await get_async_result_1() - for y in await get_async_result_2() - for z in get_sync_result_3() - ) +final_result: Result[float, int] = await do_async( Ok(len(x) + int(y) + z) for x in await get_async_result_1() for y in await get_async_result_2() for z in get_sync_result_3() ) + +``` NOTE: Python makes generators async in a counter-intuitive way. -This is a regular generator: - async def foo(): ... - do(Ok(1) for x in await foo()) - -But this is an async generator: - async def foo(): ... - async def bar(): ... - do( - Ok(1) - for x in await foo() - for y in await bar() - ) + +``` python + +# This is a regular generator: async def foo(): ... do(Ok(1) for x in await foo()) + +``` + +``` python + +# But this is an async generator: async def foo(): ... async def bar(): ... do( Ok(1) for x in await foo() for y in await bar() ) + +``` We let users try to use regular `do()`, which works in some cases of awaiting async values. If we hit a case like above, we raise @@ -149,14 +175,18 @@ See `do()`. However, for better usability, it's better for `do_async()` to also accept regular generators, as you get in the first case: -async def foo(): ... - do(Ok(1) for x in await foo()) +``` python + +async def foo(): ... do(Ok(1) for x in await foo()) + +``` Furthermore, neither mypy nor pyright can infer that the second case is actually an async generator, so we cannot annotate `do_async()` as accepting only an async generator. This is additional motivation to accept either. +``` --- diff --git a/src/result/result.py b/src/result/result.py index 2272be6..cb50cb2 100644 --- a/src/result/result.py +++ b/src/result/result.py @@ -503,7 +503,7 @@ async def async_wrapper(*args: P.args, **kwargs: P.kwargs) -> Result[R, TBE]: def is_ok(result: Result[T, E]) -> TypeGuard[Ok[T]]: """A typeguard to check if a result is an Ok - + Usage: ```python @@ -513,9 +513,9 @@ def is_ok(result: Result[T, E]) -> TypeGuard[Ok[T]]: r # r is of type Ok[int] elif is_err(r): r # r is of type Err[str] - + ``` - + """ return result.is_ok() @@ -525,14 +525,14 @@ def is_err(result: Result[T, E]) -> TypeGuard[Err[E]]: Usage: - ```python + ```python r: Result[int, str] = get_a_result() if is_ok(r): r # r is of type Ok[int] elif is_err(r): r # r is of type Err[str] - + ``` """ @@ -544,7 +544,7 @@ def do(gen: Generator[Result[T, E], None, None]) -> Result[T, E]: Usage: - + ``` rust // This is similar to