Skip to content

Commit 547f363

Browse files
hauntsaninjaKotlinIsland
authored andcommitted
Warn for missing returns with explicit Any return types
1 parent 7b04be8 commit 547f363

File tree

7 files changed

+50
-2
lines changed

7 files changed

+50
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Support `BASEDMYPY_TYPE_CHECKING` (#702)
88
- Enable stub mode within `TYPE_CHECKING` branches (#702)
99
- Infer from overloads - add default value in impl (#697)
10+
- Warn for missing returns with explicit `Any` return types (#715)
1011
### Fixes
1112
- positional arguments on overloads break super (#697)
1213
- positional arguments on overloads duplicate unions (#697)

mypy/checker.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,11 @@ def check_func_def(
15931593
if self.options.warn_no_return:
15941594
if (
15951595
not self.current_node_deferred
1596-
and not isinstance(return_type, (NoneType, AnyType))
1596+
and not isinstance(return_type, (NoneType, UntypedType))
1597+
and (
1598+
not isinstance(return_type, AnyType)
1599+
or return_type.type_of_any == TypeOfAny.explicit
1600+
)
15971601
and show_error
15981602
):
15991603
# Control flow fell off the end of a function that was

mypyc/test-data/run-primitives.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ def get_item(o: Any, k: Any) -> Any:
168168
return o[k]
169169
def set_item(o: Any, k: Any, v: Any) -> Any:
170170
o[k] = v
171+
return o
171172
[file driver.py]
172173
from native import *
173174
assert neg(6) == -6

test-data/unit/check-overloading.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ def f(x: Any) -> Any:
187187
foo = 1
188188
if int():
189189
foo = "bar" # E: Incompatible types in assignment (expression has type "str", variable has type "int")
190+
return foo
190191

191192
@overload
192193
def g(x: 'A') -> 'B': ...
@@ -4906,13 +4907,15 @@ def f() -> None:
49064907
def g(x: T) -> Dict[int, T]: ...
49074908
def g(*args, **kwargs) -> Any:
49084909
reveal_type(h(C())) # N: Revealed type is "builtins.dict[builtins.str, __main__.C]"
4910+
return args
49094911

49104912
@overload
49114913
def h() -> None: ...
49124914
@overload
49134915
def h(x: T) -> Dict[str, T]: ...
49144916
def h(*args, **kwargs) -> Any:
49154917
reveal_type(g(C())) # N: Revealed type is "builtins.dict[builtins.int, __main__.C]"
4918+
return args
49164919

49174920
[builtins fixtures/dict.pyi]
49184921
[out]

test-data/unit/check-warnings.test

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,39 @@ def f() -> int:
140140
pass
141141
[out]
142142

143+
[case testNoReturnExplicitAny]
144+
# flags: --warn-no-return
145+
from typing import Any
146+
from unknown import Mystery # type: ignore[import]
147+
from basedtyping import Untyped
148+
149+
def maybe() -> bool: ...
150+
151+
def implicit(x: Any):
152+
if maybe():
153+
return x
154+
155+
def explicit(x: Any) -> Any: # E: Missing return statement
156+
if maybe():
157+
return x
158+
159+
def explicit_with_none(x: Any) -> Any:
160+
if maybe():
161+
return x
162+
return None
163+
164+
def explicit_with_just_return(x: Any) -> Any:
165+
if maybe():
166+
return x
167+
return
168+
169+
def mystery(x: Any) -> Mystery:
170+
if maybe():
171+
return x
172+
173+
def untyped(x: Any) -> Untyped:
174+
if maybe():
175+
return x
143176

144177
-- Returning Any
145178
-- -------------

test-data/unit/deps.test

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ def f(x: str) -> submod.B: pass
917917
def f(x) -> Any:
918918
y: submod.C
919919
y.x
920+
return y
920921
[file submod.py]
921922
class A: pass
922923
class B: pass
@@ -959,6 +960,7 @@ def f(x: int) -> None: pass
959960
def f(x: str) -> str: pass
960961
def f(x: Any) -> Any:
961962
mod.g()
963+
return mod
962964
[file mod.py]
963965
def g() -> int:
964966
pass
@@ -976,6 +978,7 @@ def outer() -> None:
976978
def f(x: str) -> mod.B: pass
977979
def f(x: Any) -> Any:
978980
mod.g()
981+
return mod
979982
[file mod.py]
980983
def g() -> int:
981984
pass
@@ -997,6 +1000,7 @@ def outer() -> None:
9971000
def f(x: str) -> str: pass
9981001
def f(x: Any) -> Any:
9991002
mod.g(str())
1003+
return mod
10001004
[file mod.py]
10011005
from typing import overload
10021006
@overload
@@ -1018,7 +1022,7 @@ class Outer:
10181022
@overload
10191023
def f(self, x: str, cb=mod.g) -> str: pass
10201024
def f(self, *args: Any, **kwargs: Any) -> Any:
1021-
pass
1025+
return args
10221026
[file mod.py]
10231027
from typing import overload
10241028
@overload

test-data/unit/fine-grained.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6990,6 +6990,7 @@ def outer() -> None:
69906990
def f(x: str) -> str: pass
69916991
def f(x: Any) -> Any:
69926992
y: int = mod.f()
6993+
return y
69936994
[file mod.py]
69946995
def f() -> int:
69956996
pass
@@ -7252,6 +7253,7 @@ def f(x: str) -> submod.B: pass
72527253
def f(x) -> Any:
72537254
y: submod.C
72547255
y.x = int()
7256+
return y
72557257
[file submod.py]
72567258
import other
72577259
class A: pass

0 commit comments

Comments
 (0)