Description
Describe the bug
Pyright expects generic unions which are based on a bound type variable to be given a type which subclasses the bound rather than an instance which subclasses the bound. This breaks from normal/expected behaviour where it should expect an instance unless typing.Type
/type
is explicitly used.
As a note, I also observed unexpected behaviour when wrapping the type variable in Type while declaring the Union with typing.Union[int, Type[FooT]]
changing pyright's behaviour so that it now passes bat: FooIsh[Bar] = 42
but returns an error on bat2: FooIsh[typing.Type[Bar]] = 42
.
To Reproduce
Check the following example code with pyright and watch it produce the following unexpected error
C:\Users\Lucina\PycharmProjects\hikari\test.py
C:\Users\Lucina\PycharmProjects\hikari\test.py:19:6 - error: Could not specialize type "FooIsh[Type[FooT@FooIsh]]"
Type "Bar" is incompatible with bound type "Type[Foo]" for type variable "FooT@FooIsh"
Type "Bar" cannot be assigned to type "Type[Foo]"
1 error, 0 warnings, 0 infos
Expected behavior
Pyright should allow bat: FooIsh[Bar] = 42
since Bar subclasses the defined bound and error on bat2: FooIsh[typing.Type[Bar]] = 42
since the union isn't defined as taking Type[FooT]
.
Screenshots or Code
import typing
class Foo:
def __int__(self) -> int:
return 0
FooT = typing.TypeVar("FooT", bound=Foo)
FooIsh = typing.Union[int, FooT]
class Bar(Foo):
def __int__(self) -> int:
return super().__int__() + 1
# This should be valid but Pyright complains about it.
bat: FooIsh[Bar] = 42
# This shouldn't be valid but Pyright accepts it.
bat2: FooIsh[typing.Type[Bar]] = 42
VS Code extension or command-line
Running pyright 1.1.138 on Windows 10 Pro (21364.1000)