[Pytest-commit] commit/pytest: 2 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Thu Apr 3 00:19:09 CEST 2014


2 new commits in pytest:

https://bitbucket.org/hpk42/pytest/commits/202e6aee5890/
Changeset:   202e6aee5890
Branch:      issue486
User:        hpk42
Date:        2014-04-02 20:42:41
Summary:     fix issue486: better reporting and handling of early conftest loading failures
Affected #:  4 files

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r 202e6aee58906bf7fc5313d8567bb0451497394f CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -48,6 +48,9 @@
 - fix issue493: don't run tests in doc directory with ``python setup.py test`` 
   (use tox -e doctesting for that)
 
+- fix issue486: better reporting and handling of early conftest loading failures
+
+
 2.5.2
 -----------------------------------
 

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r 202e6aee58906bf7fc5313d8567bb0451497394f _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -7,6 +7,13 @@
 from _pytest.core import PluginManager
 
 # pytest startup
+#
+class ConftestImportFailure(Exception):
+    def __init__(self, path, excinfo):
+        Exception.__init__(self, path, excinfo)
+        self.path = path
+        self.excinfo = excinfo
+
 
 def main(args=None, plugins=None):
     """ return exit code, after performing an in-process test run.
@@ -16,8 +23,17 @@
     :arg plugins: list of plugin objects to be auto-registered during
                   initialization.
     """
-    config = _prepareconfig(args, plugins)
-    return config.hook.pytest_cmdline_main(config=config)
+    try:
+        config = _prepareconfig(args, plugins)
+    except ConftestImportFailure:
+        e = sys.exc_info()[1]
+        tw = py.io.TerminalWriter(sys.stderr)
+        for line in py.std.traceback.format_exception(*e.excinfo):
+            tw.line(line.rstrip(), red=True)
+        tw.line("ERROR: could not load %s\n" % (e.path), red=True)
+        return 4
+    else:
+        return config.hook.pytest_cmdline_main(config=config)
 
 class cmdline:  # compatibility namespace
     main = staticmethod(main)
@@ -86,8 +102,7 @@
         config.addinivalue_line("markers",
             "trylast: mark a hook implementation function such that the "
             "plugin machinery will try to call it last/as late as possible.")
-        while self._warnings:
-            warning = self._warnings.pop(0)
+        for warning in self._warnings:
             config.warn(code="I1", message=warning)
 
 
@@ -496,7 +511,8 @@
                     continue
                 conftestpath = parent.join("conftest.py")
                 if conftestpath.check(file=1):
-                    clist.append(self.importconftest(conftestpath))
+                    mod = self.importconftest(conftestpath)
+                    clist.append(mod)
             self._path2confmods[path] = clist
         return clist
 
@@ -522,7 +538,11 @@
             pkgpath = conftestpath.pypkgpath()
             if pkgpath is None:
                 _ensure_removed_sysmodule(conftestpath.purebasename)
-            self._conftestpath2mod[conftestpath] = mod = conftestpath.pyimport()
+            try:
+                mod = conftestpath.pyimport()
+            except Exception:
+                raise ConftestImportFailure(conftestpath, sys.exc_info())
+            self._conftestpath2mod[conftestpath] = mod
             dirpath = conftestpath.dirpath()
             if dirpath in self._path2confmods:
                 for path, mods in self._path2confmods.items():
@@ -682,9 +702,19 @@
         self.pluginmanager.consider_preparse(args)
         self.pluginmanager.consider_setuptools_entrypoints()
         self.pluginmanager.consider_env()
