Skip to content

Commit

Permalink
Resolve errors shown in review
Browse files Browse the repository at this point in the history
  • Loading branch information
GNUSheep committed Dec 28, 2023
1 parent babfcdd commit 4d1086d
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 64 deletions.
83 changes: 37 additions & 46 deletions docs/result.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,18 @@ A typeguard to check if a result is an Ok

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]

```


---

<a href="https://github.com/rustedpy/result/blob/master/src/result/result.py#L523"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="https://github.com/rustedpy/result/blob/master/src/result/result.py#L521"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

## <kbd>function</kbd> `is_err`

Expand All @@ -82,20 +80,18 @@ A typeguard to check if a result is an Err

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]

```


---

<a href="https://github.com/rustedpy/result/blob/master/src/result/result.py#L542"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="https://github.com/rustedpy/result/blob/master/src/result/result.py#L538"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

## <kbd>function</kbd> `do`

Expand All @@ -110,33 +106,29 @@ Do notation for Result (syntactic sugar for sequence of `and_then()` calls).
Usage:

``` rust

// This is similar to
use do_notation::m;
let final_result = m! {
x <- Ok("hello");
y <- Ok(True);
Ok(len(x) + int(y) + 0.5)
};

```

``` 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.


---

<a href="https://github.com/rustedpy/result/blob/master/src/result/result.py#L591"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="https://github.com/rustedpy/result/blob/master/src/result/result.py#L583"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

## <kbd>function</kbd> `do_async`

Expand All @@ -146,48 +138,47 @@ do_async(
) → Result[T, E]
```

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() )

```

NOTE: Python makes generators async in a counter-intuitive way.

``` python
Async version of do. Example:

# 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
an exception telling the user to use `do_async()` instead.
See `do()`.
``` 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()
)
```

However, for better usability, it's better for `do_async()` to also accept
regular generators, as you get in the first case:
NOTE: Python makes generators async in a counter-intuitive way.

``` python
``` python
# This is a regular generator:
async def foo(): ...
do(Ok(1) for x in await foo())
```

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 an exception telling the user to use `do_async()` instead. See `do()`.

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.
However, for better usability, it's better for `do_async()` to also accept regular generators, as you get in the first case:

``` 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.


---

Expand Down
20 changes: 2 additions & 18 deletions src/result/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,14 +506,12 @@ def is_ok(result: Result[T, E]) -> TypeGuard[Ok[T]]:
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]
```
"""
Expand All @@ -525,14 +523,12 @@ 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]
```
"""
Expand All @@ -546,25 +542,21 @@ def do(gen: Generator[Result[T, E], None, None]) -> Result[T, E]:
Usage:
``` rust
// This is similar to
use do_notation::m;
let final_result = m! {
x <- Ok("hello");
y <- Ok(True);
Ok(len(x) + int(y) + 0.5)
};
```
``` 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]`
Expand Down Expand Up @@ -594,28 +586,23 @@ async def do_async(
"""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()
)
```
NOTE: Python makes generators async in a counter-intuitive way.
``` 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(): ...
Expand All @@ -624,7 +611,6 @@ async def bar(): ...
for x in await foo()
for y in await bar()
)
```
We let users try to use regular `do()`, which works in some cases
Expand All @@ -636,10 +622,8 @@ async def bar(): ...
regular generators, as you get in the first case:
``` python
async def foo(): ...
do(Ok(1) for x in await foo())
```
Furthermore, neither mypy nor pyright can infer that the second case is
Expand Down

0 comments on commit 4d1086d

Please sign in to comment.