Merge pull request #1222 from nicoddemus/pastebin-unicode

Fix #1222 - pastebin when captured output contains non-ascii characters
This commit is contained in:
Ronny Pfannschmidt 2015-12-04 07:10:49 +01:00
commit 427e6c3b4d
3 changed files with 43 additions and 9 deletions

View File

@ -9,6 +9,9 @@
- fix #1198: ``--pastebin`` option now works on Python 3. Thanks - fix #1198: ``--pastebin`` option now works on Python 3. Thanks
Mehdy Khoshnoody for the PR. Mehdy Khoshnoody for the PR.
- fix #1219: ``--pastebin`` now works correctly when captured output contains
non-ascii characters. Thanks Bruno Oliveira for the PR.
- fix #1204: another error when collecting with a nasty __getattr__(). - fix #1204: another error when collecting with a nasty __getattr__().
Thanks Florian Bruhin for the PR. Thanks Florian Bruhin for the PR.

View File

@ -13,17 +13,21 @@ def pytest_addoption(parser):
@pytest.hookimpl(trylast=True) @pytest.hookimpl(trylast=True)
def pytest_configure(config): def pytest_configure(config):
import py
if config.option.pastebin == "all": if config.option.pastebin == "all":
tr = config.pluginmanager.getplugin('terminalreporter') tr = config.pluginmanager.getplugin('terminalreporter')
# if no terminal reporter plugin is present, nothing we can do here; # if no terminal reporter plugin is present, nothing we can do here;
# this can happen when this function executes in a slave node # this can happen when this function executes in a slave node
# when using pytest-xdist, for example # when using pytest-xdist, for example
if tr is not None: if tr is not None:
config._pastebinfile = tempfile.TemporaryFile('w+') # pastebin file will be utf-8 encoded binary file
config._pastebinfile = tempfile.TemporaryFile('w+b')
oldwrite = tr._tw.write oldwrite = tr._tw.write
def tee_write(s, **kwargs): def tee_write(s, **kwargs):
oldwrite(s, **kwargs) oldwrite(s, **kwargs)
config._pastebinfile.write(str(s)) if py.builtin._istext(s):
s = s.encode('utf-8')
config._pastebinfile.write(s)
tr._tw.write = tee_write tr._tw.write = tee_write
def pytest_unconfigure(config): def pytest_unconfigure(config):
@ -45,7 +49,7 @@ def create_new_paste(contents):
""" """
Creates a new paste using bpaste.net service. Creates a new paste using bpaste.net service.
:contents: paste contents :contents: paste contents as utf-8 encoded bytes
:returns: url to the pasted contents :returns: url to the pasted contents
""" """
import re import re
@ -61,8 +65,8 @@ def create_new_paste(contents):
'expiry': '1week', 'expiry': '1week',
} }
url = 'https://bpaste.net' url = 'https://bpaste.net'
response = urlopen(url, data=urlencode(params).encode()).read() response = urlopen(url, data=urlencode(params).encode('ascii')).read()
m = re.search(r'href="/raw/(\w+)"', response.decode()) m = re.search(r'href="/raw/(\w+)"', response.decode('utf-8'))
if m: if m:
return '%s/show/%s' % (url, m.group(1)) return '%s/show/%s' % (url, m.group(1))
else: else:

View File

@ -1,3 +1,4 @@
# encoding: utf-8
import sys import sys
import pytest import pytest
@ -27,6 +28,7 @@ class TestPasteCapture:
assert reprec.countoutcomes() == [1,1,1] assert reprec.countoutcomes() == [1,1,1]
def test_all(self, testdir, pastebinlist): def test_all(self, testdir, pastebinlist):
from _pytest.pytester import LineMatcher
testpath = testdir.makepyfile(""" testpath = testdir.makepyfile("""
import pytest import pytest
def test_pass(): def test_pass():
@ -39,9 +41,34 @@ class TestPasteCapture:
reprec = testdir.inline_run(testpath, "--pastebin=all", '-v') reprec = testdir.inline_run(testpath, "--pastebin=all", '-v')
assert reprec.countoutcomes() == [1,1,1] assert reprec.countoutcomes() == [1,1,1]
assert len(pastebinlist) == 1 assert len(pastebinlist) == 1
s = pastebinlist[0] contents = pastebinlist[0].decode('utf-8')
for x in 'test_fail test_skip test_pass'.split(): matcher = LineMatcher(contents.splitlines())
assert x in s matcher.fnmatch_lines([
'*test_pass PASSED*',
'*test_fail FAILED*',
'*test_skip SKIPPED*',
'*== 1 failed, 1 passed, 1 skipped in *'
])
def test_non_ascii_paste_text(self, testdir):
"""Make sure that text which contains non-ascii characters is pasted
correctly. See #1219.
"""
testdir.makepyfile(test_unicode="""
# encoding: utf-8
def test():
assert '' == 1
""")
result = testdir.runpytest('--pastebin=all')
if sys.version_info[0] == 3:
expected_msg = "*assert '' == 1*"
else:
expected_msg = "*assert '\\xe2\\x98\\xba' == 1*"
result.stdout.fnmatch_lines([
expected_msg,
"*== 1 failed in *",
'*Sending information to Paste Service*',
])
class TestPaste: class TestPaste:
@ -74,7 +101,7 @@ class TestPaste:
return calls return calls
def test_create_new_paste(self, pastebin, mocked_urlopen): def test_create_new_paste(self, pastebin, mocked_urlopen):
result = pastebin.create_new_paste('full-paste-contents') result = pastebin.create_new_paste(b'full-paste-contents')
assert result == 'https://bpaste.net/show/3c0c6750bd' assert result == 'https://bpaste.net/show/3c0c6750bd'
assert len(mocked_urlopen) == 1 assert len(mocked_urlopen) == 1
url, data = mocked_urlopen[0] url, data = mocked_urlopen[0]