fix issue 655: crude workarounds around python2/3 exception leaks
This commit is contained in:
parent
bca19a1156
commit
5941b2e071
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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("""
|
||||
|
|
Loading…
Reference in New Issue