dry-python / dry-python/returns

Standard library map on bound function

Ouverte
#807 4 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
bug
Langage dominant
Python
Étoiles
4.4k
Forks
155
Merge moyen
2 h 27 min
PR mergées (30 j)
22

Description

# Bug report

Mypy does not appear to correctly handle the standard library `map` function over an iterable of containers that returns an iterable of containers, when the function being mapped over the data has had `returns.pointfree.bind` applied to it. The same code when used without `map` (by explicit use of a for-loop) or a `bind` (by explicitly handling a container input) will not result in an error.

## What's wrong

### Code to reproduce issue

```python
from typing import Iterable

from returns.pointfree import bind
from returns.result import ResultE
from returns.result import safe

@safe
def f(x: int) -> str:
return str(x)

@safe
def g(x: str) -> int:
return int(x)

def h(xs: Iterable[ResultE[int]]) -> None:
for x in xs:
print(x.unwrap())

if __name__ == "__main__":
h(map(bind(g), map(f, range(3))))
```

### Mypy output

```bash
$ mypy test.py
test.py:24:11: error: Argument 1 to "map" has incompatible type "Kinded[Callable[[KindN[Result[Any, Any], str, Exception, NoReturn]], KindN[Result[Any, Any], int, Exception, NoReturn]]]"; expected "Callable[[Result[str, Exception]], Res
ult[int, Exception]]" [arg-type]
test.py:24:11: note: "Kinded[Callable[[KindN[Result[Any, Any], str, Exception, NoReturn]], KindN[Result[Any, Any], int, Exception, NoReturn]]].__call__" has type "Callable[[KindN[Result[Any, Any], str, Exception, NoReturn]], KindN[Resul
t[Any, Any], int, Exception, NoReturn]]"
Found 1 error in 1 file (checked 1 source file)
```

### Python output

```bash
$ python test.py
0
1
2
```

## How it should be

When the `h` function is replaced with a for-loop in `__main__` no issues are reported by Mypy and the code executes correctly:

```python
if __name__ == "__main__":
for x in map(f, range(3)):
print(x.bind(g).unwrap())
```

Can also fix the issue by swapping out the `g` function:

```python
def g(x: ResultE[str]) -> ResultE[int]:
return x.map(int)

if __name__ == "__main__":
h(map(g, map(f, range(3))))
```

## System information

- `python` version: 3.8.6
- `returns` version: 0.15.0
- `mypy` version: 0.800 (also observed in v0.782 due to `classess` library dependency)

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.