Skip to content

Commit 4554bd0

Browse files
katconnorsJelleZijlstraAlexWaygood
authored
Added error code for overlapping function signatures (#17597)
Closes #17570. This is my first contribution to mypy! 🐍 Added an error code for overlapping function signatures. Test in check-errorcodes.test is a derivative of this post: https://stackoverflow.com/q/69341607 Co-authored-by: Jelle Zijlstra <[email protected]> Co-authored-by: Alex Waygood <[email protected]>
1 parent 9d7a042 commit 4554bd0

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

docs/source/error_code_list.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,34 @@ types you expect.
11491149

11501150
See :ref:`overloading <function-overloading>` for more explanation.
11511151

1152+
1153+
.. _code-overload-cannot-match:
1154+
1155+
Check for overload signatures that cannot match [overload-cannot-match]
1156+
--------------------------------------------------------------------------
1157+
1158+
Warn if an ``@overload`` variant can never be matched, because an earlier
1159+
overload has a wider signature. For example, this can happen if the two
1160+
overloads accept the same parameters and each parameter on the first overload
1161+
has the same type or a wider type than the corresponding parameter on the second
1162+
overload.
1163+
1164+
Example:
1165+
1166+
.. code-block:: python
1167+
1168+
from typing import overload, Union
1169+
1170+
@overload
1171+
def process(response1: object, response2: object) -> object:
1172+
...
1173+
@overload
1174+
def process(response1: int, response2: int) -> int: # E: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match]
1175+
...
1176+
1177+
def process(response1: object, response2: object) -> object:
1178+
return response1 + response2
1179+
11521180
.. _code-annotation-unchecked:
11531181

11541182
Notify about an annotation in an unchecked function [annotation-unchecked]

mypy/errorcodes.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ def __hash__(self) -> int:
273273
# This is a catch-all for remaining uncategorized errors.
274274
MISC: Final[ErrorCode] = ErrorCode("misc", "Miscellaneous other checks", "General")
275275

276+
OVERLOAD_CANNOT_MATCH: Final[ErrorCode] = ErrorCode(
277+
"overload-cannot-match",
278+
"Warn if an @overload signature can never be matched",
279+
"General",
280+
sub_code_of=MISC,
281+
)
282+
283+
276284
OVERLOAD_OVERLAP: Final[ErrorCode] = ErrorCode(
277285
"overload-overlap",
278286
"Warn if multiple @overload variants overlap in unsafe ways",

mypy/messages.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,7 @@ def overloaded_signature_will_never_match(
16531653
index1=index1, index2=index2
16541654
),
16551655
context,
1656+
code=codes.OVERLOAD_CANNOT_MATCH,
16561657
)
16571658

16581659
def overloaded_signatures_typevar_specific(self, index: int, context: Context) -> None:

test-data/unit/check-errorcodes.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,3 +1222,17 @@ def f(x: str) -> TypeIs[int]: # E: Narrowed type "int" is not a subtype of inpu
12221222
pass
12231223

12241224
[builtins fixtures/tuple.pyi]
1225+
1226+
1227+
[case testOverloadedFunctionSignature]
1228+
from typing import overload, Union
1229+
1230+
@overload
1231+
def process(response1: float,response2: float) -> float:
1232+
...
1233+
@overload
1234+
def process(response1: int,response2: int) -> int: # E: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match]
1235+
...
1236+
1237+
def process(response1,response2)-> Union[float,int]:
1238+
return response1 + response2

0 commit comments

Comments
 (0)