[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