Skip to content

Commit 7bb86ab

Browse files
AWhetterPCManticore
authored andcommitted
Can access per argument type comments (#667)
Close #665
1 parent e0a298d commit 7bb86ab

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ Release Date: TBA
5151
Close PyCQA/pylint#2734
5252
Close PyCQA/pylint#2740
5353

54+
* Can access per argument type comments through new ``Arguments.type_comment_args`` attribute.
55+
56+
Close #665
57+
5458

5559
What's New in astroid 2.2.0?
5660
============================

astroid/node_classes.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,7 @@ class Arguments(mixins.AssignTypeMixin, NodeNG):
14251425
"varargannotation",
14261426
"kwargannotation",
14271427
"kwonlyargs_annotations",
1428+
"type_comment_args",
14281429
)
14291430
varargannotation = None
14301431
"""The type annotation for the variable length arguments.
@@ -1499,6 +1500,15 @@ def __init__(self, vararg=None, kwarg=None, parent=None):
14991500
:type: list(NodeNG)
15001501
"""
15011502

1503+
self.type_comment_args = []
1504+
"""The type annotation, passed by a type comment, of each argument.
1505+
1506+
If an argument does not have a type comment,
1507+
the value for that argument will be None.
1508+
1509+
:type: list(NodeNG or None)
1510+
"""
1511+
15021512
def postinit(
15031513
self,
15041514
args,
@@ -1509,6 +1519,7 @@ def postinit(
15091519
kwonlyargs_annotations=None,
15101520
varargannotation=None,
15111521
kwargannotation=None,
1522+
type_comment_args=None,
15121523
):
15131524
"""Do some setup after initialisation.
15141525
@@ -1543,6 +1554,10 @@ def postinit(
15431554
:param kwargannotation: The type annotation for the variable length
15441555
keyword arguments.
15451556
:type kwargannotation: NodeNG
1557+
1558+
:param type_comment_args: The type annotation,
1559+
passed by a type comment, of each argument.
1560+
:type type_comment_args: list(NodeNG or None)
15461561
"""
15471562
self.args = args
15481563
self.defaults = defaults
@@ -1552,6 +1567,7 @@ def postinit(
15521567
self.kwonlyargs_annotations = kwonlyargs_annotations
15531568
self.varargannotation = varargannotation
15541569
self.kwargannotation = kwargannotation
1570+
self.type_comment_args = type_comment_args
15551571

15561572
def _infer_name(self, frame, name):
15571573
if self.parent is frame:

astroid/rebuilder.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ def visit_arguments(self, node, parent):
220220
kw_defaults = []
221221
annotations = []
222222
kwonlyargs_annotations = []
223+
type_comment_args = [self.check_type_comment(child) for child in node.args]
223224

224225
newnode.postinit(
225226
args=args,
@@ -230,6 +231,7 @@ def visit_arguments(self, node, parent):
230231
kwonlyargs_annotations=kwonlyargs_annotations,
231232
varargannotation=varargannotation,
232233
kwargannotation=kwargannotation,
234+
type_comment_args=type_comment_args,
233235
)
234236
# save argument names in locals:
235237
if vararg:

astroid/tests/unittest_nodes.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,45 @@ def func2():
10231023
assert node.type_comment_returns.as_string() == expected_returns_string
10241024

10251025

1026+
@pytest.mark.skipif(not HAS_TYPED_AST, reason="requires typed_ast")
1027+
def test_type_comments_arguments():
1028+
module = builder.parse(
1029+
"""
1030+
def func(
1031+
a, # type: int
1032+
):
1033+
# type: (...) -> str
1034+
pass
1035+
def func1(
1036+
a, # type: int
1037+
b, # type: int
1038+
c, # type: int
1039+
):
1040+
# type: (...) -> (str, str)
1041+
pass
1042+
def func2(
1043+
a, # type: int
1044+
b, # type: int
1045+
c, # type: str
1046+
d, # type: List[int]
1047+
):
1048+
# type: (...) -> List[int]
1049+
pass
1050+
"""
1051+
)
1052+
expected_annotations = [
1053+
["int"],
1054+
["int", "int", "int"],
1055+
["int", "int", "str", "List[int]"],
1056+
]
1057+
for node, expected_args in zip(module.body, expected_annotations):
1058+
assert len(node.type_comment_args) == 1
1059+
assert isinstance(node.type_comment_args[0], astroid.Ellipsis)
1060+
assert len(node.args.type_comment_args) == len(expected_args)
1061+
for expected_arg, actual_arg in zip(expected_args, node.args.type_comment_args):
1062+
assert actual_arg.as_string() == expected_arg
1063+
1064+
10261065
def test_is_generator_for_yield_assignments():
10271066
node = astroid.extract_node(
10281067
"""

0 commit comments

Comments
 (0)