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

Add warn_name_override #15187

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions docs/source/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,14 @@ section of the command line docs.
Shows a warning when encountering any code inferred to be unreachable or
redundant after performing type analysis.

.. confval:: warn_name_override

:type: boolean
:default: False

Shows a warning when an argument could be used as either a positional or
keyword argument, but it has a different name than the parent argument.


Suppressing errors
******************
Expand Down
4 changes: 3 additions & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,9 @@ def check_override(
# Use boolean variable to clarify code.
fail = False
op_method_wider_note = False
if not is_subtype(override, original, ignore_pos_arg_names=True):
if not is_subtype(
override, original, ignore_pos_arg_names=not self.options.warn_name_override
):
fail = True
elif isinstance(override, Overloaded) and self.is_forward_op_method(name):
# Operator method overrides cannot extend the domain, as
Expand Down
7 changes: 7 additions & 0 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,13 @@ def add_invertible_flag(
help="Warn about statements or expressions inferred to be unreachable",
group=lint_group,
)
add_invertible_flag(
"--warn-name-override",
default=False,
strict_flag=False,
help="Warn about overridden positional argument names that could be used as keywords",
group=lint_group,
)

# Note: this group is intentionally added here even though we don't add
# --strict to this group near the end.
Expand Down
5 changes: 5 additions & 0 deletions mypy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class BuildType:
"warn_return_any",
"warn_unreachable",
"warn_unused_ignores",
"warn_name_override",
}

OPTIONS_AFFECTING_CACHE: Final = (
Expand Down Expand Up @@ -203,6 +204,10 @@ def __init__(self) -> None:
# Make arguments prepended via Concatenate be truly positional-only.
self.strict_concatenate = False

# Warn about methods that override the name of an argument that could be used
# either positionally or as a keyword argument.
self.warn_name_override = False

# Report an error for any branches inferred to be unreachable as a result of
# type analysis.
self.warn_unreachable = False
Expand Down
21 changes: 21 additions & 0 deletions test-data/unit/check-functions.test
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,27 @@ class B(A):
class C(A):
def f(self, foo: int, bar: str) -> None: pass

[case testPositionalOverridingArgumentNameSensitivityWithWarnNameOverride]
# flags: --warn-name-override
import typing

class A(object):
def f(self, a: int, b: str) -> None: pass

class B(A):
def f(self, b: str, a: int) -> None: pass # E: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "int" \
# N: This violates the Liskov substitution principle \
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides \
# E: Argument 2 of "f" is incompatible with supertype "A"; supertype defines the argument type as "str"

class C(A):
def f(self, foo: int, bar: str) -> None: pass # E: Signature of "f" incompatible with supertype "A" \
# N: Superclass: \
# N: def f(self, a: int, b: str) -> None \
# N: Subclass: \
# N: def f(self, foo: int, bar: str) -> None



[case testPositionalOverridingArgumentNamesCheckedWhenMismatchingPos]
import typing
Expand Down