Skip to content

Commit 39c2a98

Browse files
committed
Allow passing arguments as None to FunctionDef builder
1 parent 630b069 commit 39c2a98

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

astroid/nodes/node_classes.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,11 @@ def __init__(
646646
647647
Can be None if the associated function does not have a retrievable
648648
signature and the arguments are therefore unknown.
649-
This happens with builtin functions implemented in C.
649+
This can happen with (builtin) functions implemented in C that have
650+
incomplete signature information.
650651
"""
652+
# TODO: Check if other attributes should also be None when
653+
# .args is None.
651654

652655
self.defaults: list[NodeNG]
653656
"""The default values for arguments that can be passed positionally."""
@@ -700,7 +703,7 @@ def __init__(
700703
# pylint: disable=too-many-arguments
701704
def postinit(
702705
self,
703-
args: list[AssignName],
706+
args: list[AssignName] | None,
704707
defaults: list[NodeNG],
705708
kwonlyargs: list[AssignName],
706709
kw_defaults: list[NodeNG | None],

astroid/raw_building.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,17 @@ def build_function(
126126
# first argument is now a list of decorators
127127
func = nodes.FunctionDef(name)
128128
argsnode = nodes.Arguments(parent=func)
129+
130+
# If args is None we don't have any information about the signature
131+
# (in contrast to when there are no arguments and args == []). We pass
132+
# this to the builder to indicate this.
133+
if args is not None:
134+
arguments = [nodes.AssignName(name=arg, parent=argsnode) for arg in args]
135+
else:
136+
arguments = None
137+
129138
argsnode.postinit(
130-
args=[nodes.AssignName(name=arg, parent=argsnode) for arg in args or ()],
139+
args=arguments,
131140
defaults=[],
132141
kwonlyargs=[
133142
nodes.AssignName(name=arg, parent=argsnode) for arg in kwonlyargs or ()
@@ -248,9 +257,6 @@ def object_build_methoddescriptor(
248257
func = build_function(
249258
getattr(member, "__name__", None) or localname, doc=member.__doc__
250259
)
251-
# set node's arguments to None to notice that we have no information, not
252-
# and empty argument list
253-
func.args.args = None
254260
node.add_local_node(func, localname)
255261
_add_dunder_class(func, member)
256262

tests/unittest_builder.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,13 @@ def test_parse_module_with_invalid_type_comments_does_not_crash():
945945
assert isinstance(node, nodes.Module)
946946

947947

948+
def test_arguments_of_signature() -> None:
949+
"""Test that arguments is None for function without an inferable signature."""
950+
node = builder.extract_node("int")
951+
classdef: nodes.ClassDef = next(node.infer())
952+
assert all(i.args.args is None for i in classdef.getattr("__dir__"))
953+
954+
948955
class HermeticInterpreterTest(unittest.TestCase):
949956
"""Modeled on https://github.com/PyCQA/astroid/pull/1207#issuecomment-951455588"""
950957

0 commit comments

Comments
 (0)