Handle import errors with non-ascii messages when importing plugins

Fix #1998
This commit is contained in:
Bruno Oliveira 2016-10-12 17:46:47 -03:00
parent 3301a1c173
commit 78eec0d7f8
4 changed files with 29 additions and 6 deletions

View File

@ -6,7 +6,8 @@
* Import errors when collecting test modules now display the full traceback (`#1976`_).
Thanks `@cwitty`_ for the report and `@nicoddemus`_ for the PR.
*
* When loading plugins, import errors which contain non-ascii messages are now properly handled in Python 2 (`#1998`_).
Thanks `@nicoddemus`_ for the PR.
*
@ -14,6 +15,7 @@
.. _@cwitty: https://github.com/cwitty
.. _#1976: https://github.com/pytest-dev/pytest/issues/1976
.. _#1998: https://github.com/pytest-dev/pytest/issues/1998

View File

@ -214,3 +214,17 @@ def _is_unittest_unexpected_success_a_failure():
unexpectedSuccesses from tests marked with the expectedFailure() decorator.
"""
return sys.version_info >= (3, 4)
if _PY3:
def safe_str(v):
"""returns v as string"""
return str(v)
else:
def safe_str(v):
"""returns v as string, converting to ascii if necessary"""
try:
return str(v)
except UnicodeError:
errors = 'replace'
return v.encode('ascii', errors)

View File

@ -12,6 +12,7 @@ import _pytest._code
import _pytest.hookspec # the extension point definitions
import _pytest.assertion
from _pytest._pluggy import PluginManager, HookimplMarker, HookspecMarker
from _pytest.compat import safe_str
hookimpl = HookimplMarker("pytest")
hookspec = HookspecMarker("pytest")
@ -405,7 +406,7 @@ class PytestPluginManager(PluginManager):
try:
__import__(importspec)
except ImportError as e:
new_exc = ImportError('Error importing plugin "%s": %s' % (modname, 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):

View File

@ -1,3 +1,4 @@
# encoding: UTF-8
import pytest
import py
import os
@ -179,15 +180,20 @@ def test_default_markers(testdir):
])
def test_importplugin_issue375(testdir, pytestpm):
def test_importplugin_error_message(testdir, pytestpm):
"""Don't hide import errors when importing plugins and provide
an easy to debug message.
See #375 and #1998.
"""
testdir.syspathinsert(testdir.tmpdir)
testdir.makepyfile(qwe="import aaaa")
testdir.makepyfile(qwe="""
# encoding: UTF-8
raise ImportError(u'Not possible to import: ☺')
""")
with pytest.raises(ImportError) as excinfo:
pytestpm.import_plugin("qwe")
expected = '.*Error importing plugin "qwe": No module named \'?aaaa\'?'
expected = '.*Error importing plugin "qwe": Not possible to import: .'
assert py.std.re.match(expected, str(excinfo.value))