Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unicode issue while running doctests in Python 2 #2438

Merged
merged 1 commit into from
May 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
3.1.1 (unreleased)
==================

* Fix encoding errors for unicode warnings in Python 2.
* Fix encoding errors for unicode warnings in Python 2. (towncrier: 2436.bugfix)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RonnyPfannschmidt I added my entry here for now, we will want to move them to news fragments for #2431. 😁

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, thanks for putting in the extra data 👍


* Fix issue with non-ascii contents in doctest text files. (towncrier: 2434.bugfix)


3.1.0 (2017-05-22)
Expand Down
29 changes: 29 additions & 0 deletions _pytest/doctest.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ def collect(self):
optionflags = get_optionflags(self)
runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
checker=_get_checker())
_fix_spoof_python2(runner, encoding)

parser = doctest.DocTestParser()
test = parser.get_doctest(text, globs, name, filename, 0)
Expand Down Expand Up @@ -216,6 +217,10 @@ def collect(self):
optionflags = get_optionflags(self)
runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
checker=_get_checker())

encoding = self.config.getini("doctest_encoding")
_fix_spoof_python2(runner, encoding)

for test in finder.find(module, module.__name__):
if test.examples: # skip empty doctests
yield DoctestItem(test.name, self, runner, test)
Expand Down Expand Up @@ -324,6 +329,30 @@ def _get_report_choice(key):
DOCTEST_REPORT_CHOICE_NONE: 0,
}[key]


def _fix_spoof_python2(runner, encoding):
"""
Installs a "SpoofOut" into the given DebugRunner so it properly deals with unicode output.

This fixes the problem related in issue #2434.
"""
from _pytest.compat import _PY2
if not _PY2:
return

from doctest import _SpoofOut

class UnicodeSpoof(_SpoofOut):

def getvalue(self):
result = _SpoofOut.getvalue(self)
if encoding:
result = result.decode(encoding)
return result

runner._fakeout = UnicodeSpoof()


@pytest.fixture(scope='session')
def doctest_namespace():
"""
Expand Down
22 changes: 22 additions & 0 deletions testing/test_doctest.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,28 @@ def foo():
"--junit-xml=junit.xml")
reprec.assertoutcome(failed=1)

def test_unicode_doctest(self, testdir):
"""
Test case for issue 2434: DecodeError on Python 2 when doctest contains non-ascii
characters.
"""
p = testdir.maketxtfile(test_unicode_doctest="""
.. doctest::

>>> print(
... "Hi\\n\\nByé")
Hi
...
Byé
>>> 1/0 # Byé
1
""")
result = testdir.runpytest(p)
result.stdout.fnmatch_lines([
'*UNEXPECTED EXCEPTION: ZeroDivisionError*',
'*1 failed*',
])


class TestLiterals(object):

Expand Down