Skip to content

Commit

Permalink
Merge pull request #2437 from coldnight/master
Browse files Browse the repository at this point in the history
Correct warnings that contains Unicode message
  • Loading branch information
nicoddemus authored May 26, 2017
2 parents 17f6470 + 53add44 commit 8df3e55
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
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*',
])

0 comments on commit 8df3e55

Please sign in to comment.