Merge pull request #2707 from cybergrind/fix_baseexception
Catch BaseException in safe_getattr
This commit is contained in:
commit
b770a32dc8
|
@ -11,6 +11,7 @@ import functools
|
|||
import py
|
||||
|
||||
import _pytest
|
||||
from _pytest.outcomes import TEST_OUTCOME
|
||||
|
||||
|
||||
try:
|
||||
|
@ -221,14 +222,16 @@ def getimfunc(func):
|
|||
|
||||
|
||||
def safe_getattr(object, name, default):
|
||||
""" Like getattr but return default upon any Exception.
|
||||
""" Like getattr but return default upon any Exception or any OutcomeException.
|
||||
|
||||
Attribute access can potentially fail for 'evil' Python objects.
|
||||
See issue #214.
|
||||
It catches OutcomeException because of #2490 (issue #580), new outcomes are derived from BaseException
|
||||
instead of Exception (for more details check #2707)
|
||||
"""
|
||||
try:
|
||||
return getattr(object, name, default)
|
||||
except Exception:
|
||||
except TEST_OUTCOME:
|
||||
return default
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Fixed edge-case during collection: attributes which raised ``pytest.fail`` when accessed would abort the entire collection.
|
|
@ -2,7 +2,8 @@ from __future__ import absolute_import, division, print_function
|
|||
import sys
|
||||
|
||||
import pytest
|
||||
from _pytest.compat import is_generator, get_real_func
|
||||
from _pytest.compat import is_generator, get_real_func, safe_getattr
|
||||
from _pytest.outcomes import OutcomeException
|
||||
|
||||
|
||||
def test_is_generator():
|
||||
|
@ -74,3 +75,27 @@ def test_is_generator_async_syntax(testdir):
|
|||
""")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines(['*1 passed*'])
|
||||
|
||||
|
||||
class ErrorsHelper(object):
|
||||
@property
|
||||
def raise_exception(self):
|
||||
raise Exception('exception should be catched')
|
||||
|
||||
@property
|
||||
def raise_fail(self):
|
||||
pytest.fail('fail should be catched')
|
||||
|
||||
|
||||
def test_helper_failures():
|
||||
helper = ErrorsHelper()
|
||||
with pytest.raises(Exception):
|
||||
helper.raise_exception
|
||||
with pytest.raises(OutcomeException):
|
||||
helper.raise_fail
|
||||
|
||||
|
||||
def test_safe_getattr():
|
||||
helper = ErrorsHelper()
|
||||
assert safe_getattr(helper, 'raise_exception', 'default') == 'default'
|
||||
assert safe_getattr(helper, 'raise_fail', 'default') == 'default'
|
||||
|
|
Loading…
Reference in New Issue