diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 483e5eb4bc42..077d287655fb 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -486,6 +486,7 @@ def fix_function_overloads(self, stmts: List[Statement]) -> List[Statement]: ret: List[Statement] = [] current_overload: List[OverloadPart] = [] current_overload_name: Optional[str] = None + seen_unconditional_func_def = False last_if_stmt: Optional[IfStmt] = None last_if_overload: Optional[Union[Decorator, FuncDef, OverloadedFuncDef]] = None last_if_stmt_overload_name: Optional[str] = None @@ -498,6 +499,7 @@ def fix_function_overloads(self, stmts: List[Statement]) -> List[Statement]: if ( isinstance(stmt, IfStmt) and len(stmt.body[0].body) == 1 + and seen_unconditional_func_def is False and ( isinstance(stmt.body[0].body[0], (Decorator, OverloadedFuncDef)) or current_overload_name is not None @@ -527,6 +529,8 @@ def fix_function_overloads(self, stmts: List[Statement]) -> List[Statement]: self.fail_merge_overload(last_if_unknown_truth_value) last_if_unknown_truth_value = None current_overload.append(stmt) + if isinstance(stmt, FuncDef): + seen_unconditional_func_def = True elif ( current_overload_name is not None and isinstance(stmt, IfStmt) @@ -583,6 +587,7 @@ def fix_function_overloads(self, stmts: List[Statement]) -> List[Statement]: # most of mypy/mypyc assumes that all the functions in an OverloadedFuncDef are # related, but multiple underscore functions next to each other aren't necessarily # related + seen_unconditional_func_def = False if isinstance(stmt, Decorator) and not unnamed_function(stmt.name): current_overload = [stmt] current_overload_name = stmt.name diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 376ce0e30494..0d04074406e6 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -6302,3 +6302,29 @@ if True: def f12(x): ... reveal_type(f12(A())) # N: Revealed type is "__main__.A" [typing fixtures/typing-medium.pyi] + +[case testOverloadIfUnconditionalFuncDef] +# flags: --always-true True --always-false False +from typing import overload + +class A: ... +class B: ... + +# ----- +# Don't merge conditional FuncDef after unconditional one +# ----- + +@overload +def f1(x: A) -> A: ... +@overload +def f1(x: B) -> B: ... +def f1(x): ... + +@overload +def f2(x: A) -> A: ... +if True: + @overload + def f2(x: B) -> B: ... +def f2(x): ... +if True: + def f2(x): ... # E: Name "f2" already defined on line 17