Skip to content

Commit 836dc45

Browse files
committed
Fix unicode issue while running doctests in Python 2
Fix #2434
1 parent 8df3e55 commit 836dc45

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
3.1.1 (unreleased)
22
==================
33

4-
* Fix encoding errors for unicode warnings in Python 2.
4+
* Fix encoding errors for unicode warnings in Python 2. (towncrier: 2436.bugfix)
5+
6+
* Fix issue with non-ascii contents in doctest text files. (towncrier: 2434.bugfix)
57

68

79
3.1.0 (2017-05-22)

_pytest/doctest.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ def collect(self):
181181
optionflags = get_optionflags(self)
182182
runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
183183
checker=_get_checker())
184+
_fix_spoof_python2(runner, encoding)
184185

185186
parser = doctest.DocTestParser()
186187
test = parser.get_doctest(text, globs, name, filename, 0)
@@ -216,6 +217,10 @@ def collect(self):
216217
optionflags = get_optionflags(self)
217218
runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
218219
checker=_get_checker())
220+
221+
encoding = self.config.getini("doctest_encoding")
222+
_fix_spoof_python2(runner, encoding)
223+
219224
for test in finder.find(module, module.__name__):
220225
if test.examples: # skip empty doctests
221226
yield DoctestItem(test.name, self, runner, test)
@@ -324,6 +329,30 @@ def _get_report_choice(key):
324329
DOCTEST_REPORT_CHOICE_NONE: 0,
325330
}[key]
326331

332+
333+
def _fix_spoof_python2(runner, encoding):
334+
"""
335+
Installs a "SpoofOut" into the given DebugRunner so it properly deals with unicode output.
336+
337+
This fixes the problem related in issue #2434.
338+
"""
339+
from _pytest.compat import _PY2
340+
if not _PY2:
341+
return
342+
343+
from doctest import _SpoofOut
344+
345+
class UnicodeSpoof(_SpoofOut):
346+
347+
def getvalue(self):
348+
result = _SpoofOut.getvalue(self)
349+
if encoding:
350+
result = result.decode(encoding)
351+
return result
352+
353+
runner._fakeout = UnicodeSpoof()
354+
355+
327356
@pytest.fixture(scope='session')
328357
def doctest_namespace():
329358
"""

testing/test_doctest.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,28 @@ def foo():
505505
"--junit-xml=junit.xml")
506506
reprec.assertoutcome(failed=1)
507507

508+
def test_unicode_doctest(self, testdir):
509+
"""
510+
Test case for issue 2434: DecodeError on Python 2 when doctest contains non-ascii
511+
characters.
512+
"""
513+
p = testdir.maketxtfile(test_unicode_doctest="""
514+
.. doctest::
515+
516+
>>> print(
517+
... "Hi\\n\\nByé")
518+
Hi
519+
...
520+
Byé
521+
>>> 1/0 # Byé
522+
1
523+
""")
524+
result = testdir.runpytest(p)
525+
result.stdout.fnmatch_lines([
526+
'*UNEXPECTED EXCEPTION: ZeroDivisionError*',
527+
'*1 failed*',
528+
])
529+
508530

509531
class TestLiterals(object):
510532

0 commit comments

Comments
 (0)