fix issue 655: crude workarounds around python2/3 exception leaks

This commit is contained in:
Ronny Pfannschmidt 2015-01-09 19:55:49 +01:00
parent bca19a1156
commit 5941b2e071
3 changed files with 38 additions and 5 deletions

View File

@ -1,6 +1,9 @@
2.7.0.dev (compared to 2.6.4)
-----------------------------
- fix issue655: work around different ways that cause python2/3
to leak sys.exc_info into fixtures/tests causing failures in 3rd party code
- fix issue615: assertion re-writing did not correctly escape % signs
when formatting boolean operations, which tripped over mixing
booleans with modulo operators. Thanks to Tom Viner for the report,
@ -14,7 +17,7 @@
which want to wrap the execution of certain hooks for their purposes.
This supersedes the undocumented ``__multicall__`` protocol which
pytest itself and some external plugins use. Note that pytest-2.8
is scheduled to drop supporting the old ``__multicall__``
is scheduled to drop supporting the old ``__multicall__``
and only support the hookwrapper protocol.
- use hookwrapper mechanism in builtin pytest plugins.

View File

@ -15,6 +15,8 @@ NOTSET = object()
isfunction = inspect.isfunction
isclass = inspect.isclass
callable = py.builtin.callable
# used to work around a python2 exception info leak
exc_clear = getattr(sys, 'exc_clear', lambda: None)
def getfslineno(obj):
# xxx let decorators etc specify a sane ordering
@ -1389,10 +1391,12 @@ class FixtureRequest(FuncargnamesCompatAttr):
cached_result = (self, [0], None)
return PseudoFixtureDef
raise
result = self._getfuncargvalue(fixturedef)
self._funcargs[argname] = result
self._fixturedefs[argname] = fixturedef
return fixturedef
# remove indent to prevent the python3 exception
# from leaking into the call
result = self._getfuncargvalue(fixturedef)
self._funcargs[argname] = result
self._fixturedefs[argname] = fixturedef
return fixturedef
def _get_fixturestack(self):
current = self
@ -1439,6 +1443,9 @@ class FixtureRequest(FuncargnamesCompatAttr):
(scope, argname, self.scope, "\n".join(lines))))
__tracebackhide__ = False
# clear sys.exc_info before invoking the fixture (python bug?)
# if its not explicitly cleared it will leak into the call
exc_clear()
try:
# call the fixture function
val = fixturedef.execute(request=subrequest)

View File

@ -261,6 +261,29 @@ class TestFillFixtures:
])
assert "INTERNAL" not in result.stdout.str()
def test_fixture_excinfo_leak(self, testdir):
# on python2 sys.excinfo would leak into fixture executions
testdir.makepyfile("""
import sys
import traceback
import pytest
@pytest.fixture
def leak():
if sys.exc_info()[0]: # python3 bug :)
traceback.print_exc()
#fails
assert sys.exc_info() == (None, None, None)
def test_leak(leak):
if sys.exc_info()[0]: # python3 bug :)
traceback.print_exc()
assert sys.exc_info() == (None, None, None)
""")
result = testdir.runpytest()
assert result.ret == 0
class TestRequestBasic:
def test_request_attributes(self, testdir):
item = testdir.getitem("""