Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
3.1.1 (unreleased)
==================

* Fix encoding errors for unicode warnings in Python 2.


3.1.0 (2017-05-22)
==================

Expand Down
2 changes: 2 additions & 0 deletions _pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def isclass(object):
import codecs
imap = map
STRING_TYPES = bytes, str
UNICODE_TYPES = str,

def _escape_strings(val):
"""If val is pure ascii, returns it as a str(). Otherwise, escapes
Expand Down Expand Up @@ -157,6 +158,7 @@ def _escape_strings(val):
return val.encode('unicode_escape').decode('ascii')
else:
STRING_TYPES = bytes, str, unicode
UNICODE_TYPES = unicode,

from itertools import imap # NOQA

Expand Down
17 changes: 16 additions & 1 deletion _pytest/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import pytest

from _pytest import compat


def _setoption(wmod, arg):
"""
Expand Down Expand Up @@ -61,11 +63,24 @@ def catch_warnings_for_item(item):
yield

for warning in log:
warn_msg = warning.message
unicode_warning = False

if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
warn_msg.args = [compat.safe_str(m) for m in warn_msg.args]
unicode_warning = True

msg = warnings.formatwarning(
warning.message, warning.category,
warn_msg, warning.category,
warning.filename, warning.lineno, warning.line)
item.warn("unused", msg)

if unicode_warning:
warnings.warn(
"This warning %s is broken as it's message is not a str instance"
"(after all this is a stdlib problem workaround)" % msg,
UnicodeWarning)


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_protocol(item):
Expand Down
60 changes: 60 additions & 0 deletions testing/test_warnings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# -*- coding: utf8 -*-
from __future__ import unicode_literals

import sys

import pytest


Expand Down Expand Up @@ -106,3 +111,58 @@ def test_ignore(testdir, pyfile_with_warnings, method):
])
assert WARNINGS_SUMMARY_HEADER not in result.stdout.str()



@pytest.mark.skipif(sys.version_info < (3, 0),
reason='warnings message is unicode is ok in python3')
def test_unicode(testdir, pyfile_with_warnings):
testdir.makepyfile('''
# -*- coding: utf8 -*-
import warnings
import pytest


@pytest.fixture
def fix():
warnings.warn(u"测试")
yield

def test_func(fix):
pass
''')
result = testdir.runpytest()
result.stdout.fnmatch_lines([
'*== %s ==*' % WARNINGS_SUMMARY_HEADER,

'*test_unicode.py:8: UserWarning: \u6d4b\u8bd5',
'*warnings.warn(u"\u6d4b\u8bd5")',
'* 1 passed, 1 warnings*',
])


@pytest.mark.skipif(sys.version_info >= (3, 0),
reason='warnings message is broken as it is not str instance')
def test_py2_unicode(testdir, pyfile_with_warnings):
testdir.makepyfile('''
# -*- coding: utf8 -*-
import warnings
import pytest


@pytest.fixture
def fix():
warnings.warn(u"测试")
yield

def test_func(fix):
pass
''')
result = testdir.runpytest()
result.stdout.fnmatch_lines([
'*== %s ==*' % WARNINGS_SUMMARY_HEADER,

'*test_py2_unicode.py:8: UserWarning: \u6d4b\u8bd5',
'*warnings.warn(u"\u6d4b\u8bd5")',
'*warnings.py:82: UnicodeWarning: This warning*\u6d4b\u8bd5',
'* 1 passed, 2 warnings*',
])