From 391553887b072d1a533a83226995785bef28fe34 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Feb 2018 12:08:39 -0500 Subject: [PATCH 1/7] Disable output capturing in doctest to avoid losing reference to stdout. Fixes #985. --- _pytest/doctest.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/_pytest/doctest.py b/_pytest/doctest.py index bba90e551..112a700ec 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, division, print_function import traceback +import sys import pytest from _pytest._code.code import ExceptionInfo, ReprFileLocation, TerminalRepr @@ -103,8 +104,19 @@ class DoctestItem(pytest.Item): def runtest(self): _check_all_skipped(self.dtest) + self._disable_output_capturing() self.runner.run(self.dtest) + def _disable_output_capturing(self): + """ + Disable output capturing. Otherwise, stdout is lost to doctest (#985) + """ + capman = self.config.pluginmanager.getplugin("capturemanager") + if capman: + out, err = capman.suspend_global_capture(in_=True) + sys.stdout.write(out) + sys.stdout.write(err) + def repr_failure(self, excinfo): import doctest if excinfo.errisinstance((doctest.DocTestFailure, From d845af7b2405438a3f1b46f9ed65293543bc2cc7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Feb 2018 12:32:00 -0500 Subject: [PATCH 2/7] Add changelog. Ref #985. --- changelog/985.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/985.bugfix diff --git a/changelog/985.bugfix b/changelog/985.bugfix new file mode 100644 index 000000000..0024b9aa2 --- /dev/null +++ b/changelog/985.bugfix @@ -0,0 +1 @@ +Fixed output capture handling in doctests on macOS. From 247cdb835a404f9668022984bb688496b48e5809 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Feb 2018 12:41:14 -0500 Subject: [PATCH 3/7] Remove xfail; tests now pass on macOS. Ref #985. --- testing/test_pdb.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/testing/test_pdb.py b/testing/test_pdb.py index b286d57a8..8618473bb 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -267,10 +267,6 @@ class TestPDB(object): child.read() self.flush(child) - # For some reason the interaction between doctest's and pytest's output - # capturing mechanisms are messing up the stdout on mac. (See #985). - # Should be solvable, but skipping until we have a chance to investigate. - @pytest.mark.xfail("sys.platform == 'darwin'", reason='See issue #985', run=False) def test_pdb_interaction_doctest(self, testdir): p1 = testdir.makepyfile(""" import pytest From 18c84a1904e96d5a4fc265b0fde56765ca36c7c3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Feb 2018 17:51:20 -0500 Subject: [PATCH 4/7] Restrict fix to macOS only. Ref #3215. --- _pytest/doctest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_pytest/doctest.py b/_pytest/doctest.py index 112a700ec..6a2918b6f 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, division, print_function import traceback import sys +import platform import pytest from _pytest._code.code import ExceptionInfo, ReprFileLocation, TerminalRepr @@ -111,6 +112,8 @@ class DoctestItem(pytest.Item): """ Disable output capturing. Otherwise, stdout is lost to doctest (#985) """ + if platform.system() != 'Darwin': + return capman = self.config.pluginmanager.getplugin("capturemanager") if capman: out, err = capman.suspend_global_capture(in_=True) From 435b8ddc7c681a4ba4490388756c7d49666ee8bf Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 15 Feb 2018 09:17:33 -0500 Subject: [PATCH 5/7] Rename method for additional clarity. --- _pytest/doctest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_pytest/doctest.py b/_pytest/doctest.py index 6a2918b6f..09de8ba41 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -105,10 +105,10 @@ class DoctestItem(pytest.Item): def runtest(self): _check_all_skipped(self.dtest) - self._disable_output_capturing() + self._disable_output_capturing_for_darwin() self.runner.run(self.dtest) - def _disable_output_capturing(self): + def _disable_output_capturing_for_darwin(self): """ Disable output capturing. Otherwise, stdout is lost to doctest (#985) """ From 254e357076a8826d19219a769ea909c28c1d6f35 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 17 Feb 2018 12:10:29 -0500 Subject: [PATCH 6/7] Correct the broken indentation. --- _pytest/doctest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_pytest/doctest.py b/_pytest/doctest.py index 09de8ba41..d61efebe7 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -118,7 +118,7 @@ class DoctestItem(pytest.Item): if capman: out, err = capman.suspend_global_capture(in_=True) sys.stdout.write(out) - sys.stdout.write(err) + sys.stdout.write(err) def repr_failure(self, excinfo): import doctest From 4131d3f300196da059f5abe6d36f4870459692ad Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 17 Feb 2018 12:13:33 -0500 Subject: [PATCH 7/7] Probably it's best to write the err stream to stderr. --- _pytest/doctest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_pytest/doctest.py b/_pytest/doctest.py index d61efebe7..f54f833ec 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -118,7 +118,7 @@ class DoctestItem(pytest.Item): if capman: out, err = capman.suspend_global_capture(in_=True) sys.stdout.write(out) - sys.stdout.write(err) + sys.stderr.write(err) def repr_failure(self, excinfo): import doctest