[py-svn] r37872 - in py/trunk/py/io: . test
hpk at codespeak.net
hpk at codespeak.net
Sat Feb 3 14:57:27 CET 2007
Author: hpk
Date: Sat Feb 3 14:57:25 2007
New Revision: 37872
Modified:
py/trunk/py/io/stdcapture.py
py/trunk/py/io/test/test_stdcapture.py
Log:
StdCaptureFD and StdCapture now try
to take care of stdin in a mostly uniform way.
Modified: py/trunk/py/io/stdcapture.py
==============================================================================
--- py/trunk/py/io/stdcapture.py (original)
+++ py/trunk/py/io/stdcapture.py Sat Feb 3 14:57:25 2007
@@ -4,7 +4,6 @@
try: from cStringIO import StringIO
except ImportError: from StringIO import StringIO
-emptyfile = StringIO()
class Capture(object):
def call(cls, func, *args, **kwargs):
@@ -33,10 +32,17 @@
class StdCaptureFD(Capture):
- """ capture Stdout and Stderr both on filedescriptor
- and sys.stdout/stderr level.
+ """ This class allows to capture writes to FD1 and FD2
+ and may connect a NULL file to FD0 (and prevent
+ reads from sys.stdin)
"""
- def __init__(self, out=True, err=True, mixed=False, patchsys=True):
+ def __init__(self, out=True, err=True, mixed=False, in_=True, patchsys=True):
+ if in_:
+ self._oldin = (sys.stdin, os.dup(0))
+ sys.stdin = DontReadFromInput()
+ fd = os.open(devnullpath, os.O_RDONLY)
+ os.dup2(fd, 0)
+ os.close(fd)
if out:
self.out = py.io.FDCapture(1)
if patchsys:
@@ -57,17 +63,23 @@
outfile = self.out.done()
if hasattr(self, 'err'):
errfile = self.err.done()
+ if hasattr(self, '_oldin'):
+ oldsys, oldfd = self._oldin
+ os.dup2(oldfd, 0)
+ os.close(oldfd)
+ sys.stdin = oldsys
return outfile, errfile
class StdCapture(Capture):
- """ capture sys.stdout/sys.stderr (but not system level fd 1 and 2).
-
- This class allows to capture writes to sys.stdout|stderr "in-memory"
- and will raise errors on tries to read from sys.stdin.
+ """ This class allows to capture writes to sys.stdout|stderr "in-memory"
+ and will raise errors on tries to read from sys.stdin. It only
+ modifies sys.stdout|stderr|stdin attributes and does not
+ touch underlying File Descriptors (use StdCaptureFD for that).
"""
- def __init__(self, out=True, err=True, mixed=False):
+ def __init__(self, out=True, err=True, in_=True, mixed=False):
self._out = out
self._err = err
+ self._in = in_
if out:
self.oldout = sys.stdout
sys.stdout = self.newout = StringIO()
@@ -78,8 +90,9 @@
else:
newerr = StringIO()
sys.stderr = self.newerr = newerr
- self.oldin = sys.stdin
- sys.stdin = self.newin = DontReadFromInput()
+ if in_:
+ self.oldin = sys.stdin
+ sys.stdin = self.newin = DontReadFromInput()
def reset(self):
""" return captured output as strings and restore sys.stdout/err."""
@@ -106,7 +119,8 @@
del self.olderr
errfile = self.newerr
errfile.seek(0)
- sys.stdin = self.oldin
+ if self._in:
+ sys.stdin = self.oldin
return outfile, errfile
class DontReadFromInput:
@@ -121,3 +135,14 @@
readline = read
readlines = read
__iter__ = read
+
+try:
+ devnullpath = os.devnull
+except AttributeError:
+ if os.name == 'nt':
+ devnullpath = 'NUL'
+ else:
+ devnullpath = '/dev/null'
+
+emptyfile = StringIO()
+
Modified: py/trunk/py/io/test/test_stdcapture.py
==============================================================================
--- py/trunk/py/io/test/test_stdcapture.py (original)
+++ py/trunk/py/io/test/test_stdcapture.py Sat Feb 3 14:57:25 2007
@@ -79,6 +79,22 @@
assert err == "world\n"
assert not out
+ def test_stdin_restored(self):
+ old = sys.stdin
+ cap = self.getcapture(in_=True)
+ newstdin = sys.stdin
+ out, err = cap.reset()
+ assert newstdin != sys.stdin
+ assert sys.stdin is old
+
+ def test_stdin_nulled_by_default(self):
+ print "XXX this test may well hang instead of crashing"
+ print "XXX which indicates an error in the underlying capturing"
+ print "XXX mechanisms"
+ cap = self.getcapture()
+ py.test.raises(IOError, "sys.stdin.read()")
+ out, err = cap.reset()
+
class TestStdCaptureFD(TestStdCapture):
def getcapture(self, **kw):
return py.io.StdCaptureFD(**kw)
More information about the py-svn
mailing list