-        self.known_args_namespace = self._parser.parse_known_args(args)
-        self.hook.pytest_load_initial_conftests(early_config=self,
-            args=args, parser=self._parser)
+        self.known_args_namespace = ns = self._parser.parse_known_args(args)
+        try:
+            self.hook.pytest_load_initial_conftests(early_config=self,
+                    args=args, parser=self._parser)
+        except ConftestImportFailure:
+            e = sys.exc_info()[1]
+            if ns.help or ns.version:
+                # we don't want to prevent --help/--version to work 
+                # so just let is pass and print a warning at the end
+                self.pluginmanager._warnings.append(
+                        "could not load initial conftests (%s)\n" % e.path)
+            else:
+                raise
 
     def _checkversion(self):
         import pytest

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r 202e6aee58906bf7fc5313d8567bb0451497394f _pytest/helpconfig.py
--- a/_pytest/helpconfig.py
+++ b/_pytest/helpconfig.py
@@ -86,17 +86,9 @@
     tw.line("(shown according to specified file_or_dir or current dir "
             "if not specified)")
     for warning in config.pluginmanager._warnings:
-        tw.line("warning: %s" % (warning,))
+        tw.line("warning: %s" % (warning,), red=True)
     return
 
-    tw.line("conftest.py options:")
-    tw.line()
-    conftestitems = sorted(config._parser._conftestdict.items())
-    for name, help in conftest_options + conftestitems:
-        line = "   %-15s  %s" %(name, help)
-        tw.line(line[:tw.fullwidth])
-    tw.line()
-    #tw.sep( "=")
 
 conftest_options = [
     ('pytest_plugins', 'list of plugin names to load'),

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r 202e6aee58906bf7fc5313d8567bb0451497394f testing/acceptance_test.py
--- a/testing/acceptance_test.py
+++ b/testing/acceptance_test.py
@@ -124,6 +124,18 @@
             "*ERROR: not found:*%s" %(p2.basename,)
         ])
 
+    def test_issue486_better_reporting_on_conftest_load_failure(self, testdir):
+        testdir.makepyfile("")
+        testdir.makeconftest("import qwerty")
+        result = testdir.runpytest("--help")
+        result.stdout.fnmatch_lines("""
+            *--version*
+            *warning*conftest.py*
+        """)
+        result = testdir.runpytest()
+        result.stderr.fnmatch_lines("""
+            *ERROR*could not load*conftest.py*
+        """)
 
 
     def test_early_skip(self, testdir):


