Merge pull request #4632 from AnjoMan/dont-rewrite-objects-with-failing-getattr

Assertion rewrite breaks for objects that reimplement `__getattr__`
This commit is contained in:
Bruno Oliveira 2019-01-11 14:07:22 -02:00 committed by GitHub
commit 3efb26ae7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 1 deletions

View File

@ -24,6 +24,7 @@ Andy Freeland
Anthon van der Neut
Anthony Shaw
Anthony Sottile
Anton Lodder
Antony Lee
Armin Rigo
Aron Coyle

View File

@ -0,0 +1 @@
Don't rewrite assertion when ``__getattr__`` is broken

View File

@ -525,7 +525,13 @@ def _format_assertmsg(obj):
def _should_repr_global_name(obj):
return not hasattr(obj, "__name__") and not callable(obj)
if callable(obj):
return False
try:
return not hasattr(obj, "__name__")
except Exception:
return True
def _format_boolop(explanations, is_or):

View File

@ -180,6 +180,27 @@ class TestAssertionRewrite(object):
assert getmsg(f, {"cls": X}) == "assert cls == 42"
def test_dont_rewrite_if_hasattr_fails(self):
class Y(object):
""" A class whos getattr fails, but not with `AttributeError` """
def __getattr__(self, attribute_name):
raise KeyError()
def __repr__(self):
return "Y"
def __init__(self):
self.foo = 3
def f():
assert cls().foo == 2 # noqa
message = getmsg(f, {"cls": Y})
assert "assert 3 == 2" in message
assert "+ where 3 = Y.foo" in message
assert "+ where Y = cls()" in message
def test_assert_already_has_message(self):
def f():
assert False, "something bad!"