summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniël van Noord <13665637+DanielNoord@users.noreply.github.com>2023-04-03 22:27:28 +0200
committerDaniël van Noord <13665637+DanielNoord@users.noreply.github.com>2023-04-03 22:40:15 +0200
commitf70ad92f3eb235d80e65a5b0492892e7868c096c (patch)
tree800a388c8673760b8665bf5dce4b8fb72e4bee60
parentb72eaa7d0440701a72e7b79ca9b1f7e8e9603b74 (diff)
downloadastroid-git-f70ad92f3eb235d80e65a5b0492892e7868c096c.tar.gz
Fix constructors of ``Arguments``
-rw-r--r--ChangeLog1
-rw-r--r--astroid/interpreter/objectmodel.py8
-rw-r--r--astroid/nodes/node_classes.py196
-rw-r--r--astroid/raw_building.py4
-rw-r--r--tests/test_scoped_nodes.py6
5 files changed, 85 insertions, 130 deletions
diff --git a/ChangeLog b/ChangeLog
index d5916c8c..d1d93408 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,7 @@ Release date: TBA
* Improved signature of the ``__init__`` and ``__postinit__`` methods of the following nodes:
- ``nodes.AnnAssign``
+ - ``nodes.Arguments``
- ``nodes.Assign``
- ``nodes.AssignAttr``
- ``nodes.AssignName``
diff --git a/astroid/interpreter/objectmodel.py b/astroid/interpreter/objectmodel.py
index ad4db3f4..6ff64afc 100644
--- a/astroid/interpreter/objectmodel.py
+++ b/astroid/interpreter/objectmodel.py
@@ -403,7 +403,9 @@ class FunctionModel(ObjectModel):
we get a new object which has two parameters, *self* and *type*.
"""
nonlocal func
- arguments = astroid.Arguments(parent=func.args.parent)
+ arguments = astroid.Arguments(
+ parent=func.args.parent, vararg=None, kwarg=None
+ )
positional_or_keyword_params = func.args.args.copy()
positional_or_keyword_params.append(
@@ -426,6 +428,8 @@ class FunctionModel(ObjectModel):
kwonlyargs=[],
kw_defaults=[],
annotations=[],
+ kwonlyargs_annotations=[],
+ posonlyargs_annotations=[],
)
return arguments
@@ -858,7 +862,7 @@ class PropertyModel(ObjectModel):
def _init_function(self, name):
function = nodes.FunctionDef(name=name, parent=self._instance)
- args = nodes.Arguments(parent=function)
+ args = nodes.Arguments(parent=function, vararg=None, kwarg=None)
args.postinit(
args=[],
defaults=[],
diff --git a/astroid/nodes/node_classes.py b/astroid/nodes/node_classes.py
index d2b9def6..93c8d47e 100644
--- a/astroid/nodes/node_classes.py
+++ b/astroid/nodes/node_classes.py
@@ -576,94 +576,78 @@ class Arguments(_base_nodes.AssignTypeNode):
_other_fields = ("vararg", "kwarg")
- lineno: None
- col_offset: None
- end_lineno: None
- end_col_offset: None
+ args: list[AssignName] | None
+ """The names of the required arguments.
- def __init__(
- self,
- vararg: str | None = None,
- kwarg: str | None = None,
- parent: NodeNG | None = None,
- ) -> None:
- """
- :param vararg: The name of the variable length arguments.
-
- :param kwarg: The name of the variable length keyword arguments.
-
- :param parent: The parent node in the syntax tree.
- """
- super().__init__(parent=parent)
-
- self.vararg: str | None = vararg # can be None
- """The name of the variable length arguments."""
-
- self.kwarg: str | None = kwarg # can be None
- """The name of the variable length keyword arguments."""
+ Can be None if the associated function does not have a retrievable
+ signature and the arguments are therefore unknown.
+ This can happen with (builtin) functions implemented in C that have
+ incomplete signature information.
+ """
- self.args: list[AssignName] | None
- """The names of the required arguments.
+ defaults: list[NodeNG] | None
+ """The default values for arguments that can be passed positionally."""
- Can be None if the associated function does not have a retrievable
- signature and the arguments are therefore unknown.
- This can happen with (builtin) functions implemented in C that have
- incomplete signature information.
- """
- # TODO: Check if other attributes should also be None when
- # .args is None.
+ kwonlyargs: list[AssignName]
+ """The keyword arguments that cannot be passed positionally."""
- self.defaults: list[NodeNG] | None
- """The default values for arguments that can be passed positionally."""
+ posonlyargs: list[AssignName]
+ """The arguments that can only be passed positionally."""
- self.kwonlyargs: list[AssignName]
- """The keyword arguments that cannot be passed positionally."""
+ kw_defaults: list[NodeNG | None] | None
+ """The default values for keyword arguments that cannot be passed positionally."""
- self.posonlyargs: list[AssignName] = []
- """The arguments that can only be passed positionally."""
+ annotations: list[NodeNG | None]
+ """The type annotations of arguments that can be passed positionally."""
- self.kw_defaults: list[NodeNG | None] | None
- """
- The default values for keyword arguments that cannot be passed positionally.
+ posonlyargs_annotations: list[NodeNG | None]
+ """The type annotations of arguments that can only be passed positionally."""
- See .args for why this can be None.
- """
+ kwonlyargs_annotations: list[NodeNG | None]
+ """The type annotations of arguments that cannot be passed positionally."""
- self.annotations: list[NodeNG | None]
- """The type annotations of arguments that can be passed positionally."""
+ type_comment_args: list[NodeNG | None]
+ """The type annotation, passed by a type comment, of each argument.
- self.posonlyargs_annotations: list[NodeNG | None] = []
- """The type annotations of arguments that can only be passed positionally."""
+ If an argument does not have a type comment,
+ the value for that argument will be None.
+ """
- self.kwonlyargs_annotations: list[NodeNG | None] = []
- """The type annotations of arguments that cannot be passed positionally."""
+ type_comment_kwonlyargs: list[NodeNG | None]
+ """The type annotation, passed by a type comment, of each keyword only argument.
- self.type_comment_args: list[NodeNG | None] = []
- """The type annotation, passed by a type comment, of each argument.
+ If an argument does not have a type comment,
+ the value for that argument will be None.
+ """
- If an argument does not have a type comment,
- the value for that argument will be None.
- """
+ type_comment_posonlyargs: list[NodeNG | None]
+ """The type annotation, passed by a type comment, of each positional argument.
- self.type_comment_kwonlyargs: list[NodeNG | None] = []
- """The type annotation, passed by a type comment, of each keyword only argument.
+ If an argument does not have a type comment,
+ the value for that argument will be None.
+ """
- If an argument does not have a type comment,
- the value for that argument will be None.
- """
+ varargannotation: NodeNG | None
+ """The type annotation for the variable length arguments."""
- self.type_comment_posonlyargs: list[NodeNG | None] = []
- """The type annotation, passed by a type comment, of each positional argument.
+ kwargannotation: NodeNG | None
+ """The type annotation for the variable length keyword arguments."""
- If an argument does not have a type comment,
- the value for that argument will be None.
- """
+ def __init__(self, vararg: str | None, kwarg: str | None, parent: NodeNG) -> None:
+ """Almost all attributes can be None for living objects where introspection failed."""
+ super().__init__(
+ parent=parent,
+ lineno=None,
+ col_offset=None,
+ end_lineno=None,
+ end_col_offset=None,
+ )
- self.varargannotation: NodeNG | None = None # can be None
- """The type annotation for the variable length arguments."""
+ self.vararg = vararg
+ """The name of the variable length arguments."""
- self.kwargannotation: NodeNG | None = None # can be None
- """The type annotation for the variable length keyword arguments."""
+ self.kwarg = kwarg
+ """The name of the variable length keyword arguments."""
# pylint: disable=too-many-arguments
def postinit(
@@ -673,76 +657,36 @@ class Arguments(_base_nodes.AssignTypeNode):
kwonlyargs: list[AssignName],
kw_defaults: list[NodeNG | None] | None,
annotations: list[NodeNG | None],
- posonlyargs: list[AssignName] | None = None,
- kwonlyargs_annotations: list[NodeNG | None] | None = None,
- posonlyargs_annotations: list[NodeNG | None] | None = None,
+ posonlyargs: list[AssignName],
+ kwonlyargs_annotations: list[NodeNG | None],
+ posonlyargs_annotations: list[NodeNG | None],
varargannotation: NodeNG | None = None,
kwargannotation: NodeNG | None = None,
type_comment_args: list[NodeNG | None] | None = None,
type_comment_kwonlyargs: list[NodeNG | None] | None = None,
type_comment_posonlyargs: list[NodeNG | None] | None = None,
) -> None:
- """Do some setup after initialisation.
-
- :param args: The names of the required arguments.
-
- :param defaults: The default values for arguments that can be passed
- positionally.
-
- :param kwonlyargs: The keyword arguments that cannot be passed
- positionally.
-
- :param posonlyargs: The arguments that can only be passed
- positionally.
-
- :param kw_defaults: The default values for keyword arguments that
- cannot be passed positionally.
-
- :param annotations: The type annotations of arguments that can be
- passed positionally.
-
- :param kwonlyargs_annotations: The type annotations of arguments that
- cannot be passed positionally. This should always be passed in
- Python 3.
-
- :param posonlyargs_annotations: The type annotations of arguments that
- can only be passed positionally. This should always be passed in
- Python 3.
-
- :param varargannotation: The type annotation for the variable length
- arguments.
-
- :param kwargannotation: The type annotation for the variable length
- keyword arguments.
-
- :param type_comment_args: The type annotation,
- passed by a type comment, of each argument.
-
- :param type_comment_args: The type annotation,
- passed by a type comment, of each keyword only argument.
-
- :param type_comment_args: The type annotation,
- passed by a type comment, of each positional argument.
- """
self.args = args
self.defaults = defaults
self.kwonlyargs = kwonlyargs
- if posonlyargs is not None:
- self.posonlyargs = posonlyargs
+ self.posonlyargs = posonlyargs
self.kw_defaults = kw_defaults
self.annotations = annotations
- if kwonlyargs_annotations is not None:
- self.kwonlyargs_annotations = kwonlyargs_annotations
- if posonlyargs_annotations is not None:
- self.posonlyargs_annotations = posonlyargs_annotations
+ self.kwonlyargs_annotations = kwonlyargs_annotations
+ self.posonlyargs_annotations = posonlyargs_annotations
+
+ # Parameters that got added later and need a default
self.varargannotation = varargannotation
self.kwargannotation = kwargannotation
- if type_comment_args is not None:
- self.type_comment_args = type_comment_args
- if type_comment_kwonlyargs is not None:
- self.type_comment_kwonlyargs = type_comment_kwonlyargs
- if type_comment_posonlyargs is not None:
- self.type_comment_posonlyargs = type_comment_posonlyargs
+ if type_comment_args is None:
+ type_comment_args = []
+ self.type_comment_args = type_comment_args
+ if type_comment_kwonlyargs is None:
+ type_comment_kwonlyargs = []
+ self.type_comment_kwonlyargs = type_comment_kwonlyargs
+ if type_comment_posonlyargs is None:
+ type_comment_posonlyargs = []
+ self.type_comment_posonlyargs = type_comment_posonlyargs
assigned_stmts: ClassVar[AssignedStmtsCall[Arguments]]
"""Returns the assigned statement (non inferred) according to the assignment type.
diff --git a/astroid/raw_building.py b/astroid/raw_building.py
index 383a243b..bb5b9ab1 100644
--- a/astroid/raw_building.py
+++ b/astroid/raw_building.py
@@ -122,7 +122,7 @@ def build_function(
"""create and initialize an astroid FunctionDef node"""
# first argument is now a list of decorators
func = nodes.FunctionDef(name)
- argsnode = nodes.Arguments(parent=func)
+ argsnode = nodes.Arguments(parent=func, vararg=None, kwarg=None)
# If args is None we don't have any information about the signature
# (in contrast to when there are no arguments and args == []). We pass
@@ -191,6 +191,8 @@ def build_function(
)
for arg in posonlyargs or ()
],
+ kwonlyargs_annotations=[],
+ posonlyargs_annotations=[],
)
func.postinit(
args=argsnode,
diff --git a/tests/test_scoped_nodes.py b/tests/test_scoped_nodes.py
index 63fe0af7..705f5d2d 100644
--- a/tests/test_scoped_nodes.py
+++ b/tests/test_scoped_nodes.py
@@ -2883,7 +2883,11 @@ def test_deprecation_of_doc_attribute() -> None:
node_class.postinit(bases=[], body=[], decorators=[], doc_node=doc_node)
assert node_class.doc_node == doc_node
node_func = nodes.FunctionDef(name="MyFunction")
- node_func.postinit(args=nodes.Arguments(), body=[], doc_node=doc_node)
+ node_func.postinit(
+ args=nodes.Arguments(parent=node_func, vararg=None, kwarg=None),
+ body=[],
+ doc_node=doc_node,
+ )
assert node_func.doc_node == doc_node
# Test 'doc' attribute if only 'doc_node' is passed