pyright
pyright copied to clipboard
Regression in v1.1.374 with two-argument form of `super()` **inside** a class
Preamble
The release notes for pyright v1.1.374 contains:
Fixed bug that results in a false positive when using a two-argument form of super() outside of a class.
which appears to be in response to #8604 (and fixed by #8611).
This however appears to have caused a change in behavior with some code that uses super()
inside a class and which is not yet fully typed.
If the change is intended then feel free to close as not-a-bug.
(The errors below can also be fixed by adding more/the appropriate type hints so if the conclusion is more type-hints should be added then it can also be closed as not-a-bug.)
Describe the bug
Pyright now returns a different(/wrong) type for a classmethod call that uses the two-argument form of super()
.
Code or Screenshots
Minimal code example (real code is more complex and spread over multiple packages)
# pyright: strict
from typing import TypeVar, TYPE_CHECKING
_T = TypeVar("_T", bound="Model")
class Model:
def __init__(self, key: str) -> None:
self.key = key
@classmethod
def get(cls: type[_T], key: str) -> _T:
return cls(key=key)
class Base(Model):
@classmethod
def get(cls, key: str = "BASE"):
return super(Base, cls).get(key)
class Sub(Base):
pass
def show(obj: Sub):
print(obj.key)
sub = Sub.get()
print(sub.__class__)
show(sub)
if TYPE_CHECKING:
reveal_type(sub)
base = Base.get()
print(base.__class__)
if TYPE_CHECKING:
reveal_type(base)
pyright v1.1.373:
Running the code with Pyright v1.1.373:
$ PYRIGHT_PYTHON_FORCE_VERSION=1.1.373 poetry run pyright src/super.py
WARNING: there is a new pyright version available (v1.1.373 -> v1.1.376).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
.../src/super.py
.../src/super.py:37:17 - information: Type of "sub" is "Sub"
.../src/super.py:42:17 - information: Type of "base" is "Base"
0 errors, 0 warnings, 2 informations
pyright v1.1.374:
Running the code with Pyright v1.1.374:
$ PYRIGHT_PYTHON_FORCE_VERSION=1.1.374 poetry run pyright src/super.py
WARNING: there is a new pyright version available (v1.1.374 -> v1.1.376).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
.../src/super.py
.../src/super.py:35:6 - error: Argument of type "Base*" cannot be assigned to parameter "obj" of type "Sub" in function "show"
"Base*" is incompatible with "Sub" (reportArgumentType)
../src/super.py:37:17 - information: Type of "sub" is "Base*"
../src/super.py:42:17 - information: Type of "base" is "Base*"
1 error, 0 warnings, 2 informations
Avoiding the error
When the code is updated and the two-argument form of super()
removed then pyright v1.1.374 shows the same output as pyright v1.1.373.
diff --git a/src/super.py b/src/super.py
index d4f81a3..4abac31 100644
--- a/src/super.py
+++ b/src/super.py
@@ -19,7 +19,7 @@ class Model:
class Base(Model):
@classmethod
def get(cls, key: str = "BASE"):
- return super(Base, cls).get(key)
+ return super().get(key)
class Sub(Base):
Running again with pyright v1.1.374 (same output with v1.1.376):
PYRIGHT_PYTHON_FORCE_VERSION=1.1.374 poetry run pyright src/super.py
WARNING: there is a new pyright version available (v1.1.374 -> v1.1.376).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
.../src/super.py
.../src/super.py:37:17 - information: Type of "sub" is "Sub"
.../src/super.py:42:17 - information: Type of "base" is "Base"
0 errors, 0 warnings, 2 informations
Fixing the error
Really fixing the error can be done by adding more type-hints, i.e.
diff --git a/src/super.py b/src/super.py
index d4f81a3..f951d61 100644
--- a/src/super.py
+++ b/src/super.py
@@ -5,6 +5,7 @@ from typing import TypeVar, TYPE_CHECKING
_T = TypeVar("_T", bound="Model")
+_B = TypeVar("_B", bound="Base")
class Model:
@@ -18,7 +19,7 @@ class Model:
class Base(Model):
@classmethod
- def get(cls, key: str = "BASE"):
+ def get(cls: type[_B], key: str = "BASE") -> _B:
return super(Base, cls).get(key)
Running again with pyright v1.1.374 (same output with v1.1.376)
$ PYRIGHT_PYTHON_FORCE_VERSION=1.1.374 poetry run pyright src/super_fixed2.py
WARNING: there is a new pyright version available (v1.1.374 -> v1.1.376).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
.../src/super.py
.../src/super.py:38:17 - information: Type of "sub" is "Sub"
.../src/super.py:43:17 - information: Type of "base" is "Base"
0 errors, 0 warnings, 2 informations