Skip to content

Commit

Permalink
Merge pull request #4195 from nicoddemus/issue-3691
Browse files Browse the repository at this point in the history
Use safe_str() to format warning message about unicode in Python 2
  • Loading branch information
nicoddemus authored Oct 19, 2018
2 parents 366b883 + 864d7fe commit 2abd005
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
2 changes: 2 additions & 0 deletions changelog/3691.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Python 2: safely format warning message about passing unicode strings to ``warnings.warn``, which may cause
surprising ``MemoryError`` exception when monkey patching ``warnings.warn`` itself.
2 changes: 1 addition & 1 deletion src/_pytest/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def warning_record_to_str(warning_message):
if unicode_warning:
warnings.warn(
"Warning is using unicode non convertible to ascii, "
"converting to a safe representation:\n %s" % msg,
"converting to a safe representation:\n {!r}".format(compat.safe_str(msg)),
UnicodeWarning,
)
return msg
Expand Down
29 changes: 29 additions & 0 deletions testing/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import sys

import six

import pytest


Expand Down Expand Up @@ -562,3 +564,30 @@ def test_hidden_by_system(self, testdir, monkeypatch):
monkeypatch.setenv(str("PYTHONWARNINGS"), str("once::UserWarning"))
result = testdir.runpytest_subprocess()
assert WARNINGS_SUMMARY_HEADER not in result.stdout.str()


@pytest.mark.skipif(six.PY3, reason="Python 2 only issue")
def test_infinite_loop_warning_against_unicode_usage_py2(testdir):
"""
We need to be careful when raising the warning about unicode usage with "warnings.warn"
because it might be overwritten by users and this itself causes another warning (#3691).
"""
testdir.makepyfile(
"""
# -*- coding: utf8 -*-
from __future__ import unicode_literals
import warnings
import pytest
def _custom_showwarning(message, *a, **b):
return "WARNING: {}".format(message)
warnings.formatwarning = _custom_showwarning
@pytest.mark.filterwarnings("default")
def test_custom_warning_formatter():
warnings.warn("¥")
"""
)
result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines(["*1 passed, * warnings in*"])
6 changes: 3 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ envlist =

[testenv]
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest --lsof
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest --lsof {posargs}
coverage: coverage combine
coverage: coverage report
passenv = USER USERNAME COVERAGE_* TRAVIS
Expand All @@ -41,7 +41,7 @@ deps =
py27: mock
nose
commands =
pytest -n auto --runpytest=subprocess
pytest -n auto --runpytest=subprocess {posargs}


[testenv:linting]
Expand All @@ -58,7 +58,7 @@ deps =
hypothesis>=3.56
{env:_PYTEST_TOX_EXTRA_DEP:}
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto {posargs}

[testenv:py36-xdist]
# NOTE: copied from above due to https://github.com/tox-dev/tox/issues/706.
Expand Down

0 comments on commit 2abd005

Please sign in to comment.