Merge pull request #2810 from nicoddemus/issue-2809
Fix warning about non-ascii warnings even when they are ascii
This commit is contained in:
commit
61eb20df71
|
@ -149,7 +149,7 @@ if _PY3:
|
||||||
# empty bytes crashes codecs.escape_encode (#1087)
|
# empty bytes crashes codecs.escape_encode (#1087)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def _ascii_escaped(val):
|
def ascii_escaped(val):
|
||||||
"""If val is pure ascii, returns it as a str(). Otherwise, escapes
|
"""If val is pure ascii, returns it as a str(). Otherwise, escapes
|
||||||
bytes objects into a sequence of escaped bytes:
|
bytes objects into a sequence of escaped bytes:
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ else:
|
||||||
|
|
||||||
from itertools import imap, izip # NOQA
|
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
|
"""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,
|
object, return it unchanged if it is a full ascii string,
|
||||||
otherwise escape it into its binary form.
|
otherwise escape it into its binary form.
|
||||||
|
|
|
@ -19,7 +19,7 @@ import pluggy
|
||||||
from _pytest import fixtures
|
from _pytest import fixtures
|
||||||
from _pytest import main
|
from _pytest import main
|
||||||
from _pytest.compat import (
|
from _pytest.compat import (
|
||||||
isclass, isfunction, is_generator, _ascii_escaped,
|
isclass, isfunction, is_generator, ascii_escaped,
|
||||||
REGEX_TYPE, STRING_TYPES, NoneType, NOTSET,
|
REGEX_TYPE, STRING_TYPES, NoneType, NOTSET,
|
||||||
get_real_func, getfslineno, safe_getattr,
|
get_real_func, getfslineno, safe_getattr,
|
||||||
safe_str, getlocation, enum,
|
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.'
|
msg += '\nUpdate your code as this will raise an error in pytest-4.0.'
|
||||||
warnings.warn(msg, DeprecationWarning)
|
warnings.warn(msg, DeprecationWarning)
|
||||||
if s:
|
if s:
|
||||||
return _ascii_escaped(s)
|
return ascii_escaped(s)
|
||||||
|
|
||||||
if config:
|
if config:
|
||||||
hook_id = config.hook.pytest_make_parametrize_id(
|
hook_id = config.hook.pytest_make_parametrize_id(
|
||||||
|
@ -931,11 +931,11 @@ def _idval(val, argname, idx, idfn, config=None):
|
||||||
return hook_id
|
return hook_id
|
||||||
|
|
||||||
if isinstance(val, STRING_TYPES):
|
if isinstance(val, STRING_TYPES):
|
||||||
return _ascii_escaped(val)
|
return ascii_escaped(val)
|
||||||
elif isinstance(val, (float, int, bool, NoneType)):
|
elif isinstance(val, (float, int, bool, NoneType)):
|
||||||
return str(val)
|
return str(val)
|
||||||
elif isinstance(val, REGEX_TYPE):
|
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):
|
elif enum is not None and isinstance(val, enum.Enum):
|
||||||
return str(val)
|
return str(val)
|
||||||
elif isclass(val) and hasattr(val, '__name__'):
|
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)]
|
for val, argname in zip(parameterset.values, argnames)]
|
||||||
return "-".join(this_id)
|
return "-".join(this_id)
|
||||||
else:
|
else:
|
||||||
return _ascii_escaped(ids[idx])
|
return ascii_escaped(ids[idx])
|
||||||
|
|
||||||
|
|
||||||
def idmaker(argnames, parametersets, idfn=None, ids=None, config=None):
|
def idmaker(argnames, parametersets, idfn=None, ids=None, config=None):
|
||||||
|
|
|
@ -72,8 +72,8 @@ def catch_warnings_for_item(item):
|
||||||
unicode_warning = False
|
unicode_warning = False
|
||||||
|
|
||||||
if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
|
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]
|
new_args = [compat.ascii_escaped(m) for m in warn_msg.args]
|
||||||
unicode_warning = warn_msg.args != new_args
|
unicode_warning = list(warn_msg.args) != new_args
|
||||||
warn_msg.args = new_args
|
warn_msg.args = new_args
|
||||||
|
|
||||||
msg = warnings.formatwarning(
|
msg = warnings.formatwarning(
|
||||||
|
|
|
@ -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.
|
|
@ -163,13 +163,33 @@ def test_py2_unicode(testdir, pyfile_with_warnings):
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
'*== %s ==*' % WARNINGS_SUMMARY_HEADER,
|
'*== %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.warn(u"\u6d4b\u8bd5")',
|
||||||
'*warnings.py:*: UnicodeWarning: Warning is using unicode non*',
|
'*warnings.py:*: UnicodeWarning: Warning is using unicode non*',
|
||||||
'* 1 passed, 2 warnings*',
|
'* 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):
|
def test_works_with_filterwarnings(testdir):
|
||||||
"""Ensure our warnings capture does not mess with pre-installed filters (#2430)."""
|
"""Ensure our warnings capture does not mess with pre-installed filters (#2430)."""
|
||||||
testdir.makepyfile('''
|
testdir.makepyfile('''
|
||||||
|
|
Loading…
Reference in New Issue