introduce resume/suspend functionality for FDCapture and SysCapture,
fixing problems with early bailouts (from argparse's parse() function e.g.) that wrote to stdout.
This commit is contained in:
parent
ca5e6830c6
commit
2e1f6c85f6
|
@ -46,13 +46,7 @@ def pytest_load_initial_conftests(early_config, parser, args, __multicall__):
|
||||||
pluginmanager.register(capman, "capturemanager")
|
pluginmanager.register(capman, "capturemanager")
|
||||||
|
|
||||||
# make sure that capturemanager is properly reset at final shutdown
|
# make sure that capturemanager is properly reset at final shutdown
|
||||||
def teardown():
|
pluginmanager.add_shutdown(capman.reset_capturings)
|
||||||
try:
|
|
||||||
capman.reset_capturings()
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
pluginmanager.add_shutdown(teardown)
|
|
||||||
|
|
||||||
# make sure logging does not raise exceptions at the end
|
# make sure logging does not raise exceptions at the end
|
||||||
def silence_logging_at_shutdown():
|
def silence_logging_at_shutdown():
|
||||||
|
@ -124,16 +118,18 @@ class CaptureManager:
|
||||||
self._method2capture[method] = cap = self._getcapture(method)
|
self._method2capture[method] = cap = self._getcapture(method)
|
||||||
cap.start_capturing()
|
cap.start_capturing()
|
||||||
else:
|
else:
|
||||||
cap.pop_outerr_to_orig()
|
cap.resume_capturing()
|
||||||
|
|
||||||
def suspendcapture(self, item=None):
|
def suspendcapture(self, item=None):
|
||||||
self.deactivate_funcargs()
|
self.deactivate_funcargs()
|
||||||
method = self.__dict__.pop("_capturing", None)
|
method = self.__dict__.pop("_capturing", None)
|
||||||
|
outerr = "", ""
|
||||||
if method is not None:
|
if method is not None:
|
||||||
cap = self._method2capture.get(method)
|
cap = self._method2capture.get(method)
|
||||||
if cap is not None:
|
if cap is not None:
|
||||||
return cap.readouterr()
|
outerr = cap.readouterr()
|
||||||
return "", ""
|
cap.suspend_capturing()
|
||||||
|
return outerr
|
||||||
|
|
||||||
def activate_funcargs(self, pyfuncitem):
|
def activate_funcargs(self, pyfuncitem):
|
||||||
capfuncarg = pyfuncitem.__dict__.pop("_capfuncarg", None)
|
capfuncarg = pyfuncitem.__dict__.pop("_capfuncarg", None)
|
||||||
|
@ -316,6 +312,18 @@ class MultiCapture(object):
|
||||||
if err:
|
if err:
|
||||||
self.err.writeorg(err)
|
self.err.writeorg(err)
|
||||||
|
|
||||||
|
def suspend_capturing(self):
|
||||||
|
if self.out:
|
||||||
|
self.out.suspend()
|
||||||
|
if self.err:
|
||||||
|
self.err.suspend()
|
||||||
|
|
||||||
|
def resume_capturing(self):
|
||||||
|
if self.out:
|
||||||
|
self.out.resume()
|
||||||
|
if self.err:
|
||||||
|
self.err.resume()
|
||||||
|
|
||||||
def stop_capturing(self):
|
def stop_capturing(self):
|
||||||
""" stop capturing and reset capturing streams """
|
""" stop capturing and reset capturing streams """
|
||||||
if hasattr(self, '_reset'):
|
if hasattr(self, '_reset'):
|
||||||
|
@ -334,7 +342,7 @@ class MultiCapture(object):
|
||||||
self.err.snap() if self.err is not None else "")
|
self.err.snap() if self.err is not None else "")
|
||||||
|
|
||||||
class NoCapture:
|
class NoCapture:
|
||||||
__init__ = start = done = lambda *args: None
|
__init__ = start = done = suspend = resume = lambda *args: None
|
||||||
|
|
||||||
class FDCapture:
|
class FDCapture:
|
||||||
""" Capture IO to/from a given os-level filedescriptor. """
|
""" Capture IO to/from a given os-level filedescriptor. """
|
||||||
|
|
|
@ -335,6 +335,12 @@ class TestGeneralUsage:
|
||||||
res = testdir.runpytest(p.basename)
|
res = testdir.runpytest(p.basename)
|
||||||
assert res.ret == 0
|
assert res.ret == 0
|
||||||
|
|
||||||
|
def test_unknown_option(self, testdir):
|
||||||
|
result = testdir.runpytest("--qwlkej")
|
||||||
|
result.stderr.fnmatch_lines("""
|
||||||
|
*unrecognized*
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
class TestInvocationVariants:
|
class TestInvocationVariants:
|
||||||
def test_earlyinit(self, testdir):
|
def test_earlyinit(self, testdir):
|
||||||
|
|
Loading…
Reference in New Issue