diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2015-10-03 13:40:40 +0300 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2015-10-03 13:40:40 +0300 |
commit | 670427f3bfc97c3a6a50689c918e3a87f1729dbb (patch) | |
tree | b0ab9bf4e07a1a07ba67168c9d0686cc54f92d6d | |
parent | e61258e7be8330ae4e0dfd75eb3d7210f40383e0 (diff) | |
download | astroid-670427f3bfc97c3a6a50689c918e3a87f1729dbb.tar.gz |
Ignore non-callables when looking for special method implementations of bool methods
This commit verifies what a special method actually is and if it's
not a callable, then we return an YES object, since there's a big
chance to not make sense of the instance's boolean value.
-rw-r--r-- | astroid/bases.py | 2 | ||||
-rw-r--r-- | astroid/tests/unittest_inference.py | 21 |
2 files changed, 22 insertions, 1 deletions
diff --git a/astroid/bases.py b/astroid/bases.py index 3656102..3ed52bf 100644 --- a/astroid/bases.py +++ b/astroid/bases.py @@ -126,6 +126,8 @@ def _infer_method_result_truth(instance, method_name, context): # its return's truth value. meth = next(instance.igetattr(method_name, context=context), None) if meth and hasattr(meth, 'infer_call_result'): + if not meth.callable(): + return util.YES for value in meth.infer_call_result(instance, context=context): if value is util.YES: return value diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index 093b076..644e282 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -3324,16 +3324,35 @@ class TestBool(unittest.TestCase): class TrueClass: def {method}(self): return True + class C(object): + def __call__(self): + return False + class B(object): + {method} = C() bool(FalseClass) #@ bool(TrueClass) #@ bool(FalseClass()) #@ bool(TrueClass()) #@ + bool(B()) #@ '''.format(method=BOOL_SPECIAL_METHOD)) - expected = [True, True, False, True] + expected = [True, True, False, True, False] for node, expected_value in zip(ast_nodes, expected): inferred = next(node.infer()) self.assertEqual(inferred.value, expected_value) + def test_bool_instance_not_callable(self): + ast_nodes = test_utils.extract_node(''' + class BoolInvalid(object): + {method} = 42 + class LenInvalid(object): + __len__ = "a" + bool(BoolInvalid()) #@ + bool(LenInvalid()) #@ + '''.format(method=BOOL_SPECIAL_METHOD)) + for node in ast_nodes: + inferred = next(node.infer()) + self.assertEqual(inferred, util.YES) + class TestType(unittest.TestCase): |