diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2015-11-29 22:11:22 +0200 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2015-12-29 16:36:39 +0200 |
commit | c2590f59337ff742e503e4e2435467bea65c74f5 (patch) | |
tree | 3a518830893c6ed9a2745999f75bd7e773ce5a56 | |
parent | d8a87cc5055abe7f8a8a41222632b640cf89ed7f (diff) | |
download | astroid-git-c2590f59337ff742e503e4e2435467bea65c74f5.tar.gz |
Add support for handling Uninferable nodes when calling as_string
Some object, for instance List or Tuple can have, after inference,
Uninferable as their elements, happening when their components
weren't couldn't be inferred properly. This means that as_string
needs to cope with expecting Uninferable nodes part of the other
nodes coming for a string transformation. The patch adds a visit
method in AsString and ``accept`` on Yes / Uninferable nodes.
Closes issue #270.
-rw-r--r-- | astroid/as_string.py | 3 | ||||
-rw-r--r-- | astroid/tests/unittest_nodes.py | 10 | ||||
-rw-r--r-- | astroid/util.py | 6 |
3 files changed, 19 insertions, 0 deletions
diff --git a/astroid/as_string.py b/astroid/as_string.py index 37dc77d5..d160b376 100644 --- a/astroid/as_string.py +++ b/astroid/as_string.py @@ -434,6 +434,9 @@ class AsStringVisitor(object): def visit_super(self, node): return node.parent.accept(self) + def visit_uninferable(self, node): + return str(node) + class AsStringVisitor3(AsStringVisitor): """AsStringVisitor3 overwrites some AsStringVisitor methods""" diff --git a/astroid/tests/unittest_nodes.py b/astroid/tests/unittest_nodes.py index 56f70571..ce8863b3 100644 --- a/astroid/tests/unittest_nodes.py +++ b/astroid/tests/unittest_nodes.py @@ -67,6 +67,16 @@ class AsStringTest(resources.SysPathSetup, unittest.TestCase): node = parse(code) self.assertEqual(node.as_string().strip(), code.strip()) + def test_as_string_for_list_containing_uninferable(self): + node = test_utils.extract_node(''' + def foo(): + bar = [arg] * 1 + ''') + binop = node.body[0].value + inferred = next(binop.infer()) + self.assertEqual(inferred.as_string(), '[Uninferable]') + self.assertEqual(binop.as_string(), '([arg]) * (1)') + def test_frozenset_as_string(self): nodes = test_utils.extract_node(''' frozenset((1, 2, 3)) #@ diff --git a/astroid/util.py b/astroid/util.py index 9c20eb4b..6fd59cfb 100644 --- a/astroid/util.py +++ b/astroid/util.py @@ -76,17 +76,23 @@ class Uninferable(object): """Special inference object, which is returned when inference fails.""" def __repr__(self): return 'Uninferable' + __str__ = __repr__ def __getattribute__(self, name): if name == 'next': raise AttributeError('next method should not be called') if name.startswith('__') and name.endswith('__'): return object.__getattribute__(self, name) + if name == 'accept': + return object.__getattribute__(self, name) return self def __call__(self, *args, **kwargs): return self + def accept(self, visitor): + func = getattr(visitor, "visit_uninferable") + return func(self) class BadOperationMessage(object): """Object which describes a TypeError occurred somewhere in the inference chain |