https://bitbucket.org/hpk42/pytest/commits/e5b0bd42a006/
Changeset:   e5b0bd42a006
User:        bubenkoff
Date:        2014-04-03 00:19:05
Summary:     Merged in hpk42/pytest-hpk/issue486 (pull request #147)

fix issue486: better reporting and handling of early conftest loading failures
Affected #:  4 files

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r e5b0bd42a00632fec91a70fb8c61edcd7d38e898 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -48,6 +48,9 @@
 - fix issue493: don't run tests in doc directory with ``python setup.py test`` 
   (use tox -e doctesting for that)
 
+- fix issue486: better reporting and handling of early conftest loading failures
+
+
 2.5.2
 -----------------------------------
 

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r e5b0bd42a00632fec91a70fb8c61edcd7d38e898 _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -7,6 +7,13 @@
 from _pytest.core import PluginManager
 
 # pytest startup
+#
+class ConftestImportFailure(Exception):
+    def __init__(self, path, excinfo):
+        Exception.__init__(self, path, excinfo)
+        self.path = path
+        self.excinfo = excinfo
+
 
 def main(args=None, plugins=None):
     """ return exit code, after performing an in-process test run.
@@ -16,8 +23,17 @@
     :arg plugins: list of plugin objects to be auto-registered during
                   initialization.
     """
-    config = _prepareconfig(args, plugins)
-    return config.hook.pytest_cmdline_main(config=config)
+    try:
+        config = _prepareconfig(args, plugins)
+    except ConftestImportFailure:
+        e = sys.exc_info()[1]
+        tw = py.io.TerminalWriter(sys.stderr)
+        for line in py.std.traceback.format_exception(*e.excinfo):
+            tw.line(line.rstrip(), red=True)
+        tw.line("ERROR: could not load %s\n" % (e.path), red=True)
+        return 4
+    else:
+        return config.hook.pytest_cmdline_main(config=config)
 
 class cmdline:  # compatibility namespace
     main = staticmethod(main)
@@ -86,8 +102,7 @@
         config.addinivalue_line("markers",
             "trylast: mark a hook implementation function such that the "
             "plugin machinery will try to call it last/as late as possible.")
-        while self._warnings:
-            warning = self._warnings.pop(0)
+        for warning in self._warnings:
             config.warn(code="I1", message=warning)
 
 
@@ -496,7 +511,8 @@
                     continue
                 conftestpath = parent.join("conftest.py")
                 if conftestpath.check(file=1):
-                    clist.append(self.importconftest(conftestpath))
+                    mod = self.importconftest(conftestpath)
+                    clist.append(mod)
             self._path2confmods[path] = clist
         return clist
 
@@ -522,7 +538,11 @@
             pkgpath = conftestpath.pypkgpath()
             if pkgpath is None:
                 _ensure_removed_sysmodule(conftestpath.purebasename)
-            self._conftestpath2mod[conftestpath] = mod = conftestpath.pyimport()
+            try:
+                mod = conftestpath.pyimport()
+            except Exception:
+                raise ConftestImportFailure(conftestpath, sys.exc_info())
+            self._conftestpath2mod[conftestpath] = mod
             dirpath = conftestpath.dirpath()
             if dirpath in self._path2confmods:
                 for path, mods in self._path2confmods.items():
@@ -682,9 +702,19 @@
         self.pluginmanager.consider_preparse(args)
         self.pluginmanager.consider_setuptools_entrypoints()
         self.pluginmanager.consider_env()
-        self.known_args_namespace = self._parser.parse_known_args(args)
-        self.hook.pytest_load_initial_conftests(early_config=self,
-            args=args, parser=self._parser)
+        self.known_args_namespace = ns = self._parser.parse_known_args(args)
+        try:
+            self.hook.pytest_load_initial_conftests(early_config=self,
+                    args=args, parser=self._parser)
+        except ConftestImportFailure:
+            e = sys.exc_info()[1]
+            if ns.help or ns.version:
+                # we don't want to prevent --help/--version to work 
+                # so just let is pass and print a warning at the end
+                self.pluginmanager._warnings.append(
+                        "could not load initial conftests (%s)\n" % e.path)
+            else:
+                raise
 
     def _checkversion(self):
         import pytest

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r e5b0bd42a00632fec91a70fb8c61edcd7d38e898 _pytest/helpconfig.py
--- a/_pytest/helpconfig.py
+++ b/_pytest/helpconfig.py
@@ -86,17 +86,9 @@
     tw.line("(shown according to specified file_or_dir or current dir "
             "if not specified)")
     for warning in config.pluginmanager._warnings:
-        tw.line("warning: %s" % (warning,))
+        tw.line("warning: %s" % (warning,), red=True)
     return
 
-    tw.line("conftest.py options:")
-    tw.line()
-    conftestitems = sorted(config._parser._conftestdict.items())
-    for name, help in conftest_options + conftestitems:
-        line = "   %-15s  %s" %(name, help)
-        tw.line(line[:tw.fullwidth])
-    tw.line()
-    #tw.sep( "=")
 
 conftest_options = [
     ('pytest_plugins', 'list of plugin names to load'),

diff -r ceafafc62657ed15b0486e8838f20b06abc0880d -r e5b0bd42a00632fec91a70fb8c61edcd7d38e898 testing/acceptance_test.py
--- a/testing/acceptance_test.py
+++ b/testing/acceptance_test.py
@@ -124,6 +124,18 @@
             "*ERROR: not found:*%s" %(p2.basename,)
         ])
 
+    def test_issue486_better_reporting_on_conftest_load_failure(self, testdir):
+        testdir.makepyfile("")
+        testdir.makeconftest("import qwerty")
+        result = testdir.runpytest("--help")
+        result.stdout.fnmatch_lines("""
+            *--version*
+            *warning*conftest.py*
+        """)
+        result = testdir.runpytest()
+        result.stderr.fnmatch_lines("""
+            *ERROR*could not load*conftest.py*
+        """)
 
 
     def test_early_skip(self, testdir):

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