* introduce py.io.TextIO and py.io.StringIO to help with 3k transition and to clarify
intentions when doing "in-memory" files. Replace most usages of StringIO. * consolidate py.io's files and tests into fewer files, make files 3k-importable --HG-- branch : trunk
This commit is contained in:
parent
046ac957ab
commit
1fcd373bd5
|
@ -1,6 +1,10 @@
|
||||||
Changes between 1.0.x and 'trunk'
|
Changes between 1.0.x and 'trunk'
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
|
||||||
|
text/unicode and byte-streams (uses underlying standard lib io.*
|
||||||
|
if available)
|
||||||
|
|
||||||
* simplified internal localpath implementation
|
* simplified internal localpath implementation
|
||||||
|
|
||||||
Changes between 1.0.0 and 1.0.1
|
Changes between 1.0.0 and 1.0.1
|
||||||
|
|
|
@ -154,10 +154,12 @@ initpkg(__name__,
|
||||||
|
|
||||||
# input-output helping
|
# input-output helping
|
||||||
'io.__doc__' : ('./io/__init__.py', '__doc__'),
|
'io.__doc__' : ('./io/__init__.py', '__doc__'),
|
||||||
'io.dupfile' : ('./io/dupfile.py', 'dupfile'),
|
'io.dupfile' : ('./io/capture.py', 'dupfile'),
|
||||||
'io.FDCapture' : ('./io/fdcapture.py', 'FDCapture'),
|
'io.TextIO' : ('./io/capture.py', 'TextIO'),
|
||||||
'io.StdCapture' : ('./io/stdcapture.py', 'StdCapture'),
|
'io.BytesIO' : ('./io/capture.py', 'BytesIO'),
|
||||||
'io.StdCaptureFD' : ('./io/stdcapture.py', 'StdCaptureFD'),
|
'io.FDCapture' : ('./io/capture.py', 'FDCapture'),
|
||||||
|
'io.StdCapture' : ('./io/capture.py', 'StdCapture'),
|
||||||
|
'io.StdCaptureFD' : ('./io/capture.py', 'StdCaptureFD'),
|
||||||
'io.TerminalWriter' : ('./io/terminalwriter.py', 'TerminalWriter'),
|
'io.TerminalWriter' : ('./io/terminalwriter.py', 'TerminalWriter'),
|
||||||
|
|
||||||
# error module, defining all errno's as Classes
|
# error module, defining all errno's as Classes
|
||||||
|
|
|
@ -4,7 +4,6 @@ import py
|
||||||
from py.__.execnet import gateway
|
from py.__.execnet import gateway
|
||||||
mypath = py.magic.autopath()
|
mypath = py.magic.autopath()
|
||||||
|
|
||||||
from StringIO import StringIO
|
|
||||||
from py.__.execnet.register import startup_modules, getsource
|
from py.__.execnet.register import startup_modules, getsource
|
||||||
|
|
||||||
TESTTIMEOUT = 10.0 # seconds
|
TESTTIMEOUT = 10.0 # seconds
|
||||||
|
@ -43,9 +42,9 @@ def test_stdouterrin_setnull():
|
||||||
class TestMessage:
|
class TestMessage:
|
||||||
def test_wire_protocol(self):
|
def test_wire_protocol(self):
|
||||||
for cls in gateway.Message._types.values():
|
for cls in gateway.Message._types.values():
|
||||||
one = StringIO()
|
one = py.io.TextIO()
|
||||||
cls(42, '23').writeto(one)
|
cls(42, '23').writeto(one)
|
||||||
two = StringIO(one.getvalue())
|
two = py.io.TextIO(one.getvalue())
|
||||||
msg = gateway.Message.readfrom(two)
|
msg = gateway.Message.readfrom(two)
|
||||||
assert isinstance(msg, cls)
|
assert isinstance(msg, cls)
|
||||||
assert msg.channelid == 42
|
assert msg.channelid == 42
|
||||||
|
@ -317,7 +316,7 @@ class BasicRemoteExecution:
|
||||||
assert str(err).find("ValueError") != -1
|
assert str(err).find("ValueError") != -1
|
||||||
|
|
||||||
def test_remote_redirect_stdout(self):
|
def test_remote_redirect_stdout(self):
|
||||||
out = py.std.StringIO.StringIO()
|
out = py.io.TextIO()
|
||||||
handle = self.gw._remote_redirect(stdout=out)
|
handle = self.gw._remote_redirect(stdout=out)
|
||||||
c = self.gw.remote_exec("print 42")
|
c = self.gw.remote_exec("print 42")
|
||||||
c.waitclose(TESTTIMEOUT)
|
c.waitclose(TESTTIMEOUT)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from StringIO import StringIO
|
import py
|
||||||
|
|
||||||
def pickletest(mod):
|
def pickletest(mod):
|
||||||
f1 = StringIO()
|
f1 = py.io.TextIO()
|
||||||
f2 = StringIO()
|
f2 = py.io.TextIO()
|
||||||
|
|
||||||
pickler1 = mod.Pickler(f1)
|
pickler1 = mod.Pickler(f1)
|
||||||
unpickler1 = mod.Unpickler(f2)
|
unpickler1 = mod.Unpickler(f2)
|
||||||
|
|
|
@ -1,8 +1,100 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import py
|
import py
|
||||||
try: from cStringIO import StringIO
|
import tempfile
|
||||||
except ImportError: from StringIO import StringIO
|
|
||||||
|
try:
|
||||||
|
from io import StringIO
|
||||||
|
except ImportError:
|
||||||
|
from StringIO import StringIO
|
||||||
|
|
||||||
|
class TextIO(StringIO):
|
||||||
|
def write(self, data):
|
||||||
|
if not isinstance(data, unicode):
|
||||||
|
data = unicode(data, getattr(self, '_encoding', 'UTF-8'))
|
||||||
|
StringIO.write(self, data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from io import BytesIO
|
||||||
|
except ImportError:
|
||||||
|
class BytesIO(StringIO):
|
||||||
|
def write(self, data):
|
||||||
|
if isinstance(data, unicode):
|
||||||
|
raise TypeError("not a byte value: %r" %(data,))
|
||||||
|
StringIO.write(self, data)
|
||||||
|
|
||||||
|
class FDCapture:
|
||||||
|
""" Capture IO to/from a given os-level filedescriptor. """
|
||||||
|
|
||||||
|
def __init__(self, targetfd, tmpfile=None):
|
||||||
|
self.targetfd = targetfd
|
||||||
|
if tmpfile is None:
|
||||||
|
tmpfile = self.maketmpfile()
|
||||||
|
self.tmpfile = tmpfile
|
||||||
|
self._savefd = os.dup(targetfd)
|
||||||
|
os.dup2(self.tmpfile.fileno(), targetfd)
|
||||||
|
self._patched = []
|
||||||
|
|
||||||
|
def setasfile(self, name, module=sys):
|
||||||
|
""" patch <module>.<name> to self.tmpfile
|
||||||
|
"""
|
||||||
|
key = (module, name)
|
||||||
|
self._patched.append((key, getattr(module, name)))
|
||||||
|
setattr(module, name, self.tmpfile)
|
||||||
|
|
||||||
|
def unsetfiles(self):
|
||||||
|
""" unpatch all patched items
|
||||||
|
"""
|
||||||
|
while self._patched:
|
||||||
|
(module, name), value = self._patched.pop()
|
||||||
|
setattr(module, name, value)
|
||||||
|
|
||||||
|
def done(self):
|
||||||
|
""" unpatch and clean up, returns the self.tmpfile (file object)
|
||||||
|
"""
|
||||||
|
os.dup2(self._savefd, self.targetfd)
|
||||||
|
self.unsetfiles()
|
||||||
|
os.close(self._savefd)
|
||||||
|
self.tmpfile.seek(0)
|
||||||
|
return self.tmpfile
|
||||||
|
|
||||||
|
def maketmpfile(self):
|
||||||
|
""" create a temporary file
|
||||||
|
"""
|
||||||
|
f = tempfile.TemporaryFile()
|
||||||
|
newf = dupfile(f)
|
||||||
|
f.close()
|
||||||
|
return newf
|
||||||
|
|
||||||
|
def writeorg(self, str):
|
||||||
|
""" write a string to the original file descriptor
|
||||||
|
"""
|
||||||
|
tempfp = tempfile.TemporaryFile()
|
||||||
|
try:
|
||||||
|
os.dup2(self._savefd, tempfp.fileno())
|
||||||
|
tempfp.write(str)
|
||||||
|
finally:
|
||||||
|
tempfp.close()
|
||||||
|
|
||||||
|
|
||||||
|
def dupfile(f, mode=None, buffering=0, raising=False):
|
||||||
|
""" return a new open file object that's a duplicate of f
|
||||||
|
|
||||||
|
mode is duplicated if not given, 'buffering' controls
|
||||||
|
buffer size (defaulting to no buffering) and 'raising'
|
||||||
|
defines whether an exception is raised when an incompatible
|
||||||
|
file object is passed in (if raising is False, the file
|
||||||
|
object itself will be returned)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
fd = f.fileno()
|
||||||
|
except AttributeError:
|
||||||
|
if raising:
|
||||||
|
raise
|
||||||
|
return f
|
||||||
|
newfd = os.dup(fd)
|
||||||
|
mode = mode and mode or f.mode
|
||||||
|
return os.fdopen(newfd, mode, buffering)
|
||||||
|
|
||||||
|
|
||||||
class Capture(object):
|
class Capture(object):
|
||||||
|
@ -141,14 +233,14 @@ class StdCapture(Capture):
|
||||||
if out:
|
if out:
|
||||||
self._oldout = sys.stdout
|
self._oldout = sys.stdout
|
||||||
if not hasattr(out, 'write'):
|
if not hasattr(out, 'write'):
|
||||||
out = StringIO()
|
out = TextIO()
|
||||||
sys.stdout = self.out = out
|
sys.stdout = self.out = out
|
||||||
if err:
|
if err:
|
||||||
self._olderr = sys.stderr
|
self._olderr = sys.stderr
|
||||||
if out and mixed:
|
if out and mixed:
|
||||||
err = self.out
|
err = self.out
|
||||||
elif not hasattr(err, 'write'):
|
elif not hasattr(err, 'write'):
|
||||||
err = StringIO()
|
err = TextIO()
|
||||||
sys.stderr = self.err = err
|
sys.stderr = self.err = err
|
||||||
if in_:
|
if in_:
|
||||||
self._oldin = sys.stdin
|
self._oldin = sys.stdin
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
def dupfile(f, mode=None, buffering=0, raising=False):
|
|
||||||
""" return a new open file object that's a duplicate of f
|
|
||||||
|
|
||||||
mode is duplicated if not given, 'buffering' controls
|
|
||||||
buffer size (defaulting to no buffering) and 'raising'
|
|
||||||
defines whether an exception is raised when an incompatible
|
|
||||||
file object is passed in (if raising is False, the file
|
|
||||||
object itself will be returned)
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
fd = f.fileno()
|
|
||||||
except AttributeError:
|
|
||||||
if raising:
|
|
||||||
raise
|
|
||||||
return f
|
|
||||||
newfd = os.dup(fd)
|
|
||||||
mode = mode and mode or f.mode
|
|
||||||
return os.fdopen(newfd, mode, buffering)
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import py
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
class FDCapture:
|
|
||||||
""" Capture IO to/from a given os-level filedescriptor. """
|
|
||||||
|
|
||||||
def __init__(self, targetfd, tmpfile=None):
|
|
||||||
self.targetfd = targetfd
|
|
||||||
if tmpfile is None:
|
|
||||||
tmpfile = self.maketmpfile()
|
|
||||||
self.tmpfile = tmpfile
|
|
||||||
self._savefd = os.dup(targetfd)
|
|
||||||
os.dup2(self.tmpfile.fileno(), targetfd)
|
|
||||||
self._patched = []
|
|
||||||
|
|
||||||
def setasfile(self, name, module=sys):
|
|
||||||
""" patch <module>.<name> to self.tmpfile
|
|
||||||
"""
|
|
||||||
key = (module, name)
|
|
||||||
self._patched.append((key, getattr(module, name)))
|
|
||||||
setattr(module, name, self.tmpfile)
|
|
||||||
|
|
||||||
def unsetfiles(self):
|
|
||||||
""" unpatch all patched items
|
|
||||||
"""
|
|
||||||
while self._patched:
|
|
||||||
(module, name), value = self._patched.pop()
|
|
||||||
setattr(module, name, value)
|
|
||||||
|
|
||||||
def done(self):
|
|
||||||
""" unpatch and clean up, returns the self.tmpfile (file object)
|
|
||||||
"""
|
|
||||||
os.dup2(self._savefd, self.targetfd)
|
|
||||||
self.unsetfiles()
|
|
||||||
os.close(self._savefd)
|
|
||||||
self.tmpfile.seek(0)
|
|
||||||
return self.tmpfile
|
|
||||||
|
|
||||||
def maketmpfile(self):
|
|
||||||
""" create a temporary file
|
|
||||||
"""
|
|
||||||
f = tempfile.TemporaryFile()
|
|
||||||
newf = py.io.dupfile(f)
|
|
||||||
f.close()
|
|
||||||
return newf
|
|
||||||
|
|
||||||
def writeorg(self, str):
|
|
||||||
""" write a string to the original file descriptor
|
|
||||||
"""
|
|
||||||
tempfp = tempfile.TemporaryFile()
|
|
||||||
try:
|
|
||||||
os.dup2(self._savefd, tempfp.fileno())
|
|
||||||
tempfp.write(str)
|
|
||||||
finally:
|
|
||||||
tempfp.close()
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ if sys.platform == 'win32':
|
||||||
def get_terminal_width():
|
def get_terminal_width():
|
||||||
try:
|
try:
|
||||||
height, width = _getdimensions()
|
height, width = _getdimensions()
|
||||||
except (SystemExit, KeyboardInterrupt), e:
|
except (SystemExit, KeyboardInterrupt):
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
# FALLBACK
|
# FALLBACK
|
||||||
|
@ -144,7 +144,7 @@ class TerminalWriter(object):
|
||||||
def __init__(self, file=None, stringio=False):
|
def __init__(self, file=None, stringio=False):
|
||||||
if file is None:
|
if file is None:
|
||||||
if stringio:
|
if stringio:
|
||||||
self.stringio = file = py.std.cStringIO.StringIO()
|
self.stringio = file = py.io.TextIO()
|
||||||
else:
|
else:
|
||||||
file = py.std.sys.stdout
|
file = py.std.sys.stdout
|
||||||
elif callable(file):
|
elif callable(file):
|
||||||
|
|
|
@ -1,8 +1,31 @@
|
||||||
import os, sys
|
import os, sys
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
class TestTextIO:
|
||||||
|
def test_text(self):
|
||||||
|
f = py.io.TextIO()
|
||||||
|
f.write("hello")
|
||||||
|
s = f.getvalue()
|
||||||
|
assert s == "hello"
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def test_unicode_and_str_mixture(self):
|
||||||
|
f = py.io.TextIO()
|
||||||
|
f.write(u"\u00f6")
|
||||||
|
f.write(str("hello"))
|
||||||
|
s = f.getvalue()
|
||||||
|
f.close()
|
||||||
|
assert isinstance(s, unicode)
|
||||||
|
|
||||||
|
def test_bytes_io():
|
||||||
|
f = py.io.BytesIO()
|
||||||
|
f.write("hello")
|
||||||
|
py.test.raises(TypeError, "f.write(u'hello')")
|
||||||
|
s = f.getvalue()
|
||||||
|
assert s == "hello"
|
||||||
|
|
||||||
def test_dontreadfrominput():
|
def test_dontreadfrominput():
|
||||||
from py.__.io.stdcapture import DontReadFromInput
|
from py.__.io.capture import DontReadFromInput
|
||||||
f = DontReadFromInput()
|
f = DontReadFromInput()
|
||||||
assert not f.isatty()
|
assert not f.isatty()
|
||||||
py.test.raises(IOError, f.read)
|
py.test.raises(IOError, f.read)
|
||||||
|
@ -10,6 +33,81 @@ def test_dontreadfrominput():
|
||||||
py.test.raises(IOError, iter, f)
|
py.test.raises(IOError, iter, f)
|
||||||
py.test.raises(ValueError, f.fileno)
|
py.test.raises(ValueError, f.fileno)
|
||||||
|
|
||||||
|
def test_dupfile():
|
||||||
|
somefile = py.std.os.tmpfile()
|
||||||
|
flist = []
|
||||||
|
for i in range(5):
|
||||||
|
nf = py.io.dupfile(somefile)
|
||||||
|
assert nf != somefile
|
||||||
|
assert nf.fileno() != somefile.fileno()
|
||||||
|
assert nf not in flist
|
||||||
|
print >>nf, i,
|
||||||
|
flist.append(nf)
|
||||||
|
for i in range(5):
|
||||||
|
f = flist[i]
|
||||||
|
f.close()
|
||||||
|
somefile.seek(0)
|
||||||
|
s = somefile.read()
|
||||||
|
assert s.startswith("01234")
|
||||||
|
somefile.close()
|
||||||
|
|
||||||
|
class TestFDCapture:
|
||||||
|
def test_basic(self):
|
||||||
|
tmpfile = py.std.os.tmpfile()
|
||||||
|
fd = tmpfile.fileno()
|
||||||
|
cap = py.io.FDCapture(fd)
|
||||||
|
os.write(fd, "hello")
|
||||||
|
f = cap.done()
|
||||||
|
s = f.read()
|
||||||
|
assert s == "hello"
|
||||||
|
|
||||||
|
def test_stderr(self):
|
||||||
|
cap = py.io.FDCapture(2)
|
||||||
|
cap.setasfile('stderr')
|
||||||
|
print >>sys.stderr, "hello"
|
||||||
|
f = cap.done()
|
||||||
|
s = f.read()
|
||||||
|
assert s == "hello\n"
|
||||||
|
|
||||||
|
def test_stdin(self):
|
||||||
|
f = os.tmpfile()
|
||||||
|
print >>f, "3"
|
||||||
|
f.seek(0)
|
||||||
|
cap = py.io.FDCapture(0, tmpfile=f)
|
||||||
|
# check with os.read() directly instead of raw_input(), because
|
||||||
|
# sys.stdin itself may be redirected (as py.test now does by default)
|
||||||
|
x = os.read(0, 100).strip()
|
||||||
|
f = cap.done()
|
||||||
|
assert x == "3"
|
||||||
|
|
||||||
|
def test_writeorg(self):
|
||||||
|
tmppath = py.test.ensuretemp('test_writeorg').ensure('stderr',
|
||||||
|
file=True)
|
||||||
|
tmpfp = tmppath.open('w+b')
|
||||||
|
try:
|
||||||
|
cap = py.io.FDCapture(tmpfp.fileno())
|
||||||
|
print >>tmpfp, 'foo'
|
||||||
|
cap.writeorg('bar\n')
|
||||||
|
finally:
|
||||||
|
tmpfp.close()
|
||||||
|
f = cap.done()
|
||||||
|
scap = f.read()
|
||||||
|
assert scap == 'foo\n'
|
||||||
|
stmp = tmppath.read()
|
||||||
|
assert stmp == "bar\n"
|
||||||
|
|
||||||
|
def test_writeorg_wrongtype(self):
|
||||||
|
tmppath = py.test.ensuretemp('test_writeorg').ensure('stdout',
|
||||||
|
file=True)
|
||||||
|
tmpfp = tmppath.open('r')
|
||||||
|
try:
|
||||||
|
cap = py.io.FDCapture(tmpfp.fileno())
|
||||||
|
py.test.raises(IOError, "cap.writeorg('bar\\n')")
|
||||||
|
finally:
|
||||||
|
tmpfp.close()
|
||||||
|
f = cap.done()
|
||||||
|
|
||||||
|
|
||||||
class TestStdCapture:
|
class TestStdCapture:
|
||||||
def getcapture(self, **kw):
|
def getcapture(self, **kw):
|
||||||
return py.io.StdCapture(**kw)
|
return py.io.StdCapture(**kw)
|
||||||
|
@ -64,8 +162,8 @@ class TestStdCapture:
|
||||||
cap = self.getcapture()
|
cap = self.getcapture()
|
||||||
print "hello",
|
print "hello",
|
||||||
print >>sys.stderr, "world",
|
print >>sys.stderr, "world",
|
||||||
sys.stdout = py.std.StringIO.StringIO()
|
sys.stdout = py.io.TextIO()
|
||||||
sys.stderr = py.std.StringIO.StringIO()
|
sys.stderr = py.io.TextIO()
|
||||||
print "not seen"
|
print "not seen"
|
||||||
print >>sys.stderr, "not seen"
|
print >>sys.stderr, "not seen"
|
||||||
out, err = cap.reset()
|
out, err = cap.reset()
|
|
@ -1,20 +0,0 @@
|
||||||
|
|
||||||
import py
|
|
||||||
|
|
||||||
def test_dupfile():
|
|
||||||
somefile = py.std.os.tmpfile()
|
|
||||||
flist = []
|
|
||||||
for i in range(5):
|
|
||||||
nf = py.io.dupfile(somefile)
|
|
||||||
assert nf != somefile
|
|
||||||
assert nf.fileno() != somefile.fileno()
|
|
||||||
assert nf not in flist
|
|
||||||
print >>nf, i,
|
|
||||||
flist.append(nf)
|
|
||||||
for i in range(5):
|
|
||||||
f = flist[i]
|
|
||||||
f.close()
|
|
||||||
somefile.seek(0)
|
|
||||||
s = somefile.read()
|
|
||||||
assert s.startswith("01234")
|
|
||||||
somefile.close()
|
|
|
@ -1,59 +0,0 @@
|
||||||
import os, sys
|
|
||||||
import py
|
|
||||||
|
|
||||||
class TestFDCapture:
|
|
||||||
def test_basic(self):
|
|
||||||
tmpfile = py.std.os.tmpfile()
|
|
||||||
fd = tmpfile.fileno()
|
|
||||||
cap = py.io.FDCapture(fd)
|
|
||||||
os.write(fd, "hello")
|
|
||||||
f = cap.done()
|
|
||||||
s = f.read()
|
|
||||||
assert s == "hello"
|
|
||||||
|
|
||||||
def test_stderr(self):
|
|
||||||
cap = py.io.FDCapture(2)
|
|
||||||
cap.setasfile('stderr')
|
|
||||||
print >>sys.stderr, "hello"
|
|
||||||
f = cap.done()
|
|
||||||
s = f.read()
|
|
||||||
assert s == "hello\n"
|
|
||||||
|
|
||||||
def test_stdin(self):
|
|
||||||
f = os.tmpfile()
|
|
||||||
print >>f, "3"
|
|
||||||
f.seek(0)
|
|
||||||
cap = py.io.FDCapture(0, tmpfile=f)
|
|
||||||
# check with os.read() directly instead of raw_input(), because
|
|
||||||
# sys.stdin itself may be redirected (as py.test now does by default)
|
|
||||||
x = os.read(0, 100).strip()
|
|
||||||
f = cap.done()
|
|
||||||
assert x == "3"
|
|
||||||
|
|
||||||
def test_writeorg(self):
|
|
||||||
tmppath = py.test.ensuretemp('test_writeorg').ensure('stderr',
|
|
||||||
file=True)
|
|
||||||
tmpfp = tmppath.open('w+b')
|
|
||||||
try:
|
|
||||||
cap = py.io.FDCapture(tmpfp.fileno())
|
|
||||||
print >>tmpfp, 'foo'
|
|
||||||
cap.writeorg('bar\n')
|
|
||||||
finally:
|
|
||||||
tmpfp.close()
|
|
||||||
f = cap.done()
|
|
||||||
scap = f.read()
|
|
||||||
assert scap == 'foo\n'
|
|
||||||
stmp = tmppath.read()
|
|
||||||
assert stmp == "bar\n"
|
|
||||||
|
|
||||||
def test_writeorg_wrongtype(self):
|
|
||||||
tmppath = py.test.ensuretemp('test_writeorg').ensure('stdout',
|
|
||||||
file=True)
|
|
||||||
tmpfp = tmppath.open('r')
|
|
||||||
try:
|
|
||||||
cap = py.io.FDCapture(tmpfp.fileno())
|
|
||||||
py.test.raises(IOError, "cap.writeorg('bar\\n')")
|
|
||||||
finally:
|
|
||||||
tmpfp.close()
|
|
||||||
f = cap.done()
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import py
|
import py
|
||||||
import os, sys
|
import os, sys
|
||||||
from py.__.io import terminalwriter
|
from py.__.io import terminalwriter
|
||||||
import StringIO
|
|
||||||
|
|
||||||
def skip_win32():
|
def skip_win32():
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
|
@ -23,12 +22,23 @@ def test_terminalwriter_default_instantiation():
|
||||||
|
|
||||||
def test_terminalwriter_dumb_term_no_markup(monkeypatch):
|
def test_terminalwriter_dumb_term_no_markup(monkeypatch):
|
||||||
monkeypatch.setattr(os, 'environ', {'TERM': 'dumb', 'PATH': ''})
|
monkeypatch.setattr(os, 'environ', {'TERM': 'dumb', 'PATH': ''})
|
||||||
monkeypatch.setattr(sys, 'stdout', StringIO.StringIO())
|
class MyFile:
|
||||||
monkeypatch.setattr(sys.stdout, 'isatty', lambda:True)
|
def isatty(self):
|
||||||
|
return True
|
||||||
|
monkeypatch.setattr(sys, 'stdout', MyFile())
|
||||||
assert sys.stdout.isatty()
|
assert sys.stdout.isatty()
|
||||||
tw = py.io.TerminalWriter()
|
tw = py.io.TerminalWriter()
|
||||||
assert not tw.hasmarkup
|
assert not tw.hasmarkup
|
||||||
|
|
||||||
|
def test_unicode_encoding():
|
||||||
|
l = []
|
||||||
|
msg = unicode('b\u00f6y', 'utf8')
|
||||||
|
for encoding in 'utf8', 'latin1':
|
||||||
|
tw = py.io.TerminalWriter(l.append)
|
||||||
|
tw._encoding = encoding
|
||||||
|
tw.line(msg)
|
||||||
|
assert l[0] == msg.encode(encoding)
|
||||||
|
|
||||||
class BaseTests:
|
class BaseTests:
|
||||||
def test_line(self):
|
def test_line(self):
|
||||||
tw = self.getwriter()
|
tw = self.getwriter()
|
||||||
|
@ -44,8 +54,7 @@ class BaseTests:
|
||||||
msg = unicode('b\u00f6y', 'utf8')
|
msg = unicode('b\u00f6y', 'utf8')
|
||||||
tw.line(msg)
|
tw.line(msg)
|
||||||
l = self.getlines()
|
l = self.getlines()
|
||||||
assert not isinstance(l[0], unicode)
|
assert l[0] == msg + "\n"
|
||||||
assert unicode(l[0], encoding) == msg + "\n"
|
|
||||||
|
|
||||||
def test_sep_no_title(self):
|
def test_sep_no_title(self):
|
||||||
tw = self.getwriter()
|
tw = self.getwriter()
|
||||||
|
@ -105,7 +114,7 @@ class TestTmpfile(BaseTests):
|
||||||
io.flush()
|
io.flush()
|
||||||
return self.path.open('r').readlines()
|
return self.path.open('r').readlines()
|
||||||
|
|
||||||
class TestStringIO(BaseTests):
|
class TestWithStringIO(BaseTests):
|
||||||
def getwriter(self):
|
def getwriter(self):
|
||||||
self.tw = py.io.TerminalWriter(stringio=True)
|
self.tw = py.io.TerminalWriter(stringio=True)
|
||||||
return self.tw
|
return self.tw
|
||||||
|
@ -120,7 +129,7 @@ class TestCallableFile(BaseTests):
|
||||||
return py.io.TerminalWriter(self.writes.append)
|
return py.io.TerminalWriter(self.writes.append)
|
||||||
|
|
||||||
def getlines(self):
|
def getlines(self):
|
||||||
io = py.std.cStringIO.StringIO()
|
io = py.io.TextIO()
|
||||||
io.write("".join(self.writes))
|
io.write("".join(self.writes))
|
||||||
io.seek(0)
|
io.seek(0)
|
||||||
return io.readlines()
|
return io.readlines()
|
||||||
|
|
|
@ -170,61 +170,6 @@ class TestRealModule:
|
||||||
import realtest.x.module
|
import realtest.x.module
|
||||||
assert realtest.x.module.__doc__ == 'test module'
|
assert realtest.x.module.__doc__ == 'test module'
|
||||||
|
|
||||||
#class TestStdHook:
|
|
||||||
# """Tests imports for the standard Python library hook."""
|
|
||||||
#
|
|
||||||
# def setup_method(self, *args):
|
|
||||||
# """Unload the test modules before each test."""
|
|
||||||
# module_names = ['py.std.StringIO', 'py.std', 'py']
|
|
||||||
# for modname in module_names:
|
|
||||||
# if modname in sys.modules:
|
|
||||||
# del sys.modules[modname]
|
|
||||||
#
|
|
||||||
# def test_std_import_simple(self):
|
|
||||||
# import py
|
|
||||||
# StringIO = py.std.StringIO
|
|
||||||
# assert 'py' in sys.modules
|
|
||||||
# assert 'py.std' in sys.modules
|
|
||||||
# assert 'py.std.StringIO' in sys.modules
|
|
||||||
# assert hasattr(py.std.StringIO, 'StringIO')
|
|
||||||
#
|
|
||||||
# def test_std_import0(self):
|
|
||||||
# """Testing 'import py.std.StringIO'."""
|
|
||||||
# import py.std.StringIO
|
|
||||||
# assert 'py' in sys.modules
|
|
||||||
# assert 'py.std' in sys.modules
|
|
||||||
# assert 'py.std.StringIO' in sys.modules
|
|
||||||
# assert hasattr(py.std.StringIO, 'StringIO')
|
|
||||||
#
|
|
||||||
# def test_std_import1(self):
|
|
||||||
# """Testing 'from py import std'."""
|
|
||||||
# from py import std
|
|
||||||
# assert 'py' in sys.modules
|
|
||||||
# assert 'py.std' in sys.modules
|
|
||||||
#
|
|
||||||
# def test_std_from(self):
|
|
||||||
# """Testing 'from py.std import StringIO'."""
|
|
||||||
# from py.std import StringIO
|
|
||||||
# assert getattr(StringIO, 'StringIO')
|
|
||||||
#
|
|
||||||
# def test_std_star(self):
|
|
||||||
# "Test from py.std.string import *"
|
|
||||||
# """Testing 'from test.module import *'."""
|
|
||||||
# tmpdir = py.test.ensuretemp('test_initpkg')
|
|
||||||
# tfile = tmpdir.join('stdstartest.py')
|
|
||||||
# tfile.write(py.code.Source("""if True:
|
|
||||||
# from realtest.module import *
|
|
||||||
# globals()['mytest0']
|
|
||||||
# globals()['mytest1']
|
|
||||||
# globals()['MyTest']
|
|
||||||
# """))
|
|
||||||
# import stdstartest # an exception will be raise if an error occurs
|
|
||||||
|
|
||||||
##def test_help():
|
|
||||||
# help(std.path)
|
|
||||||
# #assert False
|
|
||||||
|
|
||||||
|
|
||||||
def test_autoimport():
|
def test_autoimport():
|
||||||
from py.initpkg import autoimport
|
from py.initpkg import autoimport
|
||||||
py.std.os.environ['AUTOTEST_AUTOIMPORT'] = "nonexistmodule"
|
py.std.os.environ['AUTOTEST_AUTOIMPORT'] = "nonexistmodule"
|
||||||
|
|
|
@ -224,7 +224,7 @@ class TestSvnURLAuth(object):
|
||||||
|
|
||||||
def test_log(self):
|
def test_log(self):
|
||||||
u = svnurl_no_svn('http://foo.bar/svn/foo', auth=self.auth)
|
u = svnurl_no_svn('http://foo.bar/svn/foo', auth=self.auth)
|
||||||
u.popen_output = py.std.StringIO.StringIO('''\
|
u.popen_output = py.io.TextIO('''\
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<log>
|
<log>
|
||||||
<logentry revision="51381">
|
<logentry revision="51381">
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cStringIO import StringIO
|
|
||||||
from pickle import Pickler, Unpickler
|
from pickle import Pickler, Unpickler
|
||||||
import py
|
import py
|
||||||
from py.__.execnet.channel import Channel
|
from py.__.execnet.channel import Channel
|
||||||
|
@ -58,14 +57,14 @@ class ImmutablePickler:
|
||||||
# this is for feeding objects to ourselfes
|
# this is for feeding objects to ourselfes
|
||||||
# which be the case e.g. if you want to pickle
|
# which be the case e.g. if you want to pickle
|
||||||
# from a forked process back to the original
|
# from a forked process back to the original
|
||||||
f = StringIO()
|
f = py.io.BytesIO()
|
||||||
pickler = MyPickler(f, self._protocol, uneven=self.uneven)
|
pickler = MyPickler(f, self._protocol, uneven=self.uneven)
|
||||||
pickler.memo = self._picklememo
|
pickler.memo = self._picklememo
|
||||||
pickler.memoize(obj)
|
pickler.memoize(obj)
|
||||||
self._updateunpicklememo()
|
self._updateunpicklememo()
|
||||||
|
|
||||||
def dumps(self, obj):
|
def dumps(self, obj):
|
||||||
f = StringIO()
|
f = py.io.BytesIO()
|
||||||
pickler = MyPickler(f, self._protocol, uneven=self.uneven)
|
pickler = MyPickler(f, self._protocol, uneven=self.uneven)
|
||||||
pickler.memo = self._picklememo
|
pickler.memo = self._picklememo
|
||||||
pickler.dump(obj)
|
pickler.dump(obj)
|
||||||
|
@ -76,7 +75,7 @@ class ImmutablePickler:
|
||||||
return f.getvalue()
|
return f.getvalue()
|
||||||
|
|
||||||
def loads(self, string):
|
def loads(self, string):
|
||||||
f = StringIO(string)
|
f = py.io.BytesIO(string)
|
||||||
unpickler = Unpickler(f)
|
unpickler = Unpickler(f)
|
||||||
unpickler.memo = self._unpicklememo
|
unpickler.memo = self._unpicklememo
|
||||||
res = unpickler.load()
|
res = unpickler.load()
|
||||||
|
|
|
@ -72,9 +72,6 @@ class TestPickleChannelFunctional:
|
||||||
cls.gw = py.execnet.PopenGateway()
|
cls.gw = py.execnet.PopenGateway()
|
||||||
cls.gw.remote_init_threads(5)
|
cls.gw.remote_init_threads(5)
|
||||||
|
|
||||||
def teardown_class(cls):
|
|
||||||
cls.gw.exit()
|
|
||||||
|
|
||||||
def test_popen_send_instance(self):
|
def test_popen_send_instance(self):
|
||||||
channel = self.gw.remote_exec("""
|
channel = self.gw.remote_exec("""
|
||||||
from py.__.test.dist.mypickle import PickleChannel
|
from py.__.test.dist.mypickle import PickleChannel
|
||||||
|
|
|
@ -26,8 +26,8 @@ on tests that wait on reading something from stdin.
|
||||||
You can influence output capturing mechanisms from the command line::
|
You can influence output capturing mechanisms from the command line::
|
||||||
|
|
||||||
py.test -s # disable all capturing
|
py.test -s # disable all capturing
|
||||||
py.test --capture=sys # set StringIO() to each of sys.stdout/stderr
|
py.test --capture=sys # replace sys.stdout/stderr with in-mem files
|
||||||
py.test --capture=fd # capture stdout/stderr on Filedescriptors 1/2
|
py.test --capture=fd # point filedescriptors 1 and 2 to temp file
|
||||||
|
|
||||||
If you set capturing values in a conftest file like this::
|
If you set capturing values in a conftest file like this::
|
||||||
|
|
||||||
|
@ -40,7 +40,9 @@ sys-level capturing
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
Capturing on 'sys' level means that ``sys.stdout`` and ``sys.stderr``
|
Capturing on 'sys' level means that ``sys.stdout`` and ``sys.stderr``
|
||||||
will be replaced with StringIO() objects.
|
will be replaced with in-memory files (``py.io.TextIO`` to be precise)
|
||||||
|
that capture writes and decode non-unicode strings to a unicode object
|
||||||
|
(using a default, usually, UTF-8, encoding).
|
||||||
|
|
||||||
FD-level capturing and subprocesses
|
FD-level capturing and subprocesses
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
@ -114,7 +116,7 @@ class CaptureManager:
|
||||||
return EncodedFile(newf, encoding)
|
return EncodedFile(newf, encoding)
|
||||||
|
|
||||||
def _makestringio(self):
|
def _makestringio(self):
|
||||||
return py.std.StringIO.StringIO()
|
return EncodedFile(py.io.TextIO(), 'UTF-8')
|
||||||
|
|
||||||
def _startcapture(self, method):
|
def _startcapture(self, method):
|
||||||
if method == "fd":
|
if method == "fd":
|
||||||
|
|
|
@ -445,7 +445,7 @@ def test_reportrecorder(testdir):
|
||||||
|
|
||||||
class LineComp:
|
class LineComp:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.stringio = py.std.StringIO.StringIO()
|
self.stringio = py.io.TextIO()
|
||||||
|
|
||||||
def assert_contains_lines(self, lines2):
|
def assert_contains_lines(self, lines2):
|
||||||
""" assert that lines2 are contained (linearly) in lines1.
|
""" assert that lines2 are contained (linearly) in lines1.
|
||||||
|
|
|
@ -90,7 +90,7 @@ class ResultLog(object):
|
||||||
#
|
#
|
||||||
# ===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
import os, StringIO
|
import os
|
||||||
|
|
||||||
def test_generic_path():
|
def test_generic_path():
|
||||||
from py.__.test.collect import Node, Item, FSCollector
|
from py.__.test.collect import Node, Item, FSCollector
|
||||||
|
@ -115,7 +115,7 @@ def test_generic_path():
|
||||||
|
|
||||||
def test_write_log_entry():
|
def test_write_log_entry():
|
||||||
reslog = ResultLog(None)
|
reslog = ResultLog(None)
|
||||||
reslog.logfile = StringIO.StringIO()
|
reslog.logfile = py.io.TextIO()
|
||||||
reslog.write_log_entry('name', '.', '')
|
reslog.write_log_entry('name', '.', '')
|
||||||
entry = reslog.logfile.getvalue()
|
entry = reslog.logfile.getvalue()
|
||||||
assert entry[-1] == '\n'
|
assert entry[-1] == '\n'
|
||||||
|
@ -123,7 +123,7 @@ def test_write_log_entry():
|
||||||
assert len(entry_lines) == 1
|
assert len(entry_lines) == 1
|
||||||
assert entry_lines[0] == '. name'
|
assert entry_lines[0] == '. name'
|
||||||
|
|
||||||
reslog.logfile = StringIO.StringIO()
|
reslog.logfile = py.io.TextIO()
|
||||||
reslog.write_log_entry('name', 's', 'Skipped')
|
reslog.write_log_entry('name', 's', 'Skipped')
|
||||||
entry = reslog.logfile.getvalue()
|
entry = reslog.logfile.getvalue()
|
||||||
assert entry[-1] == '\n'
|
assert entry[-1] == '\n'
|
||||||
|
@ -132,7 +132,7 @@ def test_write_log_entry():
|
||||||
assert entry_lines[0] == 's name'
|
assert entry_lines[0] == 's name'
|
||||||
assert entry_lines[1] == ' Skipped'
|
assert entry_lines[1] == ' Skipped'
|
||||||
|
|
||||||
reslog.logfile = StringIO.StringIO()
|
reslog.logfile = py.io.TextIO()
|
||||||
reslog.write_log_entry('name', 's', 'Skipped\n')
|
reslog.write_log_entry('name', 's', 'Skipped\n')
|
||||||
entry = reslog.logfile.getvalue()
|
entry = reslog.logfile.getvalue()
|
||||||
assert entry[-1] == '\n'
|
assert entry[-1] == '\n'
|
||||||
|
@ -141,7 +141,7 @@ def test_write_log_entry():
|
||||||
assert entry_lines[0] == 's name'
|
assert entry_lines[0] == 's name'
|
||||||
assert entry_lines[1] == ' Skipped'
|
assert entry_lines[1] == ' Skipped'
|
||||||
|
|
||||||
reslog.logfile = StringIO.StringIO()
|
reslog.logfile = py.io.TextIO()
|
||||||
longrepr = ' tb1\n tb 2\nE tb3\nSome Error'
|
longrepr = ' tb1\n tb 2\nE tb3\nSome Error'
|
||||||
reslog.write_log_entry('name', 'F', longrepr)
|
reslog.write_log_entry('name', 'F', longrepr)
|
||||||
entry = reslog.logfile.getvalue()
|
entry = reslog.logfile.getvalue()
|
||||||
|
@ -212,7 +212,7 @@ class TestWithFunctionIntegration:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
except ValueError:
|
except ValueError:
|
||||||
excinfo = py.code.ExceptionInfo()
|
excinfo = py.code.ExceptionInfo()
|
||||||
reslog = ResultLog(StringIO.StringIO())
|
reslog = ResultLog(py.io.TextIO())
|
||||||
reslog.pytest_internalerror(excinfo.getrepr())
|
reslog.pytest_internalerror(excinfo.getrepr())
|
||||||
entry = reslog.logfile.getvalue()
|
entry = reslog.logfile.getvalue()
|
||||||
entry_lines = entry.splitlines()
|
entry_lines = entry.splitlines()
|
||||||
|
|
|
@ -71,7 +71,7 @@ def test_capturing_unicode(testdir, method):
|
||||||
def test_capturing_bytes_in_utf8_encoding(testdir, method):
|
def test_capturing_bytes_in_utf8_encoding(testdir, method):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
def test_unicode():
|
def test_unicode():
|
||||||
print '\\xe2'
|
print 'b\\u00f6y'
|
||||||
""")
|
""")
|
||||||
result = testdir.runpytest("--capture=%s" % method)
|
result = testdir.runpytest("--capture=%s" % method)
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
|
@ -227,8 +227,8 @@ class TestLoggingInteraction:
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
def test_logging():
|
def test_logging():
|
||||||
import logging
|
import logging
|
||||||
import StringIO
|
import py
|
||||||
stream = StringIO.StringIO()
|
stream = py.io.TextIO()
|
||||||
logging.basicConfig(stream=stream)
|
logging.basicConfig(stream=stream)
|
||||||
stream.close() # to free memory/release resources
|
stream.close() # to free memory/release resources
|
||||||
""")
|
""")
|
||||||
|
|
|
@ -139,7 +139,7 @@ class TestTerminal:
|
||||||
|
|
||||||
def test_writeline(self, testdir, linecomp):
|
def test_writeline(self, testdir, linecomp):
|
||||||
modcol = testdir.getmodulecol("def test_one(): pass")
|
modcol = testdir.getmodulecol("def test_one(): pass")
|
||||||
stringio = py.std.cStringIO.StringIO()
|
stringio = py.io.TextIO()
|
||||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||||
rep.write_fspath_result(py.path.local("xy.py"), '.')
|
rep.write_fspath_result(py.path.local("xy.py"), '.')
|
||||||
rep.write_line("hello world")
|
rep.write_line("hello world")
|
||||||
|
|
|
@ -117,7 +117,7 @@ class PluginManager(object):
|
||||||
# =====================================================
|
# =====================================================
|
||||||
methods = collectattr(plugin)
|
methods = collectattr(plugin)
|
||||||
hooks = collectattr(hookspec)
|
hooks = collectattr(hookspec)
|
||||||
stringio = py.std.StringIO.StringIO()
|
stringio = py.io.TextIO()
|
||||||
def Print(*args):
|
def Print(*args):
|
||||||
if args:
|
if args:
|
||||||
stringio.write(" ".join(map(str, args)))
|
stringio.write(" ".join(map(str, args)))
|
||||||
|
|
|
@ -143,7 +143,7 @@ class TestConfigPickling:
|
||||||
testdir.makepyfile(hello="def test_x(): pass")
|
testdir.makepyfile(hello="def test_x(): pass")
|
||||||
config = testdir.parseconfig(tmpdir)
|
config = testdir.parseconfig(tmpdir)
|
||||||
col = config.getfsnode(config.topdir)
|
col = config.getfsnode(config.topdir)
|
||||||
io = py.std.cStringIO.StringIO()
|
io = py.io.TextIO()
|
||||||
pickler = Pickler(io)
|
pickler = Pickler(io)
|
||||||
pickler.dump(col)
|
pickler.dump(col)
|
||||||
io.seek(0)
|
io.seek(0)
|
||||||
|
@ -160,7 +160,7 @@ class TestConfigPickling:
|
||||||
col = config.getfsnode(config.topdir)
|
col = config.getfsnode(config.topdir)
|
||||||
col1 = col.join(dir1.basename)
|
col1 = col.join(dir1.basename)
|
||||||
assert col1.parent is col
|
assert col1.parent is col
|
||||||
io = py.std.cStringIO.StringIO()
|
io = py.io.TextIO()
|
||||||
pickler = Pickler(io)
|
pickler = Pickler(io)
|
||||||
pickler.dump(col)
|
pickler.dump(col)
|
||||||
pickler.dump(col1)
|
pickler.dump(col1)
|
||||||
|
|
Loading…
Reference in New Issue