dry-python / dry-python/returns

Higher Kinded Types Example Refactored

オープン
#1,343 コメント 0 件 リアクション 2 件 担当者 2 名 @thepabloaguilar が担当を希望しています GitHub で見る
bug documentation
主要言語
Python
スター
4.4k
フォーク
155
平均マージ
2時間 27分
マージ済み PR(30日)
22

説明

# Bug report

The typing inferred via higher-kinded types does not seem to be correct

## What's wrong

I've started to play around with the Higher-Kinded Types (I'd really love to be able to type even with type classes) that are provided in the library, following the blog post [here](https://dev.to/wemake-services/higher-kinded-types-in-python-51n8) (By the way...terrific blog!). One (seemingly basic) thing that I tried to do, was to turn the `apply_function` into a class method of `HasValue`, rather than a stand-alone function. However, I've then stumbled into a number of issues.

If one simply puts the function into the class, making it a method, you'd end up with the following conflict:

> The erased type of self "returns.primitives.hkt.KindN[_InstanceKind`-1, _ValueType`1, Any, Any]" is not a supertype of its class "test_mypy_working.HasValue[_ValueType`1]"

yes, right. The `HasValue` class does not inherit from `KindN`. Therefore, I have made `HasValue` extends the `KindSupports`, also avoiding to re-inherit this in the child classes `Bag` and `Box` .

```
class HasValue(SupportsKind1[_InstanceKind, _ValueType], Generic[_InstanceKind, _ValueType]):
@abc.abstractmethod
@property
def value(self) -> _ValueType:
"""Returns a value property."""

@abc.abstractmethod
def with_value(
self: _InstanceKind,
new_value: _NewValueType,
) -> Kind1[_InstanceKind, _NewValueType]:
"""Creates a new instance with a changed value."""

@kinded
def apply_function(
self: Kind1[_InstanceKind, _ValueType],
callback: Callable[[_ValueType], _NewValueType],
) -> Kind1[_InstanceKind, _NewValueType]:
new_value = callback(self.value)
return self.with_value(new_value)

@dataclasses.dataclass
class Box(HasValue["Box", _ValueType]):
value: _ValueType
length: int
width: int
height: int

def with_value(self, new_value: _NewValueType) -> "Box[_NewValueType]":
return Box(new_value, self.length, self.width, self.height)

@dataclasses.dataclass
class Bag(HasValue["Bag", _ValueType]):
value: _ValueType
brand: str
model: str

def with_value(self: "Bag", new_value: _NewValueType) -> "Bag[_NewValueType]":
return Bag(new_value, self.brand, self.model)

```

When doing this, however `mypy` complains with the following message:

> error: Incompatible return value type (got "KindN[_ValueType, _NewValueType, Any, Any]", expected "KindN[_InstanceKind, _NewValueType, Any, Any]")

which I can't quite understand. How does it get the `KindN[_ValueType, ...]` from the` self.with_value` method that returns `KindN[_InstanceKind, ...]`

Despite the error, if in the script I place the following lines, mypy nevertheless INDEED DOES the correct inference

```
box = Box(value=10, length=1, width=2, height=3)
reveal_type(box.apply_function(str))

Revealed type is "hkt.Box[builtins.str]"
```

## How is that should be

I suppose the error should not appear, unless I'm missing some points here. I'm still new to these features of this library and I'm still wrapping my head around it

Love dry-python? ❤️
Do you want your bugs to be solved faster?

Please consider supporting us:
👉 https://github.com/sponsors/dry-python

-->

## System information

- `python` version: 3.7.6
- `returns` version: 0.19.0
- `mypy` version: 0.941
- `mypy-extensions` version: 0.4.3

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

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。