Merge pull request #2810 from nicoddemus/issue-2809

Fix warning about non-ascii warnings even when they are ascii
This commit is contained in:
Ronny Pfannschmidt 2017-10-03 20:56:23 +02:00 committed by GitHub
commit 61eb20df71
5 changed files with 31 additions and 10 deletions

View File

@ -149,7 +149,7 @@ if _PY3:
# empty bytes crashes codecs.escape_encode (#1087)
return ''
def _ascii_escaped(val):
def ascii_escaped(val):
"""If val is pure ascii, returns it as a str(). Otherwise, escapes
bytes objects into a sequence of escaped bytes:
@ -177,7 +177,7 @@ else:
from itertools import imap, izip # NOQA
def _ascii_escaped(val):
def ascii_escaped(val):
"""In py2 bytes and str are the same type, so return if it's a bytes
object, return it unchanged if it is a full ascii string,
otherwise escape it into its binary form.

View File

@ -19,7 +19,7 @@ import pluggy
from _pytest import fixtures
from _pytest import main
from _pytest.compat import (
isclass, isfunction, is_generator, _ascii_escaped,
isclass, isfunction, is_generator, ascii_escaped,
REGEX_TYPE, STRING_TYPES, NoneType, NOTSET,
get_real_func, getfslineno, safe_getattr,
safe_str, getlocation, enum,
@ -922,7 +922,7 @@ def _idval(val, argname, idx, idfn, config=None):
msg += '\nUpdate your code as this will raise an error in pytest-4.0.'
warnings.warn(msg, DeprecationWarning)
if s:
return _ascii_escaped(s)
return ascii_escaped(s)
if config:
hook_id = config.hook.pytest_make_parametrize_id(
@ -931,11 +931,11 @@ def _idval(val, argname, idx, idfn, config=None):
return hook_id
if isinstance(val, STRING_TYPES):
return _ascii_escaped(val)
return ascii_escaped(val)
elif isinstance(val, (float, int, bool, NoneType)):
return str(val)
elif isinstance(val, REGEX_TYPE):
return _ascii_escaped(val.pattern)
return ascii_escaped(val.pattern)
elif enum is not None and isinstance(val, enum.Enum):
return str(val)
elif isclass(val) and hasattr(val, '__name__'):
@ -951,7 +951,7 @@ def _idvalset(idx, parameterset, argnames, idfn, ids, config=None):
for val, argname in zip(parameterset.values, argnames)]
return "-".join(this_id)
else:
return _ascii_escaped(ids[idx])
return ascii_escaped(ids[idx])
def idmaker(argnames, parametersets, idfn=None, ids=None, config=None):

View File

@ -72,8 +72,8 @@ def catch_warnings_for_item(item):
unicode_warning = False
if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
new_args = [compat.safe_str(m) for m in warn_msg.args]
unicode_warning = warn_msg.args != new_args
new_args = [compat.ascii_escaped(m) for m in warn_msg.args]
unicode_warning = list(warn_msg.args) != new_args
warn_msg.args = new_args
msg = warnings.formatwarning(

1
changelog/2809.bugfix Normal file
View File

@ -0,0 +1 @@
Pytest no longer complains about warnings with unicode messages being non-ascii compatible even for ascii-compatible messages. As a result of this, warnings with unicode messages are converted first to an ascii representation for safety.

View File

@ -163,13 +163,33 @@ def test_py2_unicode(testdir, pyfile_with_warnings):
result.stdout.fnmatch_lines([
'*== %s ==*' % WARNINGS_SUMMARY_HEADER,
'*test_py2_unicode.py:8: UserWarning: \u6d4b\u8bd5',
'*test_py2_unicode.py:8: UserWarning: \\u6d4b\\u8bd5',
'*warnings.warn(u"\u6d4b\u8bd5")',
'*warnings.py:*: UnicodeWarning: Warning is using unicode non*',
'* 1 passed, 2 warnings*',
])
def test_py2_unicode_ascii(testdir):
"""Ensure that our warning about 'unicode warnings containing non-ascii messages'
does not trigger with ascii-convertible messages"""
testdir.makeini('[pytest]')
testdir.makepyfile('''
import pytest
import warnings
@pytest.mark.filterwarnings('always')
def test_func():
warnings.warn(u"hello")
''')
result = testdir.runpytest()
result.stdout.fnmatch_lines([
'*== %s ==*' % WARNINGS_SUMMARY_HEADER,
'*warnings.warn(u"hello")',
'* 1 passed, 1 warnings in*'
])
def test_works_with_filterwarnings(testdir):
"""Ensure our warnings capture does not mess with pre-installed filters (#2430)."""
testdir.makepyfile('''