facebook / facebook/pyrefly

`bad-return` on class with generic type var with default that returns generic with same type var

Open
#3,523 1 comment 0 reactions 0 assignees View on GitHub
stale typechecking
Dominant language
Rust
Stars
7k
Forks
516
PR merge metrics
No merged PRs in 30d

Description

### Describe the Bug

Hello! When running pyrefly on

```python
from typing import Self

class Fails1[T: int = int]:
t: T

def __copy__(self) -> "Fails1[T]":
return Fails1()

class Fails2[T: int = int]:
t: T

def __copy__(self) -> "Fails2[T]":
return Fails2[T]()

class WithoutGenericInReturn[T: int = int]:
t: T

def __copy__(self) -> "WithoutGenericInReturn":
return WithoutGenericInReturn()

class NoDefault[T: int]:
t: T

def __copy__(self) -> "NoDefault[T]":
return NoDefault()

class UsingSelf[T: int = int]:
t: T

def __copy__(self) -> Self:
return self.__class__()
```
I get
```
ERROR Returned type `Fails1` is not assignable to declared return type `Fails1[T]` [bad-return]
--> tmp.py:8:16
|
7 | def __copy__(self) -> "Fails1[T]":
| --------- declared return type
8 | return Fails1()
| ^^^^^^^^
|
ERROR Returned type `Fails2` is not assignable to declared return type `Fails2[T]` [bad-return]
--> tmp.py:15:16
|
14 | def __copy__(self) -> "Fails2[T]":
| --------- declared return type
15 | return Fails2[T]()
| ^^^^^^^^^^^
|
```

ty gives similar, but has some information about the generics:
```
Return type does not match returned value: expected `Fails1[T@Fails1]`, found `Fails1[int]` (invalid-return-type) [Ln 8, Col 16]
Return type does not match returned value: expected `Fails2[T@Fails2]`, found `Fails2[int]` (invalid-return-type) [Ln 15, Col 16]
```

pyright gives no errors

[ty playground](https://play.ty.dev/3375e8f9-aa41-455f-9857-cec25a9f00ef)
[pyright playground](https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMoDKApgDbACwAUFVQMYkCGAzk1AGINIlMCMA2gBUAXJhT4AvKJgBdIVSgLYIgTUqKoAEyLAoAfV20wCOPoAUTUsACUUALQA%2BKACIOXXoOlO5a9YpBEYAFcQFHZObh5TK1U6RhYwtwAmQRFUCSlZeUUYZVV1LR19Q2MzCzIbB2dXbmSBT29fPwDg0OqmWukomMp6ZlYAdSQYAAswQJgAcSIUIhAkWgBJFAAlZpCUqShJNMyfBRyoFWo9zW09AyMTXXNLCscnQZGxyenZ%2BaXVoJCvLMb-L9Cj1G4ymMzmixWaxQXWOsT6UAAcmAACLaBiBEgwDY7BrZXLHfJnIqXUq3Oz3JGo4DozEeH4ndT-FqIlFojEwGGqXrxACqTFQaGIZGxYi2GVx%2B3xv1OhQuJWuZWs5MIlglviZISgioAdEU4kwzFYgA)

I'm not sure who's right here, but in any case I think it's impossible to deduce what's going on from the error message. In the actual example there was a lot going on and it was not clear at all it was the default being the problem. I'm guessing that pyrefly similarly to ty resolves `T` to be `int`

### Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0BlGFDAAddOPEBjKKjhw6AMVTQ4ARgDaAFUSd0-ALx6GAXUTi6lxrq2T0Vuphhg6AfVdTcZdwAo4wsABKOgBaAD46URBlVU0tEyjzewcrShgGAFdKexiodR9Au2lZeSUVPIAmbV1WQ2MzCysGGzsHJxd3T29XPwDg8Mjo8rgq%2BMTGlLo0zOyy1VGTAqL0GTkFAHUIBgALXAyGAHEYdBhKCCkASXQAJXSs9GrjOiNahuTLZrpbCXfHZzcPF5SL5-CJ%2BhEopsdntDsdTucrrcZhIkBMUtN7nQobt9kcTmdLjc7tklj9ims6AA5XAAEWcqAyUAYj1eSQcn2%2BaPaAK6wJ6oKCoQhIGpdLADKZ2gSqN%2BDgxs1F9MZDFJdlWpQAqnBWGwhCIWfpnvU2U0Wj82v9OkCQX0hYIAibJvL7ALCJ0SnBfIEQAAaEBkNJgKCkQgMWhQCgAYjoAAVSIHg3Q0Fg8Pg6J50JA2FlUAwILh0IRxNGhDA6NsGAxiHBEAB6WsB5zBwi8Ni1461zC4KRwWsZrM5vMF2t0MC8OioABu5VQ2Fg6YLA8oufz9i8Q-QcCL6DI0PQIUnp21BaNUQAzIQ1AAWKLiDSnaiUOAJdAZdBcHh8GCYEKYCBpKQ80PI0AHIIDYdBeBgEDxEghgQjSABHDJ-2-EIAGsYFIEJUCkKR4AUIwQIAd1QbIYPQEAAF8-VwoCYEUaAYAoZMcAIEhyCooA

### (Only applicable for extension issues) IDE Information

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.