dry-python / dry-python/returns

Kinded type behaving differently from non-kinded type in an invariant wrapper

Đang mở
#2,042 5 bình luận 0 reaction 0 người được giao Xem trên GitHub
bug
Ngôn ngữ chính
Python
Star
4.4k
Fork
155
Merge trung bình
2 giờ 27 phút
Pull request đã merge (30 ngày)
22

Mô tả

Hi Nikita, long time! Thanks for the interesting library bringing Haskell-like FP patterns to Python.

# Bug report

## What's wrong

I'm trying to extract the type `T` from a `Kind1` type (say, `Foo[T]`) that is wrapped in an invariant type, e.g., `list[Foo[T]]`. However, that's leading to some unexpected behavior.

Repro:

```py
from typing import Any, TypeVar

from returns.primitives import hkt

T = TypeVar("T")

class Foo(hkt.SupportsKind1["Foo[Any]", T]):
pass

# These are just helper functions to extract the type `T`.
def expect_list_foo(foo_list: list[Foo[T]]) -> list[T]:
return []

@hkt.kinded
def expect_list_foo__kinded(foo_list: list[hkt.Kind1[Foo[Any], T]]) -> list[T]:
return []

@hkt.kinded
def expect_tuple_foo__kinded(foo_tuple: tuple[hkt.Kind1[Foo[Any], T], str]) -> list[T]:
return []

def inferred_types(foo_list: list[Foo[int]], foo_tuple: tuple[Foo[int], str]) -> None:
x = expect_list_foo(foo_list)

y = expect_list_foo__kinded(foo_list) # <-- Problem

z = expect_tuple_foo__kinded(foo_tuple)

reveal_type(x)
reveal_type(y)
reveal_type(z)

print(x, y, z)
```

## How is that should be

I expected all three calls to work and return `list[int]`.

Actual output:

```
30: error: Argument 1 to "expect_list_foo__kinded" has incompatible type "list[Foo[int]]"; expected "list[KindN[Foo[Any], int, Any, Any]]" [arg-type]
30: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
30: note: Consider using "Sequence" instead, which is covariant
34: note: Revealed type is "builtins.list[builtins.int]"
35: note: Revealed type is "builtins.list[builtins.int]"
36: note: Revealed type is "builtins.list[builtins.int]"
Found 1 error in 1 file (checked 1 source file)
```

Seems like `list[Foo[int]]` is not treated as compatible with `list[hkt.Kind1[Foo[Any], T]]`. `tuple[Foo[int], str]` is treated as compatible with `tuple[hkt.Kind1[Foo[Any], T], str]`. So, it seems like this might be due to the invariance of `list`.

Is this expected behavior? How can I get this to work?

## System information

- `python` version: 3.10.8
- `returns` version: 0.24.0
- `mypy` version: 1.15.0

- `hypothesis` version (if any):
- `pytest` version (if any):

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.