From 9d9e60deb6bd37ac9c96858fa776dc76a2fa1bda Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:19:33 +0100 Subject: [PATCH] stubtest: Add a `--ignore-positional-only` argument --- docs/source/stubtest.rst | 4 ++++ mypy/stubtest.py | 12 ++++++++++++ mypy/test/teststubtest.py | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/docs/source/stubtest.rst b/docs/source/stubtest.rst index 59889252f0569..01601704d81a7 100644 --- a/docs/source/stubtest.rst +++ b/docs/source/stubtest.rst @@ -116,6 +116,10 @@ The rest of this section documents the command line interface of stubtest. Ignore errors for whether an argument should or shouldn't be positional-only +.. option:: --ignore-keyword-only + + Ignore errors for whether an argument should or shouldn't be keyword-only + .. option:: --allowlist FILE Use file as an allowlist. Can be passed multiple times to combine multiple diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 225c1c35c1bed..817f6e388b27a 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -135,6 +135,10 @@ def is_positional_only_related(self) -> bool: # TODO: This is hacky, use error codes or something more resilient return "leading double underscore" in self.message + def is_keyword_only_related(self) -> bool: + """Whether or not the error is for something being (or not being) keyword-only.""" + return "is not keyword-only" in self.message + def get_description(self, concise: bool = False) -> str: """Returns a description of the error. @@ -1864,6 +1868,7 @@ class _Arguments: concise: bool ignore_missing_stub: bool ignore_positional_only: bool + ignore_keyword_only: bool allowlist: list[str] generate_allowlist: bool ignore_unused_allowlist: bool @@ -1940,6 +1945,8 @@ def set_strict_flags() -> None: # not needed yet continue if args.ignore_positional_only and error.is_positional_only_related(): continue + if args.ignore_keyword_only and error.is_keyword_only_related(): + continue if error.object_desc in allowlist: allowlist[error.object_desc] = True continue @@ -2017,6 +2024,11 @@ def parse_options(args: list[str]) -> _Arguments: action="store_true", help="Ignore errors for whether an argument should or shouldn't be positional-only", ) + parser.add_argument( + "--ignore-keyword-only", + action="store_true", + help="Ignore errors for whether an argument should or shouldn't be keyword-only", + ) parser.add_argument( "--allowlist", "--whitelist", diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 55f35200a7f51..b047fed2e551e 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -2263,6 +2263,12 @@ def test_ignore_flags(self) -> None: ) assert output == "Success: no issues found in 1 module\n" + output = run_stubtest( + stub="def f(*, a): ...", runtime="def f(a): pass", options=["--ignore-keyword-only"], + ) + assert output == "Success: no issues found in 1 module\n" + + def test_allowlist(self) -> None: # Can't use this as a context because Windows allowlist = tempfile.NamedTemporaryFile(mode="w+", delete=False)