diff options
| author | Claudiu Popa <pcmanticore@gmail.com> | 2019-11-14 11:25:42 +0100 |
|---|---|---|
| committer | Claudiu Popa <pcmanticore@gmail.com> | 2019-11-14 11:25:42 +0100 |
| commit | ff9424fb26c90b03ec5f6e44568833ada5dd236e (patch) | |
| tree | 13124c1e1cd5eae91b364a661a5eef78dcbbebc6 | |
| parent | 78d5537b6a40a5d4f5f80bad7ba567ff716d728a (diff) | |
| download | astroid-git-ff9424fb26c90b03ec5f6e44568833ada5dd236e.tar.gz | |
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
| -rw-r--r-- | ChangeLog | 10 | ||||
| -rw-r--r-- | astroid/protocols.py | 3 | ||||
| -rw-r--r-- | tests/unittest_inference.py | 19 |
3 files changed, 32 insertions, 0 deletions
@@ -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() |
