introduce pluginmanager.ensure_teardown() which allows
This commit is contained in:
parent
ac19212b2d
commit
a930f44e60
|
@ -22,6 +22,13 @@ def pytest_cmdline_parse(pluginmanager, args):
|
|||
method = "sys"
|
||||
capman = CaptureManager(method)
|
||||
pluginmanager.register(capman, "capturemanager")
|
||||
# make sure that capturemanager is properly reset at final shutdown
|
||||
def teardown():
|
||||
try:
|
||||
capman.reset_capturings()
|
||||
except ValueError:
|
||||
pass
|
||||
pluginmanager.add_shutdown(teardown)
|
||||
|
||||
def addouterr(rep, outerr):
|
||||
for secname, content in zip(["out", "err"], outerr):
|
||||
|
@ -82,6 +89,7 @@ class CaptureManager:
|
|||
for name, cap in self._method2capture.items():
|
||||
cap.reset()
|
||||
|
||||
|
||||
def resumecapture_item(self, item):
|
||||
method = self._getmethod(item.config, item.fspath)
|
||||
if not hasattr(item, 'outerr'):
|
||||
|
|
|
@ -80,6 +80,7 @@ class PluginManager(object):
|
|||
self._hints = []
|
||||
self.trace = TagTracer().get("pluginmanage")
|
||||
self._plugin_distinfo = []
|
||||
self._shutdown = []
|
||||
if os.environ.get('PYTEST_DEBUG'):
|
||||
err = sys.stderr
|
||||
encoding = getattr(err, 'encoding', 'utf8')
|
||||
|
@ -118,6 +119,17 @@ class PluginManager(object):
|
|||
if value == plugin:
|
||||
del self._name2plugin[name]
|
||||
|
||||
def add_shutdown(self, func):
|
||||
self._shutdown.append(func)
|
||||
|
||||
def ensure_shutdown(self):
|
||||
while self._shutdown:
|
||||
func = self._shutdown.pop()
|
||||
func()
|
||||
self._plugins = []
|
||||
self._name2plugin.clear()
|
||||
self._listattrcache.clear()
|
||||
|
||||
def isregistered(self, plugin, name=None):
|
||||
if self.getplugin(name) is not None:
|
||||
return True
|
||||
|
@ -286,7 +298,7 @@ class PluginManager(object):
|
|||
config = self._config
|
||||
del self._config
|
||||
config.hook.pytest_unconfigure(config=config)
|
||||
config.pluginmanager.unregister(self)
|
||||
config.pluginmanager.ensure_shutdown()
|
||||
|
||||
def notify_exception(self, excinfo, option=None):
|
||||
if option and option.fulltrace:
|
||||
|
|
|
@ -106,6 +106,7 @@ def wrap_session(config, doit):
|
|||
exitstatus=session.exitstatus)
|
||||
if initstate >= 1:
|
||||
config.pluginmanager.do_unconfigure(config)
|
||||
config.pluginmanager.ensure_shutdown()
|
||||
return session.exitstatus
|
||||
|
||||
def pytest_cmdline_main(config):
|
||||
|
|
|
@ -83,6 +83,7 @@ class HookRecorder:
|
|||
|
||||
def finish_recording(self):
|
||||
for recorder in self._recorders.values():
|
||||
if self._pluginmanager.isregistered(recorder):
|
||||
self._pluginmanager.unregister(recorder)
|
||||
self._recorders.clear()
|
||||
|
||||
|
@ -361,7 +362,7 @@ class TmpTestdir:
|
|||
if not plugins:
|
||||
plugins = []
|
||||
plugins.append(Collect())
|
||||
ret = self.pytestmain(list(args), plugins=plugins)
|
||||
ret = pytest.main(list(args), plugins=plugins)
|
||||
reprec = rec[0]
|
||||
reprec.ret = ret
|
||||
assert len(rec) == 1
|
||||
|
@ -376,14 +377,15 @@ class TmpTestdir:
|
|||
args.append("--basetemp=%s" % self.tmpdir.dirpath('basetemp'))
|
||||
import _pytest.core
|
||||
config = _pytest.core._prepareconfig(args, self.plugins)
|
||||
# the in-process pytest invocation needs to avoid leaking FDs
|
||||
# so we register a "reset_capturings" callmon the capturing manager
|
||||
# and make sure it gets called
|
||||
config._cleanup.append(
|
||||
config.pluginmanager.getplugin("capturemanager").reset_capturings)
|
||||
import _pytest.config
|
||||
self.request.addfinalizer(
|
||||
lambda: _pytest.config.pytest_unconfigure(config))
|
||||
# we don't know what the test will do with this half-setup config
|
||||
# object and thus we make sure it gets unconfigured properly in any
|
||||
# case (otherwise capturing could still be active, for example)
|
||||
def ensure_unconfigure():
|
||||
if hasattr(config.pluginmanager, "_config"):
|
||||
config.pluginmanager.do_unconfigure(config)
|
||||
config.pluginmanager.ensure_shutdown()
|
||||
|
||||
self.request.addfinalizer(ensure_unconfigure)
|
||||
return config
|
||||
|
||||
def parseconfigure(self, *args):
|
||||
|
@ -428,17 +430,6 @@ class TmpTestdir:
|
|||
return py.std.subprocess.Popen(cmdargs,
|
||||
stdout=stdout, stderr=stderr, **kw)
|
||||
|
||||
def pytestmain(self, *args, **kwargs):
|
||||
class ResetCapturing:
|
||||
@pytest.mark.trylast
|
||||
def pytest_unconfigure(self, config):
|
||||
capman = config.pluginmanager.getplugin("capturemanager")
|
||||
capman.reset_capturings()
|
||||
plugins = kwargs.setdefault("plugins", [])
|
||||
rc = ResetCapturing()
|
||||
plugins.append(rc)
|
||||
return pytest.main(*args, **kwargs)
|
||||
|
||||
def run(self, *cmdargs):
|
||||
return self._run(*cmdargs)
|
||||
|
||||
|
|
|
@ -391,15 +391,15 @@ class TestInvocationVariants:
|
|||
def test_equivalence_pytest_pytest(self):
|
||||
assert pytest.main == py.test.cmdline.main
|
||||
|
||||
def test_invoke_with_string(self, testdir, capsys):
|
||||
retcode = testdir.pytestmain("-h")
|
||||
def test_invoke_with_string(self, capsys):
|
||||
retcode = pytest.main("-h")
|
||||
assert not retcode
|
||||
out, err = capsys.readouterr()
|
||||
assert "--help" in out
|
||||
pytest.raises(ValueError, lambda: pytest.main(0))
|
||||
|
||||
def test_invoke_with_path(self, testdir, capsys):
|
||||
retcode = testdir.pytestmain(testdir.tmpdir)
|
||||
def test_invoke_with_path(self, tmpdir, capsys):
|
||||
retcode = pytest.main(tmpdir)
|
||||
assert not retcode
|
||||
out, err = capsys.readouterr()
|
||||
|
||||
|
@ -408,7 +408,7 @@ class TestInvocationVariants:
|
|||
def pytest_addoption(self, parser):
|
||||
parser.addoption("--myopt")
|
||||
|
||||
testdir.pytestmain(["-h"], plugins=[MyPlugin()])
|
||||
pytest.main(["-h"], plugins=[MyPlugin()])
|
||||
out, err = capsys.readouterr()
|
||||
assert "--myopt" in out
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ class TestCollectPluginHookRelay:
|
|||
def pytest_collect_file(self, path, parent):
|
||||
wascalled.append(path)
|
||||
testdir.makefile(".abc", "xyz")
|
||||
testdir.pytestmain([testdir.tmpdir], plugins=[Plugin()])
|
||||
pytest.main([testdir.tmpdir], plugins=[Plugin()])
|
||||
assert len(wascalled) == 1
|
||||
assert wascalled[0].ext == '.abc'
|
||||
|
||||
|
@ -134,7 +134,7 @@ class TestCollectPluginHookRelay:
|
|||
wascalled.append(path.basename)
|
||||
testdir.mkdir("hello")
|
||||
testdir.mkdir("world")
|
||||
testdir.pytestmain(testdir.tmpdir, plugins=[Plugin()])
|
||||
pytest.main(testdir.tmpdir, plugins=[Plugin()])
|
||||
assert "hello" in wascalled
|
||||
assert "world" in wascalled
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import py, pytest
|
|||
import pdb
|
||||
|
||||
xfail_if_pdbpp_installed = pytest.mark.xfail(hasattr(pdb, "__author__"),
|
||||
reason="doctest/pdbpp problem: https://bitbucket.org/antocuni/pdb/issue/24/doctests-fail-when-pdbpp-is-installed")
|
||||
reason="doctest/pdbpp problem: https://bitbucket.org/antocuni/pdb/issue/24/doctests-fail-when-pdbpp-is-installed", run=False)
|
||||
|
||||
class TestDoctests:
|
||||
|
||||
|
|
Loading…
Reference in New Issue