[Pytest-commit] commit/pytest: 5 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Sat Sep 28 22:30:13 CEST 2013
5 new commits in pytest:
https://bitbucket.org/hpk42/pytest/commits/0572f79c5f9c/
Changeset: 0572f79c5f9c
User: hpk42
Date: 2013-09-28 09:52:41
Summary: move FILE_OR_DIR constant out
Affected #: 2 files
diff -r 9b4dae68a5a41d75bbe4c48b1b5d45806e522717 -r 0572f79c5f9c786d1c643352d639c8f7112a8edd _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -93,7 +93,7 @@
a = option.attrs()
arggroup.add_argument(*n, **a)
# bash like autocompletion for dirs (appending '/')
- optparser.add_argument(Config._file_or_dir, nargs='*'
+ optparser.add_argument(FILE_OR_DIR, nargs='*'
).completer=filescompleter
try_argcomplete(self.optparser)
return self.optparser.parse_args([str(x) for x in args])
@@ -102,7 +102,7 @@
parsedoption = self.parse(args)
for name, value in parsedoption.__dict__.items():
setattr(option, name, value)
- return getattr(parsedoption, Config._file_or_dir)
+ return getattr(parsedoption, FILE_OR_DIR)
def addini(self, name, help, type=None, default=None):
""" register an ini-file option.
@@ -323,22 +323,9 @@
if arg and arg[0] == '-':
msg = py.std.argparse._('unrecognized arguments: %s')
self.error(msg % ' '.join(argv))
- getattr(args, Config._file_or_dir).extend(argv)
+ getattr(args, FILE_OR_DIR).extend(argv)
return args
-# #pylib 2013-07-31
-# (12:05:53) anthon: hynek: can you get me a list of preferred py.test
-# long-options with '-' inserted at the right places?
-# (12:08:29) hynek: anthon, hpk: generally I'd love the following, decide
-# yourself which you agree and which not:
-# (12:10:51) hynek: --exit-on-first --full-trace --junit-xml --junit-prefix
-# --result-log --collect-only --conf-cut-dir --trace-config
-# --no-magic
-# (12:18:21) hpk: hynek,anthon: makes sense to me.
-# (13:40:30) hpk: hynek: let's not change names, rather only deal with
-# hyphens for now
-# (13:40:50) hynek: then --exit-first *shrug*
-
class DropShorterLongHelpFormatter(py.std.argparse.HelpFormatter):
"""shorten help for long options that differ only in extra hyphens
@@ -504,15 +491,15 @@
def __repr__(self):
return "<CmdOptions %r>" %(self.__dict__,)
+FILE_OR_DIR = 'file_or_dir'
class Config(object):
""" access to configuration values, pluginmanager and plugin hooks. """
- _file_or_dir = 'file_or_dir'
def __init__(self, pluginmanager=None):
#: access to command line option as attributes.
#: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead
self.option = CmdOptions()
- _a = self._file_or_dir
+ _a = FILE_OR_DIR
self._parser = Parser(
usage="%%(prog)s [options] [%s] [%s] [...]" % (_a, _a),
processopt=self._processopt,
diff -r 9b4dae68a5a41d75bbe4c48b1b5d45806e522717 -r 0572f79c5f9c786d1c643352d639c8f7112a8edd testing/test_parseopt.py
--- a/testing/test_parseopt.py
+++ b/testing/test_parseopt.py
@@ -95,11 +95,11 @@
parser.addoption("--hello", dest="hello", action="store")
args = parser.parse(['--hello', 'world'])
assert args.hello == "world"
- assert not getattr(args, parseopt.Config._file_or_dir)
+ assert not getattr(args, parseopt.FILE_OR_DIR)
def test_parse2(self, parser):
args = parser.parse([py.path.local()])
- assert getattr(args, parseopt.Config._file_or_dir)[0] == py.path.local()
+ assert getattr(args, parseopt.FILE_OR_DIR)[0] == py.path.local()
def test_parse_will_set_default(self, parser):
parser.addoption("--hello", dest="hello", default="x", action="store")
@@ -128,13 +128,13 @@
parser.addoption("-R", action='store_true')
parser.addoption("-S", action='store_false')
args = parser.parse(['-R', '4', '2', '-S'])
- assert getattr(args, parseopt.Config._file_or_dir) == ['4', '2']
+ assert getattr(args, parseopt.FILE_OR_DIR) == ['4', '2']
args = parser.parse(['-R', '-S', '4', '2', '-R'])
- assert getattr(args, parseopt.Config._file_or_dir) == ['4', '2']
+ assert getattr(args, parseopt.FILE_OR_DIR) == ['4', '2']
assert args.R == True
assert args.S == False
args = parser.parse(['-R', '4', '-S', '2'])
- assert getattr(args, parseopt.Config._file_or_dir) == ['4', '2']
+ assert getattr(args, parseopt.FILE_OR_DIR) == ['4', '2']
assert args.R == True
assert args.S == False
https://bitbucket.org/hpk42/pytest/commits/db80055e00dd/
Changeset: db80055e00dd
User: hpk42
Date: 2013-09-28 22:22:53
Summary: simplify Config constructor
Affected #: 4 files
diff -r 0572f79c5f9c786d1c643352d639c8f7112a8edd -r db80055e00dd94a6f5daf266ccee1deee0aac291 _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -495,7 +495,7 @@
class Config(object):
""" access to configuration values, pluginmanager and plugin hooks. """
- def __init__(self, pluginmanager=None):
+ def __init__(self, pluginmanager):
#: access to command line option as attributes.
#: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead
self.option = CmdOptions()
@@ -505,7 +505,7 @@
processopt=self._processopt,
)
#: a pluginmanager instance
- self.pluginmanager = pluginmanager or PluginManager(load=True)
+ self.pluginmanager = pluginmanager
self.trace = self.pluginmanager.trace.root.get("config")
self._conftest = Conftest(onimport=self._onimportconftest)
self.hook = self.pluginmanager.hook
@@ -516,7 +516,7 @@
@classmethod
def fromdictargs(cls, option_dict, args):
""" constructor useable for subprocesses. """
- config = cls()
+ config = cls(PluginManager(load=True))
# XXX slightly crude way to initialize capturing
import _pytest.capture
_pytest.capture.pytest_cmdline_parse(config.pluginmanager, args)
diff -r 0572f79c5f9c786d1c643352d639c8f7112a8edd -r db80055e00dd94a6f5daf266ccee1deee0aac291 testing/test_config.py
--- a/testing/test_config.py
+++ b/testing/test_config.py
@@ -82,7 +82,7 @@
class TestConfigAPI:
def test_config_trace(self, testdir):
- config = testdir.Config()
+ config = testdir.parseconfig()
l = []
config.trace.root.setwriter(l.append)
config.trace("hello")
diff -r 0572f79c5f9c786d1c643352d639c8f7112a8edd -r db80055e00dd94a6f5daf266ccee1deee0aac291 testing/test_core.py
--- a/testing/test_core.py
+++ b/testing/test_core.py
@@ -319,7 +319,7 @@
def pytest_myhook(xyz):
return xyz + 1
""")
- config = testdir.Config()
+ config = testdir.Config(PluginManager(load=True))
config._conftest.importconftest(conf)
print(config.pluginmanager.getplugins())
res = config.hook.pytest_myhook(xyz=10)
diff -r 0572f79c5f9c786d1c643352d639c8f7112a8edd -r db80055e00dd94a6f5daf266ccee1deee0aac291 testing/test_tmpdir.py
--- a/testing/test_tmpdir.py
+++ b/testing/test_tmpdir.py
@@ -36,7 +36,7 @@
class TestTempdirHandler:
def test_mktemp(self, testdir):
- config = testdir.Config()
+ config = testdir.parseconfig()
config.option.basetemp = testdir.mkdir("hello")
t = TempdirHandler(config)
tmp = t.mktemp("world")
https://bitbucket.org/hpk42/pytest/commits/1e3fe8b9de1a/
Changeset: 1e3fe8b9de1a
User: hpk42
Date: 2013-09-28 22:22:55
Summary: refine fromdictargs to avoid an uncessary re-setup of the pluginmanager
Affected #: 2 files
diff -r db80055e00dd94a6f5daf266ccee1deee0aac291 -r 1e3fe8b9de1ab56da5e4d02e60f82cc6cf8740c3 _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -516,7 +516,9 @@
@classmethod
def fromdictargs(cls, option_dict, args):
""" constructor useable for subprocesses. """
- config = cls(PluginManager(load=True))
+ from _pytest.core import get_plugin_manager
+ pluginmanager = get_plugin_manager()
+ config = cls(pluginmanager)
# XXX slightly crude way to initialize capturing
import _pytest.capture
_pytest.capture.pytest_cmdline_parse(config.pluginmanager, args)
diff -r db80055e00dd94a6f5daf266ccee1deee0aac291 -r 1e3fe8b9de1ab56da5e4d02e60f82cc6cf8740c3 _pytest/core.py
--- a/_pytest/core.py
+++ b/_pytest/core.py
@@ -460,8 +460,15 @@
_preinit = []
def _preloadplugins():
+ assert not _preinit
_preinit.append(PluginManager(load=True))
+def get_plugin_manager():
+ if _preinit:
+ return _preinit.pop(0)
+ else: # subsequent calls to main will create a fresh instance
+ return PluginManager(load=True)
+
def _prepareconfig(args=None, plugins=None):
if args is None:
args = sys.argv[1:]
@@ -471,16 +478,12 @@
if not isinstance(args, str):
raise ValueError("not a string or argument list: %r" % (args,))
args = py.std.shlex.split(args)
- if _preinit:
- _pluginmanager = _preinit.pop(0)
- else: # subsequent calls to main will create a fresh instance
- _pluginmanager = PluginManager(load=True)
- hook = _pluginmanager.hook
+ pluginmanager = get_plugin_manager()
if plugins:
for plugin in plugins:
- _pluginmanager.register(plugin)
- return hook.pytest_cmdline_parse(
- pluginmanager=_pluginmanager, args=args)
+ pluginmanager.register(plugin)
+ return pluginmanager.hook.pytest_cmdline_parse(
+ pluginmanager=pluginmanager, args=args)
def main(args=None, plugins=None):
""" return exit code, after performing an in-process test run.
https://bitbucket.org/hpk42/pytest/commits/967c8ec78e69/
Changeset: 967c8ec78e69
User: hpk42
Date: 2013-09-28 22:22:57
Summary: remove very likely unused pytest_plugin_unregister hook (pytest itself and all plugins i know don't use it)
Affected #: 3 files
diff -r 1e3fe8b9de1ab56da5e4d02e60f82cc6cf8740c3 -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,9 @@
unittest-style) will not be called if the corresponding setup method failed,
see issue322 below.
+- the pytest_plugin_unregister hook wasn't ever properly called
+ and there is no known implementation of the hook - so it got removed.
+
new features:
- experimentally allow fixture functions to "yield" instead of "return"
diff -r 1e3fe8b9de1ab56da5e4d02e60f82cc6cf8740c3 -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 _pytest/core.py
--- a/_pytest/core.py
+++ b/_pytest/core.py
@@ -114,7 +114,6 @@
if plugin is None:
plugin = self.getplugin(name=name)
self._plugins.remove(plugin)
- self.hook.pytest_plugin_unregistered(plugin=plugin)
for name, value in list(self._name2plugin.items()):
if value == plugin:
del self._name2plugin[name]
diff -r 1e3fe8b9de1ab56da5e4d02e60f82cc6cf8740c3 -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 _pytest/hookspec.py
--- a/_pytest/hookspec.py
+++ b/_pytest/hookspec.py
@@ -236,10 +236,7 @@
# -------------------------------------------------------------------------
def pytest_plugin_registered(plugin, manager):
- """ a new py lib plugin got registered. """
-
-def pytest_plugin_unregistered(plugin):
- """ a py lib plugin got unregistered. """
+ """ a new pytest plugin got registered. """
def pytest_internalerror(excrepr, excinfo):
""" called for internal errors. """
https://bitbucket.org/hpk42/pytest/commits/64445644395f/
Changeset: 64445644395f
User: hpk42
Date: 2013-09-28 22:23:00
Summary: introduce pluginmanager.ensure_teardown() which allows
Affected #: 7 files
diff -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 -r 64445644395fd57f600e0027d78692971ccd44d2 _pytest/capture.py
--- a/_pytest/capture.py
+++ b/_pytest/capture.py
@@ -22,6 +22,13 @@
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 @@
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'):
diff -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 -r 64445644395fd57f600e0027d78692971ccd44d2 _pytest/core.py
--- a/_pytest/core.py
+++ b/_pytest/core.py
@@ -80,6 +80,7 @@
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 @@
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 @@
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:
diff -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 -r 64445644395fd57f600e0027d78692971ccd44d2 _pytest/main.py
--- a/_pytest/main.py
+++ b/_pytest/main.py
@@ -106,6 +106,7 @@
exitstatus=session.exitstatus)
if initstate >= 1:
config.pluginmanager.do_unconfigure(config)
+ config.pluginmanager.ensure_shutdown()
return session.exitstatus
def pytest_cmdline_main(config):
diff -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 -r 64445644395fd57f600e0027d78692971ccd44d2 _pytest/pytester.py
--- a/_pytest/pytester.py
+++ b/_pytest/pytester.py
@@ -83,7 +83,8 @@
def finish_recording(self):
for recorder in self._recorders.values():
- self._pluginmanager.unregister(recorder)
+ if self._pluginmanager.isregistered(recorder):
+ self._pluginmanager.unregister(recorder)
self._recorders.clear()
def _makecallparser(self, method):
@@ -361,7 +362,7 @@
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 @@
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 @@
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)
diff -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 -r 64445644395fd57f600e0027d78692971ccd44d2 testing/acceptance_test.py
--- a/testing/acceptance_test.py
+++ b/testing/acceptance_test.py
@@ -391,15 +391,15 @@
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 @@
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
diff -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 -r 64445644395fd57f600e0027d78692971ccd44d2 testing/test_collection.py
--- a/testing/test_collection.py
+++ b/testing/test_collection.py
@@ -123,7 +123,7 @@
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 @@
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
diff -r 967c8ec78e6945a30090d98ffc607ba6935b3fc3 -r 64445644395fd57f600e0027d78692971ccd44d2 testing/test_doctest.py
--- a/testing/test_doctest.py
+++ b/testing/test_doctest.py
@@ -4,7 +4,7 @@
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:
Repository URL: https://bitbucket.org/hpk42/pytest/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the pytest-commit
mailing list