no-overload-impl false positive with typevar inside
Bug Report
TypeVar after overload cause mypy raise a warning about missing impl and redef
(A clear and concise description of what the bug is.)
To Reproduce
from typing import Iterable, Sequence, TypeVar, overload
@overload
def chunks(c: str, n) -> Iterable[str]: ...
@overload
def chunks(c: bytes, n) -> Iterable[bytes]: ...
_T = TypeVar("_T")
def chunks(c: Sequence[_T], n) -> Iterable[Sequence[_T]]:
# looping till length l
for i in range(0, len(c), n):
yield c[i : i + n]
Expected Behavior
should not report errors
Actual Behavior
a.py:4: error: An overloaded function outside a stub file must have an implementation [no-overload-impl] a.py:15: error: Name "chunks" already defined on line 4 [no-redef]
Your Environment
- Mypy version used: 1.9.0
- Mypy command-line flags:
- Mypy configuration options from
mypy.ini(and other config files): - Python version used: 3.10
[tool.mypy]
allow_redefinition = true
ignore_missing_imports = true
check_untyped_defs = true
warn_no_return = false
Try moving the TypeVar definition above the overloads. That will resolve the errors.
Same here. What's in between the overload and the implementation does not matter. I can reproduce with _sentinel = object() instead of _T = TypeVar("_T").
I find it surprising that Mypy would depend on the structure of the file itself. I would expect it to see that I have an implementation, even if it's a thousand lines lower, with many other things in between, as long as it's in the same scope.
@cdce8p's suggestion works, but shows brittle behavior IMO :thinking:
@cdce8p could you elaborate why you closed as not planned :slightly_smiling_face:? I'm curious: is it hard to fix? Does Mypy really depend on the order it finds nodes in the AST or something?
@cdce8p could you elaborate why you closed as not planned :slightly_smiling_face:? I'm curious: is it hard to fix? Does Mypy really depend on the order it finds nodes in the AST or something?
It's defined that way in the typing spec. To quote the relevant section here
In regular modules, a series of
@overload-decorated definitions must be followed by exactly one non-@overload-decorated definition (for the same function/method).
https://typing.readthedocs.io/en/latest/spec/overload.html
But that doesn't mean that the implementation must appear right after the last overload, or that overloads should appear one after the other for that matter. I read this as "there must be an implementation, and there must be only one". Doesn't say where this implementation should appear :thinking:
I read this as "there must be an implementation, and there must be only one". Doesn't say where this implementation should appear 🤔
That might be true, however I'd argue that it makes the most sense for the implementation to be directly below the overloads (that's also what I've seen in code so far). AFAIK the mypy check literally looks for the next statement (after the overloads) and if that isn't the implementation, the error is emitted. Feel free to disable it / add a type: ignore[no-overload-impl] comment though. Type checking should work regardless.
Anyway, I don't believe there is a motivation to change that behavior and as such I closed it with not planned.
Sure, but the warnings are very confusing: redef and no overload impl while there is an implementation and no redefinition. And I suppose ignoring these two warnings prevents further type-checking on the overloads and implementation, which isn't great. Anyway, that's fine, thanks for your answers 😊