diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | astroid/tests/unittest_inference.py | 9 | ||||
-rw-r--r-- | astroid/util.py | 23 |
3 files changed, 41 insertions, 1 deletions
@@ -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) |