Skip to content

Commit

Permalink
Assume os.dup is always available
Browse files Browse the repository at this point in the history
The commit which added the checks for os.dup a15afb5
suggests it was done for Jython. But pytest doesn't support Jython
anymore (Jython is Python 2 only).

Furthermore, it looks like the faulthandler plugin (bundled in pytest
and enabled by default) uses os.dup() unprotected and there have not
been any complaints.

So seems better to just remove these checks, and only add if someone
with a legitimate use case complains.
  • Loading branch information
bluetech committed Mar 12, 2020
1 parent e1b3a68 commit 6954b3b
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 58 deletions.
2 changes: 2 additions & 0 deletions changelog/6903.breaking.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The ``os.dup()`` function is now assumed to exist. We are not aware of any
supported Python 3 implementations which do not provide it.
10 changes: 1 addition & 9 deletions src/_pytest/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def pytest_addoption(parser):
group._addoption(
"--capture",
action="store",
default="fd" if hasattr(os, "dup") else "sys",
default="fd",
metavar="method",
choices=["fd", "sys", "no", "tee-sys"],
help="per-test capturing method: one of fd|sys|no|tee-sys.",
Expand Down Expand Up @@ -304,10 +304,6 @@ def capfd(request):
calls, which return a ``(out, err)`` namedtuple.
``out`` and ``err`` will be ``text`` objects.
"""
if not hasattr(os, "dup"):
pytest.skip(
"capfd fixture needs os.dup function which is not available in this system"
)
capman = request.config.pluginmanager.getplugin("capturemanager")
with capman._capturing_for_request(request) as fixture:
yield fixture
Expand All @@ -321,10 +317,6 @@ def capfdbinary(request):
calls, which return a ``(out, err)`` namedtuple.
``out`` and ``err`` will be ``byte`` objects.
"""
if not hasattr(os, "dup"):
pytest.skip(
"capfdbinary fixture needs os.dup function which is not available in this system"
)
capman = request.config.pluginmanager.getplugin("capturemanager")
with capman._capturing_for_request(request) as fixture:
yield fixture
Expand Down
50 changes: 1 addition & 49 deletions testing/test_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@
# pylib 1.4.20.dev2 (rev 13d9af95547e)


needsosdup = pytest.mark.skipif(
not hasattr(os, "dup"), reason="test needs os.dup, not available on this platform"
)


def StdCaptureFD(out=True, err=True, in_=True):
return capture.MultiCapture(out, err, in_, Capture=capture.FDCapture)

Expand All @@ -41,22 +36,7 @@ def TeeStdCapture(out=True, err=True, in_=True):


class TestCaptureManager:
def test_getmethod_default_no_fd(self, monkeypatch):
from _pytest.capture import pytest_addoption
from _pytest.config.argparsing import Parser

parser = Parser()
pytest_addoption(parser)
default = parser._groups[0].options[0].default
assert default == "fd" if hasattr(os, "dup") else "sys"
parser = Parser()
monkeypatch.delattr(os, "dup", raising=False)
pytest_addoption(parser)
assert parser._groups[0].options[0].default == "sys"

@pytest.mark.parametrize(
"method", ["no", "sys", pytest.param("fd", marks=needsosdup)]
)
@pytest.mark.parametrize("method", ["no", "sys", "fd"])
def test_capturing_basic_api(self, method):
capouter = StdCaptureFD()
old = sys.stdout, sys.stderr, sys.stdin
Expand Down Expand Up @@ -86,7 +66,6 @@ def test_capturing_basic_api(self, method):
finally:
capouter.stop_capturing()

@needsosdup
def test_init_capturing(self):
capouter = StdCaptureFD()
try:
Expand Down Expand Up @@ -512,7 +491,6 @@ def test_hello(cap{}):
result = testdir.runpytest(p)
result.stdout.fnmatch_lines(["xxx42xxx"])

@needsosdup
def test_stdfd_functional(self, testdir):
reprec = testdir.inline_runsource(
"""\
Expand All @@ -526,7 +504,6 @@ def test_hello(capfd):
)
reprec.assertoutcome(passed=1)

@needsosdup
def test_capfdbinary(self, testdir):
reprec = testdir.inline_runsource(
"""\
Expand Down Expand Up @@ -565,7 +542,6 @@ def test_hello(capsys, missingarg):
result = testdir.runpytest(p)
result.stdout.fnmatch_lines(["*test_partial_setup_failure*", "*1 error*"])

@needsosdup
def test_keyboardinterrupt_disables_capturing(self, testdir):
p = testdir.makepyfile(
"""\
Expand Down Expand Up @@ -700,20 +676,6 @@ def pytest_runtest_setup(item):
result.stdout.fnmatch_lines(["*ValueError(42)*", "*1 error*"])


def test_fdfuncarg_skips_on_no_osdup(testdir):
testdir.makepyfile(
"""
import os
if hasattr(os, 'dup'):
del os.dup
def test_hello(capfd):
pass
"""
)
result = testdir.runpytest_subprocess("--capture=no")
result.stdout.fnmatch_lines(["*1 skipped*"])


def test_capture_conftest_runtest_setup(testdir):
testdir.makeconftest(
"""
Expand Down Expand Up @@ -865,7 +827,6 @@ def tmpfile(testdir) -> Generator[BinaryIO, None, None]:
f.close()


@needsosdup
def test_dupfile(tmpfile) -> None:
flist = [] # type: List[TextIO]
for i in range(5):
Expand Down Expand Up @@ -924,8 +885,6 @@ def lsof_check():


class TestFDCapture:
pytestmark = needsosdup

def test_simple(self, tmpfile):
fd = tmpfile.fileno()
cap = capture.FDCapture(fd)
Expand Down Expand Up @@ -1169,7 +1128,6 @@ def test_capturing_error_recursive(self):


class TestStdCaptureFD(TestStdCapture):
pytestmark = needsosdup
captureclass = staticmethod(StdCaptureFD)

def test_simple_only_fd(self, testdir):
Expand Down Expand Up @@ -1212,8 +1170,6 @@ def test_many(self, capfd):


class TestStdCaptureFDinvalidFD:
pytestmark = needsosdup

def test_stdcapture_fd_invalid_fd(self, testdir):
testdir.makepyfile(
"""
Expand Down Expand Up @@ -1269,7 +1225,6 @@ def test_capsys_results_accessible_by_attribute(capsys):
assert capture_result.err == "eggs"


@needsosdup
@pytest.mark.parametrize("use", [True, False])
def test_fdcapture_tmpfile_remains_the_same(tmpfile, use):
if not use:
Expand All @@ -1285,7 +1240,6 @@ def test_fdcapture_tmpfile_remains_the_same(tmpfile, use):
assert capfile2 == capfile


@needsosdup
def test_close_and_capture_again(testdir):
testdir.makepyfile(
"""
Expand All @@ -1310,8 +1264,6 @@ def test_capture_again():

@pytest.mark.parametrize("method", ["SysCapture", "FDCapture", "TeeSysCapture"])
def test_capturing_and_logging_fundamentals(testdir, method):
if method == "StdCaptureFD" and not hasattr(os, "dup"):
pytest.skip("need os.dup")
# here we check a fundamental feature
p = testdir.makepyfile(
"""
Expand Down

0 comments on commit 6954b3b

Please sign in to comment.