summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--astroid/protocols.py3
-rw-r--r--tests/unittest_inference.py19
3 files changed, 32 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 3cae14b5..ba37918c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,16 @@ Release Date: TBA
* Allow inferring positional only arguments.
+* Infer args unpacking of ``self``
+
+ Certain stdlib modules use ``*args`` to encapsulate
+ the ``self`` parameter, which results in uninferable
+ instances given we rely on the presence of the ``self``
+ argument to figure out the instance where we should be
+ setting attributes.
+
+ Close PyCQA/pylint#3216
+
What's New in astroid 2.3.2?
============================
diff --git a/astroid/protocols.py b/astroid/protocols.py
index 8b682e48..84e3571b 100644
--- a/astroid/protocols.py
+++ b/astroid/protocols.py
@@ -339,6 +339,9 @@ def _arguments_infer_argname(self, name, context):
if name == self.vararg:
vararg = nodes.const_factory(())
vararg.parent = self
+ if not self.arguments and self.parent.name == "__init__":
+ cls = self.parent.parent.scope()
+ vararg.elts = [bases.Instance(cls)]
yield vararg
return
if name == self.kwarg:
diff --git a/tests/unittest_inference.py b/tests/unittest_inference.py
index a2ad7e6d..9ce0c8d2 100644
--- a/tests/unittest_inference.py
+++ b/tests/unittest_inference.py
@@ -5319,5 +5319,24 @@ def test_posonlyargs_inference():
assert inferred.type == "method"
+def test_infer_args_unpacking_of_self():
+ code = """
+ class A:
+ def __init__(*args, **kwargs):
+ self, *args = args
+ self.data = {1: 2}
+ self #@
+ A().data #@
+ """
+ self, data = extract_node(code)
+ inferred_self = next(self.infer())
+ assert isinstance(inferred_self, Instance)
+ assert inferred_self.name == "A"
+
+ inferred_data = next(data.infer())
+ assert isinstance(inferred_data, nodes.Dict)
+ assert inferred_data.as_string() == "{1: 2}"
+
+
if __name__ == "__main__":
unittest.main()