From 2c75d58b2084af8783a25e8d32adde5b3ba63258 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Tue, 22 Feb 2022 12:06:32 +0000 Subject: [PATCH 1/2] Stubtest: do not error if a function is async in the stub, but not at runtime --- mypy/stubtest.py | 28 +++++++--------------------- mypy/test/teststubtest.py | 11 ++++++----- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index e15a5503ab11..205f90bb6de2 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -700,18 +700,6 @@ def _verify_signature( yield 'runtime does not have **kwargs argument "{}"'.format(stub.varkw.variable.name) -def _verify_coroutine( - stub: nodes.FuncItem, runtime: Any, *, runtime_is_coroutine: bool -) -> Optional[str]: - if stub.is_coroutine: - if not runtime_is_coroutine: - return 'is an "async def" function in the stub, but not at runtime' - else: - if runtime_is_coroutine: - return 'is an "async def" function at runtime, but not in the stub' - return None - - @verify.register(nodes.FuncItem) def verify_funcitem( stub: nodes.FuncItem, runtime: MaybeMissing[Any], object_path: List[str] @@ -736,20 +724,18 @@ def verify_funcitem( runtime_sig = Signature.from_inspect_signature(signature) runtime_sig_desc = f'{"async " if runtime_is_coroutine else ""}def {signature}' else: - runtime_sig_desc = None - - coroutine_mismatch_error = _verify_coroutine( - stub, - runtime, - runtime_is_coroutine=runtime_is_coroutine - ) + runtime_sig_desc, stub_sig = None, None - if coroutine_mismatch_error is not None: + # Don't raise an error if the stub is a coroutine, but the runtime isn't. + # That results in false positives. + # See https://github.com/python/typeshed/issues/7344 + if runtime_is_coroutine and not stub.is_coroutine: yield Error( object_path, - coroutine_mismatch_error, + 'is an "async def" function at runtime, but not in the stub', stub, runtime, + stub_desc=f'def {stub_sig!r}', runtime_desc=runtime_sig_desc ) diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 9cdb12afdf07..fa7505e37191 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -209,16 +209,17 @@ class X: @collect_cases def test_coroutines(self) -> Iterator[Case]: - yield Case( - stub="async def foo() -> int: ...", - runtime="def foo(): return 5", - error="foo", - ) yield Case( stub="def bar() -> int: ...", runtime="async def bar(): return 5", error="bar", ) + # Don't error for this one -- we get false positives otherwise + yield Case( + stub="async def foo() -> int: ...", + runtime="def foo(): return 5", + error=None, + ) yield Case( stub="def baz() -> int: ...", runtime="def baz(): return 5", From 5982c18e101ae0472eb5bc84b7ec4d5976a7345d Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Tue, 22 Feb 2022 12:14:16 +0000 Subject: [PATCH 2/2] fix --- mypy/stubtest.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 205f90bb6de2..a08b0aac1097 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -723,8 +723,9 @@ def verify_funcitem( stub_sig = Signature.from_funcitem(stub) runtime_sig = Signature.from_inspect_signature(signature) runtime_sig_desc = f'{"async " if runtime_is_coroutine else ""}def {signature}' + stub_desc = f'def {stub_sig!r}' else: - runtime_sig_desc, stub_sig = None, None + runtime_sig_desc, stub_desc = None, None # Don't raise an error if the stub is a coroutine, but the runtime isn't. # That results in false positives. @@ -735,7 +736,7 @@ def verify_funcitem( 'is an "async def" function at runtime, but not in the stub', stub, runtime, - stub_desc=f'def {stub_sig!r}', + stub_desc=stub_desc, runtime_desc=runtime_sig_desc )