-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
False positive when decorating (e.g. with @final) an overloaded method in a subclass #8393
Comments
I confirm this still occurs on master. We recently fixed a similar issue, but it looks like only non-overloaded methods were fixed. Btw, this is another manifestation of #7724 |
any updates? |
With mypy 0.790, the following works: from typing import Sequence, Union, overload
class MyList(Sequence[int]):
@overload
def __getitem__(self, index: int) -> int:
...
@overload
def __getitem__(self, index: slice) -> Sequence[int]:
...
def __getitem__(self, index: Union[int, slice]) -> Union[int, Sequence[int]]:
if isinstance(index, int):
return index
elif isinstance(index, slice):
return list(range(slice.start or 0, slice.stop, slice.step or 1))
else:
raise TypeError
class MyTwice(MyList):
@overload
def __getitem__(self, index: int) -> int:
...
@overload
def __getitem__(self, index: slice) -> Sequence[int]:
...
def __getitem__(self, index: Union[int, slice]) -> Union[int, Sequence[int]]:
if isinstance(index, int):
return index * 2
elif isinstance(index, slice):
return list(range(slice.start * 2 or 0, slice.stop * 2, slice.step or 1))
else:
raise TypeError But it's a bit lengthy to write: all subclasses has to "copy/paste" the two overloads, removing them give back the:
|
@JulienPalard, I don't think that addresses this issue. What happens when you decorate the # test_case.py
from typing import TypeVar, Union, overload
_T = TypeVar("_T")
def identity(f: _T) -> _T:
return f
class MyTuple(tuple[int]):
@overload
def __getitem__(self, key: int) -> int:
...
@overload
def __getitem__(self, key: slice) -> "MyTuple":
...
@identity # <- comment this out and the error goes away
def __getitem__(self, key: Union[int, slice]) -> Union[int, "MyTuple"]:
if isinstance(key, int):
return 0
elif isinstance(key, slice):
return self
else:
raise TypeError(
"{} indices must be integers or slices, not {}".format(
type(self).__name__, type(key).__name__
)
) The above results in:
If I apply decorators to your example, the error(s) return: # test_case2.py
from typing import Sequence, TypeVar, Union, final, overload
_T = TypeVar("_T")
def identity(f: _T) -> _T:
return f
class MyList(Sequence[int]):
@overload
def __getitem__(self, index: int) -> int:
...
@overload
def __getitem__(self, index: slice) -> Sequence[int]:
...
def __getitem__(self, index: Union[int, slice]) -> Union[int, Sequence[int]]:
if isinstance(index, int):
return index
elif isinstance(index, slice):
return list(range(slice.start or 0, slice.stop, slice.step or 1))
else:
raise TypeError
class MyFinal(MyList):
@overload
def __getitem__(self, index: int) -> int:
...
@overload
def __getitem__(self, index: slice) -> Sequence[int]:
...
@final # <- comment this out and the error goes away
def __getitem__(self, index: Union[int, slice]) -> Union[int, Sequence[int]]:
if isinstance(index, int):
return index * 2
elif isinstance(index, slice):
return list(range(slice.start * 2 or 0, slice.stop * 2, slice.step or 1))
else:
raise TypeError
class MyIdentity(MyList):
@overload
def __getitem__(self, index: int) -> int:
...
@overload
def __getitem__(self, index: slice) -> Sequence[int]:
...
@identity # <- comment this out and the error goes away
def __getitem__(self, index: Union[int, slice]) -> Union[int, Sequence[int]]:
if isinstance(index, int):
return index * 2
elif isinstance(index, slice):
return list(range(slice.start * 2 or 0, slice.stop * 2, slice.step or 1))
else:
raise TypeError The above results in:
If I decorate
|
I think this bug was fixed along the way. I'm not able to repro it with the latest version of mypy. |
Example
No error. (without the
@final
it works)mypy 0.761, Python 3.6
Second example (without
@final
)Same error like the first example.
Workaround
Only known workaround is adding
type: ignore
The text was updated successfully, but these errors were encountered: