simplify approach to encoding of sys.stdout/stderr files, encode unicode strings and pass-through non-unicode strings

--HG--
branch : 1.0.x
This commit is contained in:
holger krekel 2009-08-19 16:42:29 +02:00
parent 5e4fcdd14e
commit b1feb81b8a
3 changed files with 43 additions and 23 deletions

View File

@ -5,10 +5,9 @@ Changes between 1.0.0 and 1.0.1
nose-style function/method/generator setup/teardown and nose-style function/method/generator setup/teardown and
tries to report functions correctly. tries to report functions correctly.
* unicode fixes: capturing and unicode writes to sys.stdout * capturing of unicode writes to sys.stdout/err work better within
(through e.g a print statement) now work within tests, encoded as "utf8" by default, also terminalwriting was adapted
they are encoded as "utf8" by default, also terminalwriting and somewhat unified between windows and linux
was adapted and somewhat unified between windows and linux
* improved documentation layout and content a lot * improved documentation layout and content a lot

View File

@ -110,8 +110,8 @@ class CaptureManager:
def _maketempfile(self): def _maketempfile(self):
f = py.std.tempfile.TemporaryFile() f = py.std.tempfile.TemporaryFile()
newf = py.io.dupfile(f) newf = py.io.dupfile(f)
f.close() encoding = getattr(newf, 'encoding', None) or "UTF-8"
return ustream(newf) return EncodedFile(newf, encoding)
def _makestringio(self): def _makestringio(self):
return py.std.StringIO.StringIO() return py.std.StringIO.StringIO()
@ -269,12 +269,21 @@ class CaptureFuncarg:
self.capture.reset() self.capture.reset()
del self.capture del self.capture
def ustream(f): class EncodedFile(object):
import codecs def __init__(self, _stream, encoding):
encoding = getattr(f, 'encoding', None) or "UTF-8" self._stream = _stream
reader = codecs.getreader(encoding) self.encoding = encoding
writer = codecs.getwriter(encoding)
srw = codecs.StreamReaderWriter(f, reader, writer) def write(self, obj):
srw.encoding = encoding if isinstance(obj, unicode):
return srw self._stream.write(obj.encode(self.encoding))
else:
self._stream.write(obj)
def writelines(self, linelist):
data = ''.join(linelist)
self.write(data)
def __getattr__(self, name):
return getattr(self._stream, name)

View File

@ -1,8 +1,7 @@
import py, os, sys import py, os, sys
from py.__.test.plugin.pytest_capture import CaptureManager, ustream from py.__.test.plugin.pytest_capture import CaptureManager, EncodedFile
class TestCaptureManager: class TestCaptureManager:
def test_configure_per_fspath(self, testdir): def test_configure_per_fspath(self, testdir):
config = testdir.parseconfig(testdir.tmpdir) config = testdir.parseconfig(testdir.tmpdir)
assert config.getvalue("capture") is None assert config.getvalue("capture") is None
@ -57,7 +56,7 @@ class TestCaptureManager:
@py.test.mark.multi(method=['fd', 'sys']) @py.test.mark.multi(method=['fd', 'sys'])
def test_capturing_unicode(testdir, method): def test_capturing_unicode(testdir, method):
testdir.makepyfile(""" testdir.makepyfile("""
# taken from issue 227 from nosests # taken from issue 227 from nosetests
def test_unicode(): def test_unicode():
import sys import sys
print sys.stdout print sys.stdout
@ -68,14 +67,27 @@ def test_capturing_unicode(testdir, method):
"*1 passed*" "*1 passed*"
]) ])
def test_ustream_helper(testdir): @py.test.mark.multi(method=['fd', 'sys'])
def test_capturing_bytes_in_utf8_encoding(testdir, method):
testdir.makepyfile("""
def test_unicode():
print '\\xe2'
""")
result = testdir.runpytest("--capture=%s" % method)
result.stdout.fnmatch_lines([
"*1 passed*"
])
def test_UnicodeFile(testdir):
p = testdir.makepyfile("hello") p = testdir.makepyfile("hello")
f = p.open('w') f = p.open('w')
#f.encoding = "utf8" pf = EncodedFile(f, "UTF-8")
x = ustream(f) pf.write(u'b\\00f6y\n')
x.write(u'b\\00f6y') pf.write('b\\00f6y\n')
x.close() pf.close()
assert f.closed
lines = p.readlines()
assert lines[0] == lines[1]
def test_collect_capturing(testdir): def test_collect_capturing(testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""