From e10cf8fd6d603086b49f3238ac22b4b62154cc95 Mon Sep 17 00:00:00 2001 From: Jeremy Nimmer Date: Fri, 21 Nov 2025 08:05:14 -0800 Subject: [PATCH] stubgen: Fix mis-parsing of double colon ("::") When parsing the docstrings of a function to find its set of overloads, C++ code samples that mention the function name were at risk of matching the C++ scoping operator "::" as a type annotation, leading to malformed output. For example "MyFunc(foo: int) -> bool" is a valid signature, but the sample code "MyFunc(Eigen::Lower)" was being mis-parsed. Fix this by patching stubgen to reset in case it sees a double colon where a single colon "name: type" stanza was expected. --- mypy/stubdoc.py | 13 +++++++++++++ mypy/test/teststubgen.py | 2 ++ 2 files changed, 15 insertions(+) diff --git a/mypy/stubdoc.py b/mypy/stubdoc.py index 89db6cb3378f..8f984037f96c 100644 --- a/mypy/stubdoc.py +++ b/mypy/stubdoc.py @@ -233,6 +233,19 @@ def add_token(self, token: tokenize.TokenInfo) -> None: self.accumulator = "" self.state.append(STATE_ARGUMENT_TYPE) + elif ( + token.type == tokenize.OP + and token.string == ":" + and self.state[-1] == STATE_ARGUMENT_TYPE + and self.accumulator == "" + ): + # We thought we were after the colon of an "arg_name: arg_type" + # stanza, so we were expecting an "arg_type" now. However, we ended + # up with "arg_name::" (with two colons). That's a C++ type name, + # not an argument name followed by a Python type. This function + # signature is malformed / invalid. + self.reset() + elif ( token.type == tokenize.OP and token.string == "=" diff --git a/mypy/test/teststubgen.py b/mypy/test/teststubgen.py index 43974cf8ec68..605409f99523 100644 --- a/mypy/test/teststubgen.py +++ b/mypy/test/teststubgen.py @@ -371,6 +371,8 @@ def test_infer_sig_from_docstring(self) -> None: [FunctionSig(name="func", args=[ArgSig(name="x", type=None)], ret_type="Any")], ) + assert_equal(infer_sig_from_docstring("\nfunc(invalid::type)", "func"), []) + assert_equal( infer_sig_from_docstring('\nfunc(x: str="")', "func"), [