##// END OF EJS Templates
Backport PR #4581....
Thomas Kluyver -
Show More
@@ -13,6 +13,7 b' Contains Stdout writer'
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from IPython.utils import io
16 from .base import WriterBase
17 from .base import WriterBase
17
18
18 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
@@ -31,4 +32,4 b' class StdoutWriter(WriterBase):'
31 See base for more...
32 See base for more...
32 """
33 """
33
34
34 print(output)
35 io.unicode_std_stream().write(output)
@@ -14,10 +14,12 b' from __future__ import print_function'
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 import codecs
17 import os
18 import os
18 import sys
19 import sys
19 import tempfile
20 import tempfile
20 from StringIO import StringIO
21 from StringIO import StringIO
22 from .py3compat import PY3
21
23
22 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
23 # Code
25 # Code
@@ -285,4 +287,25 b' class capture_output(object):'
285 sys.stdout = self.sys_stdout
287 sys.stdout = self.sys_stdout
286 sys.stderr = self.sys_stderr
288 sys.stderr = self.sys_stderr
287
289
290 def unicode_std_stream(stream='stdout'):
291 """Get a wrapper to write unicode to stdout/stderr as UTF-8.
288
292
293 This ignores environment variables and default encodings, to reliably write
294 unicode to stdout or stderr.
295
296 ::
297
298 unicode_std_stream().write(u'ł@e¶ŧ←')
299 """
300 assert stream in ('stdout', 'stderr')
301 stream = getattr(sys, stream)
302 if PY3:
303 try:
304 stream_b = stream.buffer
305 except AttributeError:
306 # sys.stdout has been replaced - use it directly
307 return stream
308 else:
309 stream_b = stream
310
311 return codecs.getwriter('utf-8')(stream_b)
@@ -12,7 +12,9 b''
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15 from __future__ import absolute_import
15
16
17 import io as stdlib_io
16 import sys
18 import sys
17
19
18 from StringIO import StringIO
20 from StringIO import StringIO
@@ -21,8 +23,9 b' from subprocess import Popen, PIPE'
21 import nose.tools as nt
23 import nose.tools as nt
22
24
23 from IPython.testing.ipunittest import ParametricTestCase
25 from IPython.testing.ipunittest import ParametricTestCase
24 from IPython.utils.io import Tee, capture_output
26 from IPython.testing.decorators import skipif
25 from IPython.utils.py3compat import doctest_refactor_print
27 from IPython.utils.io import Tee, capture_output, unicode_std_stream
28 from IPython.utils.py3compat import doctest_refactor_print, PY3
26
29
27 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
28 # Tests
31 # Tests
@@ -84,3 +87,34 b' def test_capture_output():'
84
87
85 nt.assert_equal(io.stdout, 'hi, stdout\n')
88 nt.assert_equal(io.stdout, 'hi, stdout\n')
86 nt.assert_equal(io.stderr, 'hi, stderr\n')
89 nt.assert_equal(io.stderr, 'hi, stderr\n')
90
91 def test_UnicodeStdStream():
92 # Test wrapping a bytes-level stdout
93 if PY3:
94 stdoutb = stdlib_io.BytesIO()
95 stdout = stdlib_io.TextIOWrapper(stdoutb, encoding='ascii')
96 else:
97 stdout = stdoutb = stdlib_io.BytesIO()
98
99 orig_stdout = sys.stdout
100 sys.stdout = stdout
101 try:
102 sample = u"@łe¶ŧ←"
103 unicode_std_stream().write(sample)
104
105 output = stdoutb.getvalue().decode('utf-8')
106 nt.assert_equal(output, sample)
107 assert not stdout.closed
108 finally:
109 sys.stdout = orig_stdout
110
111 @skipif(not PY3, "Not applicable on Python 2")
112 def test_UnicodeStdStream_nowrap():
113 # If we replace stdout with a StringIO, it shouldn't get wrapped.
114 orig_stdout = sys.stdout
115 sys.stdout = StringIO()
116 try:
117 nt.assert_is(unicode_std_stream(), sys.stdout)
118 assert not sys.stdout.closed
119 finally:
120 sys.stdout = orig_stdout No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now