Skip to content

Commit 05f2b00

Browse files
committed
Fix @overload decorator lines classified as Unanalyzed in lineprecision report
`@overload` is intentionally absent from the typemap, causing `StatisticsVisitor` to record `TYPE_UNANALYZED` for every decorator line. Route `OVERLOAD_NAMES` through `record_precise_if_checked_scope` and exempt them from its typemap guard. Fixes #21638.
1 parent 3179030 commit 05f2b00

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

mypy/stats.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
CallableType,
5151
FunctionLike,
5252
Instance,
53+
OVERLOAD_NAMES,
5354
TupleType,
5455
Type,
5556
TypeOfAny,
@@ -239,7 +240,10 @@ def visit_continue_stmt(self, o: ContinueStmt) -> None:
239240
self.record_precise_if_checked_scope(o)
240241

241242
def visit_name_expr(self, o: NameExpr) -> None:
242-
if o.fullname in ("builtins.None", "builtins.True", "builtins.False", "builtins.Ellipsis"):
243+
if o.fullname in (
244+
"builtins.None", "builtins.True", "builtins.False", "builtins.Ellipsis",
245+
*OVERLOAD_NAMES,
246+
):
243247
self.record_precise_if_checked_scope(o)
244248
else:
245249
self.process_node(o)
@@ -346,7 +350,12 @@ def process_node(self, node: Expression) -> None:
346350
self.type(self.typemap.get(node))
347351

348352
def record_precise_if_checked_scope(self, node: Node) -> None:
349-
if isinstance(node, Expression) and self.typemap and node not in self.typemap:
353+
if (
354+
isinstance(node, Expression)
355+
and self.typemap
356+
and node not in self.typemap
357+
and not (isinstance(node, NameExpr) and node.fullname in OVERLOAD_NAMES)
358+
):
350359
kind = TYPE_UNANALYZED
351360
elif self.is_checked_scope():
352361
kind = TYPE_PRECISE

test-data/unit/check-reports.test

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,34 @@ Name Lines Precise Imprecise Any Empty Unanalyzed
343343
-------------------------------------------------------------
344344
__main__ 5 3 0 1 1 0
345345
m 4 3 0 1 0 0
346+
347+
[case testLinePrecisionOverloadDecoratorCheckedScope]
348+
# flags: --lineprecision-report out
349+
from typing import overload
350+
351+
@overload
352+
def f(x: int) -> int: ...
353+
@overload
354+
def f(x: str) -> str: ...
355+
def f(x):
356+
return x
357+
[outfile out/lineprecision.txt]
358+
Name Lines Precise Imprecise Any Empty Unanalyzed
359+
-------------------------------------------------------------
360+
__main__ 9 5 0 2 2 0
361+
362+
[case testLinePrecisionOverloadDecoratorUncheckedScope]
363+
# flags: --lineprecision-report out
364+
from typing import overload
365+
366+
def outer():
367+
@overload
368+
def f(x: int) -> int: ...
369+
@overload
370+
def f(x: str) -> str: ...
371+
def f(x):
372+
return x
373+
[outfile out/lineprecision.txt]
374+
Name Lines Precise Imprecise Any Empty Unanalyzed
375+
-------------------------------------------------------------
376+
__main__ 10 1 0 7 2 0

0 commit comments

Comments
 (0)