summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2017-07-08 13:41:24 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2017-07-08 13:41:24 +0300
commit573b900773d249fbb2858c1a19db3f1434abbd42 (patch)
treeef694da8aa2d2abb9dd08723815dc5d1c0af34dd
parent03f3ea786885d794d3cdeaa82df4ce36d60d68e1 (diff)
downloadastroid-git-573b900773d249fbb2858c1a19db3f1434abbd42.tar.gz
Don't crash when getting the string representation of BadUnaryOperationMessage
In some cases, when the operand does not have a .name attribute, getting the string representation of a BadUnaryOperationMessage leads to a crash. Close PyCQA/pylint#1563
-rw-r--r--ChangeLog10
-rw-r--r--astroid/tests/unittest_inference.py9
-rw-r--r--astroid/util.py23
3 files changed, 41 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 74401949..1dee67af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,16 @@
Change log for the astroid package (used to be astng)
=====================================================
+--
+
+ * Don't crash when getting the string representation of BadUnaryOperationMessage
+
+ In some cases, when the operand does not have a .name attribute,
+ getting the string representation of a BadUnaryOperationMessage leads
+ to a crash.
+
+ Close PyCQA/pylint#1563
+
2017-06-03 -- 1.5.3
* enum34 dependency is forced to be at least version 1.1.3. Fixes spurious
diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py
index 9a12e322..ebf2ece7 100644
--- a/astroid/tests/unittest_inference.py
+++ b/astroid/tests/unittest_inference.py
@@ -2334,6 +2334,15 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase):
self.assertEqual(len(errors), 1, (expected, node))
self.assertEqual(str(errors[0]), expected_value)
+ def test_unary_type_errors_for_non_instance_objects(self):
+ node = extract_node('~slice(1, 2, 3)')
+ errors = node.type_errors()
+ self.assertEqual(len(errors), 1)
+ self.assertEqual(
+ str(errors[0]),
+ 'bad operand type for unary ~: slice'
+ )
+
def test_bool_value_recursive(self):
pairs = [
('{}', False),
diff --git a/astroid/util.py b/astroid/util.py
index 6d2d0177..6fd52d31 100644
--- a/astroid/util.py
+++ b/astroid/util.py
@@ -74,8 +74,29 @@ class BadUnaryOperationMessage(BadOperationMessage):
self.op = op
self.error = error
+ @property
+ def _object_type_helper(self):
+ helpers = lazy_import('helpers')
+ return helpers.object_type
+
+ def _object_type(self, obj):
+ objtype = self._object_type_helper(obj)
+ if objtype is Uninferable:
+ return None
+
+ return objtype
+
def __str__(self):
- operand_type = self.operand.name
+ if hasattr(self.operand, 'name'):
+ operand_type = self.operand.name
+ else:
+ object_type = self._object_type(self.operand)
+ if hasattr(object_type, 'name'):
+ operand_type = object_type.name
+ else:
+ # Just fallback to as_string
+ operand_type = object_type.as_string()
+
msg = "bad operand type for unary {}: {}"
return msg.format(self.op, operand_type)