##// END OF EJS Templates
Merge pull request #1870 from minrk/captureio...
Fernando Perez -
r7411:024e3846 merge
parent child Browse files
Show More
@@ -0,0 +1,182 b''
1 {
2 "metadata": {
3 "name": "Capturing Output"
4 },
5 "nbformat": 3,
6 "worksheets": [
7 {
8 "cells": [
9 {
10 "cell_type": "heading",
11 "level": 1,
12 "source": [
13 "Capturing Output with <tt>%%capture</tt>"
14 ]
15 },
16 {
17 "cell_type": "markdown",
18 "source": [
19 "One of IPython's new cell magics is `%%capture`, which captures stdout/err for a cell,",
20 "and discards them or stores them in variables in your namespace."
21 ]
22 },
23 {
24 "cell_type": "code",
25 "input": [
26 "import sys"
27 ],
28 "language": "python",
29 "outputs": []
30 },
31 {
32 "cell_type": "markdown",
33 "source": [
34 "By default, it just swallows it up. This is a simple way to suppress unwanted output."
35 ]
36 },
37 {
38 "cell_type": "code",
39 "input": [
40 "%%capture",
41 "print 'hi, stdout'",
42 "print >> sys.stderr, 'hi, stderr'"
43 ],
44 "language": "python",
45 "outputs": []
46 },
47 {
48 "cell_type": "markdown",
49 "source": [
50 "If you specify a name, then stdout and stderr will be stored in an object in your namespace."
51 ]
52 },
53 {
54 "cell_type": "code",
55 "input": [
56 "%%capture captured",
57 "print 'hi, stdout'",
58 "print >> sys.stderr, 'hi, stderr'"
59 ],
60 "language": "python",
61 "outputs": []
62 },
63 {
64 "cell_type": "code",
65 "input": [
66 "captured"
67 ],
68 "language": "python",
69 "outputs": []
70 },
71 {
72 "cell_type": "markdown",
73 "source": [
74 "Calling the object writes the output to stdout/err as appropriate."
75 ]
76 },
77 {
78 "cell_type": "code",
79 "input": [
80 "captured()"
81 ],
82 "language": "python",
83 "outputs": []
84 },
85 {
86 "cell_type": "code",
87 "input": [
88 "captured.stdout"
89 ],
90 "language": "python",
91 "outputs": []
92 },
93 {
94 "cell_type": "code",
95 "input": [
96 "captured.stderr"
97 ],
98 "language": "python",
99 "outputs": []
100 },
101 {
102 "cell_type": "markdown",
103 "source": [
104 "`%%capture` only captures stdout/err, not displaypub, so you can still do plots and use the display protocol inside %%capture"
105 ]
106 },
107 {
108 "cell_type": "code",
109 "input": [
110 "%pylab inline"
111 ],
112 "language": "python",
113 "outputs": []
114 },
115 {
116 "cell_type": "code",
117 "input": [
118 "%%capture wontshutup",
119 "",
120 "print \"setting up X\"",
121 "x = np.linspace(0,5,1000)",
122 "print \"step 2: constructing y-data\"",
123 "y = np.sin(x)",
124 "print \"step 3: display info about y\"",
125 "plt.plot(x,y)",
126 "print \"okay, I'm done now\""
127 ],
128 "language": "python",
129 "outputs": []
130 },
131 {
132 "cell_type": "code",
133 "input": [
134 "wontshutup()"
135 ],
136 "language": "python",
137 "outputs": []
138 },
139 {
140 "cell_type": "markdown",
141 "source": [
142 "And you can selectively disable capturing stdout or stderr by passing `--no-stdout/err`."
143 ]
144 },
145 {
146 "cell_type": "code",
147 "input": [
148 "%%capture cap --no-stderr",
149 "print 'hi, stdout'",
150 "print >> sys.stderr, \"hello, stderr\""
151 ],
152 "language": "python",
153 "outputs": []
154 },
155 {
156 "cell_type": "code",
157 "input": [
158 "cap.stdout"
159 ],
160 "language": "python",
161 "outputs": []
162 },
163 {
164 "cell_type": "code",
165 "input": [
166 "cap.stderr"
167 ],
168 "language": "python",
169 "outputs": []
170 },
171 {
172 "cell_type": "code",
173 "input": [
174 ""
175 ],
176 "language": "python",
177 "outputs": []
178 }
179 ]
180 }
181 ]
182 } No newline at end of file
@@ -33,13 +33,15 b' except ImportError:'
33 33
34 34 # Our own packages
35 35 from IPython.core import debugger, oinspect
36 from IPython.core import magic_arguments
36 37 from IPython.core import page
37 38 from IPython.core.error import UsageError
38 39 from IPython.core.macro import Macro
39 from IPython.core.magic import (Magics, magics_class, line_magic,
40 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
40 41 line_cell_magic, on_off, needs_local_scope)
41 42 from IPython.testing.skipdoctest import skip_doctest
42 43 from IPython.utils import py3compat
44 from IPython.utils.io import capture_output
43 45 from IPython.utils.ipstruct import Struct
44 46 from IPython.utils.module_paths import find_mod
45 47 from IPython.utils.path import get_py_filename, unquote_filename
@@ -988,3 +990,33 b' python-profiler package from non-free.""")'
988 990 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
989 991 print '=== Macro contents: ==='
990 992 print macro,
993
994 @magic_arguments.magic_arguments()
995 @magic_arguments.argument('output', type=str, default='', nargs='?',
996 help="""The name of the variable in which to store output.
997 This is a utils.io.CapturedIO object with stdout/err attributes
998 for the text of the captured output.
999
1000 CapturedOutput also has a show() method for displaying the output,
1001 and __call__ as well, so you can use that to quickly display the
1002 output.
1003
1004 If unspecified, captured output is discarded.
1005 """
1006 )
1007 @magic_arguments.argument('--no-stderr', action="store_true",
1008 help="""Don't capture stderr."""
1009 )
1010 @magic_arguments.argument('--no-stdout', action="store_true",
1011 help="""Don't capture stdout."""
1012 )
1013 @cell_magic
1014 def capture(self, line, cell):
1015 """run the cell, capturing stdout/err"""
1016 args = magic_arguments.parse_argstring(self.capture, line)
1017 out = not args.no_stdout
1018 err = not args.no_stderr
1019 with capture_output(out, err) as io:
1020 self.shell.run_cell(cell)
1021 if args.output:
1022 self.shell.user_ns[args.output] = io
@@ -100,36 +100,6 b' def skip_without(*names):'
100 100 # Classes
101 101 #-------------------------------------------------------------------------------
102 102
103 class CapturedIO(object):
104 """Simple object for containing captured stdout/err StringIO objects"""
105
106 def __init__(self, stdout, stderr):
107 self.stdout_io = stdout
108 self.stderr_io = stderr
109
110 @property
111 def stdout(self):
112 return self.stdout_io.getvalue()
113
114 @property
115 def stderr(self):
116 return self.stderr_io.getvalue()
117
118
119 class capture_output(object):
120 """context manager for capturing stdout/err"""
121
122 def __enter__(self):
123 self.sys_stdout = sys.stdout
124 self.sys_stderr = sys.stderr
125 stdout = sys.stdout = StringIO()
126 stderr = sys.stderr = StringIO()
127 return CapturedIO(stdout, stderr)
128
129 def __exit__(self, exc_type, exc_value, traceback):
130 sys.stdout = self.sys_stdout
131 sys.stderr = self.sys_stderr
132
133 103
134 104 class ClusterTestCase(BaseZMQTestCase):
135 105
@@ -18,11 +18,12 b' Authors:'
18 18
19 19 import time
20 20
21 from IPython.parallel.error import TimeoutError
21 from IPython.utils.io import capture_output
22 22
23 from IPython.parallel.error import TimeoutError
23 24 from IPython.parallel import error, Client
24 25 from IPython.parallel.tests import add_engines
25 from .clienttest import ClusterTestCase, capture_output
26 from .clienttest import ClusterTestCase
26 27
27 28 def setup():
28 29 add_engines(2, total=True)
@@ -25,6 +25,7 b' from nose import SkipTest'
25 25
26 26 from IPython.testing import decorators as dec
27 27 from IPython.testing.ipunittest import ParametricTestCase
28 from IPython.utils.io import capture_output
28 29
29 30 from IPython import parallel as pmod
30 31 from IPython.parallel import error
@@ -33,7 +34,7 b' from IPython.parallel.util import interactive'
33 34
34 35 from IPython.parallel.tests import add_engines
35 36
36 from .clienttest import ClusterTestCase, capture_output, generate_output
37 from .clienttest import ClusterTestCase, generate_output
37 38
38 39 def setup():
39 40 add_engines(3, total=True)
@@ -17,6 +17,7 b' from __future__ import print_function'
17 17 import os
18 18 import sys
19 19 import tempfile
20 from StringIO import StringIO
20 21
21 22 #-----------------------------------------------------------------------------
22 23 # Code
@@ -321,3 +322,63 b' def raw_print_err(*args, **kw):'
321 322 # Short aliases for quick debugging, do NOT use these in production code.
322 323 rprint = raw_print
323 324 rprinte = raw_print_err
325
326
327 class CapturedIO(object):
328 """Simple object for containing captured stdout/err StringIO objects"""
329
330 def __init__(self, stdout, stderr):
331 self._stdout = stdout
332 self._stderr = stderr
333
334 def __str__(self):
335 return self.stdout
336
337 @property
338 def stdout(self):
339 if not self._stdout:
340 return ''
341 return self._stdout.getvalue()
342
343 @property
344 def stderr(self):
345 if not self._stderr:
346 return ''
347 return self._stderr.getvalue()
348
349 def show(self):
350 """write my output to sys.stdout/err as appropriate"""
351 sys.stdout.write(self.stdout)
352 sys.stderr.write(self.stderr)
353 sys.stdout.flush()
354 sys.stderr.flush()
355
356 __call__ = show
357
358
359 class capture_output(object):
360 """context manager for capturing stdout/err"""
361 stdout = True
362 stderr = True
363
364 def __init__(self, stdout=True, stderr=True):
365 self.stdout = stdout
366 self.stderr = stderr
367
368 def __enter__(self):
369 self.sys_stdout = sys.stdout
370 self.sys_stderr = sys.stderr
371
372 stdout = stderr = False
373 if self.stdout:
374 stdout = sys.stdout = StringIO()
375 if self.stderr:
376 stderr = sys.stderr = StringIO()
377
378 return CapturedIO(stdout, stderr)
379
380 def __exit__(self, exc_type, exc_value, traceback):
381 sys.stdout = self.sys_stdout
382 sys.stderr = self.sys_stderr
383
384
@@ -20,7 +20,7 b' from subprocess import Popen, PIPE'
20 20 import nose.tools as nt
21 21
22 22 from IPython.testing import decorators as dec
23 from IPython.utils.io import Tee
23 from IPython.utils.io import Tee, capture_output
24 24 from IPython.utils.py3compat import doctest_refactor_print
25 25
26 26 #-----------------------------------------------------------------------------
@@ -73,3 +73,13 b' def test_io_init():'
73 73 # __class__ is a reference to the class object in Python 3, so we can't
74 74 # just test for string equality.
75 75 assert 'IPython.utils.io.IOStream' in classname, classname
76
77 def test_capture_output():
78 """capture_output() context works"""
79
80 with capture_output() as io:
81 print 'hi, stdout'
82 print >> sys.stderr, 'hi, stderr'
83
84 nt.assert_equals(io.stdout, 'hi, stdout\n')
85 nt.assert_equals(io.stderr, 'hi, stderr\n')
General Comments 0
You need to be logged in to leave comments. Login now