diff --git a/_pytest/config.py b/_pytest/config.py index 12be0c496..ccc7e7b8a 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -423,12 +423,12 @@ class PytestPluginManager(PluginManager): try: __import__(importspec) except ImportError as e: - new_exc = ImportError('Error importing plugin "%s": %s' % (modname, safe_str(e.args[0]))) - # copy over name and path attributes - for attr in ('name', 'path'): - if hasattr(e, attr): - setattr(new_exc, attr, getattr(e, attr)) - raise new_exc + new_exc_type = ImportError + new_exc_message = 'Error importing plugin "%s": %s' % (modname, safe_str(e.args[0])) + new_exc = new_exc_type(new_exc_message) + + six.reraise(new_exc_type, new_exc, sys.exc_info()[2]) + except Exception as e: import pytest if not hasattr(pytest, 'skip') or not isinstance(e, pytest.skip.Exception): diff --git a/changelog/2491.bugfix b/changelog/2491.bugfix new file mode 100644 index 000000000..fbb16e17e --- /dev/null +++ b/changelog/2491.bugfix @@ -0,0 +1,4 @@ +If an exception happens while loading a plugin, pytest no longer hides the original traceback. +In python2 it will show the original traceback with a new message that explains in which plugin. +In python3 it will show 2 canonized exceptions, the original exception while loading the plugin +in addition to an exception that PyTest throws about loading a plugin. diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 2838f83c5..55e2ea10f 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -199,12 +199,17 @@ def test_importplugin_error_message(testdir, pytestpm): testdir.syspathinsert(testdir.tmpdir) testdir.makepyfile(qwe=""" # encoding: UTF-8 - raise ImportError(u'Not possible to import: ☺') + def test_traceback(): + raise ImportError(u'Not possible to import: ☺') + test_traceback() """) with pytest.raises(ImportError) as excinfo: pytestpm.import_plugin("qwe") - expected = '.*Error importing plugin "qwe": Not possible to import: .' - assert py.std.re.match(expected, str(excinfo.value)) + + expected_message = '.*Error importing plugin "qwe": Not possible to import: .' + expected_traceback = ".*in test_traceback" + assert py.std.re.match(expected_message, str(excinfo.value)) + assert py.std.re.match(expected_traceback, str(excinfo.traceback[-1])) class TestPytestPluginManager(object):