Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added error code for overlapping function signatures #17597

Merged
merged 15 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/source/error_code_list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,32 @@ types you expect.

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


.. _code-overload-cannot-match:

Check error code of overload function signature match
katconnors marked this conversation as resolved.
Show resolved Hide resolved
katconnors marked this conversation as resolved.
Show resolved Hide resolved
--------------------------------------------------------------------------

In the case of an overloaded function, if one of the signatures is never accessible, this error may occur.
An example where this can occur is with the utilization of floats and int types, due to the behavior of integers matching floats in mypy.
katconnors marked this conversation as resolved.
Show resolved Hide resolved
Consider swapping the declaration of the two types so that the narrower signature is declared before the broader signature.

Example:

.. code-block:: python

from typing import overload, Union

@overload
def process(response1: float,response2: float) -> float:
...
@overload
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]
...

def process(response1,response2)-> Union[float,int]:
return response1 + response2
katconnors marked this conversation as resolved.
Show resolved Hide resolved

.. _code-annotation-unchecked:

Notify about an annotation in an unchecked function [annotation-unchecked]
Expand Down
8 changes: 8 additions & 0 deletions mypy/errorcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ def __hash__(self) -> int:
# This is a catch-all for remaining uncategorized errors.
MISC: Final[ErrorCode] = ErrorCode("misc", "Miscellaneous other checks", "General")

OVERLOAD_CANNOT_MATCH: Final[ErrorCode] = ErrorCode(
"overload-cannot-match",
"Warn user about signature matching for overloaded functions.",
katconnors marked this conversation as resolved.
Show resolved Hide resolved
"General",
sub_code_of=MISC,
)


OVERLOAD_OVERLAP: Final[ErrorCode] = ErrorCode(
"overload-overlap",
"Warn if multiple @overload variants overlap in unsafe ways",
Expand Down
5 changes: 5 additions & 0 deletions mypy/message_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,8 @@ def with_additional_msg(self, info: str) -> ErrorMessage:
TYPE_ALIAS_WITH_AWAIT_EXPRESSION: Final = ErrorMessage(
"Await expression cannot be used within a type alias", codes.SYNTAX
)

# Overloads
OVERLOADED_FUNCTION_SIGNATURE: Final = ErrorMessage(
katconnors marked this conversation as resolved.
Show resolved Hide resolved
"Overloaded function signature {} will never be matched", codes.OVERLOAD_CANNOT_MATCH
)
1 change: 1 addition & 0 deletions mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,7 @@ def overloaded_signature_will_never_match(
index1=index1, index2=index2
),
context,
code=codes.OVERLOAD_CANNOT_MATCH,
)

def overloaded_signatures_typevar_specific(self, index: int, context: Context) -> None:
Expand Down
14 changes: 14 additions & 0 deletions test-data/unit/check-errorcodes.test
Original file line number Diff line number Diff line change
Expand Up @@ -1196,3 +1196,17 @@ def f(x: str) -> TypeIs[int]: # E: Narrowed type "int" is not a subtype of inpu
pass

[builtins fixtures/tuple.pyi]


[case testOverloadedFunctionSignature]
from typing import overload, Union

@overload
def process(response1: float,response2: float) -> float:
...
@overload
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]
...

def process(response1,response2)-> Union[float,int]:
return response1 + response2
Loading