False inconsistent overloads error
Closed this issue · 1 comments
MCausc78 commented
Describe the bug
Pyright reports that my overloads are not consistent. I expect successful typechecking. Didn't happen on Pyright v1.1.363.
PS D:\Projects\Python\pyvolt> py -m pyright .\pyright_bug.py
d:\Projects\Python\pyvolt\pyright_bug.py
d:\Projects\Python\pyvolt\pyright_bug.py:23:9 - error: Overloaded implementation is not consistent with signature of overload 2
Type "(self: Self@UserSettings, key: str, *default: str) -> (str | None)" is incompatible with type "(self: Self@UserSettings, key: str, default: str) -> str"
Missing keyword parameter "default" (reportInconsistentOverload)
d:\Projects\Python\pyvolt\pyright_bug.py:39:19 - information: Type of "setting1" is "str | None"
d:\Projects\Python\pyvolt\pyright_bug.py:42:19 - information: Type of "setting2" is "str"
1 error, 0 warnings, 2 informations
Code or Screenshots
from datetime import datetime
import typing as t
class UserSettings:
"""The user settings."""
value: dict[str, tuple[int, str]]
"""The {user_setting_key: (timestamp, value)} mapping."""
def __init__(self, value: dict[str, tuple[int, str]]) -> None:
self.value = value
def __getitem__(self, key: str) -> str:
return self.value[key][1]
@t.overload
def get(self, key: str) -> str | None: ...
@t.overload
def get(self, key: str, default: str) -> str: ...
def get(self, key: str, *default: str) -> str | None:
"""Get a user setting."""
if key in self.value:
return self.value[key][1]
return default[0] if default else None
if __name__ == "__main__":
settings = UserSettings(
{
"theme": (1, "dark"),
"locale": (2, "uk-UA"),
}
)
setting1 = settings.get("theme")
t.reveal_type(setting1)
print(setting1)
setting2 = settings.get("locale", "en-US")
t.reveal_type(setting2)
print(setting2)
VS Code extension or command-line
Using command-line tool. Tested on 1.1.364 and got same errors.
PS D:\Projects\Python\pyvolt> py -m pip show pyright
Name: pyright
Version: 1.1.365
Summary: Command line wrapper for pyright
Home-page: https://github.com/RobertCraigie/pyright-python
Author: Robert Craigie
Author-email:
License: MIT
Location: C:\Users\mclr\AppData\Local\Programs\Python\Python312\Lib\site-packages
Requires: nodeenv
Required-by:
erictraut commented
Pyright's new behavior is correct. Older versions contained a bug. The problem is that your second overload signature accepts a parameter default
by keyword, but your implementation does not.
Here's a simplified example that demonstrates why this is a problem.
from typing import overload
@overload
def func() -> str | None: ...
@overload
def func(default: str) -> str: ...
def func(*default: str) -> str | None:
pass
func(default="") # Crashes at runtime!
Here is how I would recommend fixing your implementation to avoid the bug:
def get(self, key: str, default: str | None = None) -> str | None:
if key in self.value:
return self.value[key][1]
return default