Skip to content

Commit c5f0b8f

Browse files
committed
Fix Arguments.arguments so it actually returns all arguments
Closes #2213. Arguments.arguments() has been modified so that it returns all arguments as it should (according to its own doc). A test case was also added to verify this.
1 parent a7ab088 commit c5f0b8f

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

astroid/nodes/node_classes.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,18 @@ def fromlineno(self) -> int:
780780
@cached_property
781781
def arguments(self):
782782
"""Get all the arguments for this node, including positional only and positional and keyword"""
783-
return list(itertools.chain((self.posonlyargs or ()), self.args or ()))
783+
retval = list(itertools.chain((self.posonlyargs or ()), (self.args or ())))
784+
if self.vararg:
785+
retval.append(
786+
Name(self.vararg, -1, -1, self, end_lineno=None, end_col_offset=None)
787+
)
788+
retval += self.kwonlyargs or ()
789+
if self.kwarg:
790+
retval.append(
791+
Name(self.kwarg, -1, -1, self, end_lineno=None, end_col_offset=None)
792+
)
793+
794+
return retval
784795

785796
def format_args(self, *, skippable_names: set[str] | None = None) -> str:
786797
"""Get the arguments formatted as string.
@@ -910,7 +921,9 @@ def default_value(self, argname):
910921
:raises NoDefault: If there is no default value defined for the
911922
given argument.
912923
"""
913-
args = self.arguments
924+
args = list(
925+
filter(lambda x: not isinstance(x, Name), self.arguments)
926+
) # Ignore *args and **kwargs
914927
index = _find_arg(argname, args)[0]
915928
if index is not None:
916929
idx = index - (len(args) - len(self.defaults))
@@ -955,7 +968,9 @@ def find_argname(self, argname, rec=DEPRECATED_ARGUMENT_DEFAULT):
955968
stacklevel=2,
956969
)
957970
if self.arguments:
958-
return _find_arg(argname, self.arguments)
971+
index, argument = _find_arg(argname, self.arguments)
972+
if not isinstance(argument, Name):
973+
return index, argument
959974
return None, None
960975

961976
def get_children(self):

astroid/nodes/scoped_nodes/scoped_nodes.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -963,11 +963,7 @@ def argnames(self) -> list[str]:
963963
names = [elt.name for elt in self.args.arguments]
964964
else:
965965
names = []
966-
if self.args.vararg:
967-
names.append(self.args.vararg)
968-
names += [elt.name for elt in self.args.kwonlyargs]
969-
if self.args.kwarg:
970-
names.append(self.args.kwarg)
966+
971967
return names
972968

973969
def infer_call_result(
@@ -1280,11 +1276,7 @@ def argnames(self) -> list[str]:
12801276
names = [elt.name for elt in self.args.arguments]
12811277
else:
12821278
names = []
1283-
if self.args.vararg:
1284-
names.append(self.args.vararg)
1285-
names += [elt.name for elt in self.args.kwonlyargs]
1286-
if self.args.kwarg:
1287-
names.append(self.args.kwarg)
1279+
12881280
return names
12891281

12901282
def getattr(

tests/test_nodes.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
Uninferable,
2323
bases,
2424
builder,
25+
extract_node,
2526
nodes,
2627
parse,
2728
test_utils,
@@ -1943,3 +1944,28 @@ def test_str_repr_no_warnings(node):
19431944
test_node = node(**args)
19441945
str(test_node)
19451946
repr(test_node)
1947+
1948+
1949+
def test_arguments_contains_all():
1950+
"""Ensure Arguments.arguments actually returns all available arguments"""
1951+
1952+
def manually_get_args(arg_node) -> set:
1953+
names = set()
1954+
if arg_node.args.vararg:
1955+
names.add(arg_node.args.vararg)
1956+
if arg_node.args.kwarg:
1957+
names.add(arg_node.args.kwarg)
1958+
1959+
names.update([x.name for x in arg_node.args.args])
1960+
names.update([x.name for x in arg_node.args.kwonlyargs])
1961+
1962+
return names
1963+
1964+
node = extract_node("""def a(fruit: str, *args, b=None, c=None, **kwargs): ...""")
1965+
assert manually_get_args(node) == {x.name for x in node.args.arguments}
1966+
1967+
node = extract_node("""def a(mango: int, b="banana", c=None, **kwargs): ...""")
1968+
assert manually_get_args(node) == {x.name for x in node.args.arguments}
1969+
1970+
node = extract_node("""def a(self, num = 10, *args): ...""")
1971+
assert manually_get_args(node) == {x.name for x in node.args.arguments}

0 commit comments

Comments
 (0)