Describe the bug
I have a case where I introspect through classes with __subclasses__, and I can't get pyrefly to manage typing properly. Here is a reduced case:
In the simplest case I want pyrefly to just infer types without me telling it anything, but I get errors:
class Bottom: pass
class Mid1(Bottom): pass
class Mid2(Bottom): pass
class Top1(Mid1): pass
class Top2(Mid1): pass
class Top3(Mid2): pass
for mid in Bottom.__subclasses__(): # <-- Pyrefly(bad-argument-type) (see below)
for top in mid.__subclasses__(): # <--- Object of class `TypeVar` has no attribute `__subclasses__` Pyrefly(missing-attribute)
print(top.__name__)
... where that bad-argument-type" is Argument type is not assignable to parameter self with type TypeVar[Self] in function `type.subclasses``.
If I try and type those loop vars explicitly I get different errors:
class Bottom: pass
class Mid1(Bottom): pass
class Mid2(Bottom): pass
class Top1(Mid1): pass
class Top2(Mid1): pass
class Top3(Mid2): pass
mid: type[Bottom]
for mid in Bottom.__subclasses__(): # <-- Cannot use variable `mid` with type `type[Bottom]` to iterate through `list[TypeVar[Self]]` Pyrefly(bad-assignment)
top: type[Mid1 | Mid2]
for top in mid.__subclasses__(): # <-- Cannot use variable `top` with type `type[Mid1 | Mid2]` to iterate through `list[TypeVar[Self]]`Pyrefly(bad-assignment)
print(top.__name__)
This does seem to be a bit of a tricky case, since both mypy and pyright have varying issues as well:
- both mypy and pyright are 100% ok with the no-hints approach of the first example (no warnings or errors)
- In the second example, mypy does complain with this in the inner for loop:
Incompatible types in assignment (expression has type "type[Bottom]", variable has type "type[Mid1] | type[Mid2]")
- In the second example, pyright (via pylance) complains about the
top assignment with this:
Type "type[Bottom]" is not assignable to declared type "type[Mid1] | type[Mid2]"
Type "type[Bottom]" is not assignable to type "type[Mid1] | type[Mid2]"
"type[Bottom]" is not assignable to "type[Mid1]"
Type "type[Bottom]" is not assignable to type "type[Mid1]"
"type[Bottom]" is not assignable to "type[Mid2]"
Type "type[Bottom]" is not assignable to type "type[Mid2]" Pylance[reportAssignmentType](https://github.com/microsoft/pylance-release/blob/main/docs/diagnostics/reportAssignmentType.md)
(variable) top: type[Mid1] | type[Mid2]
VERSIONS
Relevant versions are:
- python:
3.11.13
- pyrefly vscode extension:
0.26.1
- vscode:
1.102.3
Sandbox Link
https://pyrefly.org/sandbox/?code=MYGwhgzhAEBCD2AXR8C2AuaAHSEBQeou0AsgJYAmAjABQLJoCUmOUh4UplATHUiqmbZcBIpwAq8LLXLUhrfGJiSsvWVXkil0FQGYas7prZ5UlTIgCeWAKYBtegIC6eAGbwATtDMVoZAHZw-GgAdAD6YRAArgBGSjYQETTMeNBp0ChYFtb26tAAPlwU3C7p0O5emX6BPuGRsfGJYcnoqWXpWB4BiDSZdf5gqDYRjHhAA
(Only applicable for extension issues) IDE Information
No response
Describe the bug
I have a case where I introspect through classes with
__subclasses__, and I can't get pyrefly to manage typing properly. Here is a reduced case:In the simplest case I want pyrefly to just infer types without me telling it anything, but I get errors:
... where that
bad-argument-type" isArgumenttypeis not assignable to parameterselfwith typeTypeVar[Self]in function `type.subclasses``.If I try and type those loop vars explicitly I get different errors:
This does seem to be a bit of a tricky case, since both mypy and pyright have varying issues as well:
Incompatible types in assignment (expression has type "type[Bottom]", variable has type "type[Mid1] | type[Mid2]")topassignment with this:VERSIONS
Relevant versions are:
3.11.130.26.11.102.3Sandbox Link
https://pyrefly.org/sandbox/?code=MYGwhgzhAEBCD2AXR8C2AuaAHSEBQeou0AsgJYAmAjABQLJoCUmOUh4UplATHUiqmbZcBIpwAq8LLXLUhrfGJiSsvWVXkil0FQGYas7prZ5UlTIgCeWAKYBtegIC6eAGbwATtDMVoZAHZw-GgAdAD6YRAArgBGSjYQETTMeNBp0ChYFtb26tAAPlwU3C7p0O5emX6BPuGRsfGJYcnoqWXpWB4BiDSZdf5gqDYRjHhAA
(Only applicable for extension issues) IDE Information
No response