Pyrefly confuses class name and locally defined methods, emitting false-positive `not-a-type`
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 516
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the Bug
## Summary
Pyrefly confuses method name and class name, and gives a false-positive `not-a-type`.
## Reproduction
Consider the following stub file (ng_typehint.pyi)
```ng_typehint.py
class A: ...
class B:
def A(self, name: str) -> A: ...
def take_a(self, a: A) -> str: ...
def return_a(self) -> A: ...
```
Pyright successfully typechecks with this module:
```sh
$ uvx pyright ng_typehint.pyi
0 errors, 0 warnings, 0 informations
```
On the other hand, pyrefly won't type check on this:
```sh
$ uvx pyrefly check ng_typehint.pyi
ERROR Expected a type form, got instance of `(self: Self@B, name: str) -> A` [not-a-type]
--> ng_typehint.pyi:5:25
|
5 | def take_a(self, a: A) -> str: ...
| ^
|
ERROR Expected a type form, got instance of `(self: Self@B, name: str) -> A` [not-a-type]
--> ng_typehint.pyi:6:27
|
6 | def return_a(self) -> A: ...
| ^
|
INFO 2 errors
```
## Discussion
As the first glance, the stub code might seem to have code-smell issue - but this pattern of aliasing can completely make sense because there are legitimate case to provide the smart constructors methods with the same name as the original class.
More concretely, we are developing some EDSL library in Python like this:
```py
class Type: ...
class Variable:
# Cannot be initialized without resorting to interpreter.
@property
def name(self) -> str: ...
def type(self) -> Type: ...
class Interpreter:
def Variable(self, name: str, type: Type) -> Variable:
...
def IntegerVariable(self, name: str) -> Variable: ...
```
... And actually pyright allows such a definition, and our library have been providing such feature for a long time.
So renaming smart constructors can break the entire API just to convince type checker sounds inapplicable.
### Sandbox Link
https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeSIAxlKnHAAQCCi9hbAOup9bQwEKJO9YfUwwwTABRwYUMABp66VAFsYLOABcATgEp6AWgB8TFm0JCRYiZtQBrGAH1U02QvqoWjfcfpbtZhzoIqLi9NowmgCu2ujOrnI%2BJsysQSDyIFGa0HAk5IggAMT0AKrZUBCapPRgUeiU2bjocJyc1jW42iqomo7oUSrYMNqS%2BCwQ6JpJfjqCwSIR0bE17CAAcgNDAfTA%2BAC%2Bq5zpIGQRYFCkhJq4KlAUxQAKpGcXfhg4BPSUTZAA5jE9CBNCzoYoAZRgMHoAAtNJpiHBEAB6JGncQXQidX5ImDoJGYXCUOBI77oP4Axp4jraDwAN1Q0FQ2FgXx%2BEH%2B2kBTXouGIlNynDImmhTQMtOGcCBwQAvPRVgBmQgARgATId0CA9hlUA0IOKAGLQGAUNBYPBEMiaoA
### (Only applicable for extension issues) IDE Information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.