diff --git a/py/_io/capture.py b/py/_io/capture.py index 09157fbca..b091ab3d2 100644 --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -38,7 +38,7 @@ class FDCapture: in text mode. """ self.targetfd = targetfd - if tmpfile is None: + if tmpfile is None and targetfd != 0: f = tempfile.TemporaryFile('wb+') tmpfile = dupfile(f, encoding="UTF-8") f.close() @@ -55,16 +55,24 @@ class FDCapture: except OSError: raise ValueError("saved filedescriptor not valid, " "did you call start() twice?") - os.dup2(self.tmpfile.fileno(), self.targetfd) - if hasattr(self, '_oldsys'): - setattr(sys, patchsysdict[self.targetfd], self.tmpfile) + if self.targetfd == 0 and not self.tmpfile: + fd = os.open(devnullpath, os.O_RDONLY) + os.dup2(fd, 0) + if hasattr(self, '_oldsys'): + setattr(sys, patchsysdict[self.targetfd], DontReadFromInput()) + else: + fd = self.tmpfile.fileno() + os.dup2(self.tmpfile.fileno(), self.targetfd) + if hasattr(self, '_oldsys'): + setattr(sys, patchsysdict[self.targetfd], self.tmpfile) def done(self): """ unpatch and clean up, returns the self.tmpfile (file object) """ os.dup2(self._savefd, self.targetfd) os.close(self._savefd) - self.tmpfile.seek(0) + if self.targetfd != 0: + self.tmpfile.seek(0) if hasattr(self, '_oldsys'): setattr(sys, patchsysdict[self.targetfd], self._oldsys) return self.tmpfile @@ -184,15 +192,9 @@ class StdCaptureFD(Capture): mixed = self._options['mixed'] patchsys = self._options['patchsys'] if in_: - if hasattr(in_, 'read'): - tmpfile = in_ - else: - fd = os.open(devnullpath, os.O_RDONLY) - tmpfile = os.fdopen(fd) try: - self.in_ = FDCapture(0, tmpfile=tmpfile, now=False, + self.in_ = FDCapture(0, tmpfile=None, now=False, patchsys=patchsys) - self._options['in_'] = self.in_.tmpfile except OSError: pass if out: @@ -222,14 +224,10 @@ class StdCaptureFD(Capture): def startall(self): if hasattr(self, 'in_'): self.in_.start() - sys.stdin = DontReadFromInput() - - out = getattr(self, 'out', None) - if out: - out.start() - err = getattr(self, 'err', None) - if err: - err.start() + if hasattr(self, 'out'): + self.out.start() + if hasattr(self, 'err'): + self.err.start() def resume(self): """ resume capturing with original temp files. """ diff --git a/testing/io_/test_capture.py b/testing/io_/test_capture.py index 47154040f..817103d42 100644 --- a/testing/io_/test_capture.py +++ b/testing/io_/test_capture.py @@ -372,15 +372,6 @@ class TestStdCaptureFDinvalidFD: os.close(2) cap = py.io.StdCaptureFD(out=False, err=True, in_=False) cap.done() - """) - result = testdir.runpytest("--capture=fd") - assert result.ret == 0 - assert result.parseoutcomes()['passed'] == 2 - - @py.test.mark.xfail("sys.platform == 'win32'", run=False) - def test_stdcapture_fd_invalid_fd_null(self, testdir): - testdir.makepyfile(""" - import py, os def test_stdin(): os.close(0) cap = py.io.StdCaptureFD(out=False, err=False, in_=True) @@ -388,8 +379,7 @@ class TestStdCaptureFDinvalidFD: """) result = testdir.runpytest("--capture=fd") assert result.ret == 0 - assert result.parseoutcomes()['passed'] == 1 - + assert result.parseoutcomes()['passed'] == 3 def test_capture_not_started_but_reset(): capsys = py.io.StdCapture(now=False)