diff --git a/mypy/stubdoc.py b/mypy/stubdoc.py index 6897706d1415..bfcbbdf49233 100644 --- a/mypy/stubdoc.py +++ b/mypy/stubdoc.py @@ -325,8 +325,11 @@ def add_token(self, token: tokenize.TokenInfo) -> None: token.type == tokenize.NAME and self.state[-1] == STATE_ARGUMENT_LIST and len(self.accumulator) != 0 + and self.accumulator != "*" + and self.accumulator != "**" ): - # not the first name in a row + # not the token after the argument list started + # special case for *args and **kwargs self.reset() return else: diff --git a/mypy/test/teststubgen.py b/mypy/test/teststubgen.py index 9424b9ffd9cf..29ccccce10bd 100644 --- a/mypy/test/teststubgen.py +++ b/mypy/test/teststubgen.py @@ -379,6 +379,21 @@ def test_infer_sig_from_docstring(self) -> None: ], ) + assert_equal( + infer_sig_from_docstring("\nfunc(*args)", "func"), + [FunctionSig(name="func", args=[ArgSig(name="*args")], ret_type="Any")], + ) + + assert_equal( + infer_sig_from_docstring("\nfunc(**kwargs)", "func"), + [FunctionSig(name="func", args=[ArgSig(name="**kwargs")], ret_type="Any")], + ) + + assert_equal( + infer_sig_from_docstring("\nfunc(*args, **kwargs)", "func"), + [FunctionSig(name="func", args=[ArgSig(name="*args"), ArgSig(name="**kwargs")], ret_type="Any")], + ) + def test_infer_sig_from_docstring_duplicate_args(self) -> None: assert_equal( infer_sig_from_docstring("\nfunc(x, x) -> str\nfunc(x, y) -> int", "func"), @@ -423,6 +438,21 @@ def test_infer_sig_from_docstring_invalid_signature(self) -> None: assert_equal(infer_sig_from_docstring("\nvoid func(int name) {", "func"), []) assert_equal(infer_sig_from_docstring("\nvoid func(std::vector name)", "func"), []) + def test_infer_sig_from_docstring_multiple_overloads(self) -> None: + input = """ +func(*args, **kwargs) +Overloaded function. + +1. func(self: class_type) -> None + +2. func(self: class_type, a: float, b: int) -> None +""" + assert_equal(infer_sig_from_docstring(input, "func"), [ + FunctionSig(name="func", args=[ArgSig(name="self", type="class_type")], ret_type="None"), + FunctionSig(name="func", args=[ArgSig(name="self", type="class_type"), ArgSig(name="a", type="float"), ArgSig(name="b", type="int")], ret_type="None"), + FunctionSig(name="func", args=[ArgSig(name="*args"), ArgSig(name="**kwargs")], ret_type="Any") + ]) + def test_infer_sig_from_docstring_deeply_nested_types(self) -> None: assert_equal( infer_sig_from_docstring( @@ -1489,3 +1519,15 @@ def module_to_path(out_dir: str, module: str) -> str: if os.path.exists(alt_fnam): return alt_fnam return fnam + +def main(): + suite = StubgenUtilSuite() + suite.test_infer_sig_from_docstring_invalid_signature() + suite.test_infer_sig_from_docstring() + suite.test_infer_sig_from_docstring_bad_indentation() + suite.test_infer_sig_from_docstring_duplicate_args() + suite.test_infer_sig_from_docstring_deeply_nested_types() + suite.test_infer_sig_from_docstring_multiple_overloads() + +if __name__ == "__main__": + main() \ No newline at end of file