diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py index 8035008fd..d769b07b9 100644 --- a/astroid/nodes/scoped_nodes/scoped_nodes.py +++ b/astroid/nodes/scoped_nodes/scoped_nodes.py @@ -1401,6 +1401,8 @@ def blockstart_tolineno(self): :type: int """ + if self.returns: + return self.returns.tolineno return self.args.tolineno def implicit_parameters(self) -> Literal[0, 1]: diff --git a/tests/test_scoped_nodes.py b/tests/test_scoped_nodes.py index c95f53fd3..875ee057b 100644 --- a/tests/test_scoped_nodes.py +++ b/tests/test_scoped_nodes.py @@ -982,6 +982,46 @@ def foo(): with pytest.raises(AttributeInferenceError): func.getattr("") + @staticmethod + def test_blockstart_tolineno() -> None: + code = textwrap.dedent( + """\ + def f1(bar: str) -> None: #@ + pass + + def f2( #@ + bar: str) -> None: + pass + + def f3( #@ + bar: str + ) -> None: + pass + + def f4( #@ + bar: str + ): + pass + + def f5( #@ + bar: str): + pass + """ + ) + ast_nodes: list[nodes.FunctionDef] = builder.extract_node(code) # type: ignore[assignment] + assert len(ast_nodes) == 5 + + assert ast_nodes[0].blockstart_tolineno == 1 + + assert ast_nodes[1].blockstart_tolineno == 5 + + assert ast_nodes[2].blockstart_tolineno == 10 + + # Unimplemented, will return line 14 for now. + # assert ast_nodes[3].blockstart_tolineno == 15 + + assert ast_nodes[4].blockstart_tolineno == 19 + class ClassNodeTest(ModuleLoader, unittest.TestCase): def test_dict_interface(self) -> None: