##// END OF EJS Templates
Merge pull request #1606 from Carreau/loadpycat...
Thomas Kluyver -
r6899:24a3c008 merge
parent child Browse files
Show More
@@ -1,2827 +1,2853 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import with_statement
17 from __future__ import with_statement
18 from __future__ import absolute_import
18 from __future__ import absolute_import
19
19
20 import __builtin__ as builtin_mod
20 import __builtin__ as builtin_mod
21 import __future__
21 import __future__
22 import abc
22 import abc
23 import ast
23 import ast
24 import atexit
24 import atexit
25 import codeop
26 import inspect
27 import os
25 import os
28 import re
26 import re
29 import runpy
27 import runpy
30 import sys
28 import sys
31 import tempfile
29 import tempfile
32 import types
30 import types
33
31 import urllib
34 try:
32 from io import open as io_open
35 from contextlib import nested
36 except:
37 from IPython.utils.nested_context import nested
38
33
39 from IPython.config.configurable import SingletonConfigurable
34 from IPython.config.configurable import SingletonConfigurable
40 from IPython.core import debugger, oinspect
35 from IPython.core import debugger, oinspect
41 from IPython.core import history as ipcorehist
42 from IPython.core import page
36 from IPython.core import page
43 from IPython.core import prefilter
37 from IPython.core import prefilter
44 from IPython.core import shadowns
38 from IPython.core import shadowns
45 from IPython.core import ultratb
39 from IPython.core import ultratb
46 from IPython.core.alias import AliasManager, AliasError
40 from IPython.core.alias import AliasManager, AliasError
47 from IPython.core.autocall import ExitAutocall
41 from IPython.core.autocall import ExitAutocall
48 from IPython.core.builtin_trap import BuiltinTrap
42 from IPython.core.builtin_trap import BuiltinTrap
49 from IPython.core.compilerop import CachingCompiler
43 from IPython.core.compilerop import CachingCompiler
50 from IPython.core.display_trap import DisplayTrap
44 from IPython.core.display_trap import DisplayTrap
51 from IPython.core.displayhook import DisplayHook
45 from IPython.core.displayhook import DisplayHook
52 from IPython.core.displaypub import DisplayPublisher
46 from IPython.core.displaypub import DisplayPublisher
53 from IPython.core.error import TryNext, UsageError
47 from IPython.core.error import UsageError
54 from IPython.core.extensions import ExtensionManager
48 from IPython.core.extensions import ExtensionManager
55 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
49 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
56 from IPython.core.formatters import DisplayFormatter
50 from IPython.core.formatters import DisplayFormatter
57 from IPython.core.history import HistoryManager
51 from IPython.core.history import HistoryManager
58 from IPython.core.inputsplitter import IPythonInputSplitter
52 from IPython.core.inputsplitter import IPythonInputSplitter
59 from IPython.core.logger import Logger
53 from IPython.core.logger import Logger
60 from IPython.core.macro import Macro
54 from IPython.core.macro import Macro
61 from IPython.core.magic import Magic
55 from IPython.core.magic import Magic
62 from IPython.core.payload import PayloadManager
56 from IPython.core.payload import PayloadManager
63 from IPython.core.plugin import PluginManager
57 from IPython.core.plugin import PluginManager
64 from IPython.core.prefilter import PrefilterManager, ESC_MAGIC
58 from IPython.core.prefilter import PrefilterManager, ESC_MAGIC
65 from IPython.core.profiledir import ProfileDir
59 from IPython.core.profiledir import ProfileDir
66 from IPython.core.pylabtools import pylab_activate
60 from IPython.core.pylabtools import pylab_activate
67 from IPython.core.prompts import PromptManager
61 from IPython.core.prompts import PromptManager
68 from IPython.utils import PyColorize
62 from IPython.utils import PyColorize
69 from IPython.utils import io
63 from IPython.utils import io
70 from IPython.utils import py3compat
64 from IPython.utils import py3compat
65 from IPython.utils import openpy
71 from IPython.utils.doctestreload import doctest_reload
66 from IPython.utils.doctestreload import doctest_reload
72 from IPython.utils.io import ask_yes_no, rprint
67 from IPython.utils.io import ask_yes_no
73 from IPython.utils.ipstruct import Struct
68 from IPython.utils.ipstruct import Struct
74 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
69 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
75 from IPython.utils.pickleshare import PickleShareDB
70 from IPython.utils.pickleshare import PickleShareDB
76 from IPython.utils.process import system, getoutput
71 from IPython.utils.process import system, getoutput
77 from IPython.utils.strdispatch import StrDispatch
72 from IPython.utils.strdispatch import StrDispatch
78 from IPython.utils.syspathcontext import prepended_to_syspath
73 from IPython.utils.syspathcontext import prepended_to_syspath
79 from IPython.utils.text import (num_ini_spaces, format_screen, LSString, SList,
74 from IPython.utils.text import (format_screen, LSString, SList,
80 DollarFormatter)
75 DollarFormatter)
81 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
76 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
82 List, Unicode, Instance, Type)
77 List, Unicode, Instance, Type)
83 from IPython.utils.warn import warn, error, fatal
78 from IPython.utils.warn import warn, error
84 import IPython.core.hooks
79 import IPython.core.hooks
85
80
86 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
87 # Globals
82 # Globals
88 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
89
84
90 # compiled regexps for autoindent management
85 # compiled regexps for autoindent management
91 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
86 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
92
87
93 #-----------------------------------------------------------------------------
88 #-----------------------------------------------------------------------------
94 # Utilities
89 # Utilities
95 #-----------------------------------------------------------------------------
90 #-----------------------------------------------------------------------------
96
91
97 def softspace(file, newvalue):
92 def softspace(file, newvalue):
98 """Copied from code.py, to remove the dependency"""
93 """Copied from code.py, to remove the dependency"""
99
94
100 oldvalue = 0
95 oldvalue = 0
101 try:
96 try:
102 oldvalue = file.softspace
97 oldvalue = file.softspace
103 except AttributeError:
98 except AttributeError:
104 pass
99 pass
105 try:
100 try:
106 file.softspace = newvalue
101 file.softspace = newvalue
107 except (AttributeError, TypeError):
102 except (AttributeError, TypeError):
108 # "attribute-less object" or "read-only attributes"
103 # "attribute-less object" or "read-only attributes"
109 pass
104 pass
110 return oldvalue
105 return oldvalue
111
106
112
107
113 def no_op(*a, **kw): pass
108 def no_op(*a, **kw): pass
114
109
115 class NoOpContext(object):
110 class NoOpContext(object):
116 def __enter__(self): pass
111 def __enter__(self): pass
117 def __exit__(self, type, value, traceback): pass
112 def __exit__(self, type, value, traceback): pass
118 no_op_context = NoOpContext()
113 no_op_context = NoOpContext()
119
114
120 class SpaceInInput(Exception): pass
115 class SpaceInInput(Exception): pass
121
116
122 class Bunch: pass
117 class Bunch: pass
123
118
124
119
125 def get_default_colors():
120 def get_default_colors():
126 if sys.platform=='darwin':
121 if sys.platform=='darwin':
127 return "LightBG"
122 return "LightBG"
128 elif os.name=='nt':
123 elif os.name=='nt':
129 return 'Linux'
124 return 'Linux'
130 else:
125 else:
131 return 'Linux'
126 return 'Linux'
132
127
133
128
134 class SeparateUnicode(Unicode):
129 class SeparateUnicode(Unicode):
135 """A Unicode subclass to validate separate_in, separate_out, etc.
130 """A Unicode subclass to validate separate_in, separate_out, etc.
136
131
137 This is a Unicode based trait that converts '0'->'' and '\\n'->'\n'.
132 This is a Unicode based trait that converts '0'->'' and '\\n'->'\n'.
138 """
133 """
139
134
140 def validate(self, obj, value):
135 def validate(self, obj, value):
141 if value == '0': value = ''
136 if value == '0': value = ''
142 value = value.replace('\\n','\n')
137 value = value.replace('\\n','\n')
143 return super(SeparateUnicode, self).validate(obj, value)
138 return super(SeparateUnicode, self).validate(obj, value)
144
139
145
140
146 class ReadlineNoRecord(object):
141 class ReadlineNoRecord(object):
147 """Context manager to execute some code, then reload readline history
142 """Context manager to execute some code, then reload readline history
148 so that interactive input to the code doesn't appear when pressing up."""
143 so that interactive input to the code doesn't appear when pressing up."""
149 def __init__(self, shell):
144 def __init__(self, shell):
150 self.shell = shell
145 self.shell = shell
151 self._nested_level = 0
146 self._nested_level = 0
152
147
153 def __enter__(self):
148 def __enter__(self):
154 if self._nested_level == 0:
149 if self._nested_level == 0:
155 try:
150 try:
156 self.orig_length = self.current_length()
151 self.orig_length = self.current_length()
157 self.readline_tail = self.get_readline_tail()
152 self.readline_tail = self.get_readline_tail()
158 except (AttributeError, IndexError): # Can fail with pyreadline
153 except (AttributeError, IndexError): # Can fail with pyreadline
159 self.orig_length, self.readline_tail = 999999, []
154 self.orig_length, self.readline_tail = 999999, []
160 self._nested_level += 1
155 self._nested_level += 1
161
156
162 def __exit__(self, type, value, traceback):
157 def __exit__(self, type, value, traceback):
163 self._nested_level -= 1
158 self._nested_level -= 1
164 if self._nested_level == 0:
159 if self._nested_level == 0:
165 # Try clipping the end if it's got longer
160 # Try clipping the end if it's got longer
166 try:
161 try:
167 e = self.current_length() - self.orig_length
162 e = self.current_length() - self.orig_length
168 if e > 0:
163 if e > 0:
169 for _ in range(e):
164 for _ in range(e):
170 self.shell.readline.remove_history_item(self.orig_length)
165 self.shell.readline.remove_history_item(self.orig_length)
171
166
172 # If it still doesn't match, just reload readline history.
167 # If it still doesn't match, just reload readline history.
173 if self.current_length() != self.orig_length \
168 if self.current_length() != self.orig_length \
174 or self.get_readline_tail() != self.readline_tail:
169 or self.get_readline_tail() != self.readline_tail:
175 self.shell.refill_readline_hist()
170 self.shell.refill_readline_hist()
176 except (AttributeError, IndexError):
171 except (AttributeError, IndexError):
177 pass
172 pass
178 # Returning False will cause exceptions to propagate
173 # Returning False will cause exceptions to propagate
179 return False
174 return False
180
175
181 def current_length(self):
176 def current_length(self):
182 return self.shell.readline.get_current_history_length()
177 return self.shell.readline.get_current_history_length()
183
178
184 def get_readline_tail(self, n=10):
179 def get_readline_tail(self, n=10):
185 """Get the last n items in readline history."""
180 """Get the last n items in readline history."""
186 end = self.shell.readline.get_current_history_length() + 1
181 end = self.shell.readline.get_current_history_length() + 1
187 start = max(end-n, 1)
182 start = max(end-n, 1)
188 ghi = self.shell.readline.get_history_item
183 ghi = self.shell.readline.get_history_item
189 return [ghi(x) for x in range(start, end)]
184 return [ghi(x) for x in range(start, end)]
190
185
191 #-----------------------------------------------------------------------------
186 #-----------------------------------------------------------------------------
192 # Main IPython class
187 # Main IPython class
193 #-----------------------------------------------------------------------------
188 #-----------------------------------------------------------------------------
194
189
195 class InteractiveShell(SingletonConfigurable, Magic):
190 class InteractiveShell(SingletonConfigurable, Magic):
196 """An enhanced, interactive shell for Python."""
191 """An enhanced, interactive shell for Python."""
197
192
198 _instance = None
193 _instance = None
199
194
200 autocall = Enum((0,1,2), default_value=0, config=True, help=
195 autocall = Enum((0,1,2), default_value=0, config=True, help=
201 """
196 """
202 Make IPython automatically call any callable object even if you didn't
197 Make IPython automatically call any callable object even if you didn't
203 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
198 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
204 automatically. The value can be '0' to disable the feature, '1' for
199 automatically. The value can be '0' to disable the feature, '1' for
205 'smart' autocall, where it is not applied if there are no more
200 'smart' autocall, where it is not applied if there are no more
206 arguments on the line, and '2' for 'full' autocall, where all callable
201 arguments on the line, and '2' for 'full' autocall, where all callable
207 objects are automatically called (even if no arguments are present).
202 objects are automatically called (even if no arguments are present).
208 """
203 """
209 )
204 )
210 # TODO: remove all autoindent logic and put into frontends.
205 # TODO: remove all autoindent logic and put into frontends.
211 # We can't do this yet because even runlines uses the autoindent.
206 # We can't do this yet because even runlines uses the autoindent.
212 autoindent = CBool(True, config=True, help=
207 autoindent = CBool(True, config=True, help=
213 """
208 """
214 Autoindent IPython code entered interactively.
209 Autoindent IPython code entered interactively.
215 """
210 """
216 )
211 )
217 automagic = CBool(True, config=True, help=
212 automagic = CBool(True, config=True, help=
218 """
213 """
219 Enable magic commands to be called without the leading %.
214 Enable magic commands to be called without the leading %.
220 """
215 """
221 )
216 )
222 cache_size = Integer(1000, config=True, help=
217 cache_size = Integer(1000, config=True, help=
223 """
218 """
224 Set the size of the output cache. The default is 1000, you can
219 Set the size of the output cache. The default is 1000, you can
225 change it permanently in your config file. Setting it to 0 completely
220 change it permanently in your config file. Setting it to 0 completely
226 disables the caching system, and the minimum value accepted is 20 (if
221 disables the caching system, and the minimum value accepted is 20 (if
227 you provide a value less than 20, it is reset to 0 and a warning is
222 you provide a value less than 20, it is reset to 0 and a warning is
228 issued). This limit is defined because otherwise you'll spend more
223 issued). This limit is defined because otherwise you'll spend more
229 time re-flushing a too small cache than working
224 time re-flushing a too small cache than working
230 """
225 """
231 )
226 )
232 color_info = CBool(True, config=True, help=
227 color_info = CBool(True, config=True, help=
233 """
228 """
234 Use colors for displaying information about objects. Because this
229 Use colors for displaying information about objects. Because this
235 information is passed through a pager (like 'less'), and some pagers
230 information is passed through a pager (like 'less'), and some pagers
236 get confused with color codes, this capability can be turned off.
231 get confused with color codes, this capability can be turned off.
237 """
232 """
238 )
233 )
239 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
234 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
240 default_value=get_default_colors(), config=True,
235 default_value=get_default_colors(), config=True,
241 help="Set the color scheme (NoColor, Linux, or LightBG)."
236 help="Set the color scheme (NoColor, Linux, or LightBG)."
242 )
237 )
243 colors_force = CBool(False, help=
238 colors_force = CBool(False, help=
244 """
239 """
245 Force use of ANSI color codes, regardless of OS and readline
240 Force use of ANSI color codes, regardless of OS and readline
246 availability.
241 availability.
247 """
242 """
248 # FIXME: This is essentially a hack to allow ZMQShell to show colors
243 # FIXME: This is essentially a hack to allow ZMQShell to show colors
249 # without readline on Win32. When the ZMQ formatting system is
244 # without readline on Win32. When the ZMQ formatting system is
250 # refactored, this should be removed.
245 # refactored, this should be removed.
251 )
246 )
252 debug = CBool(False, config=True)
247 debug = CBool(False, config=True)
253 deep_reload = CBool(False, config=True, help=
248 deep_reload = CBool(False, config=True, help=
254 """
249 """
255 Enable deep (recursive) reloading by default. IPython can use the
250 Enable deep (recursive) reloading by default. IPython can use the
256 deep_reload module which reloads changes in modules recursively (it
251 deep_reload module which reloads changes in modules recursively (it
257 replaces the reload() function, so you don't need to change anything to
252 replaces the reload() function, so you don't need to change anything to
258 use it). deep_reload() forces a full reload of modules whose code may
253 use it). deep_reload() forces a full reload of modules whose code may
259 have changed, which the default reload() function does not. When
254 have changed, which the default reload() function does not. When
260 deep_reload is off, IPython will use the normal reload(), but
255 deep_reload is off, IPython will use the normal reload(), but
261 deep_reload will still be available as dreload().
256 deep_reload will still be available as dreload().
262 """
257 """
263 )
258 )
264 disable_failing_post_execute = CBool(False, config=True,
259 disable_failing_post_execute = CBool(False, config=True,
265 help="Don't call post-execute functions that have failed in the past."""
260 help="Don't call post-execute functions that have failed in the past."""
266 )
261 )
267 display_formatter = Instance(DisplayFormatter)
262 display_formatter = Instance(DisplayFormatter)
268 displayhook_class = Type(DisplayHook)
263 displayhook_class = Type(DisplayHook)
269 display_pub_class = Type(DisplayPublisher)
264 display_pub_class = Type(DisplayPublisher)
270
265
271 exit_now = CBool(False)
266 exit_now = CBool(False)
272 exiter = Instance(ExitAutocall)
267 exiter = Instance(ExitAutocall)
273 def _exiter_default(self):
268 def _exiter_default(self):
274 return ExitAutocall(self)
269 return ExitAutocall(self)
275 # Monotonically increasing execution counter
270 # Monotonically increasing execution counter
276 execution_count = Integer(1)
271 execution_count = Integer(1)
277 filename = Unicode("<ipython console>")
272 filename = Unicode("<ipython console>")
278 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
273 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
279
274
280 # Input splitter, to split entire cells of input into either individual
275 # Input splitter, to split entire cells of input into either individual
281 # interactive statements or whole blocks.
276 # interactive statements or whole blocks.
282 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
277 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
283 (), {})
278 (), {})
284 logstart = CBool(False, config=True, help=
279 logstart = CBool(False, config=True, help=
285 """
280 """
286 Start logging to the default log file.
281 Start logging to the default log file.
287 """
282 """
288 )
283 )
289 logfile = Unicode('', config=True, help=
284 logfile = Unicode('', config=True, help=
290 """
285 """
291 The name of the logfile to use.
286 The name of the logfile to use.
292 """
287 """
293 )
288 )
294 logappend = Unicode('', config=True, help=
289 logappend = Unicode('', config=True, help=
295 """
290 """
296 Start logging to the given file in append mode.
291 Start logging to the given file in append mode.
297 """
292 """
298 )
293 )
299 object_info_string_level = Enum((0,1,2), default_value=0,
294 object_info_string_level = Enum((0,1,2), default_value=0,
300 config=True)
295 config=True)
301 pdb = CBool(False, config=True, help=
296 pdb = CBool(False, config=True, help=
302 """
297 """
303 Automatically call the pdb debugger after every exception.
298 Automatically call the pdb debugger after every exception.
304 """
299 """
305 )
300 )
306 multiline_history = CBool(sys.platform != 'win32', config=True,
301 multiline_history = CBool(sys.platform != 'win32', config=True,
307 help="Save multi-line entries as one entry in readline history"
302 help="Save multi-line entries as one entry in readline history"
308 )
303 )
309
304
310 # deprecated prompt traits:
305 # deprecated prompt traits:
311
306
312 prompt_in1 = Unicode('In [\\#]: ', config=True,
307 prompt_in1 = Unicode('In [\\#]: ', config=True,
313 help="Deprecated, use PromptManager.in_template")
308 help="Deprecated, use PromptManager.in_template")
314 prompt_in2 = Unicode(' .\\D.: ', config=True,
309 prompt_in2 = Unicode(' .\\D.: ', config=True,
315 help="Deprecated, use PromptManager.in2_template")
310 help="Deprecated, use PromptManager.in2_template")
316 prompt_out = Unicode('Out[\\#]: ', config=True,
311 prompt_out = Unicode('Out[\\#]: ', config=True,
317 help="Deprecated, use PromptManager.out_template")
312 help="Deprecated, use PromptManager.out_template")
318 prompts_pad_left = CBool(True, config=True,
313 prompts_pad_left = CBool(True, config=True,
319 help="Deprecated, use PromptManager.justify")
314 help="Deprecated, use PromptManager.justify")
320
315
321 def _prompt_trait_changed(self, name, old, new):
316 def _prompt_trait_changed(self, name, old, new):
322 table = {
317 table = {
323 'prompt_in1' : 'in_template',
318 'prompt_in1' : 'in_template',
324 'prompt_in2' : 'in2_template',
319 'prompt_in2' : 'in2_template',
325 'prompt_out' : 'out_template',
320 'prompt_out' : 'out_template',
326 'prompts_pad_left' : 'justify',
321 'prompts_pad_left' : 'justify',
327 }
322 }
328 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}\n".format(
323 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}\n".format(
329 name=name, newname=table[name])
324 name=name, newname=table[name])
330 )
325 )
331 # protect against weird cases where self.config may not exist:
326 # protect against weird cases where self.config may not exist:
332 if self.config is not None:
327 if self.config is not None:
333 # propagate to corresponding PromptManager trait
328 # propagate to corresponding PromptManager trait
334 setattr(self.config.PromptManager, table[name], new)
329 setattr(self.config.PromptManager, table[name], new)
335
330
336 _prompt_in1_changed = _prompt_trait_changed
331 _prompt_in1_changed = _prompt_trait_changed
337 _prompt_in2_changed = _prompt_trait_changed
332 _prompt_in2_changed = _prompt_trait_changed
338 _prompt_out_changed = _prompt_trait_changed
333 _prompt_out_changed = _prompt_trait_changed
339 _prompt_pad_left_changed = _prompt_trait_changed
334 _prompt_pad_left_changed = _prompt_trait_changed
340
335
341 show_rewritten_input = CBool(True, config=True,
336 show_rewritten_input = CBool(True, config=True,
342 help="Show rewritten input, e.g. for autocall."
337 help="Show rewritten input, e.g. for autocall."
343 )
338 )
344
339
345 quiet = CBool(False, config=True)
340 quiet = CBool(False, config=True)
346
341
347 history_length = Integer(10000, config=True)
342 history_length = Integer(10000, config=True)
348
343
349 # The readline stuff will eventually be moved to the terminal subclass
344 # The readline stuff will eventually be moved to the terminal subclass
350 # but for now, we can't do that as readline is welded in everywhere.
345 # but for now, we can't do that as readline is welded in everywhere.
351 readline_use = CBool(True, config=True)
346 readline_use = CBool(True, config=True)
352 readline_remove_delims = Unicode('-/~', config=True)
347 readline_remove_delims = Unicode('-/~', config=True)
353 # don't use \M- bindings by default, because they
348 # don't use \M- bindings by default, because they
354 # conflict with 8-bit encodings. See gh-58,gh-88
349 # conflict with 8-bit encodings. See gh-58,gh-88
355 readline_parse_and_bind = List([
350 readline_parse_and_bind = List([
356 'tab: complete',
351 'tab: complete',
357 '"\C-l": clear-screen',
352 '"\C-l": clear-screen',
358 'set show-all-if-ambiguous on',
353 'set show-all-if-ambiguous on',
359 '"\C-o": tab-insert',
354 '"\C-o": tab-insert',
360 '"\C-r": reverse-search-history',
355 '"\C-r": reverse-search-history',
361 '"\C-s": forward-search-history',
356 '"\C-s": forward-search-history',
362 '"\C-p": history-search-backward',
357 '"\C-p": history-search-backward',
363 '"\C-n": history-search-forward',
358 '"\C-n": history-search-forward',
364 '"\e[A": history-search-backward',
359 '"\e[A": history-search-backward',
365 '"\e[B": history-search-forward',
360 '"\e[B": history-search-forward',
366 '"\C-k": kill-line',
361 '"\C-k": kill-line',
367 '"\C-u": unix-line-discard',
362 '"\C-u": unix-line-discard',
368 ], allow_none=False, config=True)
363 ], allow_none=False, config=True)
369
364
370 # TODO: this part of prompt management should be moved to the frontends.
365 # TODO: this part of prompt management should be moved to the frontends.
371 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
366 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
372 separate_in = SeparateUnicode('\n', config=True)
367 separate_in = SeparateUnicode('\n', config=True)
373 separate_out = SeparateUnicode('', config=True)
368 separate_out = SeparateUnicode('', config=True)
374 separate_out2 = SeparateUnicode('', config=True)
369 separate_out2 = SeparateUnicode('', config=True)
375 wildcards_case_sensitive = CBool(True, config=True)
370 wildcards_case_sensitive = CBool(True, config=True)
376 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
371 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
377 default_value='Context', config=True)
372 default_value='Context', config=True)
378
373
379 # Subcomponents of InteractiveShell
374 # Subcomponents of InteractiveShell
380 alias_manager = Instance('IPython.core.alias.AliasManager')
375 alias_manager = Instance('IPython.core.alias.AliasManager')
381 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
376 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
382 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
377 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
383 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
378 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
384 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
379 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
385 plugin_manager = Instance('IPython.core.plugin.PluginManager')
380 plugin_manager = Instance('IPython.core.plugin.PluginManager')
386 payload_manager = Instance('IPython.core.payload.PayloadManager')
381 payload_manager = Instance('IPython.core.payload.PayloadManager')
387 history_manager = Instance('IPython.core.history.HistoryManager')
382 history_manager = Instance('IPython.core.history.HistoryManager')
388
383
389 profile_dir = Instance('IPython.core.application.ProfileDir')
384 profile_dir = Instance('IPython.core.application.ProfileDir')
390 @property
385 @property
391 def profile(self):
386 def profile(self):
392 if self.profile_dir is not None:
387 if self.profile_dir is not None:
393 name = os.path.basename(self.profile_dir.location)
388 name = os.path.basename(self.profile_dir.location)
394 return name.replace('profile_','')
389 return name.replace('profile_','')
395
390
396
391
397 # Private interface
392 # Private interface
398 _post_execute = Instance(dict)
393 _post_execute = Instance(dict)
399
394
400 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
395 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
401 user_module=None, user_ns=None,
396 user_module=None, user_ns=None,
402 custom_exceptions=((), None)):
397 custom_exceptions=((), None)):
403
398
404 # This is where traits with a config_key argument are updated
399 # This is where traits with a config_key argument are updated
405 # from the values on config.
400 # from the values on config.
406 super(InteractiveShell, self).__init__(config=config)
401 super(InteractiveShell, self).__init__(config=config)
407 self.configurables = [self]
402 self.configurables = [self]
408
403
409 # These are relatively independent and stateless
404 # These are relatively independent and stateless
410 self.init_ipython_dir(ipython_dir)
405 self.init_ipython_dir(ipython_dir)
411 self.init_profile_dir(profile_dir)
406 self.init_profile_dir(profile_dir)
412 self.init_instance_attrs()
407 self.init_instance_attrs()
413 self.init_environment()
408 self.init_environment()
414
409
415 # Check if we're in a virtualenv, and set up sys.path.
410 # Check if we're in a virtualenv, and set up sys.path.
416 self.init_virtualenv()
411 self.init_virtualenv()
417
412
418 # Create namespaces (user_ns, user_global_ns, etc.)
413 # Create namespaces (user_ns, user_global_ns, etc.)
419 self.init_create_namespaces(user_module, user_ns)
414 self.init_create_namespaces(user_module, user_ns)
420 # This has to be done after init_create_namespaces because it uses
415 # This has to be done after init_create_namespaces because it uses
421 # something in self.user_ns, but before init_sys_modules, which
416 # something in self.user_ns, but before init_sys_modules, which
422 # is the first thing to modify sys.
417 # is the first thing to modify sys.
423 # TODO: When we override sys.stdout and sys.stderr before this class
418 # TODO: When we override sys.stdout and sys.stderr before this class
424 # is created, we are saving the overridden ones here. Not sure if this
419 # is created, we are saving the overridden ones here. Not sure if this
425 # is what we want to do.
420 # is what we want to do.
426 self.save_sys_module_state()
421 self.save_sys_module_state()
427 self.init_sys_modules()
422 self.init_sys_modules()
428
423
429 # While we're trying to have each part of the code directly access what
424 # While we're trying to have each part of the code directly access what
430 # it needs without keeping redundant references to objects, we have too
425 # it needs without keeping redundant references to objects, we have too
431 # much legacy code that expects ip.db to exist.
426 # much legacy code that expects ip.db to exist.
432 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
427 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
433
428
434 self.init_history()
429 self.init_history()
435 self.init_encoding()
430 self.init_encoding()
436 self.init_prefilter()
431 self.init_prefilter()
437
432
438 Magic.__init__(self, self)
433 Magic.__init__(self, self)
439
434
440 self.init_syntax_highlighting()
435 self.init_syntax_highlighting()
441 self.init_hooks()
436 self.init_hooks()
442 self.init_pushd_popd_magic()
437 self.init_pushd_popd_magic()
443 # self.init_traceback_handlers use to be here, but we moved it below
438 # self.init_traceback_handlers use to be here, but we moved it below
444 # because it and init_io have to come after init_readline.
439 # because it and init_io have to come after init_readline.
445 self.init_user_ns()
440 self.init_user_ns()
446 self.init_logger()
441 self.init_logger()
447 self.init_alias()
442 self.init_alias()
448 self.init_builtins()
443 self.init_builtins()
449
444
450 # pre_config_initialization
445 # pre_config_initialization
451
446
452 # The next section should contain everything that was in ipmaker.
447 # The next section should contain everything that was in ipmaker.
453 self.init_logstart()
448 self.init_logstart()
454
449
455 # The following was in post_config_initialization
450 # The following was in post_config_initialization
456 self.init_inspector()
451 self.init_inspector()
457 # init_readline() must come before init_io(), because init_io uses
452 # init_readline() must come before init_io(), because init_io uses
458 # readline related things.
453 # readline related things.
459 self.init_readline()
454 self.init_readline()
460 # We save this here in case user code replaces raw_input, but it needs
455 # We save this here in case user code replaces raw_input, but it needs
461 # to be after init_readline(), because PyPy's readline works by replacing
456 # to be after init_readline(), because PyPy's readline works by replacing
462 # raw_input.
457 # raw_input.
463 if py3compat.PY3:
458 if py3compat.PY3:
464 self.raw_input_original = input
459 self.raw_input_original = input
465 else:
460 else:
466 self.raw_input_original = raw_input
461 self.raw_input_original = raw_input
467 # init_completer must come after init_readline, because it needs to
462 # init_completer must come after init_readline, because it needs to
468 # know whether readline is present or not system-wide to configure the
463 # know whether readline is present or not system-wide to configure the
469 # completers, since the completion machinery can now operate
464 # completers, since the completion machinery can now operate
470 # independently of readline (e.g. over the network)
465 # independently of readline (e.g. over the network)
471 self.init_completer()
466 self.init_completer()
472 # TODO: init_io() needs to happen before init_traceback handlers
467 # TODO: init_io() needs to happen before init_traceback handlers
473 # because the traceback handlers hardcode the stdout/stderr streams.
468 # because the traceback handlers hardcode the stdout/stderr streams.
474 # This logic in in debugger.Pdb and should eventually be changed.
469 # This logic in in debugger.Pdb and should eventually be changed.
475 self.init_io()
470 self.init_io()
476 self.init_traceback_handlers(custom_exceptions)
471 self.init_traceback_handlers(custom_exceptions)
477 self.init_prompts()
472 self.init_prompts()
478 self.init_display_formatter()
473 self.init_display_formatter()
479 self.init_display_pub()
474 self.init_display_pub()
480 self.init_displayhook()
475 self.init_displayhook()
481 self.init_reload_doctest()
476 self.init_reload_doctest()
482 self.init_magics()
477 self.init_magics()
483 self.init_pdb()
478 self.init_pdb()
484 self.init_extension_manager()
479 self.init_extension_manager()
485 self.init_plugin_manager()
480 self.init_plugin_manager()
486 self.init_payload()
481 self.init_payload()
487 self.hooks.late_startup_hook()
482 self.hooks.late_startup_hook()
488 atexit.register(self.atexit_operations)
483 atexit.register(self.atexit_operations)
489
484
490 def get_ipython(self):
485 def get_ipython(self):
491 """Return the currently running IPython instance."""
486 """Return the currently running IPython instance."""
492 return self
487 return self
493
488
494 #-------------------------------------------------------------------------
489 #-------------------------------------------------------------------------
495 # Trait changed handlers
490 # Trait changed handlers
496 #-------------------------------------------------------------------------
491 #-------------------------------------------------------------------------
497
492
498 def _ipython_dir_changed(self, name, new):
493 def _ipython_dir_changed(self, name, new):
499 if not os.path.isdir(new):
494 if not os.path.isdir(new):
500 os.makedirs(new, mode = 0777)
495 os.makedirs(new, mode = 0777)
501
496
502 def set_autoindent(self,value=None):
497 def set_autoindent(self,value=None):
503 """Set the autoindent flag, checking for readline support.
498 """Set the autoindent flag, checking for readline support.
504
499
505 If called with no arguments, it acts as a toggle."""
500 If called with no arguments, it acts as a toggle."""
506
501
507 if value != 0 and not self.has_readline:
502 if value != 0 and not self.has_readline:
508 if os.name == 'posix':
503 if os.name == 'posix':
509 warn("The auto-indent feature requires the readline library")
504 warn("The auto-indent feature requires the readline library")
510 self.autoindent = 0
505 self.autoindent = 0
511 return
506 return
512 if value is None:
507 if value is None:
513 self.autoindent = not self.autoindent
508 self.autoindent = not self.autoindent
514 else:
509 else:
515 self.autoindent = value
510 self.autoindent = value
516
511
517 #-------------------------------------------------------------------------
512 #-------------------------------------------------------------------------
518 # init_* methods called by __init__
513 # init_* methods called by __init__
519 #-------------------------------------------------------------------------
514 #-------------------------------------------------------------------------
520
515
521 def init_ipython_dir(self, ipython_dir):
516 def init_ipython_dir(self, ipython_dir):
522 if ipython_dir is not None:
517 if ipython_dir is not None:
523 self.ipython_dir = ipython_dir
518 self.ipython_dir = ipython_dir
524 return
519 return
525
520
526 self.ipython_dir = get_ipython_dir()
521 self.ipython_dir = get_ipython_dir()
527
522
528 def init_profile_dir(self, profile_dir):
523 def init_profile_dir(self, profile_dir):
529 if profile_dir is not None:
524 if profile_dir is not None:
530 self.profile_dir = profile_dir
525 self.profile_dir = profile_dir
531 return
526 return
532 self.profile_dir =\
527 self.profile_dir =\
533 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
528 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
534
529
535 def init_instance_attrs(self):
530 def init_instance_attrs(self):
536 self.more = False
531 self.more = False
537
532
538 # command compiler
533 # command compiler
539 self.compile = CachingCompiler()
534 self.compile = CachingCompiler()
540
535
541 # Make an empty namespace, which extension writers can rely on both
536 # Make an empty namespace, which extension writers can rely on both
542 # existing and NEVER being used by ipython itself. This gives them a
537 # existing and NEVER being used by ipython itself. This gives them a
543 # convenient location for storing additional information and state
538 # convenient location for storing additional information and state
544 # their extensions may require, without fear of collisions with other
539 # their extensions may require, without fear of collisions with other
545 # ipython names that may develop later.
540 # ipython names that may develop later.
546 self.meta = Struct()
541 self.meta = Struct()
547
542
548 # Temporary files used for various purposes. Deleted at exit.
543 # Temporary files used for various purposes. Deleted at exit.
549 self.tempfiles = []
544 self.tempfiles = []
550
545
551 # Keep track of readline usage (later set by init_readline)
546 # Keep track of readline usage (later set by init_readline)
552 self.has_readline = False
547 self.has_readline = False
553
548
554 # keep track of where we started running (mainly for crash post-mortem)
549 # keep track of where we started running (mainly for crash post-mortem)
555 # This is not being used anywhere currently.
550 # This is not being used anywhere currently.
556 self.starting_dir = os.getcwdu()
551 self.starting_dir = os.getcwdu()
557
552
558 # Indentation management
553 # Indentation management
559 self.indent_current_nsp = 0
554 self.indent_current_nsp = 0
560
555
561 # Dict to track post-execution functions that have been registered
556 # Dict to track post-execution functions that have been registered
562 self._post_execute = {}
557 self._post_execute = {}
563
558
564 def init_environment(self):
559 def init_environment(self):
565 """Any changes we need to make to the user's environment."""
560 """Any changes we need to make to the user's environment."""
566 pass
561 pass
567
562
568 def init_encoding(self):
563 def init_encoding(self):
569 # Get system encoding at startup time. Certain terminals (like Emacs
564 # Get system encoding at startup time. Certain terminals (like Emacs
570 # under Win32 have it set to None, and we need to have a known valid
565 # under Win32 have it set to None, and we need to have a known valid
571 # encoding to use in the raw_input() method
566 # encoding to use in the raw_input() method
572 try:
567 try:
573 self.stdin_encoding = sys.stdin.encoding or 'ascii'
568 self.stdin_encoding = sys.stdin.encoding or 'ascii'
574 except AttributeError:
569 except AttributeError:
575 self.stdin_encoding = 'ascii'
570 self.stdin_encoding = 'ascii'
576
571
577 def init_syntax_highlighting(self):
572 def init_syntax_highlighting(self):
578 # Python source parser/formatter for syntax highlighting
573 # Python source parser/formatter for syntax highlighting
579 pyformat = PyColorize.Parser().format
574 pyformat = PyColorize.Parser().format
580 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
575 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
581
576
582 def init_pushd_popd_magic(self):
577 def init_pushd_popd_magic(self):
583 # for pushd/popd management
578 # for pushd/popd management
584 self.home_dir = get_home_dir()
579 self.home_dir = get_home_dir()
585
580
586 self.dir_stack = []
581 self.dir_stack = []
587
582
588 def init_logger(self):
583 def init_logger(self):
589 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
584 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
590 logmode='rotate')
585 logmode='rotate')
591
586
592 def init_logstart(self):
587 def init_logstart(self):
593 """Initialize logging in case it was requested at the command line.
588 """Initialize logging in case it was requested at the command line.
594 """
589 """
595 if self.logappend:
590 if self.logappend:
596 self.magic_logstart(self.logappend + ' append')
591 self.magic_logstart(self.logappend + ' append')
597 elif self.logfile:
592 elif self.logfile:
598 self.magic_logstart(self.logfile)
593 self.magic_logstart(self.logfile)
599 elif self.logstart:
594 elif self.logstart:
600 self.magic_logstart()
595 self.magic_logstart()
601
596
602 def init_builtins(self):
597 def init_builtins(self):
603 # A single, static flag that we set to True. Its presence indicates
598 # A single, static flag that we set to True. Its presence indicates
604 # that an IPython shell has been created, and we make no attempts at
599 # that an IPython shell has been created, and we make no attempts at
605 # removing on exit or representing the existence of more than one
600 # removing on exit or representing the existence of more than one
606 # IPython at a time.
601 # IPython at a time.
607 builtin_mod.__dict__['__IPYTHON__'] = True
602 builtin_mod.__dict__['__IPYTHON__'] = True
608
603
609 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
604 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
610 # manage on enter/exit, but with all our shells it's virtually
605 # manage on enter/exit, but with all our shells it's virtually
611 # impossible to get all the cases right. We're leaving the name in for
606 # impossible to get all the cases right. We're leaving the name in for
612 # those who adapted their codes to check for this flag, but will
607 # those who adapted their codes to check for this flag, but will
613 # eventually remove it after a few more releases.
608 # eventually remove it after a few more releases.
614 builtin_mod.__dict__['__IPYTHON__active'] = \
609 builtin_mod.__dict__['__IPYTHON__active'] = \
615 'Deprecated, check for __IPYTHON__'
610 'Deprecated, check for __IPYTHON__'
616
611
617 self.builtin_trap = BuiltinTrap(shell=self)
612 self.builtin_trap = BuiltinTrap(shell=self)
618
613
619 def init_inspector(self):
614 def init_inspector(self):
620 # Object inspector
615 # Object inspector
621 self.inspector = oinspect.Inspector(oinspect.InspectColors,
616 self.inspector = oinspect.Inspector(oinspect.InspectColors,
622 PyColorize.ANSICodeColors,
617 PyColorize.ANSICodeColors,
623 'NoColor',
618 'NoColor',
624 self.object_info_string_level)
619 self.object_info_string_level)
625
620
626 def init_io(self):
621 def init_io(self):
627 # This will just use sys.stdout and sys.stderr. If you want to
622 # This will just use sys.stdout and sys.stderr. If you want to
628 # override sys.stdout and sys.stderr themselves, you need to do that
623 # override sys.stdout and sys.stderr themselves, you need to do that
629 # *before* instantiating this class, because io holds onto
624 # *before* instantiating this class, because io holds onto
630 # references to the underlying streams.
625 # references to the underlying streams.
631 if sys.platform == 'win32' and self.has_readline:
626 if sys.platform == 'win32' and self.has_readline:
632 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
627 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
633 else:
628 else:
634 io.stdout = io.IOStream(sys.stdout)
629 io.stdout = io.IOStream(sys.stdout)
635 io.stderr = io.IOStream(sys.stderr)
630 io.stderr = io.IOStream(sys.stderr)
636
631
637 def init_prompts(self):
632 def init_prompts(self):
638 self.prompt_manager = PromptManager(shell=self, config=self.config)
633 self.prompt_manager = PromptManager(shell=self, config=self.config)
639 self.configurables.append(self.prompt_manager)
634 self.configurables.append(self.prompt_manager)
640 # Set system prompts, so that scripts can decide if they are running
635 # Set system prompts, so that scripts can decide if they are running
641 # interactively.
636 # interactively.
642 sys.ps1 = 'In : '
637 sys.ps1 = 'In : '
643 sys.ps2 = '...: '
638 sys.ps2 = '...: '
644 sys.ps3 = 'Out: '
639 sys.ps3 = 'Out: '
645
640
646 def init_display_formatter(self):
641 def init_display_formatter(self):
647 self.display_formatter = DisplayFormatter(config=self.config)
642 self.display_formatter = DisplayFormatter(config=self.config)
648 self.configurables.append(self.display_formatter)
643 self.configurables.append(self.display_formatter)
649
644
650 def init_display_pub(self):
645 def init_display_pub(self):
651 self.display_pub = self.display_pub_class(config=self.config)
646 self.display_pub = self.display_pub_class(config=self.config)
652 self.configurables.append(self.display_pub)
647 self.configurables.append(self.display_pub)
653
648
654 def init_displayhook(self):
649 def init_displayhook(self):
655 # Initialize displayhook, set in/out prompts and printing system
650 # Initialize displayhook, set in/out prompts and printing system
656 self.displayhook = self.displayhook_class(
651 self.displayhook = self.displayhook_class(
657 config=self.config,
652 config=self.config,
658 shell=self,
653 shell=self,
659 cache_size=self.cache_size,
654 cache_size=self.cache_size,
660 )
655 )
661 self.configurables.append(self.displayhook)
656 self.configurables.append(self.displayhook)
662 # This is a context manager that installs/revmoes the displayhook at
657 # This is a context manager that installs/revmoes the displayhook at
663 # the appropriate time.
658 # the appropriate time.
664 self.display_trap = DisplayTrap(hook=self.displayhook)
659 self.display_trap = DisplayTrap(hook=self.displayhook)
665
660
666 def init_reload_doctest(self):
661 def init_reload_doctest(self):
667 # Do a proper resetting of doctest, including the necessary displayhook
662 # Do a proper resetting of doctest, including the necessary displayhook
668 # monkeypatching
663 # monkeypatching
669 try:
664 try:
670 doctest_reload()
665 doctest_reload()
671 except ImportError:
666 except ImportError:
672 warn("doctest module does not exist.")
667 warn("doctest module does not exist.")
673
668
674 def init_virtualenv(self):
669 def init_virtualenv(self):
675 """Add a virtualenv to sys.path so the user can import modules from it.
670 """Add a virtualenv to sys.path so the user can import modules from it.
676 This isn't perfect: it doesn't use the Python interpreter with which the
671 This isn't perfect: it doesn't use the Python interpreter with which the
677 virtualenv was built, and it ignores the --no-site-packages option. A
672 virtualenv was built, and it ignores the --no-site-packages option. A
678 warning will appear suggesting the user installs IPython in the
673 warning will appear suggesting the user installs IPython in the
679 virtualenv, but for many cases, it probably works well enough.
674 virtualenv, but for many cases, it probably works well enough.
680
675
681 Adapted from code snippets online.
676 Adapted from code snippets online.
682
677
683 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
678 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
684 """
679 """
685 if 'VIRTUAL_ENV' not in os.environ:
680 if 'VIRTUAL_ENV' not in os.environ:
686 # Not in a virtualenv
681 # Not in a virtualenv
687 return
682 return
688
683
689 if sys.executable.startswith(os.environ['VIRTUAL_ENV']):
684 if sys.executable.startswith(os.environ['VIRTUAL_ENV']):
690 # Running properly in the virtualenv, don't need to do anything
685 # Running properly in the virtualenv, don't need to do anything
691 return
686 return
692
687
693 warn("Attempting to work in a virtualenv. If you encounter problems, please "
688 warn("Attempting to work in a virtualenv. If you encounter problems, please "
694 "install IPython inside the virtualenv.\n")
689 "install IPython inside the virtualenv.\n")
695 if sys.platform == "win32":
690 if sys.platform == "win32":
696 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
691 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
697 else:
692 else:
698 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
693 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
699 'python%d.%d' % sys.version_info[:2], 'site-packages')
694 'python%d.%d' % sys.version_info[:2], 'site-packages')
700
695
701 import site
696 import site
702 sys.path.insert(0, virtual_env)
697 sys.path.insert(0, virtual_env)
703 site.addsitedir(virtual_env)
698 site.addsitedir(virtual_env)
704
699
705 #-------------------------------------------------------------------------
700 #-------------------------------------------------------------------------
706 # Things related to injections into the sys module
701 # Things related to injections into the sys module
707 #-------------------------------------------------------------------------
702 #-------------------------------------------------------------------------
708
703
709 def save_sys_module_state(self):
704 def save_sys_module_state(self):
710 """Save the state of hooks in the sys module.
705 """Save the state of hooks in the sys module.
711
706
712 This has to be called after self.user_module is created.
707 This has to be called after self.user_module is created.
713 """
708 """
714 self._orig_sys_module_state = {}
709 self._orig_sys_module_state = {}
715 self._orig_sys_module_state['stdin'] = sys.stdin
710 self._orig_sys_module_state['stdin'] = sys.stdin
716 self._orig_sys_module_state['stdout'] = sys.stdout
711 self._orig_sys_module_state['stdout'] = sys.stdout
717 self._orig_sys_module_state['stderr'] = sys.stderr
712 self._orig_sys_module_state['stderr'] = sys.stderr
718 self._orig_sys_module_state['excepthook'] = sys.excepthook
713 self._orig_sys_module_state['excepthook'] = sys.excepthook
719 self._orig_sys_modules_main_name = self.user_module.__name__
714 self._orig_sys_modules_main_name = self.user_module.__name__
720
715
721 def restore_sys_module_state(self):
716 def restore_sys_module_state(self):
722 """Restore the state of the sys module."""
717 """Restore the state of the sys module."""
723 try:
718 try:
724 for k, v in self._orig_sys_module_state.iteritems():
719 for k, v in self._orig_sys_module_state.iteritems():
725 setattr(sys, k, v)
720 setattr(sys, k, v)
726 except AttributeError:
721 except AttributeError:
727 pass
722 pass
728 # Reset what what done in self.init_sys_modules
723 # Reset what what done in self.init_sys_modules
729 sys.modules[self.user_module.__name__] = self._orig_sys_modules_main_name
724 sys.modules[self.user_module.__name__] = self._orig_sys_modules_main_name
730
725
731 #-------------------------------------------------------------------------
726 #-------------------------------------------------------------------------
732 # Things related to hooks
727 # Things related to hooks
733 #-------------------------------------------------------------------------
728 #-------------------------------------------------------------------------
734
729
735 def init_hooks(self):
730 def init_hooks(self):
736 # hooks holds pointers used for user-side customizations
731 # hooks holds pointers used for user-side customizations
737 self.hooks = Struct()
732 self.hooks = Struct()
738
733
739 self.strdispatchers = {}
734 self.strdispatchers = {}
740
735
741 # Set all default hooks, defined in the IPython.hooks module.
736 # Set all default hooks, defined in the IPython.hooks module.
742 hooks = IPython.core.hooks
737 hooks = IPython.core.hooks
743 for hook_name in hooks.__all__:
738 for hook_name in hooks.__all__:
744 # default hooks have priority 100, i.e. low; user hooks should have
739 # default hooks have priority 100, i.e. low; user hooks should have
745 # 0-100 priority
740 # 0-100 priority
746 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
741 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
747
742
748 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
743 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
749 """set_hook(name,hook) -> sets an internal IPython hook.
744 """set_hook(name,hook) -> sets an internal IPython hook.
750
745
751 IPython exposes some of its internal API as user-modifiable hooks. By
746 IPython exposes some of its internal API as user-modifiable hooks. By
752 adding your function to one of these hooks, you can modify IPython's
747 adding your function to one of these hooks, you can modify IPython's
753 behavior to call at runtime your own routines."""
748 behavior to call at runtime your own routines."""
754
749
755 # At some point in the future, this should validate the hook before it
750 # At some point in the future, this should validate the hook before it
756 # accepts it. Probably at least check that the hook takes the number
751 # accepts it. Probably at least check that the hook takes the number
757 # of args it's supposed to.
752 # of args it's supposed to.
758
753
759 f = types.MethodType(hook,self)
754 f = types.MethodType(hook,self)
760
755
761 # check if the hook is for strdispatcher first
756 # check if the hook is for strdispatcher first
762 if str_key is not None:
757 if str_key is not None:
763 sdp = self.strdispatchers.get(name, StrDispatch())
758 sdp = self.strdispatchers.get(name, StrDispatch())
764 sdp.add_s(str_key, f, priority )
759 sdp.add_s(str_key, f, priority )
765 self.strdispatchers[name] = sdp
760 self.strdispatchers[name] = sdp
766 return
761 return
767 if re_key is not None:
762 if re_key is not None:
768 sdp = self.strdispatchers.get(name, StrDispatch())
763 sdp = self.strdispatchers.get(name, StrDispatch())
769 sdp.add_re(re.compile(re_key), f, priority )
764 sdp.add_re(re.compile(re_key), f, priority )
770 self.strdispatchers[name] = sdp
765 self.strdispatchers[name] = sdp
771 return
766 return
772
767
773 dp = getattr(self.hooks, name, None)
768 dp = getattr(self.hooks, name, None)
774 if name not in IPython.core.hooks.__all__:
769 if name not in IPython.core.hooks.__all__:
775 print "Warning! Hook '%s' is not one of %s" % \
770 print "Warning! Hook '%s' is not one of %s" % \
776 (name, IPython.core.hooks.__all__ )
771 (name, IPython.core.hooks.__all__ )
777 if not dp:
772 if not dp:
778 dp = IPython.core.hooks.CommandChainDispatcher()
773 dp = IPython.core.hooks.CommandChainDispatcher()
779
774
780 try:
775 try:
781 dp.add(f,priority)
776 dp.add(f,priority)
782 except AttributeError:
777 except AttributeError:
783 # it was not commandchain, plain old func - replace
778 # it was not commandchain, plain old func - replace
784 dp = f
779 dp = f
785
780
786 setattr(self.hooks,name, dp)
781 setattr(self.hooks,name, dp)
787
782
788 def register_post_execute(self, func):
783 def register_post_execute(self, func):
789 """Register a function for calling after code execution.
784 """Register a function for calling after code execution.
790 """
785 """
791 if not callable(func):
786 if not callable(func):
792 raise ValueError('argument %s must be callable' % func)
787 raise ValueError('argument %s must be callable' % func)
793 self._post_execute[func] = True
788 self._post_execute[func] = True
794
789
795 #-------------------------------------------------------------------------
790 #-------------------------------------------------------------------------
796 # Things related to the "main" module
791 # Things related to the "main" module
797 #-------------------------------------------------------------------------
792 #-------------------------------------------------------------------------
798
793
799 def new_main_mod(self,ns=None):
794 def new_main_mod(self,ns=None):
800 """Return a new 'main' module object for user code execution.
795 """Return a new 'main' module object for user code execution.
801 """
796 """
802 main_mod = self._user_main_module
797 main_mod = self._user_main_module
803 init_fakemod_dict(main_mod,ns)
798 init_fakemod_dict(main_mod,ns)
804 return main_mod
799 return main_mod
805
800
806 def cache_main_mod(self,ns,fname):
801 def cache_main_mod(self,ns,fname):
807 """Cache a main module's namespace.
802 """Cache a main module's namespace.
808
803
809 When scripts are executed via %run, we must keep a reference to the
804 When scripts are executed via %run, we must keep a reference to the
810 namespace of their __main__ module (a FakeModule instance) around so
805 namespace of their __main__ module (a FakeModule instance) around so
811 that Python doesn't clear it, rendering objects defined therein
806 that Python doesn't clear it, rendering objects defined therein
812 useless.
807 useless.
813
808
814 This method keeps said reference in a private dict, keyed by the
809 This method keeps said reference in a private dict, keyed by the
815 absolute path of the module object (which corresponds to the script
810 absolute path of the module object (which corresponds to the script
816 path). This way, for multiple executions of the same script we only
811 path). This way, for multiple executions of the same script we only
817 keep one copy of the namespace (the last one), thus preventing memory
812 keep one copy of the namespace (the last one), thus preventing memory
818 leaks from old references while allowing the objects from the last
813 leaks from old references while allowing the objects from the last
819 execution to be accessible.
814 execution to be accessible.
820
815
821 Note: we can not allow the actual FakeModule instances to be deleted,
816 Note: we can not allow the actual FakeModule instances to be deleted,
822 because of how Python tears down modules (it hard-sets all their
817 because of how Python tears down modules (it hard-sets all their
823 references to None without regard for reference counts). This method
818 references to None without regard for reference counts). This method
824 must therefore make a *copy* of the given namespace, to allow the
819 must therefore make a *copy* of the given namespace, to allow the
825 original module's __dict__ to be cleared and reused.
820 original module's __dict__ to be cleared and reused.
826
821
827
822
828 Parameters
823 Parameters
829 ----------
824 ----------
830 ns : a namespace (a dict, typically)
825 ns : a namespace (a dict, typically)
831
826
832 fname : str
827 fname : str
833 Filename associated with the namespace.
828 Filename associated with the namespace.
834
829
835 Examples
830 Examples
836 --------
831 --------
837
832
838 In [10]: import IPython
833 In [10]: import IPython
839
834
840 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
835 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
841
836
842 In [12]: IPython.__file__ in _ip._main_ns_cache
837 In [12]: IPython.__file__ in _ip._main_ns_cache
843 Out[12]: True
838 Out[12]: True
844 """
839 """
845 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
840 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
846
841
847 def clear_main_mod_cache(self):
842 def clear_main_mod_cache(self):
848 """Clear the cache of main modules.
843 """Clear the cache of main modules.
849
844
850 Mainly for use by utilities like %reset.
845 Mainly for use by utilities like %reset.
851
846
852 Examples
847 Examples
853 --------
848 --------
854
849
855 In [15]: import IPython
850 In [15]: import IPython
856
851
857 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
852 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
858
853
859 In [17]: len(_ip._main_ns_cache) > 0
854 In [17]: len(_ip._main_ns_cache) > 0
860 Out[17]: True
855 Out[17]: True
861
856
862 In [18]: _ip.clear_main_mod_cache()
857 In [18]: _ip.clear_main_mod_cache()
863
858
864 In [19]: len(_ip._main_ns_cache) == 0
859 In [19]: len(_ip._main_ns_cache) == 0
865 Out[19]: True
860 Out[19]: True
866 """
861 """
867 self._main_ns_cache.clear()
862 self._main_ns_cache.clear()
868
863
869 #-------------------------------------------------------------------------
864 #-------------------------------------------------------------------------
870 # Things related to debugging
865 # Things related to debugging
871 #-------------------------------------------------------------------------
866 #-------------------------------------------------------------------------
872
867
873 def init_pdb(self):
868 def init_pdb(self):
874 # Set calling of pdb on exceptions
869 # Set calling of pdb on exceptions
875 # self.call_pdb is a property
870 # self.call_pdb is a property
876 self.call_pdb = self.pdb
871 self.call_pdb = self.pdb
877
872
878 def _get_call_pdb(self):
873 def _get_call_pdb(self):
879 return self._call_pdb
874 return self._call_pdb
880
875
881 def _set_call_pdb(self,val):
876 def _set_call_pdb(self,val):
882
877
883 if val not in (0,1,False,True):
878 if val not in (0,1,False,True):
884 raise ValueError,'new call_pdb value must be boolean'
879 raise ValueError,'new call_pdb value must be boolean'
885
880
886 # store value in instance
881 # store value in instance
887 self._call_pdb = val
882 self._call_pdb = val
888
883
889 # notify the actual exception handlers
884 # notify the actual exception handlers
890 self.InteractiveTB.call_pdb = val
885 self.InteractiveTB.call_pdb = val
891
886
892 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
887 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
893 'Control auto-activation of pdb at exceptions')
888 'Control auto-activation of pdb at exceptions')
894
889
895 def debugger(self,force=False):
890 def debugger(self,force=False):
896 """Call the pydb/pdb debugger.
891 """Call the pydb/pdb debugger.
897
892
898 Keywords:
893 Keywords:
899
894
900 - force(False): by default, this routine checks the instance call_pdb
895 - force(False): by default, this routine checks the instance call_pdb
901 flag and does not actually invoke the debugger if the flag is false.
896 flag and does not actually invoke the debugger if the flag is false.
902 The 'force' option forces the debugger to activate even if the flag
897 The 'force' option forces the debugger to activate even if the flag
903 is false.
898 is false.
904 """
899 """
905
900
906 if not (force or self.call_pdb):
901 if not (force or self.call_pdb):
907 return
902 return
908
903
909 if not hasattr(sys,'last_traceback'):
904 if not hasattr(sys,'last_traceback'):
910 error('No traceback has been produced, nothing to debug.')
905 error('No traceback has been produced, nothing to debug.')
911 return
906 return
912
907
913 # use pydb if available
908 # use pydb if available
914 if debugger.has_pydb:
909 if debugger.has_pydb:
915 from pydb import pm
910 from pydb import pm
916 else:
911 else:
917 # fallback to our internal debugger
912 # fallback to our internal debugger
918 pm = lambda : self.InteractiveTB.debugger(force=True)
913 pm = lambda : self.InteractiveTB.debugger(force=True)
919
914
920 with self.readline_no_record:
915 with self.readline_no_record:
921 pm()
916 pm()
922
917
923 #-------------------------------------------------------------------------
918 #-------------------------------------------------------------------------
924 # Things related to IPython's various namespaces
919 # Things related to IPython's various namespaces
925 #-------------------------------------------------------------------------
920 #-------------------------------------------------------------------------
926 default_user_namespaces = True
921 default_user_namespaces = True
927
922
928 def init_create_namespaces(self, user_module=None, user_ns=None):
923 def init_create_namespaces(self, user_module=None, user_ns=None):
929 # Create the namespace where the user will operate. user_ns is
924 # Create the namespace where the user will operate. user_ns is
930 # normally the only one used, and it is passed to the exec calls as
925 # normally the only one used, and it is passed to the exec calls as
931 # the locals argument. But we do carry a user_global_ns namespace
926 # the locals argument. But we do carry a user_global_ns namespace
932 # given as the exec 'globals' argument, This is useful in embedding
927 # given as the exec 'globals' argument, This is useful in embedding
933 # situations where the ipython shell opens in a context where the
928 # situations where the ipython shell opens in a context where the
934 # distinction between locals and globals is meaningful. For
929 # distinction between locals and globals is meaningful. For
935 # non-embedded contexts, it is just the same object as the user_ns dict.
930 # non-embedded contexts, it is just the same object as the user_ns dict.
936
931
937 # FIXME. For some strange reason, __builtins__ is showing up at user
932 # FIXME. For some strange reason, __builtins__ is showing up at user
938 # level as a dict instead of a module. This is a manual fix, but I
933 # level as a dict instead of a module. This is a manual fix, but I
939 # should really track down where the problem is coming from. Alex
934 # should really track down where the problem is coming from. Alex
940 # Schmolck reported this problem first.
935 # Schmolck reported this problem first.
941
936
942 # A useful post by Alex Martelli on this topic:
937 # A useful post by Alex Martelli on this topic:
943 # Re: inconsistent value from __builtins__
938 # Re: inconsistent value from __builtins__
944 # Von: Alex Martelli <aleaxit@yahoo.com>
939 # Von: Alex Martelli <aleaxit@yahoo.com>
945 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
940 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
946 # Gruppen: comp.lang.python
941 # Gruppen: comp.lang.python
947
942
948 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
943 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
949 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
944 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
950 # > <type 'dict'>
945 # > <type 'dict'>
951 # > >>> print type(__builtins__)
946 # > >>> print type(__builtins__)
952 # > <type 'module'>
947 # > <type 'module'>
953 # > Is this difference in return value intentional?
948 # > Is this difference in return value intentional?
954
949
955 # Well, it's documented that '__builtins__' can be either a dictionary
950 # Well, it's documented that '__builtins__' can be either a dictionary
956 # or a module, and it's been that way for a long time. Whether it's
951 # or a module, and it's been that way for a long time. Whether it's
957 # intentional (or sensible), I don't know. In any case, the idea is
952 # intentional (or sensible), I don't know. In any case, the idea is
958 # that if you need to access the built-in namespace directly, you
953 # that if you need to access the built-in namespace directly, you
959 # should start with "import __builtin__" (note, no 's') which will
954 # should start with "import __builtin__" (note, no 's') which will
960 # definitely give you a module. Yeah, it's somewhat confusing:-(.
955 # definitely give you a module. Yeah, it's somewhat confusing:-(.
961
956
962 # These routines return a properly built module and dict as needed by
957 # These routines return a properly built module and dict as needed by
963 # the rest of the code, and can also be used by extension writers to
958 # the rest of the code, and can also be used by extension writers to
964 # generate properly initialized namespaces.
959 # generate properly initialized namespaces.
965 if (user_ns is not None) or (user_module is not None):
960 if (user_ns is not None) or (user_module is not None):
966 self.default_user_namespaces = False
961 self.default_user_namespaces = False
967 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
962 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
968
963
969 # A record of hidden variables we have added to the user namespace, so
964 # A record of hidden variables we have added to the user namespace, so
970 # we can list later only variables defined in actual interactive use.
965 # we can list later only variables defined in actual interactive use.
971 self.user_ns_hidden = set()
966 self.user_ns_hidden = set()
972
967
973 # Now that FakeModule produces a real module, we've run into a nasty
968 # Now that FakeModule produces a real module, we've run into a nasty
974 # problem: after script execution (via %run), the module where the user
969 # problem: after script execution (via %run), the module where the user
975 # code ran is deleted. Now that this object is a true module (needed
970 # code ran is deleted. Now that this object is a true module (needed
976 # so docetst and other tools work correctly), the Python module
971 # so docetst and other tools work correctly), the Python module
977 # teardown mechanism runs over it, and sets to None every variable
972 # teardown mechanism runs over it, and sets to None every variable
978 # present in that module. Top-level references to objects from the
973 # present in that module. Top-level references to objects from the
979 # script survive, because the user_ns is updated with them. However,
974 # script survive, because the user_ns is updated with them. However,
980 # calling functions defined in the script that use other things from
975 # calling functions defined in the script that use other things from
981 # the script will fail, because the function's closure had references
976 # the script will fail, because the function's closure had references
982 # to the original objects, which are now all None. So we must protect
977 # to the original objects, which are now all None. So we must protect
983 # these modules from deletion by keeping a cache.
978 # these modules from deletion by keeping a cache.
984 #
979 #
985 # To avoid keeping stale modules around (we only need the one from the
980 # To avoid keeping stale modules around (we only need the one from the
986 # last run), we use a dict keyed with the full path to the script, so
981 # last run), we use a dict keyed with the full path to the script, so
987 # only the last version of the module is held in the cache. Note,
982 # only the last version of the module is held in the cache. Note,
988 # however, that we must cache the module *namespace contents* (their
983 # however, that we must cache the module *namespace contents* (their
989 # __dict__). Because if we try to cache the actual modules, old ones
984 # __dict__). Because if we try to cache the actual modules, old ones
990 # (uncached) could be destroyed while still holding references (such as
985 # (uncached) could be destroyed while still holding references (such as
991 # those held by GUI objects that tend to be long-lived)>
986 # those held by GUI objects that tend to be long-lived)>
992 #
987 #
993 # The %reset command will flush this cache. See the cache_main_mod()
988 # The %reset command will flush this cache. See the cache_main_mod()
994 # and clear_main_mod_cache() methods for details on use.
989 # and clear_main_mod_cache() methods for details on use.
995
990
996 # This is the cache used for 'main' namespaces
991 # This is the cache used for 'main' namespaces
997 self._main_ns_cache = {}
992 self._main_ns_cache = {}
998 # And this is the single instance of FakeModule whose __dict__ we keep
993 # And this is the single instance of FakeModule whose __dict__ we keep
999 # copying and clearing for reuse on each %run
994 # copying and clearing for reuse on each %run
1000 self._user_main_module = FakeModule()
995 self._user_main_module = FakeModule()
1001
996
1002 # A table holding all the namespaces IPython deals with, so that
997 # A table holding all the namespaces IPython deals with, so that
1003 # introspection facilities can search easily.
998 # introspection facilities can search easily.
1004 self.ns_table = {'user_global':self.user_module.__dict__,
999 self.ns_table = {'user_global':self.user_module.__dict__,
1005 'user_local':self.user_ns,
1000 'user_local':self.user_ns,
1006 'builtin':builtin_mod.__dict__
1001 'builtin':builtin_mod.__dict__
1007 }
1002 }
1008
1003
1009 @property
1004 @property
1010 def user_global_ns(self):
1005 def user_global_ns(self):
1011 return self.user_module.__dict__
1006 return self.user_module.__dict__
1012
1007
1013 def prepare_user_module(self, user_module=None, user_ns=None):
1008 def prepare_user_module(self, user_module=None, user_ns=None):
1014 """Prepare the module and namespace in which user code will be run.
1009 """Prepare the module and namespace in which user code will be run.
1015
1010
1016 When IPython is started normally, both parameters are None: a new module
1011 When IPython is started normally, both parameters are None: a new module
1017 is created automatically, and its __dict__ used as the namespace.
1012 is created automatically, and its __dict__ used as the namespace.
1018
1013
1019 If only user_module is provided, its __dict__ is used as the namespace.
1014 If only user_module is provided, its __dict__ is used as the namespace.
1020 If only user_ns is provided, a dummy module is created, and user_ns
1015 If only user_ns is provided, a dummy module is created, and user_ns
1021 becomes the global namespace. If both are provided (as they may be
1016 becomes the global namespace. If both are provided (as they may be
1022 when embedding), user_ns is the local namespace, and user_module
1017 when embedding), user_ns is the local namespace, and user_module
1023 provides the global namespace.
1018 provides the global namespace.
1024
1019
1025 Parameters
1020 Parameters
1026 ----------
1021 ----------
1027 user_module : module, optional
1022 user_module : module, optional
1028 The current user module in which IPython is being run. If None,
1023 The current user module in which IPython is being run. If None,
1029 a clean module will be created.
1024 a clean module will be created.
1030 user_ns : dict, optional
1025 user_ns : dict, optional
1031 A namespace in which to run interactive commands.
1026 A namespace in which to run interactive commands.
1032
1027
1033 Returns
1028 Returns
1034 -------
1029 -------
1035 A tuple of user_module and user_ns, each properly initialised.
1030 A tuple of user_module and user_ns, each properly initialised.
1036 """
1031 """
1037 if user_module is None and user_ns is not None:
1032 if user_module is None and user_ns is not None:
1038 user_ns.setdefault("__name__", "__main__")
1033 user_ns.setdefault("__name__", "__main__")
1039 class DummyMod(object):
1034 class DummyMod(object):
1040 "A dummy module used for IPython's interactive namespace."
1035 "A dummy module used for IPython's interactive namespace."
1041 pass
1036 pass
1042 user_module = DummyMod()
1037 user_module = DummyMod()
1043 user_module.__dict__ = user_ns
1038 user_module.__dict__ = user_ns
1044
1039
1045 if user_module is None:
1040 if user_module is None:
1046 user_module = types.ModuleType("__main__",
1041 user_module = types.ModuleType("__main__",
1047 doc="Automatically created module for IPython interactive environment")
1042 doc="Automatically created module for IPython interactive environment")
1048
1043
1049 # We must ensure that __builtin__ (without the final 's') is always
1044 # We must ensure that __builtin__ (without the final 's') is always
1050 # available and pointing to the __builtin__ *module*. For more details:
1045 # available and pointing to the __builtin__ *module*. For more details:
1051 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1046 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1052 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1047 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1053 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1048 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1054
1049
1055 if user_ns is None:
1050 if user_ns is None:
1056 user_ns = user_module.__dict__
1051 user_ns = user_module.__dict__
1057
1052
1058 return user_module, user_ns
1053 return user_module, user_ns
1059
1054
1060 def init_sys_modules(self):
1055 def init_sys_modules(self):
1061 # We need to insert into sys.modules something that looks like a
1056 # We need to insert into sys.modules something that looks like a
1062 # module but which accesses the IPython namespace, for shelve and
1057 # module but which accesses the IPython namespace, for shelve and
1063 # pickle to work interactively. Normally they rely on getting
1058 # pickle to work interactively. Normally they rely on getting
1064 # everything out of __main__, but for embedding purposes each IPython
1059 # everything out of __main__, but for embedding purposes each IPython
1065 # instance has its own private namespace, so we can't go shoving
1060 # instance has its own private namespace, so we can't go shoving
1066 # everything into __main__.
1061 # everything into __main__.
1067
1062
1068 # note, however, that we should only do this for non-embedded
1063 # note, however, that we should only do this for non-embedded
1069 # ipythons, which really mimic the __main__.__dict__ with their own
1064 # ipythons, which really mimic the __main__.__dict__ with their own
1070 # namespace. Embedded instances, on the other hand, should not do
1065 # namespace. Embedded instances, on the other hand, should not do
1071 # this because they need to manage the user local/global namespaces
1066 # this because they need to manage the user local/global namespaces
1072 # only, but they live within a 'normal' __main__ (meaning, they
1067 # only, but they live within a 'normal' __main__ (meaning, they
1073 # shouldn't overtake the execution environment of the script they're
1068 # shouldn't overtake the execution environment of the script they're
1074 # embedded in).
1069 # embedded in).
1075
1070
1076 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1071 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1077 main_name = self.user_module.__name__
1072 main_name = self.user_module.__name__
1078 sys.modules[main_name] = self.user_module
1073 sys.modules[main_name] = self.user_module
1079
1074
1080 def init_user_ns(self):
1075 def init_user_ns(self):
1081 """Initialize all user-visible namespaces to their minimum defaults.
1076 """Initialize all user-visible namespaces to their minimum defaults.
1082
1077
1083 Certain history lists are also initialized here, as they effectively
1078 Certain history lists are also initialized here, as they effectively
1084 act as user namespaces.
1079 act as user namespaces.
1085
1080
1086 Notes
1081 Notes
1087 -----
1082 -----
1088 All data structures here are only filled in, they are NOT reset by this
1083 All data structures here are only filled in, they are NOT reset by this
1089 method. If they were not empty before, data will simply be added to
1084 method. If they were not empty before, data will simply be added to
1090 therm.
1085 therm.
1091 """
1086 """
1092 # This function works in two parts: first we put a few things in
1087 # This function works in two parts: first we put a few things in
1093 # user_ns, and we sync that contents into user_ns_hidden so that these
1088 # user_ns, and we sync that contents into user_ns_hidden so that these
1094 # initial variables aren't shown by %who. After the sync, we add the
1089 # initial variables aren't shown by %who. After the sync, we add the
1095 # rest of what we *do* want the user to see with %who even on a new
1090 # rest of what we *do* want the user to see with %who even on a new
1096 # session (probably nothing, so theye really only see their own stuff)
1091 # session (probably nothing, so theye really only see their own stuff)
1097
1092
1098 # The user dict must *always* have a __builtin__ reference to the
1093 # The user dict must *always* have a __builtin__ reference to the
1099 # Python standard __builtin__ namespace, which must be imported.
1094 # Python standard __builtin__ namespace, which must be imported.
1100 # This is so that certain operations in prompt evaluation can be
1095 # This is so that certain operations in prompt evaluation can be
1101 # reliably executed with builtins. Note that we can NOT use
1096 # reliably executed with builtins. Note that we can NOT use
1102 # __builtins__ (note the 's'), because that can either be a dict or a
1097 # __builtins__ (note the 's'), because that can either be a dict or a
1103 # module, and can even mutate at runtime, depending on the context
1098 # module, and can even mutate at runtime, depending on the context
1104 # (Python makes no guarantees on it). In contrast, __builtin__ is
1099 # (Python makes no guarantees on it). In contrast, __builtin__ is
1105 # always a module object, though it must be explicitly imported.
1100 # always a module object, though it must be explicitly imported.
1106
1101
1107 # For more details:
1102 # For more details:
1108 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1103 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1109 ns = dict()
1104 ns = dict()
1110
1105
1111 # Put 'help' in the user namespace
1106 # Put 'help' in the user namespace
1112 try:
1107 try:
1113 from site import _Helper
1108 from site import _Helper
1114 ns['help'] = _Helper()
1109 ns['help'] = _Helper()
1115 except ImportError:
1110 except ImportError:
1116 warn('help() not available - check site.py')
1111 warn('help() not available - check site.py')
1117
1112
1118 # make global variables for user access to the histories
1113 # make global variables for user access to the histories
1119 ns['_ih'] = self.history_manager.input_hist_parsed
1114 ns['_ih'] = self.history_manager.input_hist_parsed
1120 ns['_oh'] = self.history_manager.output_hist
1115 ns['_oh'] = self.history_manager.output_hist
1121 ns['_dh'] = self.history_manager.dir_hist
1116 ns['_dh'] = self.history_manager.dir_hist
1122
1117
1123 ns['_sh'] = shadowns
1118 ns['_sh'] = shadowns
1124
1119
1125 # user aliases to input and output histories. These shouldn't show up
1120 # user aliases to input and output histories. These shouldn't show up
1126 # in %who, as they can have very large reprs.
1121 # in %who, as they can have very large reprs.
1127 ns['In'] = self.history_manager.input_hist_parsed
1122 ns['In'] = self.history_manager.input_hist_parsed
1128 ns['Out'] = self.history_manager.output_hist
1123 ns['Out'] = self.history_manager.output_hist
1129
1124
1130 # Store myself as the public api!!!
1125 # Store myself as the public api!!!
1131 ns['get_ipython'] = self.get_ipython
1126 ns['get_ipython'] = self.get_ipython
1132
1127
1133 ns['exit'] = self.exiter
1128 ns['exit'] = self.exiter
1134 ns['quit'] = self.exiter
1129 ns['quit'] = self.exiter
1135
1130
1136 # Sync what we've added so far to user_ns_hidden so these aren't seen
1131 # Sync what we've added so far to user_ns_hidden so these aren't seen
1137 # by %who
1132 # by %who
1138 self.user_ns_hidden.update(ns)
1133 self.user_ns_hidden.update(ns)
1139
1134
1140 # Anything put into ns now would show up in %who. Think twice before
1135 # Anything put into ns now would show up in %who. Think twice before
1141 # putting anything here, as we really want %who to show the user their
1136 # putting anything here, as we really want %who to show the user their
1142 # stuff, not our variables.
1137 # stuff, not our variables.
1143
1138
1144 # Finally, update the real user's namespace
1139 # Finally, update the real user's namespace
1145 self.user_ns.update(ns)
1140 self.user_ns.update(ns)
1146
1141
1147 @property
1142 @property
1148 def all_ns_refs(self):
1143 def all_ns_refs(self):
1149 """Get a list of references to all the namespace dictionaries in which
1144 """Get a list of references to all the namespace dictionaries in which
1150 IPython might store a user-created object.
1145 IPython might store a user-created object.
1151
1146
1152 Note that this does not include the displayhook, which also caches
1147 Note that this does not include the displayhook, which also caches
1153 objects from the output."""
1148 objects from the output."""
1154 return [self.user_ns, self.user_global_ns,
1149 return [self.user_ns, self.user_global_ns,
1155 self._user_main_module.__dict__] + self._main_ns_cache.values()
1150 self._user_main_module.__dict__] + self._main_ns_cache.values()
1156
1151
1157 def reset(self, new_session=True):
1152 def reset(self, new_session=True):
1158 """Clear all internal namespaces, and attempt to release references to
1153 """Clear all internal namespaces, and attempt to release references to
1159 user objects.
1154 user objects.
1160
1155
1161 If new_session is True, a new history session will be opened.
1156 If new_session is True, a new history session will be opened.
1162 """
1157 """
1163 # Clear histories
1158 # Clear histories
1164 self.history_manager.reset(new_session)
1159 self.history_manager.reset(new_session)
1165 # Reset counter used to index all histories
1160 # Reset counter used to index all histories
1166 if new_session:
1161 if new_session:
1167 self.execution_count = 1
1162 self.execution_count = 1
1168
1163
1169 # Flush cached output items
1164 # Flush cached output items
1170 if self.displayhook.do_full_cache:
1165 if self.displayhook.do_full_cache:
1171 self.displayhook.flush()
1166 self.displayhook.flush()
1172
1167
1173 # The main execution namespaces must be cleared very carefully,
1168 # The main execution namespaces must be cleared very carefully,
1174 # skipping the deletion of the builtin-related keys, because doing so
1169 # skipping the deletion of the builtin-related keys, because doing so
1175 # would cause errors in many object's __del__ methods.
1170 # would cause errors in many object's __del__ methods.
1176 if self.user_ns is not self.user_global_ns:
1171 if self.user_ns is not self.user_global_ns:
1177 self.user_ns.clear()
1172 self.user_ns.clear()
1178 ns = self.user_global_ns
1173 ns = self.user_global_ns
1179 drop_keys = set(ns.keys())
1174 drop_keys = set(ns.keys())
1180 drop_keys.discard('__builtin__')
1175 drop_keys.discard('__builtin__')
1181 drop_keys.discard('__builtins__')
1176 drop_keys.discard('__builtins__')
1182 drop_keys.discard('__name__')
1177 drop_keys.discard('__name__')
1183 for k in drop_keys:
1178 for k in drop_keys:
1184 del ns[k]
1179 del ns[k]
1185
1180
1186 self.user_ns_hidden.clear()
1181 self.user_ns_hidden.clear()
1187
1182
1188 # Restore the user namespaces to minimal usability
1183 # Restore the user namespaces to minimal usability
1189 self.init_user_ns()
1184 self.init_user_ns()
1190
1185
1191 # Restore the default and user aliases
1186 # Restore the default and user aliases
1192 self.alias_manager.clear_aliases()
1187 self.alias_manager.clear_aliases()
1193 self.alias_manager.init_aliases()
1188 self.alias_manager.init_aliases()
1194
1189
1195 # Flush the private list of module references kept for script
1190 # Flush the private list of module references kept for script
1196 # execution protection
1191 # execution protection
1197 self.clear_main_mod_cache()
1192 self.clear_main_mod_cache()
1198
1193
1199 # Clear out the namespace from the last %run
1194 # Clear out the namespace from the last %run
1200 self.new_main_mod()
1195 self.new_main_mod()
1201
1196
1202 def del_var(self, varname, by_name=False):
1197 def del_var(self, varname, by_name=False):
1203 """Delete a variable from the various namespaces, so that, as
1198 """Delete a variable from the various namespaces, so that, as
1204 far as possible, we're not keeping any hidden references to it.
1199 far as possible, we're not keeping any hidden references to it.
1205
1200
1206 Parameters
1201 Parameters
1207 ----------
1202 ----------
1208 varname : str
1203 varname : str
1209 The name of the variable to delete.
1204 The name of the variable to delete.
1210 by_name : bool
1205 by_name : bool
1211 If True, delete variables with the given name in each
1206 If True, delete variables with the given name in each
1212 namespace. If False (default), find the variable in the user
1207 namespace. If False (default), find the variable in the user
1213 namespace, and delete references to it.
1208 namespace, and delete references to it.
1214 """
1209 """
1215 if varname in ('__builtin__', '__builtins__'):
1210 if varname in ('__builtin__', '__builtins__'):
1216 raise ValueError("Refusing to delete %s" % varname)
1211 raise ValueError("Refusing to delete %s" % varname)
1217
1212
1218 ns_refs = self.all_ns_refs
1213 ns_refs = self.all_ns_refs
1219
1214
1220 if by_name: # Delete by name
1215 if by_name: # Delete by name
1221 for ns in ns_refs:
1216 for ns in ns_refs:
1222 try:
1217 try:
1223 del ns[varname]
1218 del ns[varname]
1224 except KeyError:
1219 except KeyError:
1225 pass
1220 pass
1226 else: # Delete by object
1221 else: # Delete by object
1227 try:
1222 try:
1228 obj = self.user_ns[varname]
1223 obj = self.user_ns[varname]
1229 except KeyError:
1224 except KeyError:
1230 raise NameError("name '%s' is not defined" % varname)
1225 raise NameError("name '%s' is not defined" % varname)
1231 # Also check in output history
1226 # Also check in output history
1232 ns_refs.append(self.history_manager.output_hist)
1227 ns_refs.append(self.history_manager.output_hist)
1233 for ns in ns_refs:
1228 for ns in ns_refs:
1234 to_delete = [n for n, o in ns.iteritems() if o is obj]
1229 to_delete = [n for n, o in ns.iteritems() if o is obj]
1235 for name in to_delete:
1230 for name in to_delete:
1236 del ns[name]
1231 del ns[name]
1237
1232
1238 # displayhook keeps extra references, but not in a dictionary
1233 # displayhook keeps extra references, but not in a dictionary
1239 for name in ('_', '__', '___'):
1234 for name in ('_', '__', '___'):
1240 if getattr(self.displayhook, name) is obj:
1235 if getattr(self.displayhook, name) is obj:
1241 setattr(self.displayhook, name, None)
1236 setattr(self.displayhook, name, None)
1242
1237
1243 def reset_selective(self, regex=None):
1238 def reset_selective(self, regex=None):
1244 """Clear selective variables from internal namespaces based on a
1239 """Clear selective variables from internal namespaces based on a
1245 specified regular expression.
1240 specified regular expression.
1246
1241
1247 Parameters
1242 Parameters
1248 ----------
1243 ----------
1249 regex : string or compiled pattern, optional
1244 regex : string or compiled pattern, optional
1250 A regular expression pattern that will be used in searching
1245 A regular expression pattern that will be used in searching
1251 variable names in the users namespaces.
1246 variable names in the users namespaces.
1252 """
1247 """
1253 if regex is not None:
1248 if regex is not None:
1254 try:
1249 try:
1255 m = re.compile(regex)
1250 m = re.compile(regex)
1256 except TypeError:
1251 except TypeError:
1257 raise TypeError('regex must be a string or compiled pattern')
1252 raise TypeError('regex must be a string or compiled pattern')
1258 # Search for keys in each namespace that match the given regex
1253 # Search for keys in each namespace that match the given regex
1259 # If a match is found, delete the key/value pair.
1254 # If a match is found, delete the key/value pair.
1260 for ns in self.all_ns_refs:
1255 for ns in self.all_ns_refs:
1261 for var in ns:
1256 for var in ns:
1262 if m.search(var):
1257 if m.search(var):
1263 del ns[var]
1258 del ns[var]
1264
1259
1265 def push(self, variables, interactive=True):
1260 def push(self, variables, interactive=True):
1266 """Inject a group of variables into the IPython user namespace.
1261 """Inject a group of variables into the IPython user namespace.
1267
1262
1268 Parameters
1263 Parameters
1269 ----------
1264 ----------
1270 variables : dict, str or list/tuple of str
1265 variables : dict, str or list/tuple of str
1271 The variables to inject into the user's namespace. If a dict, a
1266 The variables to inject into the user's namespace. If a dict, a
1272 simple update is done. If a str, the string is assumed to have
1267 simple update is done. If a str, the string is assumed to have
1273 variable names separated by spaces. A list/tuple of str can also
1268 variable names separated by spaces. A list/tuple of str can also
1274 be used to give the variable names. If just the variable names are
1269 be used to give the variable names. If just the variable names are
1275 give (list/tuple/str) then the variable values looked up in the
1270 give (list/tuple/str) then the variable values looked up in the
1276 callers frame.
1271 callers frame.
1277 interactive : bool
1272 interactive : bool
1278 If True (default), the variables will be listed with the ``who``
1273 If True (default), the variables will be listed with the ``who``
1279 magic.
1274 magic.
1280 """
1275 """
1281 vdict = None
1276 vdict = None
1282
1277
1283 # We need a dict of name/value pairs to do namespace updates.
1278 # We need a dict of name/value pairs to do namespace updates.
1284 if isinstance(variables, dict):
1279 if isinstance(variables, dict):
1285 vdict = variables
1280 vdict = variables
1286 elif isinstance(variables, (basestring, list, tuple)):
1281 elif isinstance(variables, (basestring, list, tuple)):
1287 if isinstance(variables, basestring):
1282 if isinstance(variables, basestring):
1288 vlist = variables.split()
1283 vlist = variables.split()
1289 else:
1284 else:
1290 vlist = variables
1285 vlist = variables
1291 vdict = {}
1286 vdict = {}
1292 cf = sys._getframe(1)
1287 cf = sys._getframe(1)
1293 for name in vlist:
1288 for name in vlist:
1294 try:
1289 try:
1295 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1290 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1296 except:
1291 except:
1297 print ('Could not get variable %s from %s' %
1292 print ('Could not get variable %s from %s' %
1298 (name,cf.f_code.co_name))
1293 (name,cf.f_code.co_name))
1299 else:
1294 else:
1300 raise ValueError('variables must be a dict/str/list/tuple')
1295 raise ValueError('variables must be a dict/str/list/tuple')
1301
1296
1302 # Propagate variables to user namespace
1297 # Propagate variables to user namespace
1303 self.user_ns.update(vdict)
1298 self.user_ns.update(vdict)
1304
1299
1305 # And configure interactive visibility
1300 # And configure interactive visibility
1306 user_ns_hidden = self.user_ns_hidden
1301 user_ns_hidden = self.user_ns_hidden
1307 if interactive:
1302 if interactive:
1308 user_ns_hidden.difference_update(vdict)
1303 user_ns_hidden.difference_update(vdict)
1309 else:
1304 else:
1310 user_ns_hidden.update(vdict)
1305 user_ns_hidden.update(vdict)
1311
1306
1312 def drop_by_id(self, variables):
1307 def drop_by_id(self, variables):
1313 """Remove a dict of variables from the user namespace, if they are the
1308 """Remove a dict of variables from the user namespace, if they are the
1314 same as the values in the dictionary.
1309 same as the values in the dictionary.
1315
1310
1316 This is intended for use by extensions: variables that they've added can
1311 This is intended for use by extensions: variables that they've added can
1317 be taken back out if they are unloaded, without removing any that the
1312 be taken back out if they are unloaded, without removing any that the
1318 user has overwritten.
1313 user has overwritten.
1319
1314
1320 Parameters
1315 Parameters
1321 ----------
1316 ----------
1322 variables : dict
1317 variables : dict
1323 A dictionary mapping object names (as strings) to the objects.
1318 A dictionary mapping object names (as strings) to the objects.
1324 """
1319 """
1325 for name, obj in variables.iteritems():
1320 for name, obj in variables.iteritems():
1326 if name in self.user_ns and self.user_ns[name] is obj:
1321 if name in self.user_ns and self.user_ns[name] is obj:
1327 del self.user_ns[name]
1322 del self.user_ns[name]
1328 self.user_ns_hidden.discard(name)
1323 self.user_ns_hidden.discard(name)
1329
1324
1330 #-------------------------------------------------------------------------
1325 #-------------------------------------------------------------------------
1331 # Things related to object introspection
1326 # Things related to object introspection
1332 #-------------------------------------------------------------------------
1327 #-------------------------------------------------------------------------
1333
1328
1334 def _ofind(self, oname, namespaces=None):
1329 def _ofind(self, oname, namespaces=None):
1335 """Find an object in the available namespaces.
1330 """Find an object in the available namespaces.
1336
1331
1337 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1332 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1338
1333
1339 Has special code to detect magic functions.
1334 Has special code to detect magic functions.
1340 """
1335 """
1341 oname = oname.strip()
1336 oname = oname.strip()
1342 #print '1- oname: <%r>' % oname # dbg
1337 #print '1- oname: <%r>' % oname # dbg
1343 if not py3compat.isidentifier(oname.lstrip(ESC_MAGIC), dotted=True):
1338 if not py3compat.isidentifier(oname.lstrip(ESC_MAGIC), dotted=True):
1344 return dict(found=False)
1339 return dict(found=False)
1345
1340
1346 alias_ns = None
1341 alias_ns = None
1347 if namespaces is None:
1342 if namespaces is None:
1348 # Namespaces to search in:
1343 # Namespaces to search in:
1349 # Put them in a list. The order is important so that we
1344 # Put them in a list. The order is important so that we
1350 # find things in the same order that Python finds them.
1345 # find things in the same order that Python finds them.
1351 namespaces = [ ('Interactive', self.user_ns),
1346 namespaces = [ ('Interactive', self.user_ns),
1352 ('Interactive (global)', self.user_global_ns),
1347 ('Interactive (global)', self.user_global_ns),
1353 ('Python builtin', builtin_mod.__dict__),
1348 ('Python builtin', builtin_mod.__dict__),
1354 ('Alias', self.alias_manager.alias_table),
1349 ('Alias', self.alias_manager.alias_table),
1355 ]
1350 ]
1356 alias_ns = self.alias_manager.alias_table
1351 alias_ns = self.alias_manager.alias_table
1357
1352
1358 # initialize results to 'null'
1353 # initialize results to 'null'
1359 found = False; obj = None; ospace = None; ds = None;
1354 found = False; obj = None; ospace = None; ds = None;
1360 ismagic = False; isalias = False; parent = None
1355 ismagic = False; isalias = False; parent = None
1361
1356
1362 # We need to special-case 'print', which as of python2.6 registers as a
1357 # We need to special-case 'print', which as of python2.6 registers as a
1363 # function but should only be treated as one if print_function was
1358 # function but should only be treated as one if print_function was
1364 # loaded with a future import. In this case, just bail.
1359 # loaded with a future import. In this case, just bail.
1365 if (oname == 'print' and not py3compat.PY3 and not \
1360 if (oname == 'print' and not py3compat.PY3 and not \
1366 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1361 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1367 return {'found':found, 'obj':obj, 'namespace':ospace,
1362 return {'found':found, 'obj':obj, 'namespace':ospace,
1368 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1363 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1369
1364
1370 # Look for the given name by splitting it in parts. If the head is
1365 # Look for the given name by splitting it in parts. If the head is
1371 # found, then we look for all the remaining parts as members, and only
1366 # found, then we look for all the remaining parts as members, and only
1372 # declare success if we can find them all.
1367 # declare success if we can find them all.
1373 oname_parts = oname.split('.')
1368 oname_parts = oname.split('.')
1374 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1369 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1375 for nsname,ns in namespaces:
1370 for nsname,ns in namespaces:
1376 try:
1371 try:
1377 obj = ns[oname_head]
1372 obj = ns[oname_head]
1378 except KeyError:
1373 except KeyError:
1379 continue
1374 continue
1380 else:
1375 else:
1381 #print 'oname_rest:', oname_rest # dbg
1376 #print 'oname_rest:', oname_rest # dbg
1382 for part in oname_rest:
1377 for part in oname_rest:
1383 try:
1378 try:
1384 parent = obj
1379 parent = obj
1385 obj = getattr(obj,part)
1380 obj = getattr(obj,part)
1386 except:
1381 except:
1387 # Blanket except b/c some badly implemented objects
1382 # Blanket except b/c some badly implemented objects
1388 # allow __getattr__ to raise exceptions other than
1383 # allow __getattr__ to raise exceptions other than
1389 # AttributeError, which then crashes IPython.
1384 # AttributeError, which then crashes IPython.
1390 break
1385 break
1391 else:
1386 else:
1392 # If we finish the for loop (no break), we got all members
1387 # If we finish the for loop (no break), we got all members
1393 found = True
1388 found = True
1394 ospace = nsname
1389 ospace = nsname
1395 if ns == alias_ns:
1390 if ns == alias_ns:
1396 isalias = True
1391 isalias = True
1397 break # namespace loop
1392 break # namespace loop
1398
1393
1399 # Try to see if it's magic
1394 # Try to see if it's magic
1400 if not found:
1395 if not found:
1401 if oname.startswith(ESC_MAGIC):
1396 if oname.startswith(ESC_MAGIC):
1402 oname = oname[1:]
1397 oname = oname[1:]
1403 obj = getattr(self,'magic_'+oname,None)
1398 obj = getattr(self,'magic_'+oname,None)
1404 if obj is not None:
1399 if obj is not None:
1405 found = True
1400 found = True
1406 ospace = 'IPython internal'
1401 ospace = 'IPython internal'
1407 ismagic = True
1402 ismagic = True
1408
1403
1409 # Last try: special-case some literals like '', [], {}, etc:
1404 # Last try: special-case some literals like '', [], {}, etc:
1410 if not found and oname_head in ["''",'""','[]','{}','()']:
1405 if not found and oname_head in ["''",'""','[]','{}','()']:
1411 obj = eval(oname_head)
1406 obj = eval(oname_head)
1412 found = True
1407 found = True
1413 ospace = 'Interactive'
1408 ospace = 'Interactive'
1414
1409
1415 return {'found':found, 'obj':obj, 'namespace':ospace,
1410 return {'found':found, 'obj':obj, 'namespace':ospace,
1416 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1411 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1417
1412
1418 def _ofind_property(self, oname, info):
1413 def _ofind_property(self, oname, info):
1419 """Second part of object finding, to look for property details."""
1414 """Second part of object finding, to look for property details."""
1420 if info.found:
1415 if info.found:
1421 # Get the docstring of the class property if it exists.
1416 # Get the docstring of the class property if it exists.
1422 path = oname.split('.')
1417 path = oname.split('.')
1423 root = '.'.join(path[:-1])
1418 root = '.'.join(path[:-1])
1424 if info.parent is not None:
1419 if info.parent is not None:
1425 try:
1420 try:
1426 target = getattr(info.parent, '__class__')
1421 target = getattr(info.parent, '__class__')
1427 # The object belongs to a class instance.
1422 # The object belongs to a class instance.
1428 try:
1423 try:
1429 target = getattr(target, path[-1])
1424 target = getattr(target, path[-1])
1430 # The class defines the object.
1425 # The class defines the object.
1431 if isinstance(target, property):
1426 if isinstance(target, property):
1432 oname = root + '.__class__.' + path[-1]
1427 oname = root + '.__class__.' + path[-1]
1433 info = Struct(self._ofind(oname))
1428 info = Struct(self._ofind(oname))
1434 except AttributeError: pass
1429 except AttributeError: pass
1435 except AttributeError: pass
1430 except AttributeError: pass
1436
1431
1437 # We return either the new info or the unmodified input if the object
1432 # We return either the new info or the unmodified input if the object
1438 # hadn't been found
1433 # hadn't been found
1439 return info
1434 return info
1440
1435
1441 def _object_find(self, oname, namespaces=None):
1436 def _object_find(self, oname, namespaces=None):
1442 """Find an object and return a struct with info about it."""
1437 """Find an object and return a struct with info about it."""
1443 inf = Struct(self._ofind(oname, namespaces))
1438 inf = Struct(self._ofind(oname, namespaces))
1444 return Struct(self._ofind_property(oname, inf))
1439 return Struct(self._ofind_property(oname, inf))
1445
1440
1446 def _inspect(self, meth, oname, namespaces=None, **kw):
1441 def _inspect(self, meth, oname, namespaces=None, **kw):
1447 """Generic interface to the inspector system.
1442 """Generic interface to the inspector system.
1448
1443
1449 This function is meant to be called by pdef, pdoc & friends."""
1444 This function is meant to be called by pdef, pdoc & friends."""
1450 info = self._object_find(oname)
1445 info = self._object_find(oname)
1451 if info.found:
1446 if info.found:
1452 pmethod = getattr(self.inspector, meth)
1447 pmethod = getattr(self.inspector, meth)
1453 formatter = format_screen if info.ismagic else None
1448 formatter = format_screen if info.ismagic else None
1454 if meth == 'pdoc':
1449 if meth == 'pdoc':
1455 pmethod(info.obj, oname, formatter)
1450 pmethod(info.obj, oname, formatter)
1456 elif meth == 'pinfo':
1451 elif meth == 'pinfo':
1457 pmethod(info.obj, oname, formatter, info, **kw)
1452 pmethod(info.obj, oname, formatter, info, **kw)
1458 else:
1453 else:
1459 pmethod(info.obj, oname)
1454 pmethod(info.obj, oname)
1460 else:
1455 else:
1461 print 'Object `%s` not found.' % oname
1456 print 'Object `%s` not found.' % oname
1462 return 'not found' # so callers can take other action
1457 return 'not found' # so callers can take other action
1463
1458
1464 def object_inspect(self, oname, detail_level=0):
1459 def object_inspect(self, oname, detail_level=0):
1465 with self.builtin_trap:
1460 with self.builtin_trap:
1466 info = self._object_find(oname)
1461 info = self._object_find(oname)
1467 if info.found:
1462 if info.found:
1468 return self.inspector.info(info.obj, oname, info=info,
1463 return self.inspector.info(info.obj, oname, info=info,
1469 detail_level=detail_level
1464 detail_level=detail_level
1470 )
1465 )
1471 else:
1466 else:
1472 return oinspect.object_info(name=oname, found=False)
1467 return oinspect.object_info(name=oname, found=False)
1473
1468
1474 #-------------------------------------------------------------------------
1469 #-------------------------------------------------------------------------
1475 # Things related to history management
1470 # Things related to history management
1476 #-------------------------------------------------------------------------
1471 #-------------------------------------------------------------------------
1477
1472
1478 def init_history(self):
1473 def init_history(self):
1479 """Sets up the command history, and starts regular autosaves."""
1474 """Sets up the command history, and starts regular autosaves."""
1480 self.history_manager = HistoryManager(shell=self, config=self.config)
1475 self.history_manager = HistoryManager(shell=self, config=self.config)
1481 self.configurables.append(self.history_manager)
1476 self.configurables.append(self.history_manager)
1482
1477
1483 #-------------------------------------------------------------------------
1478 #-------------------------------------------------------------------------
1484 # Things related to exception handling and tracebacks (not debugging)
1479 # Things related to exception handling and tracebacks (not debugging)
1485 #-------------------------------------------------------------------------
1480 #-------------------------------------------------------------------------
1486
1481
1487 def init_traceback_handlers(self, custom_exceptions):
1482 def init_traceback_handlers(self, custom_exceptions):
1488 # Syntax error handler.
1483 # Syntax error handler.
1489 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1484 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1490
1485
1491 # The interactive one is initialized with an offset, meaning we always
1486 # The interactive one is initialized with an offset, meaning we always
1492 # want to remove the topmost item in the traceback, which is our own
1487 # want to remove the topmost item in the traceback, which is our own
1493 # internal code. Valid modes: ['Plain','Context','Verbose']
1488 # internal code. Valid modes: ['Plain','Context','Verbose']
1494 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1489 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1495 color_scheme='NoColor',
1490 color_scheme='NoColor',
1496 tb_offset = 1,
1491 tb_offset = 1,
1497 check_cache=self.compile.check_cache)
1492 check_cache=self.compile.check_cache)
1498
1493
1499 # The instance will store a pointer to the system-wide exception hook,
1494 # The instance will store a pointer to the system-wide exception hook,
1500 # so that runtime code (such as magics) can access it. This is because
1495 # so that runtime code (such as magics) can access it. This is because
1501 # during the read-eval loop, it may get temporarily overwritten.
1496 # during the read-eval loop, it may get temporarily overwritten.
1502 self.sys_excepthook = sys.excepthook
1497 self.sys_excepthook = sys.excepthook
1503
1498
1504 # and add any custom exception handlers the user may have specified
1499 # and add any custom exception handlers the user may have specified
1505 self.set_custom_exc(*custom_exceptions)
1500 self.set_custom_exc(*custom_exceptions)
1506
1501
1507 # Set the exception mode
1502 # Set the exception mode
1508 self.InteractiveTB.set_mode(mode=self.xmode)
1503 self.InteractiveTB.set_mode(mode=self.xmode)
1509
1504
1510 def set_custom_exc(self, exc_tuple, handler):
1505 def set_custom_exc(self, exc_tuple, handler):
1511 """set_custom_exc(exc_tuple,handler)
1506 """set_custom_exc(exc_tuple,handler)
1512
1507
1513 Set a custom exception handler, which will be called if any of the
1508 Set a custom exception handler, which will be called if any of the
1514 exceptions in exc_tuple occur in the mainloop (specifically, in the
1509 exceptions in exc_tuple occur in the mainloop (specifically, in the
1515 run_code() method).
1510 run_code() method).
1516
1511
1517 Parameters
1512 Parameters
1518 ----------
1513 ----------
1519
1514
1520 exc_tuple : tuple of exception classes
1515 exc_tuple : tuple of exception classes
1521 A *tuple* of exception classes, for which to call the defined
1516 A *tuple* of exception classes, for which to call the defined
1522 handler. It is very important that you use a tuple, and NOT A
1517 handler. It is very important that you use a tuple, and NOT A
1523 LIST here, because of the way Python's except statement works. If
1518 LIST here, because of the way Python's except statement works. If
1524 you only want to trap a single exception, use a singleton tuple::
1519 you only want to trap a single exception, use a singleton tuple::
1525
1520
1526 exc_tuple == (MyCustomException,)
1521 exc_tuple == (MyCustomException,)
1527
1522
1528 handler : callable
1523 handler : callable
1529 handler must have the following signature::
1524 handler must have the following signature::
1530
1525
1531 def my_handler(self, etype, value, tb, tb_offset=None):
1526 def my_handler(self, etype, value, tb, tb_offset=None):
1532 ...
1527 ...
1533 return structured_traceback
1528 return structured_traceback
1534
1529
1535 Your handler must return a structured traceback (a list of strings),
1530 Your handler must return a structured traceback (a list of strings),
1536 or None.
1531 or None.
1537
1532
1538 This will be made into an instance method (via types.MethodType)
1533 This will be made into an instance method (via types.MethodType)
1539 of IPython itself, and it will be called if any of the exceptions
1534 of IPython itself, and it will be called if any of the exceptions
1540 listed in the exc_tuple are caught. If the handler is None, an
1535 listed in the exc_tuple are caught. If the handler is None, an
1541 internal basic one is used, which just prints basic info.
1536 internal basic one is used, which just prints basic info.
1542
1537
1543 To protect IPython from crashes, if your handler ever raises an
1538 To protect IPython from crashes, if your handler ever raises an
1544 exception or returns an invalid result, it will be immediately
1539 exception or returns an invalid result, it will be immediately
1545 disabled.
1540 disabled.
1546
1541
1547 WARNING: by putting in your own exception handler into IPython's main
1542 WARNING: by putting in your own exception handler into IPython's main
1548 execution loop, you run a very good chance of nasty crashes. This
1543 execution loop, you run a very good chance of nasty crashes. This
1549 facility should only be used if you really know what you are doing."""
1544 facility should only be used if you really know what you are doing."""
1550
1545
1551 assert type(exc_tuple)==type(()) , \
1546 assert type(exc_tuple)==type(()) , \
1552 "The custom exceptions must be given AS A TUPLE."
1547 "The custom exceptions must be given AS A TUPLE."
1553
1548
1554 def dummy_handler(self,etype,value,tb,tb_offset=None):
1549 def dummy_handler(self,etype,value,tb,tb_offset=None):
1555 print '*** Simple custom exception handler ***'
1550 print '*** Simple custom exception handler ***'
1556 print 'Exception type :',etype
1551 print 'Exception type :',etype
1557 print 'Exception value:',value
1552 print 'Exception value:',value
1558 print 'Traceback :',tb
1553 print 'Traceback :',tb
1559 #print 'Source code :','\n'.join(self.buffer)
1554 #print 'Source code :','\n'.join(self.buffer)
1560
1555
1561 def validate_stb(stb):
1556 def validate_stb(stb):
1562 """validate structured traceback return type
1557 """validate structured traceback return type
1563
1558
1564 return type of CustomTB *should* be a list of strings, but allow
1559 return type of CustomTB *should* be a list of strings, but allow
1565 single strings or None, which are harmless.
1560 single strings or None, which are harmless.
1566
1561
1567 This function will *always* return a list of strings,
1562 This function will *always* return a list of strings,
1568 and will raise a TypeError if stb is inappropriate.
1563 and will raise a TypeError if stb is inappropriate.
1569 """
1564 """
1570 msg = "CustomTB must return list of strings, not %r" % stb
1565 msg = "CustomTB must return list of strings, not %r" % stb
1571 if stb is None:
1566 if stb is None:
1572 return []
1567 return []
1573 elif isinstance(stb, basestring):
1568 elif isinstance(stb, basestring):
1574 return [stb]
1569 return [stb]
1575 elif not isinstance(stb, list):
1570 elif not isinstance(stb, list):
1576 raise TypeError(msg)
1571 raise TypeError(msg)
1577 # it's a list
1572 # it's a list
1578 for line in stb:
1573 for line in stb:
1579 # check every element
1574 # check every element
1580 if not isinstance(line, basestring):
1575 if not isinstance(line, basestring):
1581 raise TypeError(msg)
1576 raise TypeError(msg)
1582 return stb
1577 return stb
1583
1578
1584 if handler is None:
1579 if handler is None:
1585 wrapped = dummy_handler
1580 wrapped = dummy_handler
1586 else:
1581 else:
1587 def wrapped(self,etype,value,tb,tb_offset=None):
1582 def wrapped(self,etype,value,tb,tb_offset=None):
1588 """wrap CustomTB handler, to protect IPython from user code
1583 """wrap CustomTB handler, to protect IPython from user code
1589
1584
1590 This makes it harder (but not impossible) for custom exception
1585 This makes it harder (but not impossible) for custom exception
1591 handlers to crash IPython.
1586 handlers to crash IPython.
1592 """
1587 """
1593 try:
1588 try:
1594 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1589 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1595 return validate_stb(stb)
1590 return validate_stb(stb)
1596 except:
1591 except:
1597 # clear custom handler immediately
1592 # clear custom handler immediately
1598 self.set_custom_exc((), None)
1593 self.set_custom_exc((), None)
1599 print >> io.stderr, "Custom TB Handler failed, unregistering"
1594 print >> io.stderr, "Custom TB Handler failed, unregistering"
1600 # show the exception in handler first
1595 # show the exception in handler first
1601 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1596 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1602 print >> io.stdout, self.InteractiveTB.stb2text(stb)
1597 print >> io.stdout, self.InteractiveTB.stb2text(stb)
1603 print >> io.stdout, "The original exception:"
1598 print >> io.stdout, "The original exception:"
1604 stb = self.InteractiveTB.structured_traceback(
1599 stb = self.InteractiveTB.structured_traceback(
1605 (etype,value,tb), tb_offset=tb_offset
1600 (etype,value,tb), tb_offset=tb_offset
1606 )
1601 )
1607 return stb
1602 return stb
1608
1603
1609 self.CustomTB = types.MethodType(wrapped,self)
1604 self.CustomTB = types.MethodType(wrapped,self)
1610 self.custom_exceptions = exc_tuple
1605 self.custom_exceptions = exc_tuple
1611
1606
1612 def excepthook(self, etype, value, tb):
1607 def excepthook(self, etype, value, tb):
1613 """One more defense for GUI apps that call sys.excepthook.
1608 """One more defense for GUI apps that call sys.excepthook.
1614
1609
1615 GUI frameworks like wxPython trap exceptions and call
1610 GUI frameworks like wxPython trap exceptions and call
1616 sys.excepthook themselves. I guess this is a feature that
1611 sys.excepthook themselves. I guess this is a feature that
1617 enables them to keep running after exceptions that would
1612 enables them to keep running after exceptions that would
1618 otherwise kill their mainloop. This is a bother for IPython
1613 otherwise kill their mainloop. This is a bother for IPython
1619 which excepts to catch all of the program exceptions with a try:
1614 which excepts to catch all of the program exceptions with a try:
1620 except: statement.
1615 except: statement.
1621
1616
1622 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1617 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1623 any app directly invokes sys.excepthook, it will look to the user like
1618 any app directly invokes sys.excepthook, it will look to the user like
1624 IPython crashed. In order to work around this, we can disable the
1619 IPython crashed. In order to work around this, we can disable the
1625 CrashHandler and replace it with this excepthook instead, which prints a
1620 CrashHandler and replace it with this excepthook instead, which prints a
1626 regular traceback using our InteractiveTB. In this fashion, apps which
1621 regular traceback using our InteractiveTB. In this fashion, apps which
1627 call sys.excepthook will generate a regular-looking exception from
1622 call sys.excepthook will generate a regular-looking exception from
1628 IPython, and the CrashHandler will only be triggered by real IPython
1623 IPython, and the CrashHandler will only be triggered by real IPython
1629 crashes.
1624 crashes.
1630
1625
1631 This hook should be used sparingly, only in places which are not likely
1626 This hook should be used sparingly, only in places which are not likely
1632 to be true IPython errors.
1627 to be true IPython errors.
1633 """
1628 """
1634 self.showtraceback((etype,value,tb),tb_offset=0)
1629 self.showtraceback((etype,value,tb),tb_offset=0)
1635
1630
1636 def _get_exc_info(self, exc_tuple=None):
1631 def _get_exc_info(self, exc_tuple=None):
1637 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1632 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1638
1633
1639 Ensures sys.last_type,value,traceback hold the exc_info we found,
1634 Ensures sys.last_type,value,traceback hold the exc_info we found,
1640 from whichever source.
1635 from whichever source.
1641
1636
1642 raises ValueError if none of these contain any information
1637 raises ValueError if none of these contain any information
1643 """
1638 """
1644 if exc_tuple is None:
1639 if exc_tuple is None:
1645 etype, value, tb = sys.exc_info()
1640 etype, value, tb = sys.exc_info()
1646 else:
1641 else:
1647 etype, value, tb = exc_tuple
1642 etype, value, tb = exc_tuple
1648
1643
1649 if etype is None:
1644 if etype is None:
1650 if hasattr(sys, 'last_type'):
1645 if hasattr(sys, 'last_type'):
1651 etype, value, tb = sys.last_type, sys.last_value, \
1646 etype, value, tb = sys.last_type, sys.last_value, \
1652 sys.last_traceback
1647 sys.last_traceback
1653
1648
1654 if etype is None:
1649 if etype is None:
1655 raise ValueError("No exception to find")
1650 raise ValueError("No exception to find")
1656
1651
1657 # Now store the exception info in sys.last_type etc.
1652 # Now store the exception info in sys.last_type etc.
1658 # WARNING: these variables are somewhat deprecated and not
1653 # WARNING: these variables are somewhat deprecated and not
1659 # necessarily safe to use in a threaded environment, but tools
1654 # necessarily safe to use in a threaded environment, but tools
1660 # like pdb depend on their existence, so let's set them. If we
1655 # like pdb depend on their existence, so let's set them. If we
1661 # find problems in the field, we'll need to revisit their use.
1656 # find problems in the field, we'll need to revisit their use.
1662 sys.last_type = etype
1657 sys.last_type = etype
1663 sys.last_value = value
1658 sys.last_value = value
1664 sys.last_traceback = tb
1659 sys.last_traceback = tb
1665
1660
1666 return etype, value, tb
1661 return etype, value, tb
1667
1662
1668
1663
1669 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1664 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1670 exception_only=False):
1665 exception_only=False):
1671 """Display the exception that just occurred.
1666 """Display the exception that just occurred.
1672
1667
1673 If nothing is known about the exception, this is the method which
1668 If nothing is known about the exception, this is the method which
1674 should be used throughout the code for presenting user tracebacks,
1669 should be used throughout the code for presenting user tracebacks,
1675 rather than directly invoking the InteractiveTB object.
1670 rather than directly invoking the InteractiveTB object.
1676
1671
1677 A specific showsyntaxerror() also exists, but this method can take
1672 A specific showsyntaxerror() also exists, but this method can take
1678 care of calling it if needed, so unless you are explicitly catching a
1673 care of calling it if needed, so unless you are explicitly catching a
1679 SyntaxError exception, don't try to analyze the stack manually and
1674 SyntaxError exception, don't try to analyze the stack manually and
1680 simply call this method."""
1675 simply call this method."""
1681
1676
1682 try:
1677 try:
1683 try:
1678 try:
1684 etype, value, tb = self._get_exc_info(exc_tuple)
1679 etype, value, tb = self._get_exc_info(exc_tuple)
1685 except ValueError:
1680 except ValueError:
1686 self.write_err('No traceback available to show.\n')
1681 self.write_err('No traceback available to show.\n')
1687 return
1682 return
1688
1683
1689 if etype is SyntaxError:
1684 if etype is SyntaxError:
1690 # Though this won't be called by syntax errors in the input
1685 # Though this won't be called by syntax errors in the input
1691 # line, there may be SyntaxError cases with imported code.
1686 # line, there may be SyntaxError cases with imported code.
1692 self.showsyntaxerror(filename)
1687 self.showsyntaxerror(filename)
1693 elif etype is UsageError:
1688 elif etype is UsageError:
1694 self.write_err("UsageError: %s" % value)
1689 self.write_err("UsageError: %s" % value)
1695 else:
1690 else:
1696 if etype in self.custom_exceptions:
1691 if etype in self.custom_exceptions:
1697 stb = self.CustomTB(etype, value, tb, tb_offset)
1692 stb = self.CustomTB(etype, value, tb, tb_offset)
1698 else:
1693 else:
1699 if exception_only:
1694 if exception_only:
1700 stb = ['An exception has occurred, use %tb to see '
1695 stb = ['An exception has occurred, use %tb to see '
1701 'the full traceback.\n']
1696 'the full traceback.\n']
1702 stb.extend(self.InteractiveTB.get_exception_only(etype,
1697 stb.extend(self.InteractiveTB.get_exception_only(etype,
1703 value))
1698 value))
1704 else:
1699 else:
1705 stb = self.InteractiveTB.structured_traceback(etype,
1700 stb = self.InteractiveTB.structured_traceback(etype,
1706 value, tb, tb_offset=tb_offset)
1701 value, tb, tb_offset=tb_offset)
1707
1702
1708 self._showtraceback(etype, value, stb)
1703 self._showtraceback(etype, value, stb)
1709 if self.call_pdb:
1704 if self.call_pdb:
1710 # drop into debugger
1705 # drop into debugger
1711 self.debugger(force=True)
1706 self.debugger(force=True)
1712 return
1707 return
1713
1708
1714 # Actually show the traceback
1709 # Actually show the traceback
1715 self._showtraceback(etype, value, stb)
1710 self._showtraceback(etype, value, stb)
1716
1711
1717 except KeyboardInterrupt:
1712 except KeyboardInterrupt:
1718 self.write_err("\nKeyboardInterrupt\n")
1713 self.write_err("\nKeyboardInterrupt\n")
1719
1714
1720 def _showtraceback(self, etype, evalue, stb):
1715 def _showtraceback(self, etype, evalue, stb):
1721 """Actually show a traceback.
1716 """Actually show a traceback.
1722
1717
1723 Subclasses may override this method to put the traceback on a different
1718 Subclasses may override this method to put the traceback on a different
1724 place, like a side channel.
1719 place, like a side channel.
1725 """
1720 """
1726 print >> io.stdout, self.InteractiveTB.stb2text(stb)
1721 print >> io.stdout, self.InteractiveTB.stb2text(stb)
1727
1722
1728 def showsyntaxerror(self, filename=None):
1723 def showsyntaxerror(self, filename=None):
1729 """Display the syntax error that just occurred.
1724 """Display the syntax error that just occurred.
1730
1725
1731 This doesn't display a stack trace because there isn't one.
1726 This doesn't display a stack trace because there isn't one.
1732
1727
1733 If a filename is given, it is stuffed in the exception instead
1728 If a filename is given, it is stuffed in the exception instead
1734 of what was there before (because Python's parser always uses
1729 of what was there before (because Python's parser always uses
1735 "<string>" when reading from a string).
1730 "<string>" when reading from a string).
1736 """
1731 """
1737 etype, value, last_traceback = self._get_exc_info()
1732 etype, value, last_traceback = self._get_exc_info()
1738
1733
1739 if filename and etype is SyntaxError:
1734 if filename and etype is SyntaxError:
1740 try:
1735 try:
1741 value.filename = filename
1736 value.filename = filename
1742 except:
1737 except:
1743 # Not the format we expect; leave it alone
1738 # Not the format we expect; leave it alone
1744 pass
1739 pass
1745
1740
1746 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1741 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1747 self._showtraceback(etype, value, stb)
1742 self._showtraceback(etype, value, stb)
1748
1743
1749 # This is overridden in TerminalInteractiveShell to show a message about
1744 # This is overridden in TerminalInteractiveShell to show a message about
1750 # the %paste magic.
1745 # the %paste magic.
1751 def showindentationerror(self):
1746 def showindentationerror(self):
1752 """Called by run_cell when there's an IndentationError in code entered
1747 """Called by run_cell when there's an IndentationError in code entered
1753 at the prompt.
1748 at the prompt.
1754
1749
1755 This is overridden in TerminalInteractiveShell to show a message about
1750 This is overridden in TerminalInteractiveShell to show a message about
1756 the %paste magic."""
1751 the %paste magic."""
1757 self.showsyntaxerror()
1752 self.showsyntaxerror()
1758
1753
1759 #-------------------------------------------------------------------------
1754 #-------------------------------------------------------------------------
1760 # Things related to readline
1755 # Things related to readline
1761 #-------------------------------------------------------------------------
1756 #-------------------------------------------------------------------------
1762
1757
1763 def init_readline(self):
1758 def init_readline(self):
1764 """Command history completion/saving/reloading."""
1759 """Command history completion/saving/reloading."""
1765
1760
1766 if self.readline_use:
1761 if self.readline_use:
1767 import IPython.utils.rlineimpl as readline
1762 import IPython.utils.rlineimpl as readline
1768
1763
1769 self.rl_next_input = None
1764 self.rl_next_input = None
1770 self.rl_do_indent = False
1765 self.rl_do_indent = False
1771
1766
1772 if not self.readline_use or not readline.have_readline:
1767 if not self.readline_use or not readline.have_readline:
1773 self.has_readline = False
1768 self.has_readline = False
1774 self.readline = None
1769 self.readline = None
1775 # Set a number of methods that depend on readline to be no-op
1770 # Set a number of methods that depend on readline to be no-op
1776 self.readline_no_record = no_op_context
1771 self.readline_no_record = no_op_context
1777 self.set_readline_completer = no_op
1772 self.set_readline_completer = no_op
1778 self.set_custom_completer = no_op
1773 self.set_custom_completer = no_op
1779 self.set_completer_frame = no_op
1774 self.set_completer_frame = no_op
1780 if self.readline_use:
1775 if self.readline_use:
1781 warn('Readline services not available or not loaded.')
1776 warn('Readline services not available or not loaded.')
1782 else:
1777 else:
1783 self.has_readline = True
1778 self.has_readline = True
1784 self.readline = readline
1779 self.readline = readline
1785 sys.modules['readline'] = readline
1780 sys.modules['readline'] = readline
1786
1781
1787 # Platform-specific configuration
1782 # Platform-specific configuration
1788 if os.name == 'nt':
1783 if os.name == 'nt':
1789 # FIXME - check with Frederick to see if we can harmonize
1784 # FIXME - check with Frederick to see if we can harmonize
1790 # naming conventions with pyreadline to avoid this
1785 # naming conventions with pyreadline to avoid this
1791 # platform-dependent check
1786 # platform-dependent check
1792 self.readline_startup_hook = readline.set_pre_input_hook
1787 self.readline_startup_hook = readline.set_pre_input_hook
1793 else:
1788 else:
1794 self.readline_startup_hook = readline.set_startup_hook
1789 self.readline_startup_hook = readline.set_startup_hook
1795
1790
1796 # Load user's initrc file (readline config)
1791 # Load user's initrc file (readline config)
1797 # Or if libedit is used, load editrc.
1792 # Or if libedit is used, load editrc.
1798 inputrc_name = os.environ.get('INPUTRC')
1793 inputrc_name = os.environ.get('INPUTRC')
1799 if inputrc_name is None:
1794 if inputrc_name is None:
1800 inputrc_name = '.inputrc'
1795 inputrc_name = '.inputrc'
1801 if readline.uses_libedit:
1796 if readline.uses_libedit:
1802 inputrc_name = '.editrc'
1797 inputrc_name = '.editrc'
1803 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1798 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1804 if os.path.isfile(inputrc_name):
1799 if os.path.isfile(inputrc_name):
1805 try:
1800 try:
1806 readline.read_init_file(inputrc_name)
1801 readline.read_init_file(inputrc_name)
1807 except:
1802 except:
1808 warn('Problems reading readline initialization file <%s>'
1803 warn('Problems reading readline initialization file <%s>'
1809 % inputrc_name)
1804 % inputrc_name)
1810
1805
1811 # Configure readline according to user's prefs
1806 # Configure readline according to user's prefs
1812 # This is only done if GNU readline is being used. If libedit
1807 # This is only done if GNU readline is being used. If libedit
1813 # is being used (as on Leopard) the readline config is
1808 # is being used (as on Leopard) the readline config is
1814 # not run as the syntax for libedit is different.
1809 # not run as the syntax for libedit is different.
1815 if not readline.uses_libedit:
1810 if not readline.uses_libedit:
1816 for rlcommand in self.readline_parse_and_bind:
1811 for rlcommand in self.readline_parse_and_bind:
1817 #print "loading rl:",rlcommand # dbg
1812 #print "loading rl:",rlcommand # dbg
1818 readline.parse_and_bind(rlcommand)
1813 readline.parse_and_bind(rlcommand)
1819
1814
1820 # Remove some chars from the delimiters list. If we encounter
1815 # Remove some chars from the delimiters list. If we encounter
1821 # unicode chars, discard them.
1816 # unicode chars, discard them.
1822 delims = readline.get_completer_delims()
1817 delims = readline.get_completer_delims()
1823 if not py3compat.PY3:
1818 if not py3compat.PY3:
1824 delims = delims.encode("ascii", "ignore")
1819 delims = delims.encode("ascii", "ignore")
1825 for d in self.readline_remove_delims:
1820 for d in self.readline_remove_delims:
1826 delims = delims.replace(d, "")
1821 delims = delims.replace(d, "")
1827 delims = delims.replace(ESC_MAGIC, '')
1822 delims = delims.replace(ESC_MAGIC, '')
1828 readline.set_completer_delims(delims)
1823 readline.set_completer_delims(delims)
1829 # otherwise we end up with a monster history after a while:
1824 # otherwise we end up with a monster history after a while:
1830 readline.set_history_length(self.history_length)
1825 readline.set_history_length(self.history_length)
1831
1826
1832 self.refill_readline_hist()
1827 self.refill_readline_hist()
1833 self.readline_no_record = ReadlineNoRecord(self)
1828 self.readline_no_record = ReadlineNoRecord(self)
1834
1829
1835 # Configure auto-indent for all platforms
1830 # Configure auto-indent for all platforms
1836 self.set_autoindent(self.autoindent)
1831 self.set_autoindent(self.autoindent)
1837
1832
1838 def refill_readline_hist(self):
1833 def refill_readline_hist(self):
1839 # Load the last 1000 lines from history
1834 # Load the last 1000 lines from history
1840 self.readline.clear_history()
1835 self.readline.clear_history()
1841 stdin_encoding = sys.stdin.encoding or "utf-8"
1836 stdin_encoding = sys.stdin.encoding or "utf-8"
1842 last_cell = u""
1837 last_cell = u""
1843 for _, _, cell in self.history_manager.get_tail(1000,
1838 for _, _, cell in self.history_manager.get_tail(1000,
1844 include_latest=True):
1839 include_latest=True):
1845 # Ignore blank lines and consecutive duplicates
1840 # Ignore blank lines and consecutive duplicates
1846 cell = cell.rstrip()
1841 cell = cell.rstrip()
1847 if cell and (cell != last_cell):
1842 if cell and (cell != last_cell):
1848 if self.multiline_history:
1843 if self.multiline_history:
1849 self.readline.add_history(py3compat.unicode_to_str(cell,
1844 self.readline.add_history(py3compat.unicode_to_str(cell,
1850 stdin_encoding))
1845 stdin_encoding))
1851 else:
1846 else:
1852 for line in cell.splitlines():
1847 for line in cell.splitlines():
1853 self.readline.add_history(py3compat.unicode_to_str(line,
1848 self.readline.add_history(py3compat.unicode_to_str(line,
1854 stdin_encoding))
1849 stdin_encoding))
1855 last_cell = cell
1850 last_cell = cell
1856
1851
1857 def set_next_input(self, s):
1852 def set_next_input(self, s):
1858 """ Sets the 'default' input string for the next command line.
1853 """ Sets the 'default' input string for the next command line.
1859
1854
1860 Requires readline.
1855 Requires readline.
1861
1856
1862 Example:
1857 Example:
1863
1858
1864 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1859 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1865 [D:\ipython]|2> Hello Word_ # cursor is here
1860 [D:\ipython]|2> Hello Word_ # cursor is here
1866 """
1861 """
1867 self.rl_next_input = py3compat.cast_bytes_py2(s)
1862 self.rl_next_input = py3compat.cast_bytes_py2(s)
1868
1863
1869 # Maybe move this to the terminal subclass?
1864 # Maybe move this to the terminal subclass?
1870 def pre_readline(self):
1865 def pre_readline(self):
1871 """readline hook to be used at the start of each line.
1866 """readline hook to be used at the start of each line.
1872
1867
1873 Currently it handles auto-indent only."""
1868 Currently it handles auto-indent only."""
1874
1869
1875 if self.rl_do_indent:
1870 if self.rl_do_indent:
1876 self.readline.insert_text(self._indent_current_str())
1871 self.readline.insert_text(self._indent_current_str())
1877 if self.rl_next_input is not None:
1872 if self.rl_next_input is not None:
1878 self.readline.insert_text(self.rl_next_input)
1873 self.readline.insert_text(self.rl_next_input)
1879 self.rl_next_input = None
1874 self.rl_next_input = None
1880
1875
1881 def _indent_current_str(self):
1876 def _indent_current_str(self):
1882 """return the current level of indentation as a string"""
1877 """return the current level of indentation as a string"""
1883 return self.input_splitter.indent_spaces * ' '
1878 return self.input_splitter.indent_spaces * ' '
1884
1879
1885 #-------------------------------------------------------------------------
1880 #-------------------------------------------------------------------------
1886 # Things related to text completion
1881 # Things related to text completion
1887 #-------------------------------------------------------------------------
1882 #-------------------------------------------------------------------------
1888
1883
1889 def init_completer(self):
1884 def init_completer(self):
1890 """Initialize the completion machinery.
1885 """Initialize the completion machinery.
1891
1886
1892 This creates completion machinery that can be used by client code,
1887 This creates completion machinery that can be used by client code,
1893 either interactively in-process (typically triggered by the readline
1888 either interactively in-process (typically triggered by the readline
1894 library), programatically (such as in test suites) or out-of-prcess
1889 library), programatically (such as in test suites) or out-of-prcess
1895 (typically over the network by remote frontends).
1890 (typically over the network by remote frontends).
1896 """
1891 """
1897 from IPython.core.completer import IPCompleter
1892 from IPython.core.completer import IPCompleter
1898 from IPython.core.completerlib import (module_completer,
1893 from IPython.core.completerlib import (module_completer,
1899 magic_run_completer, cd_completer, reset_completer)
1894 magic_run_completer, cd_completer, reset_completer)
1900
1895
1901 self.Completer = IPCompleter(shell=self,
1896 self.Completer = IPCompleter(shell=self,
1902 namespace=self.user_ns,
1897 namespace=self.user_ns,
1903 global_namespace=self.user_global_ns,
1898 global_namespace=self.user_global_ns,
1904 alias_table=self.alias_manager.alias_table,
1899 alias_table=self.alias_manager.alias_table,
1905 use_readline=self.has_readline,
1900 use_readline=self.has_readline,
1906 config=self.config,
1901 config=self.config,
1907 )
1902 )
1908 self.configurables.append(self.Completer)
1903 self.configurables.append(self.Completer)
1909
1904
1910 # Add custom completers to the basic ones built into IPCompleter
1905 # Add custom completers to the basic ones built into IPCompleter
1911 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1906 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1912 self.strdispatchers['complete_command'] = sdisp
1907 self.strdispatchers['complete_command'] = sdisp
1913 self.Completer.custom_completers = sdisp
1908 self.Completer.custom_completers = sdisp
1914
1909
1915 self.set_hook('complete_command', module_completer, str_key = 'import')
1910 self.set_hook('complete_command', module_completer, str_key = 'import')
1916 self.set_hook('complete_command', module_completer, str_key = 'from')
1911 self.set_hook('complete_command', module_completer, str_key = 'from')
1917 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1912 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1918 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1913 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1919 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1914 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1920
1915
1921 # Only configure readline if we truly are using readline. IPython can
1916 # Only configure readline if we truly are using readline. IPython can
1922 # do tab-completion over the network, in GUIs, etc, where readline
1917 # do tab-completion over the network, in GUIs, etc, where readline
1923 # itself may be absent
1918 # itself may be absent
1924 if self.has_readline:
1919 if self.has_readline:
1925 self.set_readline_completer()
1920 self.set_readline_completer()
1926
1921
1927 def complete(self, text, line=None, cursor_pos=None):
1922 def complete(self, text, line=None, cursor_pos=None):
1928 """Return the completed text and a list of completions.
1923 """Return the completed text and a list of completions.
1929
1924
1930 Parameters
1925 Parameters
1931 ----------
1926 ----------
1932
1927
1933 text : string
1928 text : string
1934 A string of text to be completed on. It can be given as empty and
1929 A string of text to be completed on. It can be given as empty and
1935 instead a line/position pair are given. In this case, the
1930 instead a line/position pair are given. In this case, the
1936 completer itself will split the line like readline does.
1931 completer itself will split the line like readline does.
1937
1932
1938 line : string, optional
1933 line : string, optional
1939 The complete line that text is part of.
1934 The complete line that text is part of.
1940
1935
1941 cursor_pos : int, optional
1936 cursor_pos : int, optional
1942 The position of the cursor on the input line.
1937 The position of the cursor on the input line.
1943
1938
1944 Returns
1939 Returns
1945 -------
1940 -------
1946 text : string
1941 text : string
1947 The actual text that was completed.
1942 The actual text that was completed.
1948
1943
1949 matches : list
1944 matches : list
1950 A sorted list with all possible completions.
1945 A sorted list with all possible completions.
1951
1946
1952 The optional arguments allow the completion to take more context into
1947 The optional arguments allow the completion to take more context into
1953 account, and are part of the low-level completion API.
1948 account, and are part of the low-level completion API.
1954
1949
1955 This is a wrapper around the completion mechanism, similar to what
1950 This is a wrapper around the completion mechanism, similar to what
1956 readline does at the command line when the TAB key is hit. By
1951 readline does at the command line when the TAB key is hit. By
1957 exposing it as a method, it can be used by other non-readline
1952 exposing it as a method, it can be used by other non-readline
1958 environments (such as GUIs) for text completion.
1953 environments (such as GUIs) for text completion.
1959
1954
1960 Simple usage example:
1955 Simple usage example:
1961
1956
1962 In [1]: x = 'hello'
1957 In [1]: x = 'hello'
1963
1958
1964 In [2]: _ip.complete('x.l')
1959 In [2]: _ip.complete('x.l')
1965 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1960 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1966 """
1961 """
1967
1962
1968 # Inject names into __builtin__ so we can complete on the added names.
1963 # Inject names into __builtin__ so we can complete on the added names.
1969 with self.builtin_trap:
1964 with self.builtin_trap:
1970 return self.Completer.complete(text, line, cursor_pos)
1965 return self.Completer.complete(text, line, cursor_pos)
1971
1966
1972 def set_custom_completer(self, completer, pos=0):
1967 def set_custom_completer(self, completer, pos=0):
1973 """Adds a new custom completer function.
1968 """Adds a new custom completer function.
1974
1969
1975 The position argument (defaults to 0) is the index in the completers
1970 The position argument (defaults to 0) is the index in the completers
1976 list where you want the completer to be inserted."""
1971 list where you want the completer to be inserted."""
1977
1972
1978 newcomp = types.MethodType(completer,self.Completer)
1973 newcomp = types.MethodType(completer,self.Completer)
1979 self.Completer.matchers.insert(pos,newcomp)
1974 self.Completer.matchers.insert(pos,newcomp)
1980
1975
1981 def set_readline_completer(self):
1976 def set_readline_completer(self):
1982 """Reset readline's completer to be our own."""
1977 """Reset readline's completer to be our own."""
1983 self.readline.set_completer(self.Completer.rlcomplete)
1978 self.readline.set_completer(self.Completer.rlcomplete)
1984
1979
1985 def set_completer_frame(self, frame=None):
1980 def set_completer_frame(self, frame=None):
1986 """Set the frame of the completer."""
1981 """Set the frame of the completer."""
1987 if frame:
1982 if frame:
1988 self.Completer.namespace = frame.f_locals
1983 self.Completer.namespace = frame.f_locals
1989 self.Completer.global_namespace = frame.f_globals
1984 self.Completer.global_namespace = frame.f_globals
1990 else:
1985 else:
1991 self.Completer.namespace = self.user_ns
1986 self.Completer.namespace = self.user_ns
1992 self.Completer.global_namespace = self.user_global_ns
1987 self.Completer.global_namespace = self.user_global_ns
1993
1988
1994 #-------------------------------------------------------------------------
1989 #-------------------------------------------------------------------------
1995 # Things related to magics
1990 # Things related to magics
1996 #-------------------------------------------------------------------------
1991 #-------------------------------------------------------------------------
1997
1992
1998 def init_magics(self):
1993 def init_magics(self):
1999 # FIXME: Move the color initialization to the DisplayHook, which
1994 # FIXME: Move the color initialization to the DisplayHook, which
2000 # should be split into a prompt manager and displayhook. We probably
1995 # should be split into a prompt manager and displayhook. We probably
2001 # even need a centralize colors management object.
1996 # even need a centralize colors management object.
2002 self.magic_colors(self.colors)
1997 self.magic_colors(self.colors)
2003 # History was moved to a separate module
1998 # History was moved to a separate module
2004 from IPython.core import history
1999 from IPython.core import history
2005 history.init_ipython(self)
2000 history.init_ipython(self)
2006
2001
2007 def magic(self, arg_s, next_input=None):
2002 def magic(self, arg_s, next_input=None):
2008 """Call a magic function by name.
2003 """Call a magic function by name.
2009
2004
2010 Input: a string containing the name of the magic function to call and
2005 Input: a string containing the name of the magic function to call and
2011 any additional arguments to be passed to the magic.
2006 any additional arguments to be passed to the magic.
2012
2007
2013 magic('name -opt foo bar') is equivalent to typing at the ipython
2008 magic('name -opt foo bar') is equivalent to typing at the ipython
2014 prompt:
2009 prompt:
2015
2010
2016 In[1]: %name -opt foo bar
2011 In[1]: %name -opt foo bar
2017
2012
2018 To call a magic without arguments, simply use magic('name').
2013 To call a magic without arguments, simply use magic('name').
2019
2014
2020 This provides a proper Python function to call IPython's magics in any
2015 This provides a proper Python function to call IPython's magics in any
2021 valid Python code you can type at the interpreter, including loops and
2016 valid Python code you can type at the interpreter, including loops and
2022 compound statements.
2017 compound statements.
2023 """
2018 """
2024 # Allow setting the next input - this is used if the user does `a=abs?`.
2019 # Allow setting the next input - this is used if the user does `a=abs?`.
2025 # We do this first so that magic functions can override it.
2020 # We do this first so that magic functions can override it.
2026 if next_input:
2021 if next_input:
2027 self.set_next_input(next_input)
2022 self.set_next_input(next_input)
2028
2023
2029 magic_name, _, magic_args = arg_s.partition(' ')
2024 magic_name, _, magic_args = arg_s.partition(' ')
2030 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2025 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2031
2026
2032 fn = getattr(self,'magic_'+magic_name,None)
2027 fn = getattr(self,'magic_'+magic_name,None)
2033 if fn is None:
2028 if fn is None:
2034 error("Magic function `%s` not found." % magic_name)
2029 error("Magic function `%s` not found." % magic_name)
2035 else:
2030 else:
2036 magic_args = self.var_expand(magic_args,1)
2031 magic_args = self.var_expand(magic_args,1)
2037 # Grab local namespace if we need it:
2032 # Grab local namespace if we need it:
2038 if getattr(fn, "needs_local_scope", False):
2033 if getattr(fn, "needs_local_scope", False):
2039 self._magic_locals = sys._getframe(1).f_locals
2034 self._magic_locals = sys._getframe(1).f_locals
2040 with self.builtin_trap:
2035 with self.builtin_trap:
2041 result = fn(magic_args)
2036 result = fn(magic_args)
2042 # Ensure we're not keeping object references around:
2037 # Ensure we're not keeping object references around:
2043 self._magic_locals = {}
2038 self._magic_locals = {}
2044 return result
2039 return result
2045
2040
2046 def define_magic(self, magicname, func):
2041 def define_magic(self, magicname, func):
2047 """Expose own function as magic function for ipython
2042 """Expose own function as magic function for ipython
2048
2043
2049 Example::
2044 Example::
2050
2045
2051 def foo_impl(self,parameter_s=''):
2046 def foo_impl(self,parameter_s=''):
2052 'My very own magic!. (Use docstrings, IPython reads them).'
2047 'My very own magic!. (Use docstrings, IPython reads them).'
2053 print 'Magic function. Passed parameter is between < >:'
2048 print 'Magic function. Passed parameter is between < >:'
2054 print '<%s>' % parameter_s
2049 print '<%s>' % parameter_s
2055 print 'The self object is:', self
2050 print 'The self object is:', self
2056
2051
2057 ip.define_magic('foo',foo_impl)
2052 ip.define_magic('foo',foo_impl)
2058 """
2053 """
2059 im = types.MethodType(func,self)
2054 im = types.MethodType(func,self)
2060 old = getattr(self, "magic_" + magicname, None)
2055 old = getattr(self, "magic_" + magicname, None)
2061 setattr(self, "magic_" + magicname, im)
2056 setattr(self, "magic_" + magicname, im)
2062 return old
2057 return old
2063
2058
2064 #-------------------------------------------------------------------------
2059 #-------------------------------------------------------------------------
2065 # Things related to macros
2060 # Things related to macros
2066 #-------------------------------------------------------------------------
2061 #-------------------------------------------------------------------------
2067
2062
2068 def define_macro(self, name, themacro):
2063 def define_macro(self, name, themacro):
2069 """Define a new macro
2064 """Define a new macro
2070
2065
2071 Parameters
2066 Parameters
2072 ----------
2067 ----------
2073 name : str
2068 name : str
2074 The name of the macro.
2069 The name of the macro.
2075 themacro : str or Macro
2070 themacro : str or Macro
2076 The action to do upon invoking the macro. If a string, a new
2071 The action to do upon invoking the macro. If a string, a new
2077 Macro object is created by passing the string to it.
2072 Macro object is created by passing the string to it.
2078 """
2073 """
2079
2074
2080 from IPython.core import macro
2075 from IPython.core import macro
2081
2076
2082 if isinstance(themacro, basestring):
2077 if isinstance(themacro, basestring):
2083 themacro = macro.Macro(themacro)
2078 themacro = macro.Macro(themacro)
2084 if not isinstance(themacro, macro.Macro):
2079 if not isinstance(themacro, macro.Macro):
2085 raise ValueError('A macro must be a string or a Macro instance.')
2080 raise ValueError('A macro must be a string or a Macro instance.')
2086 self.user_ns[name] = themacro
2081 self.user_ns[name] = themacro
2087
2082
2088 #-------------------------------------------------------------------------
2083 #-------------------------------------------------------------------------
2089 # Things related to the running of system commands
2084 # Things related to the running of system commands
2090 #-------------------------------------------------------------------------
2085 #-------------------------------------------------------------------------
2091
2086
2092 def system_piped(self, cmd):
2087 def system_piped(self, cmd):
2093 """Call the given cmd in a subprocess, piping stdout/err
2088 """Call the given cmd in a subprocess, piping stdout/err
2094
2089
2095 Parameters
2090 Parameters
2096 ----------
2091 ----------
2097 cmd : str
2092 cmd : str
2098 Command to execute (can not end in '&', as background processes are
2093 Command to execute (can not end in '&', as background processes are
2099 not supported. Should not be a command that expects input
2094 not supported. Should not be a command that expects input
2100 other than simple text.
2095 other than simple text.
2101 """
2096 """
2102 if cmd.rstrip().endswith('&'):
2097 if cmd.rstrip().endswith('&'):
2103 # this is *far* from a rigorous test
2098 # this is *far* from a rigorous test
2104 # We do not support backgrounding processes because we either use
2099 # We do not support backgrounding processes because we either use
2105 # pexpect or pipes to read from. Users can always just call
2100 # pexpect or pipes to read from. Users can always just call
2106 # os.system() or use ip.system=ip.system_raw
2101 # os.system() or use ip.system=ip.system_raw
2107 # if they really want a background process.
2102 # if they really want a background process.
2108 raise OSError("Background processes not supported.")
2103 raise OSError("Background processes not supported.")
2109
2104
2110 # we explicitly do NOT return the subprocess status code, because
2105 # we explicitly do NOT return the subprocess status code, because
2111 # a non-None value would trigger :func:`sys.displayhook` calls.
2106 # a non-None value would trigger :func:`sys.displayhook` calls.
2112 # Instead, we store the exit_code in user_ns.
2107 # Instead, we store the exit_code in user_ns.
2113 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=2))
2108 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=2))
2114
2109
2115 def system_raw(self, cmd):
2110 def system_raw(self, cmd):
2116 """Call the given cmd in a subprocess using os.system
2111 """Call the given cmd in a subprocess using os.system
2117
2112
2118 Parameters
2113 Parameters
2119 ----------
2114 ----------
2120 cmd : str
2115 cmd : str
2121 Command to execute.
2116 Command to execute.
2122 """
2117 """
2123 cmd = self.var_expand(cmd, depth=2)
2118 cmd = self.var_expand(cmd, depth=2)
2124 # protect os.system from UNC paths on Windows, which it can't handle:
2119 # protect os.system from UNC paths on Windows, which it can't handle:
2125 if sys.platform == 'win32':
2120 if sys.platform == 'win32':
2126 from IPython.utils._process_win32 import AvoidUNCPath
2121 from IPython.utils._process_win32 import AvoidUNCPath
2127 with AvoidUNCPath() as path:
2122 with AvoidUNCPath() as path:
2128 if path is not None:
2123 if path is not None:
2129 cmd = '"pushd %s &&"%s' % (path, cmd)
2124 cmd = '"pushd %s &&"%s' % (path, cmd)
2130 cmd = py3compat.unicode_to_str(cmd)
2125 cmd = py3compat.unicode_to_str(cmd)
2131 ec = os.system(cmd)
2126 ec = os.system(cmd)
2132 else:
2127 else:
2133 cmd = py3compat.unicode_to_str(cmd)
2128 cmd = py3compat.unicode_to_str(cmd)
2134 ec = os.system(cmd)
2129 ec = os.system(cmd)
2135
2130
2136 # We explicitly do NOT return the subprocess status code, because
2131 # We explicitly do NOT return the subprocess status code, because
2137 # a non-None value would trigger :func:`sys.displayhook` calls.
2132 # a non-None value would trigger :func:`sys.displayhook` calls.
2138 # Instead, we store the exit_code in user_ns.
2133 # Instead, we store the exit_code in user_ns.
2139 self.user_ns['_exit_code'] = ec
2134 self.user_ns['_exit_code'] = ec
2140
2135
2141 # use piped system by default, because it is better behaved
2136 # use piped system by default, because it is better behaved
2142 system = system_piped
2137 system = system_piped
2143
2138
2144 def getoutput(self, cmd, split=True):
2139 def getoutput(self, cmd, split=True):
2145 """Get output (possibly including stderr) from a subprocess.
2140 """Get output (possibly including stderr) from a subprocess.
2146
2141
2147 Parameters
2142 Parameters
2148 ----------
2143 ----------
2149 cmd : str
2144 cmd : str
2150 Command to execute (can not end in '&', as background processes are
2145 Command to execute (can not end in '&', as background processes are
2151 not supported.
2146 not supported.
2152 split : bool, optional
2147 split : bool, optional
2153
2148
2154 If True, split the output into an IPython SList. Otherwise, an
2149 If True, split the output into an IPython SList. Otherwise, an
2155 IPython LSString is returned. These are objects similar to normal
2150 IPython LSString is returned. These are objects similar to normal
2156 lists and strings, with a few convenience attributes for easier
2151 lists and strings, with a few convenience attributes for easier
2157 manipulation of line-based output. You can use '?' on them for
2152 manipulation of line-based output. You can use '?' on them for
2158 details.
2153 details.
2159 """
2154 """
2160 if cmd.rstrip().endswith('&'):
2155 if cmd.rstrip().endswith('&'):
2161 # this is *far* from a rigorous test
2156 # this is *far* from a rigorous test
2162 raise OSError("Background processes not supported.")
2157 raise OSError("Background processes not supported.")
2163 out = getoutput(self.var_expand(cmd, depth=2))
2158 out = getoutput(self.var_expand(cmd, depth=2))
2164 if split:
2159 if split:
2165 out = SList(out.splitlines())
2160 out = SList(out.splitlines())
2166 else:
2161 else:
2167 out = LSString(out)
2162 out = LSString(out)
2168 return out
2163 return out
2169
2164
2170 #-------------------------------------------------------------------------
2165 #-------------------------------------------------------------------------
2171 # Things related to aliases
2166 # Things related to aliases
2172 #-------------------------------------------------------------------------
2167 #-------------------------------------------------------------------------
2173
2168
2174 def init_alias(self):
2169 def init_alias(self):
2175 self.alias_manager = AliasManager(shell=self, config=self.config)
2170 self.alias_manager = AliasManager(shell=self, config=self.config)
2176 self.configurables.append(self.alias_manager)
2171 self.configurables.append(self.alias_manager)
2177 self.ns_table['alias'] = self.alias_manager.alias_table,
2172 self.ns_table['alias'] = self.alias_manager.alias_table,
2178
2173
2179 #-------------------------------------------------------------------------
2174 #-------------------------------------------------------------------------
2180 # Things related to extensions and plugins
2175 # Things related to extensions and plugins
2181 #-------------------------------------------------------------------------
2176 #-------------------------------------------------------------------------
2182
2177
2183 def init_extension_manager(self):
2178 def init_extension_manager(self):
2184 self.extension_manager = ExtensionManager(shell=self, config=self.config)
2179 self.extension_manager = ExtensionManager(shell=self, config=self.config)
2185 self.configurables.append(self.extension_manager)
2180 self.configurables.append(self.extension_manager)
2186
2181
2187 def init_plugin_manager(self):
2182 def init_plugin_manager(self):
2188 self.plugin_manager = PluginManager(config=self.config)
2183 self.plugin_manager = PluginManager(config=self.config)
2189 self.configurables.append(self.plugin_manager)
2184 self.configurables.append(self.plugin_manager)
2190
2185
2191
2186
2192 #-------------------------------------------------------------------------
2187 #-------------------------------------------------------------------------
2193 # Things related to payloads
2188 # Things related to payloads
2194 #-------------------------------------------------------------------------
2189 #-------------------------------------------------------------------------
2195
2190
2196 def init_payload(self):
2191 def init_payload(self):
2197 self.payload_manager = PayloadManager(config=self.config)
2192 self.payload_manager = PayloadManager(config=self.config)
2198 self.configurables.append(self.payload_manager)
2193 self.configurables.append(self.payload_manager)
2199
2194
2200 #-------------------------------------------------------------------------
2195 #-------------------------------------------------------------------------
2201 # Things related to the prefilter
2196 # Things related to the prefilter
2202 #-------------------------------------------------------------------------
2197 #-------------------------------------------------------------------------
2203
2198
2204 def init_prefilter(self):
2199 def init_prefilter(self):
2205 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
2200 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
2206 self.configurables.append(self.prefilter_manager)
2201 self.configurables.append(self.prefilter_manager)
2207 # Ultimately this will be refactored in the new interpreter code, but
2202 # Ultimately this will be refactored in the new interpreter code, but
2208 # for now, we should expose the main prefilter method (there's legacy
2203 # for now, we should expose the main prefilter method (there's legacy
2209 # code out there that may rely on this).
2204 # code out there that may rely on this).
2210 self.prefilter = self.prefilter_manager.prefilter_lines
2205 self.prefilter = self.prefilter_manager.prefilter_lines
2211
2206
2212 def auto_rewrite_input(self, cmd):
2207 def auto_rewrite_input(self, cmd):
2213 """Print to the screen the rewritten form of the user's command.
2208 """Print to the screen the rewritten form of the user's command.
2214
2209
2215 This shows visual feedback by rewriting input lines that cause
2210 This shows visual feedback by rewriting input lines that cause
2216 automatic calling to kick in, like::
2211 automatic calling to kick in, like::
2217
2212
2218 /f x
2213 /f x
2219
2214
2220 into::
2215 into::
2221
2216
2222 ------> f(x)
2217 ------> f(x)
2223
2218
2224 after the user's input prompt. This helps the user understand that the
2219 after the user's input prompt. This helps the user understand that the
2225 input line was transformed automatically by IPython.
2220 input line was transformed automatically by IPython.
2226 """
2221 """
2227 if not self.show_rewritten_input:
2222 if not self.show_rewritten_input:
2228 return
2223 return
2229
2224
2230 rw = self.prompt_manager.render('rewrite') + cmd
2225 rw = self.prompt_manager.render('rewrite') + cmd
2231
2226
2232 try:
2227 try:
2233 # plain ascii works better w/ pyreadline, on some machines, so
2228 # plain ascii works better w/ pyreadline, on some machines, so
2234 # we use it and only print uncolored rewrite if we have unicode
2229 # we use it and only print uncolored rewrite if we have unicode
2235 rw = str(rw)
2230 rw = str(rw)
2236 print >> io.stdout, rw
2231 print >> io.stdout, rw
2237 except UnicodeEncodeError:
2232 except UnicodeEncodeError:
2238 print "------> " + cmd
2233 print "------> " + cmd
2239
2234
2240 #-------------------------------------------------------------------------
2235 #-------------------------------------------------------------------------
2241 # Things related to extracting values/expressions from kernel and user_ns
2236 # Things related to extracting values/expressions from kernel and user_ns
2242 #-------------------------------------------------------------------------
2237 #-------------------------------------------------------------------------
2243
2238
2244 def _simple_error(self):
2239 def _simple_error(self):
2245 etype, value = sys.exc_info()[:2]
2240 etype, value = sys.exc_info()[:2]
2246 return u'[ERROR] {e.__name__}: {v}'.format(e=etype, v=value)
2241 return u'[ERROR] {e.__name__}: {v}'.format(e=etype, v=value)
2247
2242
2248 def user_variables(self, names):
2243 def user_variables(self, names):
2249 """Get a list of variable names from the user's namespace.
2244 """Get a list of variable names from the user's namespace.
2250
2245
2251 Parameters
2246 Parameters
2252 ----------
2247 ----------
2253 names : list of strings
2248 names : list of strings
2254 A list of names of variables to be read from the user namespace.
2249 A list of names of variables to be read from the user namespace.
2255
2250
2256 Returns
2251 Returns
2257 -------
2252 -------
2258 A dict, keyed by the input names and with the repr() of each value.
2253 A dict, keyed by the input names and with the repr() of each value.
2259 """
2254 """
2260 out = {}
2255 out = {}
2261 user_ns = self.user_ns
2256 user_ns = self.user_ns
2262 for varname in names:
2257 for varname in names:
2263 try:
2258 try:
2264 value = repr(user_ns[varname])
2259 value = repr(user_ns[varname])
2265 except:
2260 except:
2266 value = self._simple_error()
2261 value = self._simple_error()
2267 out[varname] = value
2262 out[varname] = value
2268 return out
2263 return out
2269
2264
2270 def user_expressions(self, expressions):
2265 def user_expressions(self, expressions):
2271 """Evaluate a dict of expressions in the user's namespace.
2266 """Evaluate a dict of expressions in the user's namespace.
2272
2267
2273 Parameters
2268 Parameters
2274 ----------
2269 ----------
2275 expressions : dict
2270 expressions : dict
2276 A dict with string keys and string values. The expression values
2271 A dict with string keys and string values. The expression values
2277 should be valid Python expressions, each of which will be evaluated
2272 should be valid Python expressions, each of which will be evaluated
2278 in the user namespace.
2273 in the user namespace.
2279
2274
2280 Returns
2275 Returns
2281 -------
2276 -------
2282 A dict, keyed like the input expressions dict, with the repr() of each
2277 A dict, keyed like the input expressions dict, with the repr() of each
2283 value.
2278 value.
2284 """
2279 """
2285 out = {}
2280 out = {}
2286 user_ns = self.user_ns
2281 user_ns = self.user_ns
2287 global_ns = self.user_global_ns
2282 global_ns = self.user_global_ns
2288 for key, expr in expressions.iteritems():
2283 for key, expr in expressions.iteritems():
2289 try:
2284 try:
2290 value = repr(eval(expr, global_ns, user_ns))
2285 value = repr(eval(expr, global_ns, user_ns))
2291 except:
2286 except:
2292 value = self._simple_error()
2287 value = self._simple_error()
2293 out[key] = value
2288 out[key] = value
2294 return out
2289 return out
2295
2290
2296 #-------------------------------------------------------------------------
2291 #-------------------------------------------------------------------------
2297 # Things related to the running of code
2292 # Things related to the running of code
2298 #-------------------------------------------------------------------------
2293 #-------------------------------------------------------------------------
2299
2294
2300 def ex(self, cmd):
2295 def ex(self, cmd):
2301 """Execute a normal python statement in user namespace."""
2296 """Execute a normal python statement in user namespace."""
2302 with self.builtin_trap:
2297 with self.builtin_trap:
2303 exec cmd in self.user_global_ns, self.user_ns
2298 exec cmd in self.user_global_ns, self.user_ns
2304
2299
2305 def ev(self, expr):
2300 def ev(self, expr):
2306 """Evaluate python expression expr in user namespace.
2301 """Evaluate python expression expr in user namespace.
2307
2302
2308 Returns the result of evaluation
2303 Returns the result of evaluation
2309 """
2304 """
2310 with self.builtin_trap:
2305 with self.builtin_trap:
2311 return eval(expr, self.user_global_ns, self.user_ns)
2306 return eval(expr, self.user_global_ns, self.user_ns)
2312
2307
2313 def safe_execfile(self, fname, *where, **kw):
2308 def safe_execfile(self, fname, *where, **kw):
2314 """A safe version of the builtin execfile().
2309 """A safe version of the builtin execfile().
2315
2310
2316 This version will never throw an exception, but instead print
2311 This version will never throw an exception, but instead print
2317 helpful error messages to the screen. This only works on pure
2312 helpful error messages to the screen. This only works on pure
2318 Python files with the .py extension.
2313 Python files with the .py extension.
2319
2314
2320 Parameters
2315 Parameters
2321 ----------
2316 ----------
2322 fname : string
2317 fname : string
2323 The name of the file to be executed.
2318 The name of the file to be executed.
2324 where : tuple
2319 where : tuple
2325 One or two namespaces, passed to execfile() as (globals,locals).
2320 One or two namespaces, passed to execfile() as (globals,locals).
2326 If only one is given, it is passed as both.
2321 If only one is given, it is passed as both.
2327 exit_ignore : bool (False)
2322 exit_ignore : bool (False)
2328 If True, then silence SystemExit for non-zero status (it is always
2323 If True, then silence SystemExit for non-zero status (it is always
2329 silenced for zero status, as it is so common).
2324 silenced for zero status, as it is so common).
2330 raise_exceptions : bool (False)
2325 raise_exceptions : bool (False)
2331 If True raise exceptions everywhere. Meant for testing.
2326 If True raise exceptions everywhere. Meant for testing.
2332
2327
2333 """
2328 """
2334 kw.setdefault('exit_ignore', False)
2329 kw.setdefault('exit_ignore', False)
2335 kw.setdefault('raise_exceptions', False)
2330 kw.setdefault('raise_exceptions', False)
2336
2331
2337 fname = os.path.abspath(os.path.expanduser(fname))
2332 fname = os.path.abspath(os.path.expanduser(fname))
2338
2333
2339 # Make sure we can open the file
2334 # Make sure we can open the file
2340 try:
2335 try:
2341 with open(fname) as thefile:
2336 with open(fname) as thefile:
2342 pass
2337 pass
2343 except:
2338 except:
2344 warn('Could not open file <%s> for safe execution.' % fname)
2339 warn('Could not open file <%s> for safe execution.' % fname)
2345 return
2340 return
2346
2341
2347 # Find things also in current directory. This is needed to mimic the
2342 # Find things also in current directory. This is needed to mimic the
2348 # behavior of running a script from the system command line, where
2343 # behavior of running a script from the system command line, where
2349 # Python inserts the script's directory into sys.path
2344 # Python inserts the script's directory into sys.path
2350 dname = os.path.dirname(fname)
2345 dname = os.path.dirname(fname)
2351
2346
2352 with prepended_to_syspath(dname):
2347 with prepended_to_syspath(dname):
2353 try:
2348 try:
2354 py3compat.execfile(fname,*where)
2349 py3compat.execfile(fname,*where)
2355 except SystemExit, status:
2350 except SystemExit, status:
2356 # If the call was made with 0 or None exit status (sys.exit(0)
2351 # If the call was made with 0 or None exit status (sys.exit(0)
2357 # or sys.exit() ), don't bother showing a traceback, as both of
2352 # or sys.exit() ), don't bother showing a traceback, as both of
2358 # these are considered normal by the OS:
2353 # these are considered normal by the OS:
2359 # > python -c'import sys;sys.exit(0)'; echo $?
2354 # > python -c'import sys;sys.exit(0)'; echo $?
2360 # 0
2355 # 0
2361 # > python -c'import sys;sys.exit()'; echo $?
2356 # > python -c'import sys;sys.exit()'; echo $?
2362 # 0
2357 # 0
2363 # For other exit status, we show the exception unless
2358 # For other exit status, we show the exception unless
2364 # explicitly silenced, but only in short form.
2359 # explicitly silenced, but only in short form.
2365 if kw['raise_exceptions']:
2360 if kw['raise_exceptions']:
2366 raise
2361 raise
2367 if status.code not in (0, None) and not kw['exit_ignore']:
2362 if status.code not in (0, None) and not kw['exit_ignore']:
2368 self.showtraceback(exception_only=True)
2363 self.showtraceback(exception_only=True)
2369 except:
2364 except:
2370 if kw['raise_exceptions']:
2365 if kw['raise_exceptions']:
2371 raise
2366 raise
2372 self.showtraceback()
2367 self.showtraceback()
2373
2368
2374 def safe_execfile_ipy(self, fname):
2369 def safe_execfile_ipy(self, fname):
2375 """Like safe_execfile, but for .ipy files with IPython syntax.
2370 """Like safe_execfile, but for .ipy files with IPython syntax.
2376
2371
2377 Parameters
2372 Parameters
2378 ----------
2373 ----------
2379 fname : str
2374 fname : str
2380 The name of the file to execute. The filename must have a
2375 The name of the file to execute. The filename must have a
2381 .ipy extension.
2376 .ipy extension.
2382 """
2377 """
2383 fname = os.path.abspath(os.path.expanduser(fname))
2378 fname = os.path.abspath(os.path.expanduser(fname))
2384
2379
2385 # Make sure we can open the file
2380 # Make sure we can open the file
2386 try:
2381 try:
2387 with open(fname) as thefile:
2382 with open(fname) as thefile:
2388 pass
2383 pass
2389 except:
2384 except:
2390 warn('Could not open file <%s> for safe execution.' % fname)
2385 warn('Could not open file <%s> for safe execution.' % fname)
2391 return
2386 return
2392
2387
2393 # Find things also in current directory. This is needed to mimic the
2388 # Find things also in current directory. This is needed to mimic the
2394 # behavior of running a script from the system command line, where
2389 # behavior of running a script from the system command line, where
2395 # Python inserts the script's directory into sys.path
2390 # Python inserts the script's directory into sys.path
2396 dname = os.path.dirname(fname)
2391 dname = os.path.dirname(fname)
2397
2392
2398 with prepended_to_syspath(dname):
2393 with prepended_to_syspath(dname):
2399 try:
2394 try:
2400 with open(fname) as thefile:
2395 with open(fname) as thefile:
2401 # self.run_cell currently captures all exceptions
2396 # self.run_cell currently captures all exceptions
2402 # raised in user code. It would be nice if there were
2397 # raised in user code. It would be nice if there were
2403 # versions of runlines, execfile that did raise, so
2398 # versions of runlines, execfile that did raise, so
2404 # we could catch the errors.
2399 # we could catch the errors.
2405 self.run_cell(thefile.read(), store_history=False)
2400 self.run_cell(thefile.read(), store_history=False)
2406 except:
2401 except:
2407 self.showtraceback()
2402 self.showtraceback()
2408 warn('Unknown failure executing file: <%s>' % fname)
2403 warn('Unknown failure executing file: <%s>' % fname)
2409
2404
2410 def safe_run_module(self, mod_name, where):
2405 def safe_run_module(self, mod_name, where):
2411 """A safe version of runpy.run_module().
2406 """A safe version of runpy.run_module().
2412
2407
2413 This version will never throw an exception, but instead print
2408 This version will never throw an exception, but instead print
2414 helpful error messages to the screen.
2409 helpful error messages to the screen.
2415
2410
2416 Parameters
2411 Parameters
2417 ----------
2412 ----------
2418 mod_name : string
2413 mod_name : string
2419 The name of the module to be executed.
2414 The name of the module to be executed.
2420 where : dict
2415 where : dict
2421 The globals namespace.
2416 The globals namespace.
2422 """
2417 """
2423 try:
2418 try:
2424 where.update(
2419 where.update(
2425 runpy.run_module(str(mod_name), run_name="__main__",
2420 runpy.run_module(str(mod_name), run_name="__main__",
2426 alter_sys=True)
2421 alter_sys=True)
2427 )
2422 )
2428 except:
2423 except:
2429 self.showtraceback()
2424 self.showtraceback()
2430 warn('Unknown failure executing module: <%s>' % mod_name)
2425 warn('Unknown failure executing module: <%s>' % mod_name)
2431
2426
2432 def run_cell(self, raw_cell, store_history=False):
2427 def run_cell(self, raw_cell, store_history=False):
2433 """Run a complete IPython cell.
2428 """Run a complete IPython cell.
2434
2429
2435 Parameters
2430 Parameters
2436 ----------
2431 ----------
2437 raw_cell : str
2432 raw_cell : str
2438 The code (including IPython code such as %magic functions) to run.
2433 The code (including IPython code such as %magic functions) to run.
2439 store_history : bool
2434 store_history : bool
2440 If True, the raw and translated cell will be stored in IPython's
2435 If True, the raw and translated cell will be stored in IPython's
2441 history. For user code calling back into IPython's machinery, this
2436 history. For user code calling back into IPython's machinery, this
2442 should be set to False.
2437 should be set to False.
2443 """
2438 """
2444 if (not raw_cell) or raw_cell.isspace():
2439 if (not raw_cell) or raw_cell.isspace():
2445 return
2440 return
2446
2441
2447 for line in raw_cell.splitlines():
2442 for line in raw_cell.splitlines():
2448 self.input_splitter.push(line)
2443 self.input_splitter.push(line)
2449 cell = self.input_splitter.source_reset()
2444 cell = self.input_splitter.source_reset()
2450
2445
2451 with self.builtin_trap:
2446 with self.builtin_trap:
2452 prefilter_failed = False
2447 prefilter_failed = False
2453 if len(cell.splitlines()) == 1:
2448 if len(cell.splitlines()) == 1:
2454 try:
2449 try:
2455 # use prefilter_lines to handle trailing newlines
2450 # use prefilter_lines to handle trailing newlines
2456 # restore trailing newline for ast.parse
2451 # restore trailing newline for ast.parse
2457 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2452 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2458 except AliasError as e:
2453 except AliasError as e:
2459 error(e)
2454 error(e)
2460 prefilter_failed = True
2455 prefilter_failed = True
2461 except Exception:
2456 except Exception:
2462 # don't allow prefilter errors to crash IPython
2457 # don't allow prefilter errors to crash IPython
2463 self.showtraceback()
2458 self.showtraceback()
2464 prefilter_failed = True
2459 prefilter_failed = True
2465
2460
2466 # Store raw and processed history
2461 # Store raw and processed history
2467 if store_history:
2462 if store_history:
2468 self.history_manager.store_inputs(self.execution_count,
2463 self.history_manager.store_inputs(self.execution_count,
2469 cell, raw_cell)
2464 cell, raw_cell)
2470
2465
2471 self.logger.log(cell, raw_cell)
2466 self.logger.log(cell, raw_cell)
2472
2467
2473 if not prefilter_failed:
2468 if not prefilter_failed:
2474 # don't run if prefilter failed
2469 # don't run if prefilter failed
2475 cell_name = self.compile.cache(cell, self.execution_count)
2470 cell_name = self.compile.cache(cell, self.execution_count)
2476
2471
2477 with self.display_trap:
2472 with self.display_trap:
2478 try:
2473 try:
2479 code_ast = self.compile.ast_parse(cell, filename=cell_name)
2474 code_ast = self.compile.ast_parse(cell, filename=cell_name)
2480 except IndentationError:
2475 except IndentationError:
2481 self.showindentationerror()
2476 self.showindentationerror()
2482 if store_history:
2477 if store_history:
2483 self.execution_count += 1
2478 self.execution_count += 1
2484 return None
2479 return None
2485 except (OverflowError, SyntaxError, ValueError, TypeError,
2480 except (OverflowError, SyntaxError, ValueError, TypeError,
2486 MemoryError):
2481 MemoryError):
2487 self.showsyntaxerror()
2482 self.showsyntaxerror()
2488 if store_history:
2483 if store_history:
2489 self.execution_count += 1
2484 self.execution_count += 1
2490 return None
2485 return None
2491
2486
2492 self.run_ast_nodes(code_ast.body, cell_name,
2487 self.run_ast_nodes(code_ast.body, cell_name,
2493 interactivity="last_expr")
2488 interactivity="last_expr")
2494
2489
2495 # Execute any registered post-execution functions.
2490 # Execute any registered post-execution functions.
2496 for func, status in self._post_execute.iteritems():
2491 for func, status in self._post_execute.iteritems():
2497 if self.disable_failing_post_execute and not status:
2492 if self.disable_failing_post_execute and not status:
2498 continue
2493 continue
2499 try:
2494 try:
2500 func()
2495 func()
2501 except KeyboardInterrupt:
2496 except KeyboardInterrupt:
2502 print >> io.stderr, "\nKeyboardInterrupt"
2497 print >> io.stderr, "\nKeyboardInterrupt"
2503 except Exception:
2498 except Exception:
2504 # register as failing:
2499 # register as failing:
2505 self._post_execute[func] = False
2500 self._post_execute[func] = False
2506 self.showtraceback()
2501 self.showtraceback()
2507 print >> io.stderr, '\n'.join([
2502 print >> io.stderr, '\n'.join([
2508 "post-execution function %r produced an error." % func,
2503 "post-execution function %r produced an error." % func,
2509 "If this problem persists, you can disable failing post-exec functions with:",
2504 "If this problem persists, you can disable failing post-exec functions with:",
2510 "",
2505 "",
2511 " get_ipython().disable_failing_post_execute = True"
2506 " get_ipython().disable_failing_post_execute = True"
2512 ])
2507 ])
2513
2508
2514 if store_history:
2509 if store_history:
2515 # Write output to the database. Does nothing unless
2510 # Write output to the database. Does nothing unless
2516 # history output logging is enabled.
2511 # history output logging is enabled.
2517 self.history_manager.store_output(self.execution_count)
2512 self.history_manager.store_output(self.execution_count)
2518 # Each cell is a *single* input, regardless of how many lines it has
2513 # Each cell is a *single* input, regardless of how many lines it has
2519 self.execution_count += 1
2514 self.execution_count += 1
2520
2515
2521 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2516 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2522 """Run a sequence of AST nodes. The execution mode depends on the
2517 """Run a sequence of AST nodes. The execution mode depends on the
2523 interactivity parameter.
2518 interactivity parameter.
2524
2519
2525 Parameters
2520 Parameters
2526 ----------
2521 ----------
2527 nodelist : list
2522 nodelist : list
2528 A sequence of AST nodes to run.
2523 A sequence of AST nodes to run.
2529 cell_name : str
2524 cell_name : str
2530 Will be passed to the compiler as the filename of the cell. Typically
2525 Will be passed to the compiler as the filename of the cell. Typically
2531 the value returned by ip.compile.cache(cell).
2526 the value returned by ip.compile.cache(cell).
2532 interactivity : str
2527 interactivity : str
2533 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2528 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2534 run interactively (displaying output from expressions). 'last_expr'
2529 run interactively (displaying output from expressions). 'last_expr'
2535 will run the last node interactively only if it is an expression (i.e.
2530 will run the last node interactively only if it is an expression (i.e.
2536 expressions in loops or other blocks are not displayed. Other values
2531 expressions in loops or other blocks are not displayed. Other values
2537 for this parameter will raise a ValueError.
2532 for this parameter will raise a ValueError.
2538 """
2533 """
2539 if not nodelist:
2534 if not nodelist:
2540 return
2535 return
2541
2536
2542 if interactivity == 'last_expr':
2537 if interactivity == 'last_expr':
2543 if isinstance(nodelist[-1], ast.Expr):
2538 if isinstance(nodelist[-1], ast.Expr):
2544 interactivity = "last"
2539 interactivity = "last"
2545 else:
2540 else:
2546 interactivity = "none"
2541 interactivity = "none"
2547
2542
2548 if interactivity == 'none':
2543 if interactivity == 'none':
2549 to_run_exec, to_run_interactive = nodelist, []
2544 to_run_exec, to_run_interactive = nodelist, []
2550 elif interactivity == 'last':
2545 elif interactivity == 'last':
2551 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2546 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2552 elif interactivity == 'all':
2547 elif interactivity == 'all':
2553 to_run_exec, to_run_interactive = [], nodelist
2548 to_run_exec, to_run_interactive = [], nodelist
2554 else:
2549 else:
2555 raise ValueError("Interactivity was %r" % interactivity)
2550 raise ValueError("Interactivity was %r" % interactivity)
2556
2551
2557 exec_count = self.execution_count
2552 exec_count = self.execution_count
2558
2553
2559 try:
2554 try:
2560 for i, node in enumerate(to_run_exec):
2555 for i, node in enumerate(to_run_exec):
2561 mod = ast.Module([node])
2556 mod = ast.Module([node])
2562 code = self.compile(mod, cell_name, "exec")
2557 code = self.compile(mod, cell_name, "exec")
2563 if self.run_code(code):
2558 if self.run_code(code):
2564 return True
2559 return True
2565
2560
2566 for i, node in enumerate(to_run_interactive):
2561 for i, node in enumerate(to_run_interactive):
2567 mod = ast.Interactive([node])
2562 mod = ast.Interactive([node])
2568 code = self.compile(mod, cell_name, "single")
2563 code = self.compile(mod, cell_name, "single")
2569 if self.run_code(code):
2564 if self.run_code(code):
2570 return True
2565 return True
2571
2566
2572 # Flush softspace
2567 # Flush softspace
2573 if softspace(sys.stdout, 0):
2568 if softspace(sys.stdout, 0):
2574 print
2569 print
2575
2570
2576 except:
2571 except:
2577 # It's possible to have exceptions raised here, typically by
2572 # It's possible to have exceptions raised here, typically by
2578 # compilation of odd code (such as a naked 'return' outside a
2573 # compilation of odd code (such as a naked 'return' outside a
2579 # function) that did parse but isn't valid. Typically the exception
2574 # function) that did parse but isn't valid. Typically the exception
2580 # is a SyntaxError, but it's safest just to catch anything and show
2575 # is a SyntaxError, but it's safest just to catch anything and show
2581 # the user a traceback.
2576 # the user a traceback.
2582
2577
2583 # We do only one try/except outside the loop to minimize the impact
2578 # We do only one try/except outside the loop to minimize the impact
2584 # on runtime, and also because if any node in the node list is
2579 # on runtime, and also because if any node in the node list is
2585 # broken, we should stop execution completely.
2580 # broken, we should stop execution completely.
2586 self.showtraceback()
2581 self.showtraceback()
2587
2582
2588 return False
2583 return False
2589
2584
2590 def run_code(self, code_obj):
2585 def run_code(self, code_obj):
2591 """Execute a code object.
2586 """Execute a code object.
2592
2587
2593 When an exception occurs, self.showtraceback() is called to display a
2588 When an exception occurs, self.showtraceback() is called to display a
2594 traceback.
2589 traceback.
2595
2590
2596 Parameters
2591 Parameters
2597 ----------
2592 ----------
2598 code_obj : code object
2593 code_obj : code object
2599 A compiled code object, to be executed
2594 A compiled code object, to be executed
2600
2595
2601 Returns
2596 Returns
2602 -------
2597 -------
2603 False : successful execution.
2598 False : successful execution.
2604 True : an error occurred.
2599 True : an error occurred.
2605 """
2600 """
2606
2601
2607 # Set our own excepthook in case the user code tries to call it
2602 # Set our own excepthook in case the user code tries to call it
2608 # directly, so that the IPython crash handler doesn't get triggered
2603 # directly, so that the IPython crash handler doesn't get triggered
2609 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2604 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2610
2605
2611 # we save the original sys.excepthook in the instance, in case config
2606 # we save the original sys.excepthook in the instance, in case config
2612 # code (such as magics) needs access to it.
2607 # code (such as magics) needs access to it.
2613 self.sys_excepthook = old_excepthook
2608 self.sys_excepthook = old_excepthook
2614 outflag = 1 # happens in more places, so it's easier as default
2609 outflag = 1 # happens in more places, so it's easier as default
2615 try:
2610 try:
2616 try:
2611 try:
2617 self.hooks.pre_run_code_hook()
2612 self.hooks.pre_run_code_hook()
2618 #rprint('Running code', repr(code_obj)) # dbg
2613 #rprint('Running code', repr(code_obj)) # dbg
2619 exec code_obj in self.user_global_ns, self.user_ns
2614 exec code_obj in self.user_global_ns, self.user_ns
2620 finally:
2615 finally:
2621 # Reset our crash handler in place
2616 # Reset our crash handler in place
2622 sys.excepthook = old_excepthook
2617 sys.excepthook = old_excepthook
2623 except SystemExit:
2618 except SystemExit:
2624 self.showtraceback(exception_only=True)
2619 self.showtraceback(exception_only=True)
2625 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2620 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2626 except self.custom_exceptions:
2621 except self.custom_exceptions:
2627 etype,value,tb = sys.exc_info()
2622 etype,value,tb = sys.exc_info()
2628 self.CustomTB(etype,value,tb)
2623 self.CustomTB(etype,value,tb)
2629 except:
2624 except:
2630 self.showtraceback()
2625 self.showtraceback()
2631 else:
2626 else:
2632 outflag = 0
2627 outflag = 0
2633 return outflag
2628 return outflag
2634
2629
2635 # For backwards compatibility
2630 # For backwards compatibility
2636 runcode = run_code
2631 runcode = run_code
2637
2632
2638 #-------------------------------------------------------------------------
2633 #-------------------------------------------------------------------------
2639 # Things related to GUI support and pylab
2634 # Things related to GUI support and pylab
2640 #-------------------------------------------------------------------------
2635 #-------------------------------------------------------------------------
2641
2636
2642 def enable_gui(self, gui=None):
2637 def enable_gui(self, gui=None):
2643 raise NotImplementedError('Implement enable_gui in a subclass')
2638 raise NotImplementedError('Implement enable_gui in a subclass')
2644
2639
2645 def enable_pylab(self, gui=None, import_all=True):
2640 def enable_pylab(self, gui=None, import_all=True):
2646 """Activate pylab support at runtime.
2641 """Activate pylab support at runtime.
2647
2642
2648 This turns on support for matplotlib, preloads into the interactive
2643 This turns on support for matplotlib, preloads into the interactive
2649 namespace all of numpy and pylab, and configures IPython to correctly
2644 namespace all of numpy and pylab, and configures IPython to correctly
2650 interact with the GUI event loop. The GUI backend to be used can be
2645 interact with the GUI event loop. The GUI backend to be used can be
2651 optionally selected with the optional :param:`gui` argument.
2646 optionally selected with the optional :param:`gui` argument.
2652
2647
2653 Parameters
2648 Parameters
2654 ----------
2649 ----------
2655 gui : optional, string
2650 gui : optional, string
2656
2651
2657 If given, dictates the choice of matplotlib GUI backend to use
2652 If given, dictates the choice of matplotlib GUI backend to use
2658 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2653 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2659 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2654 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2660 matplotlib (as dictated by the matplotlib build-time options plus the
2655 matplotlib (as dictated by the matplotlib build-time options plus the
2661 user's matplotlibrc configuration file). Note that not all backends
2656 user's matplotlibrc configuration file). Note that not all backends
2662 make sense in all contexts, for example a terminal ipython can't
2657 make sense in all contexts, for example a terminal ipython can't
2663 display figures inline.
2658 display figures inline.
2664 """
2659 """
2665
2660
2666 # We want to prevent the loading of pylab to pollute the user's
2661 # We want to prevent the loading of pylab to pollute the user's
2667 # namespace as shown by the %who* magics, so we execute the activation
2662 # namespace as shown by the %who* magics, so we execute the activation
2668 # code in an empty namespace, and we update *both* user_ns and
2663 # code in an empty namespace, and we update *both* user_ns and
2669 # user_ns_hidden with this information.
2664 # user_ns_hidden with this information.
2670 ns = {}
2665 ns = {}
2671 try:
2666 try:
2672 gui = pylab_activate(ns, gui, import_all, self)
2667 gui = pylab_activate(ns, gui, import_all, self)
2673 except KeyError:
2668 except KeyError:
2674 error("Backend %r not supported" % gui)
2669 error("Backend %r not supported" % gui)
2675 return
2670 return
2676 self.user_ns.update(ns)
2671 self.user_ns.update(ns)
2677 self.user_ns_hidden.update(ns)
2672 self.user_ns_hidden.update(ns)
2678 # Now we must activate the gui pylab wants to use, and fix %run to take
2673 # Now we must activate the gui pylab wants to use, and fix %run to take
2679 # plot updates into account
2674 # plot updates into account
2680 self.enable_gui(gui)
2675 self.enable_gui(gui)
2681 self.magic_run = self._pylab_magic_run
2676 self.magic_run = self._pylab_magic_run
2682
2677
2683 #-------------------------------------------------------------------------
2678 #-------------------------------------------------------------------------
2684 # Utilities
2679 # Utilities
2685 #-------------------------------------------------------------------------
2680 #-------------------------------------------------------------------------
2686
2681
2687 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2682 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2688 """Expand python variables in a string.
2683 """Expand python variables in a string.
2689
2684
2690 The depth argument indicates how many frames above the caller should
2685 The depth argument indicates how many frames above the caller should
2691 be walked to look for the local namespace where to expand variables.
2686 be walked to look for the local namespace where to expand variables.
2692
2687
2693 The global namespace for expansion is always the user's interactive
2688 The global namespace for expansion is always the user's interactive
2694 namespace.
2689 namespace.
2695 """
2690 """
2696 ns = self.user_ns.copy()
2691 ns = self.user_ns.copy()
2697 ns.update(sys._getframe(depth+1).f_locals)
2692 ns.update(sys._getframe(depth+1).f_locals)
2698 ns.pop('self', None)
2693 ns.pop('self', None)
2699 try:
2694 try:
2700 cmd = formatter.format(cmd, **ns)
2695 cmd = formatter.format(cmd, **ns)
2701 except Exception:
2696 except Exception:
2702 # if formatter couldn't format, just let it go untransformed
2697 # if formatter couldn't format, just let it go untransformed
2703 pass
2698 pass
2704 return cmd
2699 return cmd
2705
2700
2706 def mktempfile(self, data=None, prefix='ipython_edit_'):
2701 def mktempfile(self, data=None, prefix='ipython_edit_'):
2707 """Make a new tempfile and return its filename.
2702 """Make a new tempfile and return its filename.
2708
2703
2709 This makes a call to tempfile.mktemp, but it registers the created
2704 This makes a call to tempfile.mktemp, but it registers the created
2710 filename internally so ipython cleans it up at exit time.
2705 filename internally so ipython cleans it up at exit time.
2711
2706
2712 Optional inputs:
2707 Optional inputs:
2713
2708
2714 - data(None): if data is given, it gets written out to the temp file
2709 - data(None): if data is given, it gets written out to the temp file
2715 immediately, and the file is closed again."""
2710 immediately, and the file is closed again."""
2716
2711
2717 filename = tempfile.mktemp('.py', prefix)
2712 filename = tempfile.mktemp('.py', prefix)
2718 self.tempfiles.append(filename)
2713 self.tempfiles.append(filename)
2719
2714
2720 if data:
2715 if data:
2721 tmp_file = open(filename,'w')
2716 tmp_file = open(filename,'w')
2722 tmp_file.write(data)
2717 tmp_file.write(data)
2723 tmp_file.close()
2718 tmp_file.close()
2724 return filename
2719 return filename
2725
2720
2726 # TODO: This should be removed when Term is refactored.
2721 # TODO: This should be removed when Term is refactored.
2727 def write(self,data):
2722 def write(self,data):
2728 """Write a string to the default output"""
2723 """Write a string to the default output"""
2729 io.stdout.write(data)
2724 io.stdout.write(data)
2730
2725
2731 # TODO: This should be removed when Term is refactored.
2726 # TODO: This should be removed when Term is refactored.
2732 def write_err(self,data):
2727 def write_err(self,data):
2733 """Write a string to the default error output"""
2728 """Write a string to the default error output"""
2734 io.stderr.write(data)
2729 io.stderr.write(data)
2735
2730
2736 def ask_yes_no(self, prompt, default=None):
2731 def ask_yes_no(self, prompt, default=None):
2737 if self.quiet:
2732 if self.quiet:
2738 return True
2733 return True
2739 return ask_yes_no(prompt,default)
2734 return ask_yes_no(prompt,default)
2740
2735
2741 def show_usage(self):
2736 def show_usage(self):
2742 """Show a usage message"""
2737 """Show a usage message"""
2743 page.page(IPython.core.usage.interactive_usage)
2738 page.page(IPython.core.usage.interactive_usage)
2744
2739
2745 def find_user_code(self, target, raw=True):
2740 def find_user_code(self, target, raw=True, py_only=False):
2746 """Get a code string from history, file, or a string or macro.
2741 """Get a code string from history, file, url, or a string or macro.
2747
2742
2748 This is mainly used by magic functions.
2743 This is mainly used by magic functions.
2749
2744
2750 Parameters
2745 Parameters
2751 ----------
2746 ----------
2747
2752 target : str
2748 target : str
2749
2753 A string specifying code to retrieve. This will be tried respectively
2750 A string specifying code to retrieve. This will be tried respectively
2754 as: ranges of input history (see %history for syntax), a filename, or
2751 as: ranges of input history (see %history for syntax), url,
2755 an expression evaluating to a string or Macro in the user namespace.
2752 correspnding .py file, filename, or an expression evaluating to a
2753 string or Macro in the user namespace.
2754
2756 raw : bool
2755 raw : bool
2757 If true (default), retrieve raw history. Has no effect on the other
2756 If true (default), retrieve raw history. Has no effect on the other
2758 retrieval mechanisms.
2757 retrieval mechanisms.
2759
2758
2759 py_only : bool (default False)
2760 Only try to fetch python code, do not try alternative methods to decode file
2761 if unicode fails.
2762
2760 Returns
2763 Returns
2761 -------
2764 -------
2762 A string of code.
2765 A string of code.
2763
2766
2764 ValueError is raised if nothing is found, and TypeError if it evaluates
2767 ValueError is raised if nothing is found, and TypeError if it evaluates
2765 to an object of another type. In each case, .args[0] is a printable
2768 to an object of another type. In each case, .args[0] is a printable
2766 message.
2769 message.
2767 """
2770 """
2768 code = self.extract_input_lines(target, raw=raw) # Grab history
2771 code = self.extract_input_lines(target, raw=raw) # Grab history
2769 if code:
2772 if code:
2770 return code
2773 return code
2771 if os.path.isfile(target): # Read file
2774 utarget = unquote_filename(target)
2772 return open(target, "r").read()
2775 try:
2776 if utarget.startswith(('http://', 'https://')):
2777 return openpy.read_py_url(utarget, skip_encoding_cookie=True)
2778 except UnicodeDecodeError:
2779 if not py_only :
2780 response = urllib.urlopen(target)
2781 return response.read().decode('latin1')
2782 raise ValueError(("'%s' seem to be unreadable.") % utarget)
2783
2784 potential_target = [target]
2785 try :
2786 potential_target.insert(0,get_py_filename(target))
2787 except IOError:
2788 pass
2789
2790 for tgt in potential_target :
2791 if os.path.isfile(tgt): # Read file
2792 try :
2793 return openpy.read_py_file(tgt, skip_encoding_cookie=True)
2794 except UnicodeDecodeError :
2795 if not py_only :
2796 with io_open(tgt,'r', encoding='latin1') as f :
2797 return f.read()
2798 raise ValueError(("'%s' seem to be unreadable.") % target)
2773
2799
2774 try: # User namespace
2800 try: # User namespace
2775 codeobj = eval(target, self.user_ns)
2801 codeobj = eval(target, self.user_ns)
2776 except Exception:
2802 except Exception:
2777 raise ValueError(("'%s' was not found in history, as a file, nor in"
2803 raise ValueError(("'%s' was not found in history, as a file, url, "
2778 " the user namespace.") % target)
2804 "nor in the user namespace.") % target)
2779 if isinstance(codeobj, basestring):
2805 if isinstance(codeobj, basestring):
2780 return codeobj
2806 return codeobj
2781 elif isinstance(codeobj, Macro):
2807 elif isinstance(codeobj, Macro):
2782 return codeobj.value
2808 return codeobj.value
2783
2809
2784 raise TypeError("%s is neither a string nor a macro." % target,
2810 raise TypeError("%s is neither a string nor a macro." % target,
2785 codeobj)
2811 codeobj)
2786
2812
2787 #-------------------------------------------------------------------------
2813 #-------------------------------------------------------------------------
2788 # Things related to IPython exiting
2814 # Things related to IPython exiting
2789 #-------------------------------------------------------------------------
2815 #-------------------------------------------------------------------------
2790 def atexit_operations(self):
2816 def atexit_operations(self):
2791 """This will be executed at the time of exit.
2817 """This will be executed at the time of exit.
2792
2818
2793 Cleanup operations and saving of persistent data that is done
2819 Cleanup operations and saving of persistent data that is done
2794 unconditionally by IPython should be performed here.
2820 unconditionally by IPython should be performed here.
2795
2821
2796 For things that may depend on startup flags or platform specifics (such
2822 For things that may depend on startup flags or platform specifics (such
2797 as having readline or not), register a separate atexit function in the
2823 as having readline or not), register a separate atexit function in the
2798 code that has the appropriate information, rather than trying to
2824 code that has the appropriate information, rather than trying to
2799 clutter
2825 clutter
2800 """
2826 """
2801 # Close the history session (this stores the end time and line count)
2827 # Close the history session (this stores the end time and line count)
2802 # this must be *before* the tempfile cleanup, in case of temporary
2828 # this must be *before* the tempfile cleanup, in case of temporary
2803 # history db
2829 # history db
2804 self.history_manager.end_session()
2830 self.history_manager.end_session()
2805
2831
2806 # Cleanup all tempfiles left around
2832 # Cleanup all tempfiles left around
2807 for tfile in self.tempfiles:
2833 for tfile in self.tempfiles:
2808 try:
2834 try:
2809 os.unlink(tfile)
2835 os.unlink(tfile)
2810 except OSError:
2836 except OSError:
2811 pass
2837 pass
2812
2838
2813 # Clear all user namespaces to release all references cleanly.
2839 # Clear all user namespaces to release all references cleanly.
2814 self.reset(new_session=False)
2840 self.reset(new_session=False)
2815
2841
2816 # Run user hooks
2842 # Run user hooks
2817 self.hooks.shutdown_hook()
2843 self.hooks.shutdown_hook()
2818
2844
2819 def cleanup(self):
2845 def cleanup(self):
2820 self.restore_sys_module_state()
2846 self.restore_sys_module_state()
2821
2847
2822
2848
2823 class InteractiveShellABC(object):
2849 class InteractiveShellABC(object):
2824 """An abstract base class for InteractiveShell."""
2850 """An abstract base class for InteractiveShell."""
2825 __metaclass__ = abc.ABCMeta
2851 __metaclass__ = abc.ABCMeta
2826
2852
2827 InteractiveShellABC.register(InteractiveShell)
2853 InteractiveShellABC.register(InteractiveShell)
@@ -1,3827 +1,3852 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Magic functions for InteractiveShell.
2 """Magic functions for InteractiveShell.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2008-2011 The IPython Development Team
8 # Copyright (C) 2008-2011 The IPython Development Team
9
9
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 import __builtin__ as builtin_mod
18 import __builtin__ as builtin_mod
19 import __future__
19 import __future__
20 import bdb
20 import bdb
21 import inspect
21 import inspect
22 import imp
23 import io
22 import io
24 import json
23 import json
25 import os
24 import os
26 import sys
25 import sys
27 import shutil
28 import re
26 import re
29 import time
27 import time
30 import gc
28 import gc
31 from StringIO import StringIO
29 from StringIO import StringIO
32 from getopt import getopt,GetoptError
30 from getopt import getopt,GetoptError
33 from pprint import pformat
31 from pprint import pformat
34 from urllib2 import urlopen
32 from urllib2 import urlopen
35
33
36 # cProfile was added in Python2.5
34 # cProfile was added in Python2.5
37 try:
35 try:
38 import cProfile as profile
36 import cProfile as profile
39 import pstats
37 import pstats
40 except ImportError:
38 except ImportError:
41 # profile isn't bundled by default in Debian for license reasons
39 # profile isn't bundled by default in Debian for license reasons
42 try:
40 try:
43 import profile,pstats
41 import profile,pstats
44 except ImportError:
42 except ImportError:
45 profile = pstats = None
43 profile = pstats = None
46
44
47 import IPython
48 from IPython.core import debugger, oinspect
45 from IPython.core import debugger, oinspect
49 from IPython.core.error import TryNext
46 from IPython.core.error import TryNext
50 from IPython.core.error import UsageError
47 from IPython.core.error import UsageError
51 from IPython.core.error import StdinNotImplementedError
48 from IPython.core.error import StdinNotImplementedError
52 from IPython.core.fakemodule import FakeModule
53 from IPython.core.profiledir import ProfileDir
54 from IPython.core.macro import Macro
49 from IPython.core.macro import Macro
55 from IPython.core import magic_arguments, page
50 from IPython.core import magic_arguments, page
56 from IPython.core.prefilter import ESC_MAGIC
51 from IPython.core.prefilter import ESC_MAGIC
57 from IPython.core.pylabtools import mpl_runner
52 from IPython.core.pylabtools import mpl_runner
58 from IPython.testing.skipdoctest import skip_doctest
53 from IPython.testing.skipdoctest import skip_doctest
59 from IPython.utils import py3compat
54 from IPython.utils import py3compat
60 from IPython.utils import openpy
61 from IPython.utils.encoding import DEFAULT_ENCODING
55 from IPython.utils.encoding import DEFAULT_ENCODING
62 from IPython.utils.io import file_read, nlprint
56 from IPython.utils.io import file_read, nlprint
63 from IPython.utils.module_paths import find_mod
57 from IPython.utils.module_paths import find_mod
64 from IPython.utils.path import get_py_filename, unquote_filename
58 from IPython.utils.path import get_py_filename, unquote_filename
65 from IPython.utils.process import arg_split, abbrev_cwd
59 from IPython.utils.process import arg_split, abbrev_cwd
66 from IPython.utils.terminal import set_term_title
60 from IPython.utils.terminal import set_term_title
67 from IPython.utils.text import LSString, SList, format_screen
61 from IPython.utils.text import format_screen
68 from IPython.utils.timing import clock, clock2
62 from IPython.utils.timing import clock, clock2
69 from IPython.utils.warn import warn, error
63 from IPython.utils.warn import warn, error
70 from IPython.utils.ipstruct import Struct
64 from IPython.utils.ipstruct import Struct
71 from IPython.config.application import Application
65 from IPython.config.application import Application
72
66
73 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
74 # Utility functions
68 # Utility functions
75 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
76
70
77 def on_off(tag):
71 def on_off(tag):
78 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
72 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
79 return ['OFF','ON'][tag]
73 return ['OFF','ON'][tag]
80
74
81 class Bunch: pass
75 class Bunch: pass
82
76
83 def compress_dhist(dh):
77 def compress_dhist(dh):
84 head, tail = dh[:-10], dh[-10:]
78 head, tail = dh[:-10], dh[-10:]
85
79
86 newhead = []
80 newhead = []
87 done = set()
81 done = set()
88 for h in head:
82 for h in head:
89 if h in done:
83 if h in done:
90 continue
84 continue
91 newhead.append(h)
85 newhead.append(h)
92 done.add(h)
86 done.add(h)
93
87
94 return newhead + tail
88 return newhead + tail
95
89
96 def needs_local_scope(func):
90 def needs_local_scope(func):
97 """Decorator to mark magic functions which need to local scope to run."""
91 """Decorator to mark magic functions which need to local scope to run."""
98 func.needs_local_scope = True
92 func.needs_local_scope = True
99 return func
93 return func
100
94
101
95
102 # Used for exception handling in magic_edit
96 # Used for exception handling in magic_edit
103 class MacroToEdit(ValueError): pass
97 class MacroToEdit(ValueError): pass
104
98
105 #***************************************************************************
99 #***************************************************************************
106 # Main class implementing Magic functionality
100 # Main class implementing Magic functionality
107
101
108 # XXX - for some odd reason, if Magic is made a new-style class, we get errors
102 # XXX - for some odd reason, if Magic is made a new-style class, we get errors
109 # on construction of the main InteractiveShell object. Something odd is going
103 # on construction of the main InteractiveShell object. Something odd is going
110 # on with super() calls, Configurable and the MRO... For now leave it as-is, but
104 # on with super() calls, Configurable and the MRO... For now leave it as-is, but
111 # eventually this needs to be clarified.
105 # eventually this needs to be clarified.
112 # BG: This is because InteractiveShell inherits from this, but is itself a
106 # BG: This is because InteractiveShell inherits from this, but is itself a
113 # Configurable. This messes up the MRO in some way. The fix is that we need to
107 # Configurable. This messes up the MRO in some way. The fix is that we need to
114 # make Magic a configurable that InteractiveShell does not subclass.
108 # make Magic a configurable that InteractiveShell does not subclass.
115
109
116 class Magic:
110 class Magic:
117 """Magic functions for InteractiveShell.
111 """Magic functions for InteractiveShell.
118
112
119 Shell functions which can be reached as %function_name. All magic
113 Shell functions which can be reached as %function_name. All magic
120 functions should accept a string, which they can parse for their own
114 functions should accept a string, which they can parse for their own
121 needs. This can make some functions easier to type, eg `%cd ../`
115 needs. This can make some functions easier to type, eg `%cd ../`
122 vs. `%cd("../")`
116 vs. `%cd("../")`
123
117
124 ALL definitions MUST begin with the prefix magic_. The user won't need it
118 ALL definitions MUST begin with the prefix magic_. The user won't need it
125 at the command line, but it is is needed in the definition. """
119 at the command line, but it is is needed in the definition. """
126
120
127 # class globals
121 # class globals
128 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
122 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
129 'Automagic is ON, % prefix NOT needed for magic functions.']
123 'Automagic is ON, % prefix NOT needed for magic functions.']
130
124
131
125
132 configurables = None
126 configurables = None
133 #......................................................................
127 #......................................................................
134 # some utility functions
128 # some utility functions
135
129
136 def __init__(self,shell):
130 def __init__(self,shell):
137
131
138 self.options_table = {}
132 self.options_table = {}
139 if profile is None:
133 if profile is None:
140 self.magic_prun = self.profile_missing_notice
134 self.magic_prun = self.profile_missing_notice
141 self.shell = shell
135 self.shell = shell
142 if self.configurables is None:
136 if self.configurables is None:
143 self.configurables = []
137 self.configurables = []
144
138
145 # namespace for holding state we may need
139 # namespace for holding state we may need
146 self._magic_state = Bunch()
140 self._magic_state = Bunch()
147
141
148 def profile_missing_notice(self, *args, **kwargs):
142 def profile_missing_notice(self, *args, **kwargs):
149 error("""\
143 error("""\
150 The profile module could not be found. It has been removed from the standard
144 The profile module could not be found. It has been removed from the standard
151 python packages because of its non-free license. To use profiling, install the
145 python packages because of its non-free license. To use profiling, install the
152 python-profiler package from non-free.""")
146 python-profiler package from non-free.""")
153
147
154 def default_option(self,fn,optstr):
148 def default_option(self,fn,optstr):
155 """Make an entry in the options_table for fn, with value optstr"""
149 """Make an entry in the options_table for fn, with value optstr"""
156
150
157 if fn not in self.lsmagic():
151 if fn not in self.lsmagic():
158 error("%s is not a magic function" % fn)
152 error("%s is not a magic function" % fn)
159 self.options_table[fn] = optstr
153 self.options_table[fn] = optstr
160
154
161 def lsmagic(self):
155 def lsmagic(self):
162 """Return a list of currently available magic functions.
156 """Return a list of currently available magic functions.
163
157
164 Gives a list of the bare names after mangling (['ls','cd', ...], not
158 Gives a list of the bare names after mangling (['ls','cd', ...], not
165 ['magic_ls','magic_cd',...]"""
159 ['magic_ls','magic_cd',...]"""
166
160
167 # FIXME. This needs a cleanup, in the way the magics list is built.
161 # FIXME. This needs a cleanup, in the way the magics list is built.
168
162
169 # magics in class definition
163 # magics in class definition
170 class_magic = lambda fn: fn.startswith('magic_') and \
164 class_magic = lambda fn: fn.startswith('magic_') and \
171 callable(Magic.__dict__[fn])
165 callable(Magic.__dict__[fn])
172 # in instance namespace (run-time user additions)
166 # in instance namespace (run-time user additions)
173 inst_magic = lambda fn: fn.startswith('magic_') and \
167 inst_magic = lambda fn: fn.startswith('magic_') and \
174 callable(self.__dict__[fn])
168 callable(self.__dict__[fn])
175 # and bound magics by user (so they can access self):
169 # and bound magics by user (so they can access self):
176 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
170 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
177 callable(self.__class__.__dict__[fn])
171 callable(self.__class__.__dict__[fn])
178 magics = filter(class_magic,Magic.__dict__.keys()) + \
172 magics = filter(class_magic,Magic.__dict__.keys()) + \
179 filter(inst_magic,self.__dict__.keys()) + \
173 filter(inst_magic,self.__dict__.keys()) + \
180 filter(inst_bound_magic,self.__class__.__dict__.keys())
174 filter(inst_bound_magic,self.__class__.__dict__.keys())
181 out = []
175 out = []
182 for fn in set(magics):
176 for fn in set(magics):
183 out.append(fn.replace('magic_','',1))
177 out.append(fn.replace('magic_','',1))
184 out.sort()
178 out.sort()
185 return out
179 return out
186
180
187 def extract_input_lines(self, range_str, raw=False):
181 def extract_input_lines(self, range_str, raw=False):
188 """Return as a string a set of input history slices.
182 """Return as a string a set of input history slices.
189
183
190 Parameters
184 Parameters
191 ----------
185 ----------
192 range_str : string
186 range_str : string
193 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
187 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
194 since this function is for use by magic functions which get their
188 since this function is for use by magic functions which get their
195 arguments as strings. The number before the / is the session
189 arguments as strings. The number before the / is the session
196 number: ~n goes n back from the current session.
190 number: ~n goes n back from the current session.
197
191
198 Optional Parameters:
192 Optional Parameters:
199 - raw(False): by default, the processed input is used. If this is
193 - raw(False): by default, the processed input is used. If this is
200 true, the raw input history is used instead.
194 true, the raw input history is used instead.
201
195
202 Note that slices can be called with two notations:
196 Note that slices can be called with two notations:
203
197
204 N:M -> standard python form, means including items N...(M-1).
198 N:M -> standard python form, means including items N...(M-1).
205
199
206 N-M -> include items N..M (closed endpoint)."""
200 N-M -> include items N..M (closed endpoint)."""
207 lines = self.shell.history_manager.\
201 lines = self.shell.history_manager.\
208 get_range_by_str(range_str, raw=raw)
202 get_range_by_str(range_str, raw=raw)
209 return "\n".join(x for _, _, x in lines)
203 return "\n".join(x for _, _, x in lines)
210
204
211 def arg_err(self,func):
205 def arg_err(self,func):
212 """Print docstring if incorrect arguments were passed"""
206 """Print docstring if incorrect arguments were passed"""
213 print 'Error in arguments:'
207 print 'Error in arguments:'
214 print oinspect.getdoc(func)
208 print oinspect.getdoc(func)
215
209
216 def format_latex(self,strng):
210 def format_latex(self,strng):
217 """Format a string for latex inclusion."""
211 """Format a string for latex inclusion."""
218
212
219 # Characters that need to be escaped for latex:
213 # Characters that need to be escaped for latex:
220 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
214 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
221 # Magic command names as headers:
215 # Magic command names as headers:
222 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
216 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
223 re.MULTILINE)
217 re.MULTILINE)
224 # Magic commands
218 # Magic commands
225 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
219 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
226 re.MULTILINE)
220 re.MULTILINE)
227 # Paragraph continue
221 # Paragraph continue
228 par_re = re.compile(r'\\$',re.MULTILINE)
222 par_re = re.compile(r'\\$',re.MULTILINE)
229
223
230 # The "\n" symbol
224 # The "\n" symbol
231 newline_re = re.compile(r'\\n')
225 newline_re = re.compile(r'\\n')
232
226
233 # Now build the string for output:
227 # Now build the string for output:
234 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
228 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
235 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
229 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
236 strng)
230 strng)
237 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
231 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
238 strng = par_re.sub(r'\\\\',strng)
232 strng = par_re.sub(r'\\\\',strng)
239 strng = escape_re.sub(r'\\\1',strng)
233 strng = escape_re.sub(r'\\\1',strng)
240 strng = newline_re.sub(r'\\textbackslash{}n',strng)
234 strng = newline_re.sub(r'\\textbackslash{}n',strng)
241 return strng
235 return strng
242
236
243 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
237 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
244 """Parse options passed to an argument string.
238 """Parse options passed to an argument string.
245
239
246 The interface is similar to that of getopt(), but it returns back a
240 The interface is similar to that of getopt(), but it returns back a
247 Struct with the options as keys and the stripped argument string still
241 Struct with the options as keys and the stripped argument string still
248 as a string.
242 as a string.
249
243
250 arg_str is quoted as a true sys.argv vector by using shlex.split.
244 arg_str is quoted as a true sys.argv vector by using shlex.split.
251 This allows us to easily expand variables, glob files, quote
245 This allows us to easily expand variables, glob files, quote
252 arguments, etc.
246 arguments, etc.
253
247
254 Options:
248 Options:
255 -mode: default 'string'. If given as 'list', the argument string is
249 -mode: default 'string'. If given as 'list', the argument string is
256 returned as a list (split on whitespace) instead of a string.
250 returned as a list (split on whitespace) instead of a string.
257
251
258 -list_all: put all option values in lists. Normally only options
252 -list_all: put all option values in lists. Normally only options
259 appearing more than once are put in a list.
253 appearing more than once are put in a list.
260
254
261 -posix (True): whether to split the input line in POSIX mode or not,
255 -posix (True): whether to split the input line in POSIX mode or not,
262 as per the conventions outlined in the shlex module from the
256 as per the conventions outlined in the shlex module from the
263 standard library."""
257 standard library."""
264
258
265 # inject default options at the beginning of the input line
259 # inject default options at the beginning of the input line
266 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
260 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
267 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
261 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
268
262
269 mode = kw.get('mode','string')
263 mode = kw.get('mode','string')
270 if mode not in ['string','list']:
264 if mode not in ['string','list']:
271 raise ValueError,'incorrect mode given: %s' % mode
265 raise ValueError,'incorrect mode given: %s' % mode
272 # Get options
266 # Get options
273 list_all = kw.get('list_all',0)
267 list_all = kw.get('list_all',0)
274 posix = kw.get('posix', os.name == 'posix')
268 posix = kw.get('posix', os.name == 'posix')
275 strict = kw.get('strict', True)
269 strict = kw.get('strict', True)
276
270
277 # Check if we have more than one argument to warrant extra processing:
271 # Check if we have more than one argument to warrant extra processing:
278 odict = {} # Dictionary with options
272 odict = {} # Dictionary with options
279 args = arg_str.split()
273 args = arg_str.split()
280 if len(args) >= 1:
274 if len(args) >= 1:
281 # If the list of inputs only has 0 or 1 thing in it, there's no
275 # If the list of inputs only has 0 or 1 thing in it, there's no
282 # need to look for options
276 # need to look for options
283 argv = arg_split(arg_str, posix, strict)
277 argv = arg_split(arg_str, posix, strict)
284 # Do regular option processing
278 # Do regular option processing
285 try:
279 try:
286 opts,args = getopt(argv,opt_str,*long_opts)
280 opts,args = getopt(argv,opt_str,*long_opts)
287 except GetoptError,e:
281 except GetoptError,e:
288 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
282 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
289 " ".join(long_opts)))
283 " ".join(long_opts)))
290 for o,a in opts:
284 for o,a in opts:
291 if o.startswith('--'):
285 if o.startswith('--'):
292 o = o[2:]
286 o = o[2:]
293 else:
287 else:
294 o = o[1:]
288 o = o[1:]
295 try:
289 try:
296 odict[o].append(a)
290 odict[o].append(a)
297 except AttributeError:
291 except AttributeError:
298 odict[o] = [odict[o],a]
292 odict[o] = [odict[o],a]
299 except KeyError:
293 except KeyError:
300 if list_all:
294 if list_all:
301 odict[o] = [a]
295 odict[o] = [a]
302 else:
296 else:
303 odict[o] = a
297 odict[o] = a
304
298
305 # Prepare opts,args for return
299 # Prepare opts,args for return
306 opts = Struct(odict)
300 opts = Struct(odict)
307 if mode == 'string':
301 if mode == 'string':
308 args = ' '.join(args)
302 args = ' '.join(args)
309
303
310 return opts,args
304 return opts,args
311
305
312 #......................................................................
306 #......................................................................
313 # And now the actual magic functions
307 # And now the actual magic functions
314
308
315 # Functions for IPython shell work (vars,funcs, config, etc)
309 # Functions for IPython shell work (vars,funcs, config, etc)
316 def magic_lsmagic(self, parameter_s = ''):
310 def magic_lsmagic(self, parameter_s = ''):
317 """List currently available magic functions."""
311 """List currently available magic functions."""
318 mesc = ESC_MAGIC
312 mesc = ESC_MAGIC
319 print 'Available magic functions:\n'+mesc+\
313 print 'Available magic functions:\n'+mesc+\
320 (' '+mesc).join(self.lsmagic())
314 (' '+mesc).join(self.lsmagic())
321 print '\n' + Magic.auto_status[self.shell.automagic]
315 print '\n' + Magic.auto_status[self.shell.automagic]
322 return None
316 return None
323
317
324 def magic_magic(self, parameter_s = ''):
318 def magic_magic(self, parameter_s = ''):
325 """Print information about the magic function system.
319 """Print information about the magic function system.
326
320
327 Supported formats: -latex, -brief, -rest
321 Supported formats: -latex, -brief, -rest
328 """
322 """
329
323
330 mode = ''
324 mode = ''
331 try:
325 try:
332 if parameter_s.split()[0] == '-latex':
326 if parameter_s.split()[0] == '-latex':
333 mode = 'latex'
327 mode = 'latex'
334 if parameter_s.split()[0] == '-brief':
328 if parameter_s.split()[0] == '-brief':
335 mode = 'brief'
329 mode = 'brief'
336 if parameter_s.split()[0] == '-rest':
330 if parameter_s.split()[0] == '-rest':
337 mode = 'rest'
331 mode = 'rest'
338 rest_docs = []
332 rest_docs = []
339 except:
333 except:
340 pass
334 pass
341
335
342 magic_docs = []
336 magic_docs = []
343 for fname in self.lsmagic():
337 for fname in self.lsmagic():
344 mname = 'magic_' + fname
338 mname = 'magic_' + fname
345 for space in (Magic,self,self.__class__):
339 for space in (Magic,self,self.__class__):
346 try:
340 try:
347 fn = space.__dict__[mname]
341 fn = space.__dict__[mname]
348 except KeyError:
342 except KeyError:
349 pass
343 pass
350 else:
344 else:
351 break
345 break
352 if mode == 'brief':
346 if mode == 'brief':
353 # only first line
347 # only first line
354 if fn.__doc__:
348 if fn.__doc__:
355 fndoc = fn.__doc__.split('\n',1)[0]
349 fndoc = fn.__doc__.split('\n',1)[0]
356 else:
350 else:
357 fndoc = 'No documentation'
351 fndoc = 'No documentation'
358 else:
352 else:
359 if fn.__doc__:
353 if fn.__doc__:
360 fndoc = fn.__doc__.rstrip()
354 fndoc = fn.__doc__.rstrip()
361 else:
355 else:
362 fndoc = 'No documentation'
356 fndoc = 'No documentation'
363
357
364
358
365 if mode == 'rest':
359 if mode == 'rest':
366 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(ESC_MAGIC,
360 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(ESC_MAGIC,
367 fname,fndoc))
361 fname,fndoc))
368
362
369 else:
363 else:
370 magic_docs.append('%s%s:\n\t%s\n' %(ESC_MAGIC,
364 magic_docs.append('%s%s:\n\t%s\n' %(ESC_MAGIC,
371 fname,fndoc))
365 fname,fndoc))
372
366
373 magic_docs = ''.join(magic_docs)
367 magic_docs = ''.join(magic_docs)
374
368
375 if mode == 'rest':
369 if mode == 'rest':
376 return "".join(rest_docs)
370 return "".join(rest_docs)
377
371
378 if mode == 'latex':
372 if mode == 'latex':
379 print self.format_latex(magic_docs)
373 print self.format_latex(magic_docs)
380 return
374 return
381 else:
375 else:
382 magic_docs = format_screen(magic_docs)
376 magic_docs = format_screen(magic_docs)
383 if mode == 'brief':
377 if mode == 'brief':
384 return magic_docs
378 return magic_docs
385
379
386 outmsg = """
380 outmsg = """
387 IPython's 'magic' functions
381 IPython's 'magic' functions
388 ===========================
382 ===========================
389
383
390 The magic function system provides a series of functions which allow you to
384 The magic function system provides a series of functions which allow you to
391 control the behavior of IPython itself, plus a lot of system-type
385 control the behavior of IPython itself, plus a lot of system-type
392 features. All these functions are prefixed with a % character, but parameters
386 features. All these functions are prefixed with a % character, but parameters
393 are given without parentheses or quotes.
387 are given without parentheses or quotes.
394
388
395 NOTE: If you have 'automagic' enabled (via the command line option or with the
389 NOTE: If you have 'automagic' enabled (via the command line option or with the
396 %automagic function), you don't need to type in the % explicitly. By default,
390 %automagic function), you don't need to type in the % explicitly. By default,
397 IPython ships with automagic on, so you should only rarely need the % escape.
391 IPython ships with automagic on, so you should only rarely need the % escape.
398
392
399 Example: typing '%cd mydir' (without the quotes) changes you working directory
393 Example: typing '%cd mydir' (without the quotes) changes you working directory
400 to 'mydir', if it exists.
394 to 'mydir', if it exists.
401
395
402 For a list of the available magic functions, use %lsmagic. For a description
396 For a list of the available magic functions, use %lsmagic. For a description
403 of any of them, type %magic_name?, e.g. '%cd?'.
397 of any of them, type %magic_name?, e.g. '%cd?'.
404
398
405 Currently the magic system has the following functions:\n"""
399 Currently the magic system has the following functions:\n"""
406
400
407 mesc = ESC_MAGIC
401 mesc = ESC_MAGIC
408 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
402 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
409 "\n\n%s%s\n\n%s" % (outmsg,
403 "\n\n%s%s\n\n%s" % (outmsg,
410 magic_docs,mesc,mesc,
404 magic_docs,mesc,mesc,
411 (' '+mesc).join(self.lsmagic()),
405 (' '+mesc).join(self.lsmagic()),
412 Magic.auto_status[self.shell.automagic] ) )
406 Magic.auto_status[self.shell.automagic] ) )
413 page.page(outmsg)
407 page.page(outmsg)
414
408
415 def magic_automagic(self, parameter_s = ''):
409 def magic_automagic(self, parameter_s = ''):
416 """Make magic functions callable without having to type the initial %.
410 """Make magic functions callable without having to type the initial %.
417
411
418 Without argumentsl toggles on/off (when off, you must call it as
412 Without argumentsl toggles on/off (when off, you must call it as
419 %automagic, of course). With arguments it sets the value, and you can
413 %automagic, of course). With arguments it sets the value, and you can
420 use any of (case insensitive):
414 use any of (case insensitive):
421
415
422 - on,1,True: to activate
416 - on,1,True: to activate
423
417
424 - off,0,False: to deactivate.
418 - off,0,False: to deactivate.
425
419
426 Note that magic functions have lowest priority, so if there's a
420 Note that magic functions have lowest priority, so if there's a
427 variable whose name collides with that of a magic fn, automagic won't
421 variable whose name collides with that of a magic fn, automagic won't
428 work for that function (you get the variable instead). However, if you
422 work for that function (you get the variable instead). However, if you
429 delete the variable (del var), the previously shadowed magic function
423 delete the variable (del var), the previously shadowed magic function
430 becomes visible to automagic again."""
424 becomes visible to automagic again."""
431
425
432 arg = parameter_s.lower()
426 arg = parameter_s.lower()
433 if parameter_s in ('on','1','true'):
427 if parameter_s in ('on','1','true'):
434 self.shell.automagic = True
428 self.shell.automagic = True
435 elif parameter_s in ('off','0','false'):
429 elif parameter_s in ('off','0','false'):
436 self.shell.automagic = False
430 self.shell.automagic = False
437 else:
431 else:
438 self.shell.automagic = not self.shell.automagic
432 self.shell.automagic = not self.shell.automagic
439 print '\n' + Magic.auto_status[self.shell.automagic]
433 print '\n' + Magic.auto_status[self.shell.automagic]
440
434
441 @skip_doctest
435 @skip_doctest
442 def magic_autocall(self, parameter_s = ''):
436 def magic_autocall(self, parameter_s = ''):
443 """Make functions callable without having to type parentheses.
437 """Make functions callable without having to type parentheses.
444
438
445 Usage:
439 Usage:
446
440
447 %autocall [mode]
441 %autocall [mode]
448
442
449 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
443 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
450 value is toggled on and off (remembering the previous state).
444 value is toggled on and off (remembering the previous state).
451
445
452 In more detail, these values mean:
446 In more detail, these values mean:
453
447
454 0 -> fully disabled
448 0 -> fully disabled
455
449
456 1 -> active, but do not apply if there are no arguments on the line.
450 1 -> active, but do not apply if there are no arguments on the line.
457
451
458 In this mode, you get::
452 In this mode, you get::
459
453
460 In [1]: callable
454 In [1]: callable
461 Out[1]: <built-in function callable>
455 Out[1]: <built-in function callable>
462
456
463 In [2]: callable 'hello'
457 In [2]: callable 'hello'
464 ------> callable('hello')
458 ------> callable('hello')
465 Out[2]: False
459 Out[2]: False
466
460
467 2 -> Active always. Even if no arguments are present, the callable
461 2 -> Active always. Even if no arguments are present, the callable
468 object is called::
462 object is called::
469
463
470 In [2]: float
464 In [2]: float
471 ------> float()
465 ------> float()
472 Out[2]: 0.0
466 Out[2]: 0.0
473
467
474 Note that even with autocall off, you can still use '/' at the start of
468 Note that even with autocall off, you can still use '/' at the start of
475 a line to treat the first argument on the command line as a function
469 a line to treat the first argument on the command line as a function
476 and add parentheses to it::
470 and add parentheses to it::
477
471
478 In [8]: /str 43
472 In [8]: /str 43
479 ------> str(43)
473 ------> str(43)
480 Out[8]: '43'
474 Out[8]: '43'
481
475
482 # all-random (note for auto-testing)
476 # all-random (note for auto-testing)
483 """
477 """
484
478
485 if parameter_s:
479 if parameter_s:
486 arg = int(parameter_s)
480 arg = int(parameter_s)
487 else:
481 else:
488 arg = 'toggle'
482 arg = 'toggle'
489
483
490 if not arg in (0,1,2,'toggle'):
484 if not arg in (0,1,2,'toggle'):
491 error('Valid modes: (0->Off, 1->Smart, 2->Full')
485 error('Valid modes: (0->Off, 1->Smart, 2->Full')
492 return
486 return
493
487
494 if arg in (0,1,2):
488 if arg in (0,1,2):
495 self.shell.autocall = arg
489 self.shell.autocall = arg
496 else: # toggle
490 else: # toggle
497 if self.shell.autocall:
491 if self.shell.autocall:
498 self._magic_state.autocall_save = self.shell.autocall
492 self._magic_state.autocall_save = self.shell.autocall
499 self.shell.autocall = 0
493 self.shell.autocall = 0
500 else:
494 else:
501 try:
495 try:
502 self.shell.autocall = self._magic_state.autocall_save
496 self.shell.autocall = self._magic_state.autocall_save
503 except AttributeError:
497 except AttributeError:
504 self.shell.autocall = self._magic_state.autocall_save = 1
498 self.shell.autocall = self._magic_state.autocall_save = 1
505
499
506 print "Automatic calling is:",['OFF','Smart','Full'][self.shell.autocall]
500 print "Automatic calling is:",['OFF','Smart','Full'][self.shell.autocall]
507
501
508
502
509 def magic_page(self, parameter_s=''):
503 def magic_page(self, parameter_s=''):
510 """Pretty print the object and display it through a pager.
504 """Pretty print the object and display it through a pager.
511
505
512 %page [options] OBJECT
506 %page [options] OBJECT
513
507
514 If no object is given, use _ (last output).
508 If no object is given, use _ (last output).
515
509
516 Options:
510 Options:
517
511
518 -r: page str(object), don't pretty-print it."""
512 -r: page str(object), don't pretty-print it."""
519
513
520 # After a function contributed by Olivier Aubert, slightly modified.
514 # After a function contributed by Olivier Aubert, slightly modified.
521
515
522 # Process options/args
516 # Process options/args
523 opts,args = self.parse_options(parameter_s,'r')
517 opts,args = self.parse_options(parameter_s,'r')
524 raw = 'r' in opts
518 raw = 'r' in opts
525
519
526 oname = args and args or '_'
520 oname = args and args or '_'
527 info = self._ofind(oname)
521 info = self._ofind(oname)
528 if info['found']:
522 if info['found']:
529 txt = (raw and str or pformat)( info['obj'] )
523 txt = (raw and str or pformat)( info['obj'] )
530 page.page(txt)
524 page.page(txt)
531 else:
525 else:
532 print 'Object `%s` not found' % oname
526 print 'Object `%s` not found' % oname
533
527
534 def magic_profile(self, parameter_s=''):
528 def magic_profile(self, parameter_s=''):
535 """Print your currently active IPython profile."""
529 """Print your currently active IPython profile."""
536 from IPython.core.application import BaseIPythonApplication
530 from IPython.core.application import BaseIPythonApplication
537 if BaseIPythonApplication.initialized():
531 if BaseIPythonApplication.initialized():
538 print BaseIPythonApplication.instance().profile
532 print BaseIPythonApplication.instance().profile
539 else:
533 else:
540 error("profile is an application-level value, but you don't appear to be in an IPython application")
534 error("profile is an application-level value, but you don't appear to be in an IPython application")
541
535
542 def magic_pinfo(self, parameter_s='', namespaces=None):
536 def magic_pinfo(self, parameter_s='', namespaces=None):
543 """Provide detailed information about an object.
537 """Provide detailed information about an object.
544
538
545 '%pinfo object' is just a synonym for object? or ?object."""
539 '%pinfo object' is just a synonym for object? or ?object."""
546
540
547 #print 'pinfo par: <%s>' % parameter_s # dbg
541 #print 'pinfo par: <%s>' % parameter_s # dbg
548
542
549
543
550 # detail_level: 0 -> obj? , 1 -> obj??
544 # detail_level: 0 -> obj? , 1 -> obj??
551 detail_level = 0
545 detail_level = 0
552 # We need to detect if we got called as 'pinfo pinfo foo', which can
546 # We need to detect if we got called as 'pinfo pinfo foo', which can
553 # happen if the user types 'pinfo foo?' at the cmd line.
547 # happen if the user types 'pinfo foo?' at the cmd line.
554 pinfo,qmark1,oname,qmark2 = \
548 pinfo,qmark1,oname,qmark2 = \
555 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
549 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
556 if pinfo or qmark1 or qmark2:
550 if pinfo or qmark1 or qmark2:
557 detail_level = 1
551 detail_level = 1
558 if "*" in oname:
552 if "*" in oname:
559 self.magic_psearch(oname)
553 self.magic_psearch(oname)
560 else:
554 else:
561 self.shell._inspect('pinfo', oname, detail_level=detail_level,
555 self.shell._inspect('pinfo', oname, detail_level=detail_level,
562 namespaces=namespaces)
556 namespaces=namespaces)
563
557
564 def magic_pinfo2(self, parameter_s='', namespaces=None):
558 def magic_pinfo2(self, parameter_s='', namespaces=None):
565 """Provide extra detailed information about an object.
559 """Provide extra detailed information about an object.
566
560
567 '%pinfo2 object' is just a synonym for object?? or ??object."""
561 '%pinfo2 object' is just a synonym for object?? or ??object."""
568 self.shell._inspect('pinfo', parameter_s, detail_level=1,
562 self.shell._inspect('pinfo', parameter_s, detail_level=1,
569 namespaces=namespaces)
563 namespaces=namespaces)
570
564
571 @skip_doctest
565 @skip_doctest
572 def magic_pdef(self, parameter_s='', namespaces=None):
566 def magic_pdef(self, parameter_s='', namespaces=None):
573 """Print the definition header for any callable object.
567 """Print the definition header for any callable object.
574
568
575 If the object is a class, print the constructor information.
569 If the object is a class, print the constructor information.
576
570
577 Examples
571 Examples
578 --------
572 --------
579 ::
573 ::
580
574
581 In [3]: %pdef urllib.urlopen
575 In [3]: %pdef urllib.urlopen
582 urllib.urlopen(url, data=None, proxies=None)
576 urllib.urlopen(url, data=None, proxies=None)
583 """
577 """
584 self._inspect('pdef',parameter_s, namespaces)
578 self._inspect('pdef',parameter_s, namespaces)
585
579
586 def magic_pdoc(self, parameter_s='', namespaces=None):
580 def magic_pdoc(self, parameter_s='', namespaces=None):
587 """Print the docstring for an object.
581 """Print the docstring for an object.
588
582
589 If the given object is a class, it will print both the class and the
583 If the given object is a class, it will print both the class and the
590 constructor docstrings."""
584 constructor docstrings."""
591 self._inspect('pdoc',parameter_s, namespaces)
585 self._inspect('pdoc',parameter_s, namespaces)
592
586
593 def magic_psource(self, parameter_s='', namespaces=None):
587 def magic_psource(self, parameter_s='', namespaces=None):
594 """Print (or run through pager) the source code for an object."""
588 """Print (or run through pager) the source code for an object."""
595 self._inspect('psource',parameter_s, namespaces)
589 self._inspect('psource',parameter_s, namespaces)
596
590
597 def magic_pfile(self, parameter_s=''):
591 def magic_pfile(self, parameter_s=''):
598 """Print (or run through pager) the file where an object is defined.
592 """Print (or run through pager) the file where an object is defined.
599
593
600 The file opens at the line where the object definition begins. IPython
594 The file opens at the line where the object definition begins. IPython
601 will honor the environment variable PAGER if set, and otherwise will
595 will honor the environment variable PAGER if set, and otherwise will
602 do its best to print the file in a convenient form.
596 do its best to print the file in a convenient form.
603
597
604 If the given argument is not an object currently defined, IPython will
598 If the given argument is not an object currently defined, IPython will
605 try to interpret it as a filename (automatically adding a .py extension
599 try to interpret it as a filename (automatically adding a .py extension
606 if needed). You can thus use %pfile as a syntax highlighting code
600 if needed). You can thus use %pfile as a syntax highlighting code
607 viewer."""
601 viewer."""
608
602
609 # first interpret argument as an object name
603 # first interpret argument as an object name
610 out = self._inspect('pfile',parameter_s)
604 out = self._inspect('pfile',parameter_s)
611 # if not, try the input as a filename
605 # if not, try the input as a filename
612 if out == 'not found':
606 if out == 'not found':
613 try:
607 try:
614 filename = get_py_filename(parameter_s)
608 filename = get_py_filename(parameter_s)
615 except IOError,msg:
609 except IOError,msg:
616 print msg
610 print msg
617 return
611 return
618 page.page(self.shell.inspector.format(open(filename).read()))
612 page.page(self.shell.inspector.format(open(filename).read()))
619
613
620 def magic_psearch(self, parameter_s=''):
614 def magic_psearch(self, parameter_s=''):
621 """Search for object in namespaces by wildcard.
615 """Search for object in namespaces by wildcard.
622
616
623 %psearch [options] PATTERN [OBJECT TYPE]
617 %psearch [options] PATTERN [OBJECT TYPE]
624
618
625 Note: ? can be used as a synonym for %psearch, at the beginning or at
619 Note: ? can be used as a synonym for %psearch, at the beginning or at
626 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
620 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
627 rest of the command line must be unchanged (options come first), so
621 rest of the command line must be unchanged (options come first), so
628 for example the following forms are equivalent
622 for example the following forms are equivalent
629
623
630 %psearch -i a* function
624 %psearch -i a* function
631 -i a* function?
625 -i a* function?
632 ?-i a* function
626 ?-i a* function
633
627
634 Arguments:
628 Arguments:
635
629
636 PATTERN
630 PATTERN
637
631
638 where PATTERN is a string containing * as a wildcard similar to its
632 where PATTERN is a string containing * as a wildcard similar to its
639 use in a shell. The pattern is matched in all namespaces on the
633 use in a shell. The pattern is matched in all namespaces on the
640 search path. By default objects starting with a single _ are not
634 search path. By default objects starting with a single _ are not
641 matched, many IPython generated objects have a single
635 matched, many IPython generated objects have a single
642 underscore. The default is case insensitive matching. Matching is
636 underscore. The default is case insensitive matching. Matching is
643 also done on the attributes of objects and not only on the objects
637 also done on the attributes of objects and not only on the objects
644 in a module.
638 in a module.
645
639
646 [OBJECT TYPE]
640 [OBJECT TYPE]
647
641
648 Is the name of a python type from the types module. The name is
642 Is the name of a python type from the types module. The name is
649 given in lowercase without the ending type, ex. StringType is
643 given in lowercase without the ending type, ex. StringType is
650 written string. By adding a type here only objects matching the
644 written string. By adding a type here only objects matching the
651 given type are matched. Using all here makes the pattern match all
645 given type are matched. Using all here makes the pattern match all
652 types (this is the default).
646 types (this is the default).
653
647
654 Options:
648 Options:
655
649
656 -a: makes the pattern match even objects whose names start with a
650 -a: makes the pattern match even objects whose names start with a
657 single underscore. These names are normally omitted from the
651 single underscore. These names are normally omitted from the
658 search.
652 search.
659
653
660 -i/-c: make the pattern case insensitive/sensitive. If neither of
654 -i/-c: make the pattern case insensitive/sensitive. If neither of
661 these options are given, the default is read from your configuration
655 these options are given, the default is read from your configuration
662 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
656 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
663 If this option is not specified in your configuration file, IPython's
657 If this option is not specified in your configuration file, IPython's
664 internal default is to do a case sensitive search.
658 internal default is to do a case sensitive search.
665
659
666 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
660 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
667 specify can be searched in any of the following namespaces:
661 specify can be searched in any of the following namespaces:
668 'builtin', 'user', 'user_global','internal', 'alias', where
662 'builtin', 'user', 'user_global','internal', 'alias', where
669 'builtin' and 'user' are the search defaults. Note that you should
663 'builtin' and 'user' are the search defaults. Note that you should
670 not use quotes when specifying namespaces.
664 not use quotes when specifying namespaces.
671
665
672 'Builtin' contains the python module builtin, 'user' contains all
666 'Builtin' contains the python module builtin, 'user' contains all
673 user data, 'alias' only contain the shell aliases and no python
667 user data, 'alias' only contain the shell aliases and no python
674 objects, 'internal' contains objects used by IPython. The
668 objects, 'internal' contains objects used by IPython. The
675 'user_global' namespace is only used by embedded IPython instances,
669 'user_global' namespace is only used by embedded IPython instances,
676 and it contains module-level globals. You can add namespaces to the
670 and it contains module-level globals. You can add namespaces to the
677 search with -s or exclude them with -e (these options can be given
671 search with -s or exclude them with -e (these options can be given
678 more than once).
672 more than once).
679
673
680 Examples
674 Examples
681 --------
675 --------
682 ::
676 ::
683
677
684 %psearch a* -> objects beginning with an a
678 %psearch a* -> objects beginning with an a
685 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
679 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
686 %psearch a* function -> all functions beginning with an a
680 %psearch a* function -> all functions beginning with an a
687 %psearch re.e* -> objects beginning with an e in module re
681 %psearch re.e* -> objects beginning with an e in module re
688 %psearch r*.e* -> objects that start with e in modules starting in r
682 %psearch r*.e* -> objects that start with e in modules starting in r
689 %psearch r*.* string -> all strings in modules beginning with r
683 %psearch r*.* string -> all strings in modules beginning with r
690
684
691 Case sensitive search::
685 Case sensitive search::
692
686
693 %psearch -c a* list all object beginning with lower case a
687 %psearch -c a* list all object beginning with lower case a
694
688
695 Show objects beginning with a single _::
689 Show objects beginning with a single _::
696
690
697 %psearch -a _* list objects beginning with a single underscore"""
691 %psearch -a _* list objects beginning with a single underscore"""
698 try:
692 try:
699 parameter_s.encode('ascii')
693 parameter_s.encode('ascii')
700 except UnicodeEncodeError:
694 except UnicodeEncodeError:
701 print 'Python identifiers can only contain ascii characters.'
695 print 'Python identifiers can only contain ascii characters.'
702 return
696 return
703
697
704 # default namespaces to be searched
698 # default namespaces to be searched
705 def_search = ['user_local', 'user_global', 'builtin']
699 def_search = ['user_local', 'user_global', 'builtin']
706
700
707 # Process options/args
701 # Process options/args
708 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
702 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
709 opt = opts.get
703 opt = opts.get
710 shell = self.shell
704 shell = self.shell
711 psearch = shell.inspector.psearch
705 psearch = shell.inspector.psearch
712
706
713 # select case options
707 # select case options
714 if opts.has_key('i'):
708 if opts.has_key('i'):
715 ignore_case = True
709 ignore_case = True
716 elif opts.has_key('c'):
710 elif opts.has_key('c'):
717 ignore_case = False
711 ignore_case = False
718 else:
712 else:
719 ignore_case = not shell.wildcards_case_sensitive
713 ignore_case = not shell.wildcards_case_sensitive
720
714
721 # Build list of namespaces to search from user options
715 # Build list of namespaces to search from user options
722 def_search.extend(opt('s',[]))
716 def_search.extend(opt('s',[]))
723 ns_exclude = ns_exclude=opt('e',[])
717 ns_exclude = ns_exclude=opt('e',[])
724 ns_search = [nm for nm in def_search if nm not in ns_exclude]
718 ns_search = [nm for nm in def_search if nm not in ns_exclude]
725
719
726 # Call the actual search
720 # Call the actual search
727 try:
721 try:
728 psearch(args,shell.ns_table,ns_search,
722 psearch(args,shell.ns_table,ns_search,
729 show_all=opt('a'),ignore_case=ignore_case)
723 show_all=opt('a'),ignore_case=ignore_case)
730 except:
724 except:
731 shell.showtraceback()
725 shell.showtraceback()
732
726
733 @skip_doctest
727 @skip_doctest
734 def magic_who_ls(self, parameter_s=''):
728 def magic_who_ls(self, parameter_s=''):
735 """Return a sorted list of all interactive variables.
729 """Return a sorted list of all interactive variables.
736
730
737 If arguments are given, only variables of types matching these
731 If arguments are given, only variables of types matching these
738 arguments are returned.
732 arguments are returned.
739
733
740 Examples
734 Examples
741 --------
735 --------
742
736
743 Define two variables and list them with who_ls::
737 Define two variables and list them with who_ls::
744
738
745 In [1]: alpha = 123
739 In [1]: alpha = 123
746
740
747 In [2]: beta = 'test'
741 In [2]: beta = 'test'
748
742
749 In [3]: %who_ls
743 In [3]: %who_ls
750 Out[3]: ['alpha', 'beta']
744 Out[3]: ['alpha', 'beta']
751
745
752 In [4]: %who_ls int
746 In [4]: %who_ls int
753 Out[4]: ['alpha']
747 Out[4]: ['alpha']
754
748
755 In [5]: %who_ls str
749 In [5]: %who_ls str
756 Out[5]: ['beta']
750 Out[5]: ['beta']
757 """
751 """
758
752
759 user_ns = self.shell.user_ns
753 user_ns = self.shell.user_ns
760 user_ns_hidden = self.shell.user_ns_hidden
754 user_ns_hidden = self.shell.user_ns_hidden
761 out = [ i for i in user_ns
755 out = [ i for i in user_ns
762 if not i.startswith('_') \
756 if not i.startswith('_') \
763 and not i in user_ns_hidden ]
757 and not i in user_ns_hidden ]
764
758
765 typelist = parameter_s.split()
759 typelist = parameter_s.split()
766 if typelist:
760 if typelist:
767 typeset = set(typelist)
761 typeset = set(typelist)
768 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
762 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
769
763
770 out.sort()
764 out.sort()
771 return out
765 return out
772
766
773 @skip_doctest
767 @skip_doctest
774 def magic_who(self, parameter_s=''):
768 def magic_who(self, parameter_s=''):
775 """Print all interactive variables, with some minimal formatting.
769 """Print all interactive variables, with some minimal formatting.
776
770
777 If any arguments are given, only variables whose type matches one of
771 If any arguments are given, only variables whose type matches one of
778 these are printed. For example::
772 these are printed. For example::
779
773
780 %who function str
774 %who function str
781
775
782 will only list functions and strings, excluding all other types of
776 will only list functions and strings, excluding all other types of
783 variables. To find the proper type names, simply use type(var) at a
777 variables. To find the proper type names, simply use type(var) at a
784 command line to see how python prints type names. For example:
778 command line to see how python prints type names. For example:
785
779
786 ::
780 ::
787
781
788 In [1]: type('hello')\\
782 In [1]: type('hello')\\
789 Out[1]: <type 'str'>
783 Out[1]: <type 'str'>
790
784
791 indicates that the type name for strings is 'str'.
785 indicates that the type name for strings is 'str'.
792
786
793 ``%who`` always excludes executed names loaded through your configuration
787 ``%who`` always excludes executed names loaded through your configuration
794 file and things which are internal to IPython.
788 file and things which are internal to IPython.
795
789
796 This is deliberate, as typically you may load many modules and the
790 This is deliberate, as typically you may load many modules and the
797 purpose of %who is to show you only what you've manually defined.
791 purpose of %who is to show you only what you've manually defined.
798
792
799 Examples
793 Examples
800 --------
794 --------
801
795
802 Define two variables and list them with who::
796 Define two variables and list them with who::
803
797
804 In [1]: alpha = 123
798 In [1]: alpha = 123
805
799
806 In [2]: beta = 'test'
800 In [2]: beta = 'test'
807
801
808 In [3]: %who
802 In [3]: %who
809 alpha beta
803 alpha beta
810
804
811 In [4]: %who int
805 In [4]: %who int
812 alpha
806 alpha
813
807
814 In [5]: %who str
808 In [5]: %who str
815 beta
809 beta
816 """
810 """
817
811
818 varlist = self.magic_who_ls(parameter_s)
812 varlist = self.magic_who_ls(parameter_s)
819 if not varlist:
813 if not varlist:
820 if parameter_s:
814 if parameter_s:
821 print 'No variables match your requested type.'
815 print 'No variables match your requested type.'
822 else:
816 else:
823 print 'Interactive namespace is empty.'
817 print 'Interactive namespace is empty.'
824 return
818 return
825
819
826 # if we have variables, move on...
820 # if we have variables, move on...
827 count = 0
821 count = 0
828 for i in varlist:
822 for i in varlist:
829 print i+'\t',
823 print i+'\t',
830 count += 1
824 count += 1
831 if count > 8:
825 if count > 8:
832 count = 0
826 count = 0
833 print
827 print
834 print
828 print
835
829
836 @skip_doctest
830 @skip_doctest
837 def magic_whos(self, parameter_s=''):
831 def magic_whos(self, parameter_s=''):
838 """Like %who, but gives some extra information about each variable.
832 """Like %who, but gives some extra information about each variable.
839
833
840 The same type filtering of %who can be applied here.
834 The same type filtering of %who can be applied here.
841
835
842 For all variables, the type is printed. Additionally it prints:
836 For all variables, the type is printed. Additionally it prints:
843
837
844 - For {},[],(): their length.
838 - For {},[],(): their length.
845
839
846 - For numpy arrays, a summary with shape, number of
840 - For numpy arrays, a summary with shape, number of
847 elements, typecode and size in memory.
841 elements, typecode and size in memory.
848
842
849 - Everything else: a string representation, snipping their middle if
843 - Everything else: a string representation, snipping their middle if
850 too long.
844 too long.
851
845
852 Examples
846 Examples
853 --------
847 --------
854
848
855 Define two variables and list them with whos::
849 Define two variables and list them with whos::
856
850
857 In [1]: alpha = 123
851 In [1]: alpha = 123
858
852
859 In [2]: beta = 'test'
853 In [2]: beta = 'test'
860
854
861 In [3]: %whos
855 In [3]: %whos
862 Variable Type Data/Info
856 Variable Type Data/Info
863 --------------------------------
857 --------------------------------
864 alpha int 123
858 alpha int 123
865 beta str test
859 beta str test
866 """
860 """
867
861
868 varnames = self.magic_who_ls(parameter_s)
862 varnames = self.magic_who_ls(parameter_s)
869 if not varnames:
863 if not varnames:
870 if parameter_s:
864 if parameter_s:
871 print 'No variables match your requested type.'
865 print 'No variables match your requested type.'
872 else:
866 else:
873 print 'Interactive namespace is empty.'
867 print 'Interactive namespace is empty.'
874 return
868 return
875
869
876 # if we have variables, move on...
870 # if we have variables, move on...
877
871
878 # for these types, show len() instead of data:
872 # for these types, show len() instead of data:
879 seq_types = ['dict', 'list', 'tuple']
873 seq_types = ['dict', 'list', 'tuple']
880
874
881 # for numpy arrays, display summary info
875 # for numpy arrays, display summary info
882 ndarray_type = None
876 ndarray_type = None
883 if 'numpy' in sys.modules:
877 if 'numpy' in sys.modules:
884 try:
878 try:
885 from numpy import ndarray
879 from numpy import ndarray
886 except ImportError:
880 except ImportError:
887 pass
881 pass
888 else:
882 else:
889 ndarray_type = ndarray.__name__
883 ndarray_type = ndarray.__name__
890
884
891 # Find all variable names and types so we can figure out column sizes
885 # Find all variable names and types so we can figure out column sizes
892 def get_vars(i):
886 def get_vars(i):
893 return self.shell.user_ns[i]
887 return self.shell.user_ns[i]
894
888
895 # some types are well known and can be shorter
889 # some types are well known and can be shorter
896 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
890 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
897 def type_name(v):
891 def type_name(v):
898 tn = type(v).__name__
892 tn = type(v).__name__
899 return abbrevs.get(tn,tn)
893 return abbrevs.get(tn,tn)
900
894
901 varlist = map(get_vars,varnames)
895 varlist = map(get_vars,varnames)
902
896
903 typelist = []
897 typelist = []
904 for vv in varlist:
898 for vv in varlist:
905 tt = type_name(vv)
899 tt = type_name(vv)
906
900
907 if tt=='instance':
901 if tt=='instance':
908 typelist.append( abbrevs.get(str(vv.__class__),
902 typelist.append( abbrevs.get(str(vv.__class__),
909 str(vv.__class__)))
903 str(vv.__class__)))
910 else:
904 else:
911 typelist.append(tt)
905 typelist.append(tt)
912
906
913 # column labels and # of spaces as separator
907 # column labels and # of spaces as separator
914 varlabel = 'Variable'
908 varlabel = 'Variable'
915 typelabel = 'Type'
909 typelabel = 'Type'
916 datalabel = 'Data/Info'
910 datalabel = 'Data/Info'
917 colsep = 3
911 colsep = 3
918 # variable format strings
912 # variable format strings
919 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
913 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
920 aformat = "%s: %s elems, type `%s`, %s bytes"
914 aformat = "%s: %s elems, type `%s`, %s bytes"
921 # find the size of the columns to format the output nicely
915 # find the size of the columns to format the output nicely
922 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
916 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
923 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
917 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
924 # table header
918 # table header
925 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
919 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
926 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
920 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
927 # and the table itself
921 # and the table itself
928 kb = 1024
922 kb = 1024
929 Mb = 1048576 # kb**2
923 Mb = 1048576 # kb**2
930 for vname,var,vtype in zip(varnames,varlist,typelist):
924 for vname,var,vtype in zip(varnames,varlist,typelist):
931 print vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth),
925 print vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth),
932 if vtype in seq_types:
926 if vtype in seq_types:
933 print "n="+str(len(var))
927 print "n="+str(len(var))
934 elif vtype == ndarray_type:
928 elif vtype == ndarray_type:
935 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
929 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
936 if vtype==ndarray_type:
930 if vtype==ndarray_type:
937 # numpy
931 # numpy
938 vsize = var.size
932 vsize = var.size
939 vbytes = vsize*var.itemsize
933 vbytes = vsize*var.itemsize
940 vdtype = var.dtype
934 vdtype = var.dtype
941
935
942 if vbytes < 100000:
936 if vbytes < 100000:
943 print aformat % (vshape,vsize,vdtype,vbytes)
937 print aformat % (vshape,vsize,vdtype,vbytes)
944 else:
938 else:
945 print aformat % (vshape,vsize,vdtype,vbytes),
939 print aformat % (vshape,vsize,vdtype,vbytes),
946 if vbytes < Mb:
940 if vbytes < Mb:
947 print '(%s kb)' % (vbytes/kb,)
941 print '(%s kb)' % (vbytes/kb,)
948 else:
942 else:
949 print '(%s Mb)' % (vbytes/Mb,)
943 print '(%s Mb)' % (vbytes/Mb,)
950 else:
944 else:
951 try:
945 try:
952 vstr = str(var)
946 vstr = str(var)
953 except UnicodeEncodeError:
947 except UnicodeEncodeError:
954 vstr = unicode(var).encode(DEFAULT_ENCODING,
948 vstr = unicode(var).encode(DEFAULT_ENCODING,
955 'backslashreplace')
949 'backslashreplace')
956 except:
950 except:
957 vstr = "<object with id %d (str() failed)>" % id(var)
951 vstr = "<object with id %d (str() failed)>" % id(var)
958 vstr = vstr.replace('\n','\\n')
952 vstr = vstr.replace('\n','\\n')
959 if len(vstr) < 50:
953 if len(vstr) < 50:
960 print vstr
954 print vstr
961 else:
955 else:
962 print vstr[:25] + "<...>" + vstr[-25:]
956 print vstr[:25] + "<...>" + vstr[-25:]
963
957
964 def magic_reset(self, parameter_s=''):
958 def magic_reset(self, parameter_s=''):
965 """Resets the namespace by removing all names defined by the user, if
959 """Resets the namespace by removing all names defined by the user, if
966 called without arguments, or by removing some types of objects, such
960 called without arguments, or by removing some types of objects, such
967 as everything currently in IPython's In[] and Out[] containers (see
961 as everything currently in IPython's In[] and Out[] containers (see
968 the parameters for details).
962 the parameters for details).
969
963
970 Parameters
964 Parameters
971 ----------
965 ----------
972 -f : force reset without asking for confirmation.
966 -f : force reset without asking for confirmation.
973
967
974 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
968 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
975 References to objects may be kept. By default (without this option),
969 References to objects may be kept. By default (without this option),
976 we do a 'hard' reset, giving you a new session and removing all
970 we do a 'hard' reset, giving you a new session and removing all
977 references to objects from the current session.
971 references to objects from the current session.
978
972
979 in : reset input history
973 in : reset input history
980
974
981 out : reset output history
975 out : reset output history
982
976
983 dhist : reset directory history
977 dhist : reset directory history
984
978
985 array : reset only variables that are NumPy arrays
979 array : reset only variables that are NumPy arrays
986
980
987 See Also
981 See Also
988 --------
982 --------
989 magic_reset_selective : invoked as ``%reset_selective``
983 magic_reset_selective : invoked as ``%reset_selective``
990
984
991 Examples
985 Examples
992 --------
986 --------
993 ::
987 ::
994
988
995 In [6]: a = 1
989 In [6]: a = 1
996
990
997 In [7]: a
991 In [7]: a
998 Out[7]: 1
992 Out[7]: 1
999
993
1000 In [8]: 'a' in _ip.user_ns
994 In [8]: 'a' in _ip.user_ns
1001 Out[8]: True
995 Out[8]: True
1002
996
1003 In [9]: %reset -f
997 In [9]: %reset -f
1004
998
1005 In [1]: 'a' in _ip.user_ns
999 In [1]: 'a' in _ip.user_ns
1006 Out[1]: False
1000 Out[1]: False
1007
1001
1008 In [2]: %reset -f in
1002 In [2]: %reset -f in
1009 Flushing input history
1003 Flushing input history
1010
1004
1011 In [3]: %reset -f dhist in
1005 In [3]: %reset -f dhist in
1012 Flushing directory history
1006 Flushing directory history
1013 Flushing input history
1007 Flushing input history
1014
1008
1015 Notes
1009 Notes
1016 -----
1010 -----
1017 Calling this magic from clients that do not implement standard input,
1011 Calling this magic from clients that do not implement standard input,
1018 such as the ipython notebook interface, will reset the namespace
1012 such as the ipython notebook interface, will reset the namespace
1019 without confirmation.
1013 without confirmation.
1020 """
1014 """
1021 opts, args = self.parse_options(parameter_s,'sf', mode='list')
1015 opts, args = self.parse_options(parameter_s,'sf', mode='list')
1022 if 'f' in opts:
1016 if 'f' in opts:
1023 ans = True
1017 ans = True
1024 else:
1018 else:
1025 try:
1019 try:
1026 ans = self.shell.ask_yes_no(
1020 ans = self.shell.ask_yes_no(
1027 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ", default='n')
1021 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ", default='n')
1028 except StdinNotImplementedError:
1022 except StdinNotImplementedError:
1029 ans = True
1023 ans = True
1030 if not ans:
1024 if not ans:
1031 print 'Nothing done.'
1025 print 'Nothing done.'
1032 return
1026 return
1033
1027
1034 if 's' in opts: # Soft reset
1028 if 's' in opts: # Soft reset
1035 user_ns = self.shell.user_ns
1029 user_ns = self.shell.user_ns
1036 for i in self.magic_who_ls():
1030 for i in self.magic_who_ls():
1037 del(user_ns[i])
1031 del(user_ns[i])
1038 elif len(args) == 0: # Hard reset
1032 elif len(args) == 0: # Hard reset
1039 self.shell.reset(new_session = False)
1033 self.shell.reset(new_session = False)
1040
1034
1041 # reset in/out/dhist/array: previously extensinions/clearcmd.py
1035 # reset in/out/dhist/array: previously extensinions/clearcmd.py
1042 ip = self.shell
1036 ip = self.shell
1043 user_ns = self.user_ns # local lookup, heavily used
1037 user_ns = self.user_ns # local lookup, heavily used
1044
1038
1045 for target in args:
1039 for target in args:
1046 target = target.lower() # make matches case insensitive
1040 target = target.lower() # make matches case insensitive
1047 if target == 'out':
1041 if target == 'out':
1048 print "Flushing output cache (%d entries)" % len(user_ns['_oh'])
1042 print "Flushing output cache (%d entries)" % len(user_ns['_oh'])
1049 self.displayhook.flush()
1043 self.displayhook.flush()
1050
1044
1051 elif target == 'in':
1045 elif target == 'in':
1052 print "Flushing input history"
1046 print "Flushing input history"
1053 pc = self.displayhook.prompt_count + 1
1047 pc = self.displayhook.prompt_count + 1
1054 for n in range(1, pc):
1048 for n in range(1, pc):
1055 key = '_i'+repr(n)
1049 key = '_i'+repr(n)
1056 user_ns.pop(key,None)
1050 user_ns.pop(key,None)
1057 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
1051 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
1058 hm = ip.history_manager
1052 hm = ip.history_manager
1059 # don't delete these, as %save and %macro depending on the length
1053 # don't delete these, as %save and %macro depending on the length
1060 # of these lists to be preserved
1054 # of these lists to be preserved
1061 hm.input_hist_parsed[:] = [''] * pc
1055 hm.input_hist_parsed[:] = [''] * pc
1062 hm.input_hist_raw[:] = [''] * pc
1056 hm.input_hist_raw[:] = [''] * pc
1063 # hm has internal machinery for _i,_ii,_iii, clear it out
1057 # hm has internal machinery for _i,_ii,_iii, clear it out
1064 hm._i = hm._ii = hm._iii = hm._i00 = u''
1058 hm._i = hm._ii = hm._iii = hm._i00 = u''
1065
1059
1066 elif target == 'array':
1060 elif target == 'array':
1067 # Support cleaning up numpy arrays
1061 # Support cleaning up numpy arrays
1068 try:
1062 try:
1069 from numpy import ndarray
1063 from numpy import ndarray
1070 # This must be done with items and not iteritems because we're
1064 # This must be done with items and not iteritems because we're
1071 # going to modify the dict in-place.
1065 # going to modify the dict in-place.
1072 for x,val in user_ns.items():
1066 for x,val in user_ns.items():
1073 if isinstance(val,ndarray):
1067 if isinstance(val,ndarray):
1074 del user_ns[x]
1068 del user_ns[x]
1075 except ImportError:
1069 except ImportError:
1076 print "reset array only works if Numpy is available."
1070 print "reset array only works if Numpy is available."
1077
1071
1078 elif target == 'dhist':
1072 elif target == 'dhist':
1079 print "Flushing directory history"
1073 print "Flushing directory history"
1080 del user_ns['_dh'][:]
1074 del user_ns['_dh'][:]
1081
1075
1082 else:
1076 else:
1083 print "Don't know how to reset ",
1077 print "Don't know how to reset ",
1084 print target + ", please run `%reset?` for details"
1078 print target + ", please run `%reset?` for details"
1085
1079
1086 gc.collect()
1080 gc.collect()
1087
1081
1088 def magic_reset_selective(self, parameter_s=''):
1082 def magic_reset_selective(self, parameter_s=''):
1089 """Resets the namespace by removing names defined by the user.
1083 """Resets the namespace by removing names defined by the user.
1090
1084
1091 Input/Output history are left around in case you need them.
1085 Input/Output history are left around in case you need them.
1092
1086
1093 %reset_selective [-f] regex
1087 %reset_selective [-f] regex
1094
1088
1095 No action is taken if regex is not included
1089 No action is taken if regex is not included
1096
1090
1097 Options
1091 Options
1098 -f : force reset without asking for confirmation.
1092 -f : force reset without asking for confirmation.
1099
1093
1100 See Also
1094 See Also
1101 --------
1095 --------
1102 magic_reset : invoked as ``%reset``
1096 magic_reset : invoked as ``%reset``
1103
1097
1104 Examples
1098 Examples
1105 --------
1099 --------
1106
1100
1107 We first fully reset the namespace so your output looks identical to
1101 We first fully reset the namespace so your output looks identical to
1108 this example for pedagogical reasons; in practice you do not need a
1102 this example for pedagogical reasons; in practice you do not need a
1109 full reset::
1103 full reset::
1110
1104
1111 In [1]: %reset -f
1105 In [1]: %reset -f
1112
1106
1113 Now, with a clean namespace we can make a few variables and use
1107 Now, with a clean namespace we can make a few variables and use
1114 ``%reset_selective`` to only delete names that match our regexp::
1108 ``%reset_selective`` to only delete names that match our regexp::
1115
1109
1116 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
1110 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
1117
1111
1118 In [3]: who_ls
1112 In [3]: who_ls
1119 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
1113 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
1120
1114
1121 In [4]: %reset_selective -f b[2-3]m
1115 In [4]: %reset_selective -f b[2-3]m
1122
1116
1123 In [5]: who_ls
1117 In [5]: who_ls
1124 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
1118 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
1125
1119
1126 In [6]: %reset_selective -f d
1120 In [6]: %reset_selective -f d
1127
1121
1128 In [7]: who_ls
1122 In [7]: who_ls
1129 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
1123 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
1130
1124
1131 In [8]: %reset_selective -f c
1125 In [8]: %reset_selective -f c
1132
1126
1133 In [9]: who_ls
1127 In [9]: who_ls
1134 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
1128 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
1135
1129
1136 In [10]: %reset_selective -f b
1130 In [10]: %reset_selective -f b
1137
1131
1138 In [11]: who_ls
1132 In [11]: who_ls
1139 Out[11]: ['a']
1133 Out[11]: ['a']
1140
1134
1141 Notes
1135 Notes
1142 -----
1136 -----
1143 Calling this magic from clients that do not implement standard input,
1137 Calling this magic from clients that do not implement standard input,
1144 such as the ipython notebook interface, will reset the namespace
1138 such as the ipython notebook interface, will reset the namespace
1145 without confirmation.
1139 without confirmation.
1146 """
1140 """
1147
1141
1148 opts, regex = self.parse_options(parameter_s,'f')
1142 opts, regex = self.parse_options(parameter_s,'f')
1149
1143
1150 if opts.has_key('f'):
1144 if opts.has_key('f'):
1151 ans = True
1145 ans = True
1152 else:
1146 else:
1153 try:
1147 try:
1154 ans = self.shell.ask_yes_no(
1148 ans = self.shell.ask_yes_no(
1155 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
1149 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
1156 default='n')
1150 default='n')
1157 except StdinNotImplementedError:
1151 except StdinNotImplementedError:
1158 ans = True
1152 ans = True
1159 if not ans:
1153 if not ans:
1160 print 'Nothing done.'
1154 print 'Nothing done.'
1161 return
1155 return
1162 user_ns = self.shell.user_ns
1156 user_ns = self.shell.user_ns
1163 if not regex:
1157 if not regex:
1164 print 'No regex pattern specified. Nothing done.'
1158 print 'No regex pattern specified. Nothing done.'
1165 return
1159 return
1166 else:
1160 else:
1167 try:
1161 try:
1168 m = re.compile(regex)
1162 m = re.compile(regex)
1169 except TypeError:
1163 except TypeError:
1170 raise TypeError('regex must be a string or compiled pattern')
1164 raise TypeError('regex must be a string or compiled pattern')
1171 for i in self.magic_who_ls():
1165 for i in self.magic_who_ls():
1172 if m.search(i):
1166 if m.search(i):
1173 del(user_ns[i])
1167 del(user_ns[i])
1174
1168
1175 def magic_xdel(self, parameter_s=''):
1169 def magic_xdel(self, parameter_s=''):
1176 """Delete a variable, trying to clear it from anywhere that
1170 """Delete a variable, trying to clear it from anywhere that
1177 IPython's machinery has references to it. By default, this uses
1171 IPython's machinery has references to it. By default, this uses
1178 the identity of the named object in the user namespace to remove
1172 the identity of the named object in the user namespace to remove
1179 references held under other names. The object is also removed
1173 references held under other names. The object is also removed
1180 from the output history.
1174 from the output history.
1181
1175
1182 Options
1176 Options
1183 -n : Delete the specified name from all namespaces, without
1177 -n : Delete the specified name from all namespaces, without
1184 checking their identity.
1178 checking their identity.
1185 """
1179 """
1186 opts, varname = self.parse_options(parameter_s,'n')
1180 opts, varname = self.parse_options(parameter_s,'n')
1187 try:
1181 try:
1188 self.shell.del_var(varname, ('n' in opts))
1182 self.shell.del_var(varname, ('n' in opts))
1189 except (NameError, ValueError) as e:
1183 except (NameError, ValueError) as e:
1190 print type(e).__name__ +": "+ str(e)
1184 print type(e).__name__ +": "+ str(e)
1191
1185
1192 def magic_logstart(self,parameter_s=''):
1186 def magic_logstart(self,parameter_s=''):
1193 """Start logging anywhere in a session.
1187 """Start logging anywhere in a session.
1194
1188
1195 %logstart [-o|-r|-t] [log_name [log_mode]]
1189 %logstart [-o|-r|-t] [log_name [log_mode]]
1196
1190
1197 If no name is given, it defaults to a file named 'ipython_log.py' in your
1191 If no name is given, it defaults to a file named 'ipython_log.py' in your
1198 current directory, in 'rotate' mode (see below).
1192 current directory, in 'rotate' mode (see below).
1199
1193
1200 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1194 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1201 history up to that point and then continues logging.
1195 history up to that point and then continues logging.
1202
1196
1203 %logstart takes a second optional parameter: logging mode. This can be one
1197 %logstart takes a second optional parameter: logging mode. This can be one
1204 of (note that the modes are given unquoted):\\
1198 of (note that the modes are given unquoted):\\
1205 append: well, that says it.\\
1199 append: well, that says it.\\
1206 backup: rename (if exists) to name~ and start name.\\
1200 backup: rename (if exists) to name~ and start name.\\
1207 global: single logfile in your home dir, appended to.\\
1201 global: single logfile in your home dir, appended to.\\
1208 over : overwrite existing log.\\
1202 over : overwrite existing log.\\
1209 rotate: create rotating logs name.1~, name.2~, etc.
1203 rotate: create rotating logs name.1~, name.2~, etc.
1210
1204
1211 Options:
1205 Options:
1212
1206
1213 -o: log also IPython's output. In this mode, all commands which
1207 -o: log also IPython's output. In this mode, all commands which
1214 generate an Out[NN] prompt are recorded to the logfile, right after
1208 generate an Out[NN] prompt are recorded to the logfile, right after
1215 their corresponding input line. The output lines are always
1209 their corresponding input line. The output lines are always
1216 prepended with a '#[Out]# ' marker, so that the log remains valid
1210 prepended with a '#[Out]# ' marker, so that the log remains valid
1217 Python code.
1211 Python code.
1218
1212
1219 Since this marker is always the same, filtering only the output from
1213 Since this marker is always the same, filtering only the output from
1220 a log is very easy, using for example a simple awk call::
1214 a log is very easy, using for example a simple awk call::
1221
1215
1222 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1216 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1223
1217
1224 -r: log 'raw' input. Normally, IPython's logs contain the processed
1218 -r: log 'raw' input. Normally, IPython's logs contain the processed
1225 input, so that user lines are logged in their final form, converted
1219 input, so that user lines are logged in their final form, converted
1226 into valid Python. For example, %Exit is logged as
1220 into valid Python. For example, %Exit is logged as
1227 _ip.magic("Exit"). If the -r flag is given, all input is logged
1221 _ip.magic("Exit"). If the -r flag is given, all input is logged
1228 exactly as typed, with no transformations applied.
1222 exactly as typed, with no transformations applied.
1229
1223
1230 -t: put timestamps before each input line logged (these are put in
1224 -t: put timestamps before each input line logged (these are put in
1231 comments)."""
1225 comments)."""
1232
1226
1233 opts,par = self.parse_options(parameter_s,'ort')
1227 opts,par = self.parse_options(parameter_s,'ort')
1234 log_output = 'o' in opts
1228 log_output = 'o' in opts
1235 log_raw_input = 'r' in opts
1229 log_raw_input = 'r' in opts
1236 timestamp = 't' in opts
1230 timestamp = 't' in opts
1237
1231
1238 logger = self.shell.logger
1232 logger = self.shell.logger
1239
1233
1240 # if no args are given, the defaults set in the logger constructor by
1234 # if no args are given, the defaults set in the logger constructor by
1241 # ipython remain valid
1235 # ipython remain valid
1242 if par:
1236 if par:
1243 try:
1237 try:
1244 logfname,logmode = par.split()
1238 logfname,logmode = par.split()
1245 except:
1239 except:
1246 logfname = par
1240 logfname = par
1247 logmode = 'backup'
1241 logmode = 'backup'
1248 else:
1242 else:
1249 logfname = logger.logfname
1243 logfname = logger.logfname
1250 logmode = logger.logmode
1244 logmode = logger.logmode
1251 # put logfname into rc struct as if it had been called on the command
1245 # put logfname into rc struct as if it had been called on the command
1252 # line, so it ends up saved in the log header Save it in case we need
1246 # line, so it ends up saved in the log header Save it in case we need
1253 # to restore it...
1247 # to restore it...
1254 old_logfile = self.shell.logfile
1248 old_logfile = self.shell.logfile
1255 if logfname:
1249 if logfname:
1256 logfname = os.path.expanduser(logfname)
1250 logfname = os.path.expanduser(logfname)
1257 self.shell.logfile = logfname
1251 self.shell.logfile = logfname
1258
1252
1259 loghead = '# IPython log file\n\n'
1253 loghead = '# IPython log file\n\n'
1260 try:
1254 try:
1261 started = logger.logstart(logfname,loghead,logmode,
1255 started = logger.logstart(logfname,loghead,logmode,
1262 log_output,timestamp,log_raw_input)
1256 log_output,timestamp,log_raw_input)
1263 except:
1257 except:
1264 self.shell.logfile = old_logfile
1258 self.shell.logfile = old_logfile
1265 warn("Couldn't start log: %s" % sys.exc_info()[1])
1259 warn("Couldn't start log: %s" % sys.exc_info()[1])
1266 else:
1260 else:
1267 # log input history up to this point, optionally interleaving
1261 # log input history up to this point, optionally interleaving
1268 # output if requested
1262 # output if requested
1269
1263
1270 if timestamp:
1264 if timestamp:
1271 # disable timestamping for the previous history, since we've
1265 # disable timestamping for the previous history, since we've
1272 # lost those already (no time machine here).
1266 # lost those already (no time machine here).
1273 logger.timestamp = False
1267 logger.timestamp = False
1274
1268
1275 if log_raw_input:
1269 if log_raw_input:
1276 input_hist = self.shell.history_manager.input_hist_raw
1270 input_hist = self.shell.history_manager.input_hist_raw
1277 else:
1271 else:
1278 input_hist = self.shell.history_manager.input_hist_parsed
1272 input_hist = self.shell.history_manager.input_hist_parsed
1279
1273
1280 if log_output:
1274 if log_output:
1281 log_write = logger.log_write
1275 log_write = logger.log_write
1282 output_hist = self.shell.history_manager.output_hist
1276 output_hist = self.shell.history_manager.output_hist
1283 for n in range(1,len(input_hist)-1):
1277 for n in range(1,len(input_hist)-1):
1284 log_write(input_hist[n].rstrip() + '\n')
1278 log_write(input_hist[n].rstrip() + '\n')
1285 if n in output_hist:
1279 if n in output_hist:
1286 log_write(repr(output_hist[n]),'output')
1280 log_write(repr(output_hist[n]),'output')
1287 else:
1281 else:
1288 logger.log_write('\n'.join(input_hist[1:]))
1282 logger.log_write('\n'.join(input_hist[1:]))
1289 logger.log_write('\n')
1283 logger.log_write('\n')
1290 if timestamp:
1284 if timestamp:
1291 # re-enable timestamping
1285 # re-enable timestamping
1292 logger.timestamp = True
1286 logger.timestamp = True
1293
1287
1294 print ('Activating auto-logging. '
1288 print ('Activating auto-logging. '
1295 'Current session state plus future input saved.')
1289 'Current session state plus future input saved.')
1296 logger.logstate()
1290 logger.logstate()
1297
1291
1298 def magic_logstop(self,parameter_s=''):
1292 def magic_logstop(self,parameter_s=''):
1299 """Fully stop logging and close log file.
1293 """Fully stop logging and close log file.
1300
1294
1301 In order to start logging again, a new %logstart call needs to be made,
1295 In order to start logging again, a new %logstart call needs to be made,
1302 possibly (though not necessarily) with a new filename, mode and other
1296 possibly (though not necessarily) with a new filename, mode and other
1303 options."""
1297 options."""
1304 self.logger.logstop()
1298 self.logger.logstop()
1305
1299
1306 def magic_logoff(self,parameter_s=''):
1300 def magic_logoff(self,parameter_s=''):
1307 """Temporarily stop logging.
1301 """Temporarily stop logging.
1308
1302
1309 You must have previously started logging."""
1303 You must have previously started logging."""
1310 self.shell.logger.switch_log(0)
1304 self.shell.logger.switch_log(0)
1311
1305
1312 def magic_logon(self,parameter_s=''):
1306 def magic_logon(self,parameter_s=''):
1313 """Restart logging.
1307 """Restart logging.
1314
1308
1315 This function is for restarting logging which you've temporarily
1309 This function is for restarting logging which you've temporarily
1316 stopped with %logoff. For starting logging for the first time, you
1310 stopped with %logoff. For starting logging for the first time, you
1317 must use the %logstart function, which allows you to specify an
1311 must use the %logstart function, which allows you to specify an
1318 optional log filename."""
1312 optional log filename."""
1319
1313
1320 self.shell.logger.switch_log(1)
1314 self.shell.logger.switch_log(1)
1321
1315
1322 def magic_logstate(self,parameter_s=''):
1316 def magic_logstate(self,parameter_s=''):
1323 """Print the status of the logging system."""
1317 """Print the status of the logging system."""
1324
1318
1325 self.shell.logger.logstate()
1319 self.shell.logger.logstate()
1326
1320
1327 def magic_pdb(self, parameter_s=''):
1321 def magic_pdb(self, parameter_s=''):
1328 """Control the automatic calling of the pdb interactive debugger.
1322 """Control the automatic calling of the pdb interactive debugger.
1329
1323
1330 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1324 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1331 argument it works as a toggle.
1325 argument it works as a toggle.
1332
1326
1333 When an exception is triggered, IPython can optionally call the
1327 When an exception is triggered, IPython can optionally call the
1334 interactive pdb debugger after the traceback printout. %pdb toggles
1328 interactive pdb debugger after the traceback printout. %pdb toggles
1335 this feature on and off.
1329 this feature on and off.
1336
1330
1337 The initial state of this feature is set in your configuration
1331 The initial state of this feature is set in your configuration
1338 file (the option is ``InteractiveShell.pdb``).
1332 file (the option is ``InteractiveShell.pdb``).
1339
1333
1340 If you want to just activate the debugger AFTER an exception has fired,
1334 If you want to just activate the debugger AFTER an exception has fired,
1341 without having to type '%pdb on' and rerunning your code, you can use
1335 without having to type '%pdb on' and rerunning your code, you can use
1342 the %debug magic."""
1336 the %debug magic."""
1343
1337
1344 par = parameter_s.strip().lower()
1338 par = parameter_s.strip().lower()
1345
1339
1346 if par:
1340 if par:
1347 try:
1341 try:
1348 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1342 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1349 except KeyError:
1343 except KeyError:
1350 print ('Incorrect argument. Use on/1, off/0, '
1344 print ('Incorrect argument. Use on/1, off/0, '
1351 'or nothing for a toggle.')
1345 'or nothing for a toggle.')
1352 return
1346 return
1353 else:
1347 else:
1354 # toggle
1348 # toggle
1355 new_pdb = not self.shell.call_pdb
1349 new_pdb = not self.shell.call_pdb
1356
1350
1357 # set on the shell
1351 # set on the shell
1358 self.shell.call_pdb = new_pdb
1352 self.shell.call_pdb = new_pdb
1359 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1353 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1360
1354
1361 def magic_debug(self, parameter_s=''):
1355 def magic_debug(self, parameter_s=''):
1362 """Activate the interactive debugger in post-mortem mode.
1356 """Activate the interactive debugger in post-mortem mode.
1363
1357
1364 If an exception has just occurred, this lets you inspect its stack
1358 If an exception has just occurred, this lets you inspect its stack
1365 frames interactively. Note that this will always work only on the last
1359 frames interactively. Note that this will always work only on the last
1366 traceback that occurred, so you must call this quickly after an
1360 traceback that occurred, so you must call this quickly after an
1367 exception that you wish to inspect has fired, because if another one
1361 exception that you wish to inspect has fired, because if another one
1368 occurs, it clobbers the previous one.
1362 occurs, it clobbers the previous one.
1369
1363
1370 If you want IPython to automatically do this on every exception, see
1364 If you want IPython to automatically do this on every exception, see
1371 the %pdb magic for more details.
1365 the %pdb magic for more details.
1372 """
1366 """
1373 self.shell.debugger(force=True)
1367 self.shell.debugger(force=True)
1374
1368
1375 @skip_doctest
1369 @skip_doctest
1376 def magic_prun(self, parameter_s ='',user_mode=1,
1370 def magic_prun(self, parameter_s ='',user_mode=1,
1377 opts=None,arg_lst=None,prog_ns=None):
1371 opts=None,arg_lst=None,prog_ns=None):
1378
1372
1379 """Run a statement through the python code profiler.
1373 """Run a statement through the python code profiler.
1380
1374
1381 Usage:
1375 Usage:
1382 %prun [options] statement
1376 %prun [options] statement
1383
1377
1384 The given statement (which doesn't require quote marks) is run via the
1378 The given statement (which doesn't require quote marks) is run via the
1385 python profiler in a manner similar to the profile.run() function.
1379 python profiler in a manner similar to the profile.run() function.
1386 Namespaces are internally managed to work correctly; profile.run
1380 Namespaces are internally managed to work correctly; profile.run
1387 cannot be used in IPython because it makes certain assumptions about
1381 cannot be used in IPython because it makes certain assumptions about
1388 namespaces which do not hold under IPython.
1382 namespaces which do not hold under IPython.
1389
1383
1390 Options:
1384 Options:
1391
1385
1392 -l <limit>: you can place restrictions on what or how much of the
1386 -l <limit>: you can place restrictions on what or how much of the
1393 profile gets printed. The limit value can be:
1387 profile gets printed. The limit value can be:
1394
1388
1395 * A string: only information for function names containing this string
1389 * A string: only information for function names containing this string
1396 is printed.
1390 is printed.
1397
1391
1398 * An integer: only these many lines are printed.
1392 * An integer: only these many lines are printed.
1399
1393
1400 * A float (between 0 and 1): this fraction of the report is printed
1394 * A float (between 0 and 1): this fraction of the report is printed
1401 (for example, use a limit of 0.4 to see the topmost 40% only).
1395 (for example, use a limit of 0.4 to see the topmost 40% only).
1402
1396
1403 You can combine several limits with repeated use of the option. For
1397 You can combine several limits with repeated use of the option. For
1404 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1398 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1405 information about class constructors.
1399 information about class constructors.
1406
1400
1407 -r: return the pstats.Stats object generated by the profiling. This
1401 -r: return the pstats.Stats object generated by the profiling. This
1408 object has all the information about the profile in it, and you can
1402 object has all the information about the profile in it, and you can
1409 later use it for further analysis or in other functions.
1403 later use it for further analysis or in other functions.
1410
1404
1411 -s <key>: sort profile by given key. You can provide more than one key
1405 -s <key>: sort profile by given key. You can provide more than one key
1412 by using the option several times: '-s key1 -s key2 -s key3...'. The
1406 by using the option several times: '-s key1 -s key2 -s key3...'. The
1413 default sorting key is 'time'.
1407 default sorting key is 'time'.
1414
1408
1415 The following is copied verbatim from the profile documentation
1409 The following is copied verbatim from the profile documentation
1416 referenced below:
1410 referenced below:
1417
1411
1418 When more than one key is provided, additional keys are used as
1412 When more than one key is provided, additional keys are used as
1419 secondary criteria when the there is equality in all keys selected
1413 secondary criteria when the there is equality in all keys selected
1420 before them.
1414 before them.
1421
1415
1422 Abbreviations can be used for any key names, as long as the
1416 Abbreviations can be used for any key names, as long as the
1423 abbreviation is unambiguous. The following are the keys currently
1417 abbreviation is unambiguous. The following are the keys currently
1424 defined:
1418 defined:
1425
1419
1426 Valid Arg Meaning
1420 Valid Arg Meaning
1427 "calls" call count
1421 "calls" call count
1428 "cumulative" cumulative time
1422 "cumulative" cumulative time
1429 "file" file name
1423 "file" file name
1430 "module" file name
1424 "module" file name
1431 "pcalls" primitive call count
1425 "pcalls" primitive call count
1432 "line" line number
1426 "line" line number
1433 "name" function name
1427 "name" function name
1434 "nfl" name/file/line
1428 "nfl" name/file/line
1435 "stdname" standard name
1429 "stdname" standard name
1436 "time" internal time
1430 "time" internal time
1437
1431
1438 Note that all sorts on statistics are in descending order (placing
1432 Note that all sorts on statistics are in descending order (placing
1439 most time consuming items first), where as name, file, and line number
1433 most time consuming items first), where as name, file, and line number
1440 searches are in ascending order (i.e., alphabetical). The subtle
1434 searches are in ascending order (i.e., alphabetical). The subtle
1441 distinction between "nfl" and "stdname" is that the standard name is a
1435 distinction between "nfl" and "stdname" is that the standard name is a
1442 sort of the name as printed, which means that the embedded line
1436 sort of the name as printed, which means that the embedded line
1443 numbers get compared in an odd way. For example, lines 3, 20, and 40
1437 numbers get compared in an odd way. For example, lines 3, 20, and 40
1444 would (if the file names were the same) appear in the string order
1438 would (if the file names were the same) appear in the string order
1445 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1439 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1446 line numbers. In fact, sort_stats("nfl") is the same as
1440 line numbers. In fact, sort_stats("nfl") is the same as
1447 sort_stats("name", "file", "line").
1441 sort_stats("name", "file", "line").
1448
1442
1449 -T <filename>: save profile results as shown on screen to a text
1443 -T <filename>: save profile results as shown on screen to a text
1450 file. The profile is still shown on screen.
1444 file. The profile is still shown on screen.
1451
1445
1452 -D <filename>: save (via dump_stats) profile statistics to given
1446 -D <filename>: save (via dump_stats) profile statistics to given
1453 filename. This data is in a format understood by the pstats module, and
1447 filename. This data is in a format understood by the pstats module, and
1454 is generated by a call to the dump_stats() method of profile
1448 is generated by a call to the dump_stats() method of profile
1455 objects. The profile is still shown on screen.
1449 objects. The profile is still shown on screen.
1456
1450
1457 -q: suppress output to the pager. Best used with -T and/or -D above.
1451 -q: suppress output to the pager. Best used with -T and/or -D above.
1458
1452
1459 If you want to run complete programs under the profiler's control, use
1453 If you want to run complete programs under the profiler's control, use
1460 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1454 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1461 contains profiler specific options as described here.
1455 contains profiler specific options as described here.
1462
1456
1463 You can read the complete documentation for the profile module with::
1457 You can read the complete documentation for the profile module with::
1464
1458
1465 In [1]: import profile; profile.help()
1459 In [1]: import profile; profile.help()
1466 """
1460 """
1467
1461
1468 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1462 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1469
1463
1470 if user_mode: # regular user call
1464 if user_mode: # regular user call
1471 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
1465 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
1472 list_all=1, posix=False)
1466 list_all=1, posix=False)
1473 namespace = self.shell.user_ns
1467 namespace = self.shell.user_ns
1474 else: # called to run a program by %run -p
1468 else: # called to run a program by %run -p
1475 try:
1469 try:
1476 filename = get_py_filename(arg_lst[0])
1470 filename = get_py_filename(arg_lst[0])
1477 except IOError as e:
1471 except IOError as e:
1478 try:
1472 try:
1479 msg = str(e)
1473 msg = str(e)
1480 except UnicodeError:
1474 except UnicodeError:
1481 msg = e.message
1475 msg = e.message
1482 error(msg)
1476 error(msg)
1483 return
1477 return
1484
1478
1485 arg_str = 'execfile(filename,prog_ns)'
1479 arg_str = 'execfile(filename,prog_ns)'
1486 namespace = {
1480 namespace = {
1487 'execfile': self.shell.safe_execfile,
1481 'execfile': self.shell.safe_execfile,
1488 'prog_ns': prog_ns,
1482 'prog_ns': prog_ns,
1489 'filename': filename
1483 'filename': filename
1490 }
1484 }
1491
1485
1492 opts.merge(opts_def)
1486 opts.merge(opts_def)
1493
1487
1494 prof = profile.Profile()
1488 prof = profile.Profile()
1495 try:
1489 try:
1496 prof = prof.runctx(arg_str,namespace,namespace)
1490 prof = prof.runctx(arg_str,namespace,namespace)
1497 sys_exit = ''
1491 sys_exit = ''
1498 except SystemExit:
1492 except SystemExit:
1499 sys_exit = """*** SystemExit exception caught in code being profiled."""
1493 sys_exit = """*** SystemExit exception caught in code being profiled."""
1500
1494
1501 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1495 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1502
1496
1503 lims = opts.l
1497 lims = opts.l
1504 if lims:
1498 if lims:
1505 lims = [] # rebuild lims with ints/floats/strings
1499 lims = [] # rebuild lims with ints/floats/strings
1506 for lim in opts.l:
1500 for lim in opts.l:
1507 try:
1501 try:
1508 lims.append(int(lim))
1502 lims.append(int(lim))
1509 except ValueError:
1503 except ValueError:
1510 try:
1504 try:
1511 lims.append(float(lim))
1505 lims.append(float(lim))
1512 except ValueError:
1506 except ValueError:
1513 lims.append(lim)
1507 lims.append(lim)
1514
1508
1515 # Trap output.
1509 # Trap output.
1516 stdout_trap = StringIO()
1510 stdout_trap = StringIO()
1517
1511
1518 if hasattr(stats,'stream'):
1512 if hasattr(stats,'stream'):
1519 # In newer versions of python, the stats object has a 'stream'
1513 # In newer versions of python, the stats object has a 'stream'
1520 # attribute to write into.
1514 # attribute to write into.
1521 stats.stream = stdout_trap
1515 stats.stream = stdout_trap
1522 stats.print_stats(*lims)
1516 stats.print_stats(*lims)
1523 else:
1517 else:
1524 # For older versions, we manually redirect stdout during printing
1518 # For older versions, we manually redirect stdout during printing
1525 sys_stdout = sys.stdout
1519 sys_stdout = sys.stdout
1526 try:
1520 try:
1527 sys.stdout = stdout_trap
1521 sys.stdout = stdout_trap
1528 stats.print_stats(*lims)
1522 stats.print_stats(*lims)
1529 finally:
1523 finally:
1530 sys.stdout = sys_stdout
1524 sys.stdout = sys_stdout
1531
1525
1532 output = stdout_trap.getvalue()
1526 output = stdout_trap.getvalue()
1533 output = output.rstrip()
1527 output = output.rstrip()
1534
1528
1535 if 'q' not in opts:
1529 if 'q' not in opts:
1536 page.page(output)
1530 page.page(output)
1537 print sys_exit,
1531 print sys_exit,
1538
1532
1539 dump_file = opts.D[0]
1533 dump_file = opts.D[0]
1540 text_file = opts.T[0]
1534 text_file = opts.T[0]
1541 if dump_file:
1535 if dump_file:
1542 dump_file = unquote_filename(dump_file)
1536 dump_file = unquote_filename(dump_file)
1543 prof.dump_stats(dump_file)
1537 prof.dump_stats(dump_file)
1544 print '\n*** Profile stats marshalled to file',\
1538 print '\n*** Profile stats marshalled to file',\
1545 `dump_file`+'.',sys_exit
1539 `dump_file`+'.',sys_exit
1546 if text_file:
1540 if text_file:
1547 text_file = unquote_filename(text_file)
1541 text_file = unquote_filename(text_file)
1548 pfile = open(text_file,'w')
1542 pfile = open(text_file,'w')
1549 pfile.write(output)
1543 pfile.write(output)
1550 pfile.close()
1544 pfile.close()
1551 print '\n*** Profile printout saved to text file',\
1545 print '\n*** Profile printout saved to text file',\
1552 `text_file`+'.',sys_exit
1546 `text_file`+'.',sys_exit
1553
1547
1554 if opts.has_key('r'):
1548 if opts.has_key('r'):
1555 return stats
1549 return stats
1556 else:
1550 else:
1557 return None
1551 return None
1558
1552
1559 @skip_doctest
1553 @skip_doctest
1560 def magic_run(self, parameter_s ='', runner=None,
1554 def magic_run(self, parameter_s ='', runner=None,
1561 file_finder=get_py_filename):
1555 file_finder=get_py_filename):
1562 """Run the named file inside IPython as a program.
1556 """Run the named file inside IPython as a program.
1563
1557
1564 Usage:\\
1558 Usage:\\
1565 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1559 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1566
1560
1567 Parameters after the filename are passed as command-line arguments to
1561 Parameters after the filename are passed as command-line arguments to
1568 the program (put in sys.argv). Then, control returns to IPython's
1562 the program (put in sys.argv). Then, control returns to IPython's
1569 prompt.
1563 prompt.
1570
1564
1571 This is similar to running at a system prompt:\\
1565 This is similar to running at a system prompt:\\
1572 $ python file args\\
1566 $ python file args\\
1573 but with the advantage of giving you IPython's tracebacks, and of
1567 but with the advantage of giving you IPython's tracebacks, and of
1574 loading all variables into your interactive namespace for further use
1568 loading all variables into your interactive namespace for further use
1575 (unless -p is used, see below).
1569 (unless -p is used, see below).
1576
1570
1577 The file is executed in a namespace initially consisting only of
1571 The file is executed in a namespace initially consisting only of
1578 __name__=='__main__' and sys.argv constructed as indicated. It thus
1572 __name__=='__main__' and sys.argv constructed as indicated. It thus
1579 sees its environment as if it were being run as a stand-alone program
1573 sees its environment as if it were being run as a stand-alone program
1580 (except for sharing global objects such as previously imported
1574 (except for sharing global objects such as previously imported
1581 modules). But after execution, the IPython interactive namespace gets
1575 modules). But after execution, the IPython interactive namespace gets
1582 updated with all variables defined in the program (except for __name__
1576 updated with all variables defined in the program (except for __name__
1583 and sys.argv). This allows for very convenient loading of code for
1577 and sys.argv). This allows for very convenient loading of code for
1584 interactive work, while giving each program a 'clean sheet' to run in.
1578 interactive work, while giving each program a 'clean sheet' to run in.
1585
1579
1586 Options:
1580 Options:
1587
1581
1588 -n: __name__ is NOT set to '__main__', but to the running file's name
1582 -n: __name__ is NOT set to '__main__', but to the running file's name
1589 without extension (as python does under import). This allows running
1583 without extension (as python does under import). This allows running
1590 scripts and reloading the definitions in them without calling code
1584 scripts and reloading the definitions in them without calling code
1591 protected by an ' if __name__ == "__main__" ' clause.
1585 protected by an ' if __name__ == "__main__" ' clause.
1592
1586
1593 -i: run the file in IPython's namespace instead of an empty one. This
1587 -i: run the file in IPython's namespace instead of an empty one. This
1594 is useful if you are experimenting with code written in a text editor
1588 is useful if you are experimenting with code written in a text editor
1595 which depends on variables defined interactively.
1589 which depends on variables defined interactively.
1596
1590
1597 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1591 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1598 being run. This is particularly useful if IPython is being used to
1592 being run. This is particularly useful if IPython is being used to
1599 run unittests, which always exit with a sys.exit() call. In such
1593 run unittests, which always exit with a sys.exit() call. In such
1600 cases you are interested in the output of the test results, not in
1594 cases you are interested in the output of the test results, not in
1601 seeing a traceback of the unittest module.
1595 seeing a traceback of the unittest module.
1602
1596
1603 -t: print timing information at the end of the run. IPython will give
1597 -t: print timing information at the end of the run. IPython will give
1604 you an estimated CPU time consumption for your script, which under
1598 you an estimated CPU time consumption for your script, which under
1605 Unix uses the resource module to avoid the wraparound problems of
1599 Unix uses the resource module to avoid the wraparound problems of
1606 time.clock(). Under Unix, an estimate of time spent on system tasks
1600 time.clock(). Under Unix, an estimate of time spent on system tasks
1607 is also given (for Windows platforms this is reported as 0.0).
1601 is also given (for Windows platforms this is reported as 0.0).
1608
1602
1609 If -t is given, an additional -N<N> option can be given, where <N>
1603 If -t is given, an additional -N<N> option can be given, where <N>
1610 must be an integer indicating how many times you want the script to
1604 must be an integer indicating how many times you want the script to
1611 run. The final timing report will include total and per run results.
1605 run. The final timing report will include total and per run results.
1612
1606
1613 For example (testing the script uniq_stable.py)::
1607 For example (testing the script uniq_stable.py)::
1614
1608
1615 In [1]: run -t uniq_stable
1609 In [1]: run -t uniq_stable
1616
1610
1617 IPython CPU timings (estimated):\\
1611 IPython CPU timings (estimated):\\
1618 User : 0.19597 s.\\
1612 User : 0.19597 s.\\
1619 System: 0.0 s.\\
1613 System: 0.0 s.\\
1620
1614
1621 In [2]: run -t -N5 uniq_stable
1615 In [2]: run -t -N5 uniq_stable
1622
1616
1623 IPython CPU timings (estimated):\\
1617 IPython CPU timings (estimated):\\
1624 Total runs performed: 5\\
1618 Total runs performed: 5\\
1625 Times : Total Per run\\
1619 Times : Total Per run\\
1626 User : 0.910862 s, 0.1821724 s.\\
1620 User : 0.910862 s, 0.1821724 s.\\
1627 System: 0.0 s, 0.0 s.
1621 System: 0.0 s, 0.0 s.
1628
1622
1629 -d: run your program under the control of pdb, the Python debugger.
1623 -d: run your program under the control of pdb, the Python debugger.
1630 This allows you to execute your program step by step, watch variables,
1624 This allows you to execute your program step by step, watch variables,
1631 etc. Internally, what IPython does is similar to calling:
1625 etc. Internally, what IPython does is similar to calling:
1632
1626
1633 pdb.run('execfile("YOURFILENAME")')
1627 pdb.run('execfile("YOURFILENAME")')
1634
1628
1635 with a breakpoint set on line 1 of your file. You can change the line
1629 with a breakpoint set on line 1 of your file. You can change the line
1636 number for this automatic breakpoint to be <N> by using the -bN option
1630 number for this automatic breakpoint to be <N> by using the -bN option
1637 (where N must be an integer). For example::
1631 (where N must be an integer). For example::
1638
1632
1639 %run -d -b40 myscript
1633 %run -d -b40 myscript
1640
1634
1641 will set the first breakpoint at line 40 in myscript.py. Note that
1635 will set the first breakpoint at line 40 in myscript.py. Note that
1642 the first breakpoint must be set on a line which actually does
1636 the first breakpoint must be set on a line which actually does
1643 something (not a comment or docstring) for it to stop execution.
1637 something (not a comment or docstring) for it to stop execution.
1644
1638
1645 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1639 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1646 first enter 'c' (without quotes) to start execution up to the first
1640 first enter 'c' (without quotes) to start execution up to the first
1647 breakpoint.
1641 breakpoint.
1648
1642
1649 Entering 'help' gives information about the use of the debugger. You
1643 Entering 'help' gives information about the use of the debugger. You
1650 can easily see pdb's full documentation with "import pdb;pdb.help()"
1644 can easily see pdb's full documentation with "import pdb;pdb.help()"
1651 at a prompt.
1645 at a prompt.
1652
1646
1653 -p: run program under the control of the Python profiler module (which
1647 -p: run program under the control of the Python profiler module (which
1654 prints a detailed report of execution times, function calls, etc).
1648 prints a detailed report of execution times, function calls, etc).
1655
1649
1656 You can pass other options after -p which affect the behavior of the
1650 You can pass other options after -p which affect the behavior of the
1657 profiler itself. See the docs for %prun for details.
1651 profiler itself. See the docs for %prun for details.
1658
1652
1659 In this mode, the program's variables do NOT propagate back to the
1653 In this mode, the program's variables do NOT propagate back to the
1660 IPython interactive namespace (because they remain in the namespace
1654 IPython interactive namespace (because they remain in the namespace
1661 where the profiler executes them).
1655 where the profiler executes them).
1662
1656
1663 Internally this triggers a call to %prun, see its documentation for
1657 Internally this triggers a call to %prun, see its documentation for
1664 details on the options available specifically for profiling.
1658 details on the options available specifically for profiling.
1665
1659
1666 There is one special usage for which the text above doesn't apply:
1660 There is one special usage for which the text above doesn't apply:
1667 if the filename ends with .ipy, the file is run as ipython script,
1661 if the filename ends with .ipy, the file is run as ipython script,
1668 just as if the commands were written on IPython prompt.
1662 just as if the commands were written on IPython prompt.
1669
1663
1670 -m: specify module name to load instead of script path. Similar to
1664 -m: specify module name to load instead of script path. Similar to
1671 the -m option for the python interpreter. Use this option last if you
1665 the -m option for the python interpreter. Use this option last if you
1672 want to combine with other %run options. Unlike the python interpreter
1666 want to combine with other %run options. Unlike the python interpreter
1673 only source modules are allowed no .pyc or .pyo files.
1667 only source modules are allowed no .pyc or .pyo files.
1674 For example::
1668 For example::
1675
1669
1676 %run -m example
1670 %run -m example
1677
1671
1678 will run the example module.
1672 will run the example module.
1679
1673
1680 """
1674 """
1681
1675
1682 # get arguments and set sys.argv for program to be run.
1676 # get arguments and set sys.argv for program to be run.
1683 opts, arg_lst = self.parse_options(parameter_s, 'nidtN:b:pD:l:rs:T:em:',
1677 opts, arg_lst = self.parse_options(parameter_s, 'nidtN:b:pD:l:rs:T:em:',
1684 mode='list', list_all=1)
1678 mode='list', list_all=1)
1685 if "m" in opts:
1679 if "m" in opts:
1686 modulename = opts["m"][0]
1680 modulename = opts["m"][0]
1687 modpath = find_mod(modulename)
1681 modpath = find_mod(modulename)
1688 if modpath is None:
1682 if modpath is None:
1689 warn('%r is not a valid modulename on sys.path'%modulename)
1683 warn('%r is not a valid modulename on sys.path'%modulename)
1690 return
1684 return
1691 arg_lst = [modpath] + arg_lst
1685 arg_lst = [modpath] + arg_lst
1692 try:
1686 try:
1693 filename = file_finder(arg_lst[0])
1687 filename = file_finder(arg_lst[0])
1694 except IndexError:
1688 except IndexError:
1695 warn('you must provide at least a filename.')
1689 warn('you must provide at least a filename.')
1696 print '\n%run:\n', oinspect.getdoc(self.magic_run)
1690 print '\n%run:\n', oinspect.getdoc(self.magic_run)
1697 return
1691 return
1698 except IOError as e:
1692 except IOError as e:
1699 try:
1693 try:
1700 msg = str(e)
1694 msg = str(e)
1701 except UnicodeError:
1695 except UnicodeError:
1702 msg = e.message
1696 msg = e.message
1703 error(msg)
1697 error(msg)
1704 return
1698 return
1705
1699
1706 if filename.lower().endswith('.ipy'):
1700 if filename.lower().endswith('.ipy'):
1707 self.shell.safe_execfile_ipy(filename)
1701 self.shell.safe_execfile_ipy(filename)
1708 return
1702 return
1709
1703
1710 # Control the response to exit() calls made by the script being run
1704 # Control the response to exit() calls made by the script being run
1711 exit_ignore = 'e' in opts
1705 exit_ignore = 'e' in opts
1712
1706
1713 # Make sure that the running script gets a proper sys.argv as if it
1707 # Make sure that the running script gets a proper sys.argv as if it
1714 # were run from a system shell.
1708 # were run from a system shell.
1715 save_argv = sys.argv # save it for later restoring
1709 save_argv = sys.argv # save it for later restoring
1716
1710
1717 # simulate shell expansion on arguments, at least tilde expansion
1711 # simulate shell expansion on arguments, at least tilde expansion
1718 args = [ os.path.expanduser(a) for a in arg_lst[1:] ]
1712 args = [ os.path.expanduser(a) for a in arg_lst[1:] ]
1719
1713
1720 sys.argv = [filename] + args # put in the proper filename
1714 sys.argv = [filename] + args # put in the proper filename
1721 # protect sys.argv from potential unicode strings on Python 2:
1715 # protect sys.argv from potential unicode strings on Python 2:
1722 if not py3compat.PY3:
1716 if not py3compat.PY3:
1723 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
1717 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
1724
1718
1725 if 'i' in opts:
1719 if 'i' in opts:
1726 # Run in user's interactive namespace
1720 # Run in user's interactive namespace
1727 prog_ns = self.shell.user_ns
1721 prog_ns = self.shell.user_ns
1728 __name__save = self.shell.user_ns['__name__']
1722 __name__save = self.shell.user_ns['__name__']
1729 prog_ns['__name__'] = '__main__'
1723 prog_ns['__name__'] = '__main__'
1730 main_mod = self.shell.new_main_mod(prog_ns)
1724 main_mod = self.shell.new_main_mod(prog_ns)
1731 else:
1725 else:
1732 # Run in a fresh, empty namespace
1726 # Run in a fresh, empty namespace
1733 if 'n' in opts:
1727 if 'n' in opts:
1734 name = os.path.splitext(os.path.basename(filename))[0]
1728 name = os.path.splitext(os.path.basename(filename))[0]
1735 else:
1729 else:
1736 name = '__main__'
1730 name = '__main__'
1737
1731
1738 main_mod = self.shell.new_main_mod()
1732 main_mod = self.shell.new_main_mod()
1739 prog_ns = main_mod.__dict__
1733 prog_ns = main_mod.__dict__
1740 prog_ns['__name__'] = name
1734 prog_ns['__name__'] = name
1741
1735
1742 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1736 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1743 # set the __file__ global in the script's namespace
1737 # set the __file__ global in the script's namespace
1744 prog_ns['__file__'] = filename
1738 prog_ns['__file__'] = filename
1745
1739
1746 # pickle fix. See interactiveshell for an explanation. But we need to make sure
1740 # pickle fix. See interactiveshell for an explanation. But we need to make sure
1747 # that, if we overwrite __main__, we replace it at the end
1741 # that, if we overwrite __main__, we replace it at the end
1748 main_mod_name = prog_ns['__name__']
1742 main_mod_name = prog_ns['__name__']
1749
1743
1750 if main_mod_name == '__main__':
1744 if main_mod_name == '__main__':
1751 restore_main = sys.modules['__main__']
1745 restore_main = sys.modules['__main__']
1752 else:
1746 else:
1753 restore_main = False
1747 restore_main = False
1754
1748
1755 # This needs to be undone at the end to prevent holding references to
1749 # This needs to be undone at the end to prevent holding references to
1756 # every single object ever created.
1750 # every single object ever created.
1757 sys.modules[main_mod_name] = main_mod
1751 sys.modules[main_mod_name] = main_mod
1758
1752
1759 try:
1753 try:
1760 stats = None
1754 stats = None
1761 with self.readline_no_record:
1755 with self.readline_no_record:
1762 if 'p' in opts:
1756 if 'p' in opts:
1763 stats = self.magic_prun('', 0, opts, arg_lst, prog_ns)
1757 stats = self.magic_prun('', 0, opts, arg_lst, prog_ns)
1764 else:
1758 else:
1765 if 'd' in opts:
1759 if 'd' in opts:
1766 deb = debugger.Pdb(self.shell.colors)
1760 deb = debugger.Pdb(self.shell.colors)
1767 # reset Breakpoint state, which is moronically kept
1761 # reset Breakpoint state, which is moronically kept
1768 # in a class
1762 # in a class
1769 bdb.Breakpoint.next = 1
1763 bdb.Breakpoint.next = 1
1770 bdb.Breakpoint.bplist = {}
1764 bdb.Breakpoint.bplist = {}
1771 bdb.Breakpoint.bpbynumber = [None]
1765 bdb.Breakpoint.bpbynumber = [None]
1772 # Set an initial breakpoint to stop execution
1766 # Set an initial breakpoint to stop execution
1773 maxtries = 10
1767 maxtries = 10
1774 bp = int(opts.get('b', [1])[0])
1768 bp = int(opts.get('b', [1])[0])
1775 checkline = deb.checkline(filename, bp)
1769 checkline = deb.checkline(filename, bp)
1776 if not checkline:
1770 if not checkline:
1777 for bp in range(bp + 1, bp + maxtries + 1):
1771 for bp in range(bp + 1, bp + maxtries + 1):
1778 if deb.checkline(filename, bp):
1772 if deb.checkline(filename, bp):
1779 break
1773 break
1780 else:
1774 else:
1781 msg = ("\nI failed to find a valid line to set "
1775 msg = ("\nI failed to find a valid line to set "
1782 "a breakpoint\n"
1776 "a breakpoint\n"
1783 "after trying up to line: %s.\n"
1777 "after trying up to line: %s.\n"
1784 "Please set a valid breakpoint manually "
1778 "Please set a valid breakpoint manually "
1785 "with the -b option." % bp)
1779 "with the -b option." % bp)
1786 error(msg)
1780 error(msg)
1787 return
1781 return
1788 # if we find a good linenumber, set the breakpoint
1782 # if we find a good linenumber, set the breakpoint
1789 deb.do_break('%s:%s' % (filename, bp))
1783 deb.do_break('%s:%s' % (filename, bp))
1790 # Start file run
1784 # Start file run
1791 print "NOTE: Enter 'c' at the",
1785 print "NOTE: Enter 'c' at the",
1792 print "%s prompt to start your script." % deb.prompt
1786 print "%s prompt to start your script." % deb.prompt
1793 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
1787 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
1794 try:
1788 try:
1795 deb.run('execfile("%s", prog_ns)' % filename, ns)
1789 deb.run('execfile("%s", prog_ns)' % filename, ns)
1796
1790
1797 except:
1791 except:
1798 etype, value, tb = sys.exc_info()
1792 etype, value, tb = sys.exc_info()
1799 # Skip three frames in the traceback: the %run one,
1793 # Skip three frames in the traceback: the %run one,
1800 # one inside bdb.py, and the command-line typed by the
1794 # one inside bdb.py, and the command-line typed by the
1801 # user (run by exec in pdb itself).
1795 # user (run by exec in pdb itself).
1802 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
1796 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
1803 else:
1797 else:
1804 if runner is None:
1798 if runner is None:
1805 runner = self.shell.safe_execfile
1799 runner = self.shell.safe_execfile
1806 if 't' in opts:
1800 if 't' in opts:
1807 # timed execution
1801 # timed execution
1808 try:
1802 try:
1809 nruns = int(opts['N'][0])
1803 nruns = int(opts['N'][0])
1810 if nruns < 1:
1804 if nruns < 1:
1811 error('Number of runs must be >=1')
1805 error('Number of runs must be >=1')
1812 return
1806 return
1813 except (KeyError):
1807 except (KeyError):
1814 nruns = 1
1808 nruns = 1
1815 twall0 = time.time()
1809 twall0 = time.time()
1816 if nruns == 1:
1810 if nruns == 1:
1817 t0 = clock2()
1811 t0 = clock2()
1818 runner(filename, prog_ns, prog_ns,
1812 runner(filename, prog_ns, prog_ns,
1819 exit_ignore=exit_ignore)
1813 exit_ignore=exit_ignore)
1820 t1 = clock2()
1814 t1 = clock2()
1821 t_usr = t1[0] - t0[0]
1815 t_usr = t1[0] - t0[0]
1822 t_sys = t1[1] - t0[1]
1816 t_sys = t1[1] - t0[1]
1823 print "\nIPython CPU timings (estimated):"
1817 print "\nIPython CPU timings (estimated):"
1824 print " User : %10.2f s." % t_usr
1818 print " User : %10.2f s." % t_usr
1825 print " System : %10.2f s." % t_sys
1819 print " System : %10.2f s." % t_sys
1826 else:
1820 else:
1827 runs = range(nruns)
1821 runs = range(nruns)
1828 t0 = clock2()
1822 t0 = clock2()
1829 for nr in runs:
1823 for nr in runs:
1830 runner(filename, prog_ns, prog_ns,
1824 runner(filename, prog_ns, prog_ns,
1831 exit_ignore=exit_ignore)
1825 exit_ignore=exit_ignore)
1832 t1 = clock2()
1826 t1 = clock2()
1833 t_usr = t1[0] - t0[0]
1827 t_usr = t1[0] - t0[0]
1834 t_sys = t1[1] - t0[1]
1828 t_sys = t1[1] - t0[1]
1835 print "\nIPython CPU timings (estimated):"
1829 print "\nIPython CPU timings (estimated):"
1836 print "Total runs performed:", nruns
1830 print "Total runs performed:", nruns
1837 print " Times : %10.2f %10.2f" % ('Total', 'Per run')
1831 print " Times : %10.2f %10.2f" % ('Total', 'Per run')
1838 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
1832 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
1839 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
1833 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
1840 twall1 = time.time()
1834 twall1 = time.time()
1841 print "Wall time: %10.2f s." % (twall1 - twall0)
1835 print "Wall time: %10.2f s." % (twall1 - twall0)
1842
1836
1843 else:
1837 else:
1844 # regular execution
1838 # regular execution
1845 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
1839 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
1846
1840
1847 if 'i' in opts:
1841 if 'i' in opts:
1848 self.shell.user_ns['__name__'] = __name__save
1842 self.shell.user_ns['__name__'] = __name__save
1849 else:
1843 else:
1850 # The shell MUST hold a reference to prog_ns so after %run
1844 # The shell MUST hold a reference to prog_ns so after %run
1851 # exits, the python deletion mechanism doesn't zero it out
1845 # exits, the python deletion mechanism doesn't zero it out
1852 # (leaving dangling references).
1846 # (leaving dangling references).
1853 self.shell.cache_main_mod(prog_ns, filename)
1847 self.shell.cache_main_mod(prog_ns, filename)
1854 # update IPython interactive namespace
1848 # update IPython interactive namespace
1855
1849
1856 # Some forms of read errors on the file may mean the
1850 # Some forms of read errors on the file may mean the
1857 # __name__ key was never set; using pop we don't have to
1851 # __name__ key was never set; using pop we don't have to
1858 # worry about a possible KeyError.
1852 # worry about a possible KeyError.
1859 prog_ns.pop('__name__', None)
1853 prog_ns.pop('__name__', None)
1860
1854
1861 self.shell.user_ns.update(prog_ns)
1855 self.shell.user_ns.update(prog_ns)
1862 finally:
1856 finally:
1863 # It's a bit of a mystery why, but __builtins__ can change from
1857 # It's a bit of a mystery why, but __builtins__ can change from
1864 # being a module to becoming a dict missing some key data after
1858 # being a module to becoming a dict missing some key data after
1865 # %run. As best I can see, this is NOT something IPython is doing
1859 # %run. As best I can see, this is NOT something IPython is doing
1866 # at all, and similar problems have been reported before:
1860 # at all, and similar problems have been reported before:
1867 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
1861 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
1868 # Since this seems to be done by the interpreter itself, the best
1862 # Since this seems to be done by the interpreter itself, the best
1869 # we can do is to at least restore __builtins__ for the user on
1863 # we can do is to at least restore __builtins__ for the user on
1870 # exit.
1864 # exit.
1871 self.shell.user_ns['__builtins__'] = builtin_mod
1865 self.shell.user_ns['__builtins__'] = builtin_mod
1872
1866
1873 # Ensure key global structures are restored
1867 # Ensure key global structures are restored
1874 sys.argv = save_argv
1868 sys.argv = save_argv
1875 if restore_main:
1869 if restore_main:
1876 sys.modules['__main__'] = restore_main
1870 sys.modules['__main__'] = restore_main
1877 else:
1871 else:
1878 # Remove from sys.modules the reference to main_mod we'd
1872 # Remove from sys.modules the reference to main_mod we'd
1879 # added. Otherwise it will trap references to objects
1873 # added. Otherwise it will trap references to objects
1880 # contained therein.
1874 # contained therein.
1881 del sys.modules[main_mod_name]
1875 del sys.modules[main_mod_name]
1882
1876
1883 return stats
1877 return stats
1884
1878
1885 @skip_doctest
1879 @skip_doctest
1886 def magic_timeit(self, parameter_s =''):
1880 def magic_timeit(self, parameter_s =''):
1887 """Time execution of a Python statement or expression
1881 """Time execution of a Python statement or expression
1888
1882
1889 Usage:\\
1883 Usage:\\
1890 %timeit [-n<N> -r<R> [-t|-c]] statement
1884 %timeit [-n<N> -r<R> [-t|-c]] statement
1891
1885
1892 Time execution of a Python statement or expression using the timeit
1886 Time execution of a Python statement or expression using the timeit
1893 module.
1887 module.
1894
1888
1895 Options:
1889 Options:
1896 -n<N>: execute the given statement <N> times in a loop. If this value
1890 -n<N>: execute the given statement <N> times in a loop. If this value
1897 is not given, a fitting value is chosen.
1891 is not given, a fitting value is chosen.
1898
1892
1899 -r<R>: repeat the loop iteration <R> times and take the best result.
1893 -r<R>: repeat the loop iteration <R> times and take the best result.
1900 Default: 3
1894 Default: 3
1901
1895
1902 -t: use time.time to measure the time, which is the default on Unix.
1896 -t: use time.time to measure the time, which is the default on Unix.
1903 This function measures wall time.
1897 This function measures wall time.
1904
1898
1905 -c: use time.clock to measure the time, which is the default on
1899 -c: use time.clock to measure the time, which is the default on
1906 Windows and measures wall time. On Unix, resource.getrusage is used
1900 Windows and measures wall time. On Unix, resource.getrusage is used
1907 instead and returns the CPU user time.
1901 instead and returns the CPU user time.
1908
1902
1909 -p<P>: use a precision of <P> digits to display the timing result.
1903 -p<P>: use a precision of <P> digits to display the timing result.
1910 Default: 3
1904 Default: 3
1911
1905
1912
1906
1913 Examples
1907 Examples
1914 --------
1908 --------
1915 ::
1909 ::
1916
1910
1917 In [1]: %timeit pass
1911 In [1]: %timeit pass
1918 10000000 loops, best of 3: 53.3 ns per loop
1912 10000000 loops, best of 3: 53.3 ns per loop
1919
1913
1920 In [2]: u = None
1914 In [2]: u = None
1921
1915
1922 In [3]: %timeit u is None
1916 In [3]: %timeit u is None
1923 10000000 loops, best of 3: 184 ns per loop
1917 10000000 loops, best of 3: 184 ns per loop
1924
1918
1925 In [4]: %timeit -r 4 u == None
1919 In [4]: %timeit -r 4 u == None
1926 1000000 loops, best of 4: 242 ns per loop
1920 1000000 loops, best of 4: 242 ns per loop
1927
1921
1928 In [5]: import time
1922 In [5]: import time
1929
1923
1930 In [6]: %timeit -n1 time.sleep(2)
1924 In [6]: %timeit -n1 time.sleep(2)
1931 1 loops, best of 3: 2 s per loop
1925 1 loops, best of 3: 2 s per loop
1932
1926
1933
1927
1934 The times reported by %timeit will be slightly higher than those
1928 The times reported by %timeit will be slightly higher than those
1935 reported by the timeit.py script when variables are accessed. This is
1929 reported by the timeit.py script when variables are accessed. This is
1936 due to the fact that %timeit executes the statement in the namespace
1930 due to the fact that %timeit executes the statement in the namespace
1937 of the shell, compared with timeit.py, which uses a single setup
1931 of the shell, compared with timeit.py, which uses a single setup
1938 statement to import function or create variables. Generally, the bias
1932 statement to import function or create variables. Generally, the bias
1939 does not matter as long as results from timeit.py are not mixed with
1933 does not matter as long as results from timeit.py are not mixed with
1940 those from %timeit."""
1934 those from %timeit."""
1941
1935
1942 import timeit
1936 import timeit
1943 import math
1937 import math
1944
1938
1945 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
1939 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
1946 # certain terminals. Until we figure out a robust way of
1940 # certain terminals. Until we figure out a robust way of
1947 # auto-detecting if the terminal can deal with it, use plain 'us' for
1941 # auto-detecting if the terminal can deal with it, use plain 'us' for
1948 # microseconds. I am really NOT happy about disabling the proper
1942 # microseconds. I am really NOT happy about disabling the proper
1949 # 'micro' prefix, but crashing is worse... If anyone knows what the
1943 # 'micro' prefix, but crashing is worse... If anyone knows what the
1950 # right solution for this is, I'm all ears...
1944 # right solution for this is, I'm all ears...
1951 #
1945 #
1952 # Note: using
1946 # Note: using
1953 #
1947 #
1954 # s = u'\xb5'
1948 # s = u'\xb5'
1955 # s.encode(sys.getdefaultencoding())
1949 # s.encode(sys.getdefaultencoding())
1956 #
1950 #
1957 # is not sufficient, as I've seen terminals where that fails but
1951 # is not sufficient, as I've seen terminals where that fails but
1958 # print s
1952 # print s
1959 #
1953 #
1960 # succeeds
1954 # succeeds
1961 #
1955 #
1962 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1956 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1963
1957
1964 #units = [u"s", u"ms",u'\xb5',"ns"]
1958 #units = [u"s", u"ms",u'\xb5',"ns"]
1965 units = [u"s", u"ms",u'us',"ns"]
1959 units = [u"s", u"ms",u'us',"ns"]
1966
1960
1967 scaling = [1, 1e3, 1e6, 1e9]
1961 scaling = [1, 1e3, 1e6, 1e9]
1968
1962
1969 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1963 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1970 posix=False, strict=False)
1964 posix=False, strict=False)
1971 if stmt == "":
1965 if stmt == "":
1972 return
1966 return
1973 timefunc = timeit.default_timer
1967 timefunc = timeit.default_timer
1974 number = int(getattr(opts, "n", 0))
1968 number = int(getattr(opts, "n", 0))
1975 repeat = int(getattr(opts, "r", timeit.default_repeat))
1969 repeat = int(getattr(opts, "r", timeit.default_repeat))
1976 precision = int(getattr(opts, "p", 3))
1970 precision = int(getattr(opts, "p", 3))
1977 if hasattr(opts, "t"):
1971 if hasattr(opts, "t"):
1978 timefunc = time.time
1972 timefunc = time.time
1979 if hasattr(opts, "c"):
1973 if hasattr(opts, "c"):
1980 timefunc = clock
1974 timefunc = clock
1981
1975
1982 timer = timeit.Timer(timer=timefunc)
1976 timer = timeit.Timer(timer=timefunc)
1983 # this code has tight coupling to the inner workings of timeit.Timer,
1977 # this code has tight coupling to the inner workings of timeit.Timer,
1984 # but is there a better way to achieve that the code stmt has access
1978 # but is there a better way to achieve that the code stmt has access
1985 # to the shell namespace?
1979 # to the shell namespace?
1986
1980
1987 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1981 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1988 'setup': "pass"}
1982 'setup': "pass"}
1989 # Track compilation time so it can be reported if too long
1983 # Track compilation time so it can be reported if too long
1990 # Minimum time above which compilation time will be reported
1984 # Minimum time above which compilation time will be reported
1991 tc_min = 0.1
1985 tc_min = 0.1
1992
1986
1993 t0 = clock()
1987 t0 = clock()
1994 code = compile(src, "<magic-timeit>", "exec")
1988 code = compile(src, "<magic-timeit>", "exec")
1995 tc = clock()-t0
1989 tc = clock()-t0
1996
1990
1997 ns = {}
1991 ns = {}
1998 exec code in self.shell.user_ns, ns
1992 exec code in self.shell.user_ns, ns
1999 timer.inner = ns["inner"]
1993 timer.inner = ns["inner"]
2000
1994
2001 if number == 0:
1995 if number == 0:
2002 # determine number so that 0.2 <= total time < 2.0
1996 # determine number so that 0.2 <= total time < 2.0
2003 number = 1
1997 number = 1
2004 for i in range(1, 10):
1998 for i in range(1, 10):
2005 if timer.timeit(number) >= 0.2:
1999 if timer.timeit(number) >= 0.2:
2006 break
2000 break
2007 number *= 10
2001 number *= 10
2008
2002
2009 best = min(timer.repeat(repeat, number)) / number
2003 best = min(timer.repeat(repeat, number)) / number
2010
2004
2011 if best > 0.0 and best < 1000.0:
2005 if best > 0.0 and best < 1000.0:
2012 order = min(-int(math.floor(math.log10(best)) // 3), 3)
2006 order = min(-int(math.floor(math.log10(best)) // 3), 3)
2013 elif best >= 1000.0:
2007 elif best >= 1000.0:
2014 order = 0
2008 order = 0
2015 else:
2009 else:
2016 order = 3
2010 order = 3
2017 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
2011 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
2018 precision,
2012 precision,
2019 best * scaling[order],
2013 best * scaling[order],
2020 units[order])
2014 units[order])
2021 if tc > tc_min:
2015 if tc > tc_min:
2022 print "Compiler time: %.2f s" % tc
2016 print "Compiler time: %.2f s" % tc
2023
2017
2024 @skip_doctest
2018 @skip_doctest
2025 @needs_local_scope
2019 @needs_local_scope
2026 def magic_time(self,parameter_s = ''):
2020 def magic_time(self,parameter_s = ''):
2027 """Time execution of a Python statement or expression.
2021 """Time execution of a Python statement or expression.
2028
2022
2029 The CPU and wall clock times are printed, and the value of the
2023 The CPU and wall clock times are printed, and the value of the
2030 expression (if any) is returned. Note that under Win32, system time
2024 expression (if any) is returned. Note that under Win32, system time
2031 is always reported as 0, since it can not be measured.
2025 is always reported as 0, since it can not be measured.
2032
2026
2033 This function provides very basic timing functionality. In Python
2027 This function provides very basic timing functionality. In Python
2034 2.3, the timeit module offers more control and sophistication, so this
2028 2.3, the timeit module offers more control and sophistication, so this
2035 could be rewritten to use it (patches welcome).
2029 could be rewritten to use it (patches welcome).
2036
2030
2037 Examples
2031 Examples
2038 --------
2032 --------
2039 ::
2033 ::
2040
2034
2041 In [1]: time 2**128
2035 In [1]: time 2**128
2042 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2036 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2043 Wall time: 0.00
2037 Wall time: 0.00
2044 Out[1]: 340282366920938463463374607431768211456L
2038 Out[1]: 340282366920938463463374607431768211456L
2045
2039
2046 In [2]: n = 1000000
2040 In [2]: n = 1000000
2047
2041
2048 In [3]: time sum(range(n))
2042 In [3]: time sum(range(n))
2049 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
2043 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
2050 Wall time: 1.37
2044 Wall time: 1.37
2051 Out[3]: 499999500000L
2045 Out[3]: 499999500000L
2052
2046
2053 In [4]: time print 'hello world'
2047 In [4]: time print 'hello world'
2054 hello world
2048 hello world
2055 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2049 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2056 Wall time: 0.00
2050 Wall time: 0.00
2057
2051
2058 Note that the time needed by Python to compile the given expression
2052 Note that the time needed by Python to compile the given expression
2059 will be reported if it is more than 0.1s. In this example, the
2053 will be reported if it is more than 0.1s. In this example, the
2060 actual exponentiation is done by Python at compilation time, so while
2054 actual exponentiation is done by Python at compilation time, so while
2061 the expression can take a noticeable amount of time to compute, that
2055 the expression can take a noticeable amount of time to compute, that
2062 time is purely due to the compilation:
2056 time is purely due to the compilation:
2063
2057
2064 In [5]: time 3**9999;
2058 In [5]: time 3**9999;
2065 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2059 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2066 Wall time: 0.00 s
2060 Wall time: 0.00 s
2067
2061
2068 In [6]: time 3**999999;
2062 In [6]: time 3**999999;
2069 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2063 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
2070 Wall time: 0.00 s
2064 Wall time: 0.00 s
2071 Compiler : 0.78 s
2065 Compiler : 0.78 s
2072 """
2066 """
2073
2067
2074 # fail immediately if the given expression can't be compiled
2068 # fail immediately if the given expression can't be compiled
2075
2069
2076 expr = self.shell.prefilter(parameter_s,False)
2070 expr = self.shell.prefilter(parameter_s,False)
2077
2071
2078 # Minimum time above which compilation time will be reported
2072 # Minimum time above which compilation time will be reported
2079 tc_min = 0.1
2073 tc_min = 0.1
2080
2074
2081 try:
2075 try:
2082 mode = 'eval'
2076 mode = 'eval'
2083 t0 = clock()
2077 t0 = clock()
2084 code = compile(expr,'<timed eval>',mode)
2078 code = compile(expr,'<timed eval>',mode)
2085 tc = clock()-t0
2079 tc = clock()-t0
2086 except SyntaxError:
2080 except SyntaxError:
2087 mode = 'exec'
2081 mode = 'exec'
2088 t0 = clock()
2082 t0 = clock()
2089 code = compile(expr,'<timed exec>',mode)
2083 code = compile(expr,'<timed exec>',mode)
2090 tc = clock()-t0
2084 tc = clock()-t0
2091 # skew measurement as little as possible
2085 # skew measurement as little as possible
2092 glob = self.shell.user_ns
2086 glob = self.shell.user_ns
2093 locs = self._magic_locals
2087 locs = self._magic_locals
2094 clk = clock2
2088 clk = clock2
2095 wtime = time.time
2089 wtime = time.time
2096 # time execution
2090 # time execution
2097 wall_st = wtime()
2091 wall_st = wtime()
2098 if mode=='eval':
2092 if mode=='eval':
2099 st = clk()
2093 st = clk()
2100 out = eval(code, glob, locs)
2094 out = eval(code, glob, locs)
2101 end = clk()
2095 end = clk()
2102 else:
2096 else:
2103 st = clk()
2097 st = clk()
2104 exec code in glob, locs
2098 exec code in glob, locs
2105 end = clk()
2099 end = clk()
2106 out = None
2100 out = None
2107 wall_end = wtime()
2101 wall_end = wtime()
2108 # Compute actual times and report
2102 # Compute actual times and report
2109 wall_time = wall_end-wall_st
2103 wall_time = wall_end-wall_st
2110 cpu_user = end[0]-st[0]
2104 cpu_user = end[0]-st[0]
2111 cpu_sys = end[1]-st[1]
2105 cpu_sys = end[1]-st[1]
2112 cpu_tot = cpu_user+cpu_sys
2106 cpu_tot = cpu_user+cpu_sys
2113 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
2107 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
2114 (cpu_user,cpu_sys,cpu_tot)
2108 (cpu_user,cpu_sys,cpu_tot)
2115 print "Wall time: %.2f s" % wall_time
2109 print "Wall time: %.2f s" % wall_time
2116 if tc > tc_min:
2110 if tc > tc_min:
2117 print "Compiler : %.2f s" % tc
2111 print "Compiler : %.2f s" % tc
2118 return out
2112 return out
2119
2113
2120 @skip_doctest
2114 @skip_doctest
2121 def magic_macro(self,parameter_s = ''):
2115 def magic_macro(self,parameter_s = ''):
2122 """Define a macro for future re-execution. It accepts ranges of history,
2116 """Define a macro for future re-execution. It accepts ranges of history,
2123 filenames or string objects.
2117 filenames or string objects.
2124
2118
2125 Usage:\\
2119 Usage:\\
2126 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
2120 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
2127
2121
2128 Options:
2122 Options:
2129
2123
2130 -r: use 'raw' input. By default, the 'processed' history is used,
2124 -r: use 'raw' input. By default, the 'processed' history is used,
2131 so that magics are loaded in their transformed version to valid
2125 so that magics are loaded in their transformed version to valid
2132 Python. If this option is given, the raw input as typed as the
2126 Python. If this option is given, the raw input as typed as the
2133 command line is used instead.
2127 command line is used instead.
2134
2128
2135 This will define a global variable called `name` which is a string
2129 This will define a global variable called `name` which is a string
2136 made of joining the slices and lines you specify (n1,n2,... numbers
2130 made of joining the slices and lines you specify (n1,n2,... numbers
2137 above) from your input history into a single string. This variable
2131 above) from your input history into a single string. This variable
2138 acts like an automatic function which re-executes those lines as if
2132 acts like an automatic function which re-executes those lines as if
2139 you had typed them. You just type 'name' at the prompt and the code
2133 you had typed them. You just type 'name' at the prompt and the code
2140 executes.
2134 executes.
2141
2135
2142 The syntax for indicating input ranges is described in %history.
2136 The syntax for indicating input ranges is described in %history.
2143
2137
2144 Note: as a 'hidden' feature, you can also use traditional python slice
2138 Note: as a 'hidden' feature, you can also use traditional python slice
2145 notation, where N:M means numbers N through M-1.
2139 notation, where N:M means numbers N through M-1.
2146
2140
2147 For example, if your history contains (%hist prints it)::
2141 For example, if your history contains (%hist prints it)::
2148
2142
2149 44: x=1
2143 44: x=1
2150 45: y=3
2144 45: y=3
2151 46: z=x+y
2145 46: z=x+y
2152 47: print x
2146 47: print x
2153 48: a=5
2147 48: a=5
2154 49: print 'x',x,'y',y
2148 49: print 'x',x,'y',y
2155
2149
2156 you can create a macro with lines 44 through 47 (included) and line 49
2150 you can create a macro with lines 44 through 47 (included) and line 49
2157 called my_macro with::
2151 called my_macro with::
2158
2152
2159 In [55]: %macro my_macro 44-47 49
2153 In [55]: %macro my_macro 44-47 49
2160
2154
2161 Now, typing `my_macro` (without quotes) will re-execute all this code
2155 Now, typing `my_macro` (without quotes) will re-execute all this code
2162 in one pass.
2156 in one pass.
2163
2157
2164 You don't need to give the line-numbers in order, and any given line
2158 You don't need to give the line-numbers in order, and any given line
2165 number can appear multiple times. You can assemble macros with any
2159 number can appear multiple times. You can assemble macros with any
2166 lines from your input history in any order.
2160 lines from your input history in any order.
2167
2161
2168 The macro is a simple object which holds its value in an attribute,
2162 The macro is a simple object which holds its value in an attribute,
2169 but IPython's display system checks for macros and executes them as
2163 but IPython's display system checks for macros and executes them as
2170 code instead of printing them when you type their name.
2164 code instead of printing them when you type their name.
2171
2165
2172 You can view a macro's contents by explicitly printing it with::
2166 You can view a macro's contents by explicitly printing it with::
2173
2167
2174 print macro_name
2168 print macro_name
2175
2169
2176 """
2170 """
2177 opts,args = self.parse_options(parameter_s,'r',mode='list')
2171 opts,args = self.parse_options(parameter_s,'r',mode='list')
2178 if not args: # List existing macros
2172 if not args: # List existing macros
2179 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
2173 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
2180 isinstance(v, Macro))
2174 isinstance(v, Macro))
2181 if len(args) == 1:
2175 if len(args) == 1:
2182 raise UsageError(
2176 raise UsageError(
2183 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2177 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2184 name, codefrom = args[0], " ".join(args[1:])
2178 name, codefrom = args[0], " ".join(args[1:])
2185
2179
2186 #print 'rng',ranges # dbg
2180 #print 'rng',ranges # dbg
2187 try:
2181 try:
2188 lines = self.shell.find_user_code(codefrom, 'r' in opts)
2182 lines = self.shell.find_user_code(codefrom, 'r' in opts)
2189 except (ValueError, TypeError) as e:
2183 except (ValueError, TypeError) as e:
2190 print e.args[0]
2184 print e.args[0]
2191 return
2185 return
2192 macro = Macro(lines)
2186 macro = Macro(lines)
2193 self.shell.define_macro(name, macro)
2187 self.shell.define_macro(name, macro)
2194 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2188 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2195 print '=== Macro contents: ==='
2189 print '=== Macro contents: ==='
2196 print macro,
2190 print macro,
2197
2191
2198 def magic_save(self,parameter_s = ''):
2192 def magic_save(self,parameter_s = ''):
2199 """Save a set of lines or a macro to a given filename.
2193 """Save a set of lines or a macro to a given filename.
2200
2194
2201 Usage:\\
2195 Usage:\\
2202 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2196 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2203
2197
2204 Options:
2198 Options:
2205
2199
2206 -r: use 'raw' input. By default, the 'processed' history is used,
2200 -r: use 'raw' input. By default, the 'processed' history is used,
2207 so that magics are loaded in their transformed version to valid
2201 so that magics are loaded in their transformed version to valid
2208 Python. If this option is given, the raw input as typed as the
2202 Python. If this option is given, the raw input as typed as the
2209 command line is used instead.
2203 command line is used instead.
2210
2204
2211 This function uses the same syntax as %history for input ranges,
2205 This function uses the same syntax as %history for input ranges,
2212 then saves the lines to the filename you specify.
2206 then saves the lines to the filename you specify.
2213
2207
2214 It adds a '.py' extension to the file if you don't do so yourself, and
2208 It adds a '.py' extension to the file if you don't do so yourself, and
2215 it asks for confirmation before overwriting existing files."""
2209 it asks for confirmation before overwriting existing files."""
2216
2210
2217 opts,args = self.parse_options(parameter_s,'r',mode='list')
2211 opts,args = self.parse_options(parameter_s,'r',mode='list')
2218 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
2212 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
2219 if not fname.endswith('.py'):
2213 if not fname.endswith('.py'):
2220 fname += '.py'
2214 fname += '.py'
2221 if os.path.isfile(fname):
2215 if os.path.isfile(fname):
2222 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2216 overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
2223 if ans.lower() not in ['y','yes']:
2217 if not overwrite :
2224 print 'Operation cancelled.'
2218 print 'Operation cancelled.'
2225 return
2219 return
2226 try:
2220 try:
2227 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
2221 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
2228 except (TypeError, ValueError) as e:
2222 except (TypeError, ValueError) as e:
2229 print e.args[0]
2223 print e.args[0]
2230 return
2224 return
2231 with io.open(fname,'w', encoding="utf-8") as f:
2225 with io.open(fname,'w', encoding="utf-8") as f:
2232 f.write(u"# coding: utf-8\n")
2226 f.write(u"# coding: utf-8\n")
2233 f.write(py3compat.cast_unicode(cmds))
2227 f.write(py3compat.cast_unicode(cmds))
2234 print 'The following commands were written to file `%s`:' % fname
2228 print 'The following commands were written to file `%s`:' % fname
2235 print cmds
2229 print cmds
2236
2230
2237 def magic_pastebin(self, parameter_s = ''):
2231 def magic_pastebin(self, parameter_s = ''):
2238 """Upload code to Github's Gist paste bin, returning the URL.
2232 """Upload code to Github's Gist paste bin, returning the URL.
2239
2233
2240 Usage:\\
2234 Usage:\\
2241 %pastebin [-d "Custom description"] 1-7
2235 %pastebin [-d "Custom description"] 1-7
2242
2236
2243 The argument can be an input history range, a filename, or the name of a
2237 The argument can be an input history range, a filename, or the name of a
2244 string or macro.
2238 string or macro.
2245
2239
2246 Options:
2240 Options:
2247
2241
2248 -d: Pass a custom description for the gist. The default will say
2242 -d: Pass a custom description for the gist. The default will say
2249 "Pasted from IPython".
2243 "Pasted from IPython".
2250 """
2244 """
2251 opts, args = self.parse_options(parameter_s, 'd:')
2245 opts, args = self.parse_options(parameter_s, 'd:')
2252
2246
2253 try:
2247 try:
2254 code = self.shell.find_user_code(args)
2248 code = self.shell.find_user_code(args)
2255 except (ValueError, TypeError) as e:
2249 except (ValueError, TypeError) as e:
2256 print e.args[0]
2250 print e.args[0]
2257 return
2251 return
2258
2252
2259 post_data = json.dumps({
2253 post_data = json.dumps({
2260 "description": opts.get('d', "Pasted from IPython"),
2254 "description": opts.get('d', "Pasted from IPython"),
2261 "public": True,
2255 "public": True,
2262 "files": {
2256 "files": {
2263 "file1.py": {
2257 "file1.py": {
2264 "content": code
2258 "content": code
2265 }
2259 }
2266 }
2260 }
2267 }).encode('utf-8')
2261 }).encode('utf-8')
2268
2262
2269 response = urlopen("https://api.github.com/gists", post_data)
2263 response = urlopen("https://api.github.com/gists", post_data)
2270 response_data = json.loads(response.read().decode('utf-8'))
2264 response_data = json.loads(response.read().decode('utf-8'))
2271 return response_data['html_url']
2265 return response_data['html_url']
2272
2266
2273 def magic_loadpy(self, arg_s):
2267 def magic_loadpy(self, arg_s):
2274 """Load a .py python script into the GUI console.
2268 """Alias of `%load`
2269
2270 `%loadpy` has gained some flexibility and droped the requirement of a `.py`
2271 extension. So it has been renamed simply into %load. You can look at
2272 `%load`'s docstring for more info.
2273 """
2274 self.magic_load(arg_s)
2275
2276 def magic_load(self, arg_s):
2277 """Load code into the current frontend.
2278
2279 Usage:\\
2280 %load [options] source
2281
2282 where source can be a filename, URL, input history range or macro
2283
2284 Options:
2285 --------
2286 -y : Don't ask confirmation for loading source above 200 000 characters.
2275
2287
2276 This magic command can either take a local filename or a url::
2288 This magic command can either take a local filename, a URL, an history
2289 range (see %history) or a macro as argument, it will prompt for
2290 confirmation before loading source with more than 200 000 characters, unless
2291 -y flag is passed or if the frontend does not support raw_input::
2277
2292
2278 %loadpy myscript.py
2293 %load myscript.py
2279 %loadpy http://www.example.com/myscript.py
2294 %load 7-27
2295 %load myMacro
2296 %load http://www.example.com/myscript.py
2280 """
2297 """
2281 arg_s = unquote_filename(arg_s)
2298 opts,args = self.parse_options(arg_s,'y')
2282 remote_url = arg_s.startswith(('http://', 'https://'))
2299
2283 local_url = not remote_url
2300 contents = self.shell.find_user_code(args)
2284 if local_url and not arg_s.endswith('.py'):
2301 l = len(contents)
2285 # Local files must be .py; for remote URLs it's possible that the
2302
2286 # fetch URL doesn't have a .py in it (many servers have an opaque
2303 # 200 000 is ~ 2500 full 80 caracter lines
2287 # URL, such as scipy-central.org).
2304 # so in average, more than 5000 lines
2288 raise ValueError('%%loadpy only works with .py files: %s' % arg_s)
2305 if l > 200000 and 'y' not in opts:
2289
2306 try:
2290 # openpy takes care of finding the source encoding (per PEP 263)
2307 ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\
2291 if remote_url:
2308 " (%d characters). Continue (y/[N]) ?" % l), default='n' )
2292 contents = openpy.read_py_url(arg_s, skip_encoding_cookie=True)
2309 except StdinNotImplementedError:
2293 else:
2310 #asume yes if raw input not implemented
2294 contents = openpy.read_py_file(arg_s, skip_encoding_cookie=True)
2311 ans = True
2295
2312
2313 if ans is False :
2314 print 'Operation cancelled.'
2315 return
2316
2296 self.set_next_input(contents)
2317 self.set_next_input(contents)
2297
2318
2298 def _find_edit_target(self, args, opts, last_call):
2319 def _find_edit_target(self, args, opts, last_call):
2299 """Utility method used by magic_edit to find what to edit."""
2320 """Utility method used by magic_edit to find what to edit."""
2300
2321
2301 def make_filename(arg):
2322 def make_filename(arg):
2302 "Make a filename from the given args"
2323 "Make a filename from the given args"
2303 arg = unquote_filename(arg)
2324 arg = unquote_filename(arg)
2304 try:
2325 try:
2305 filename = get_py_filename(arg)
2326 filename = get_py_filename(arg)
2306 except IOError:
2327 except IOError:
2307 # If it ends with .py but doesn't already exist, assume we want
2328 # If it ends with .py but doesn't already exist, assume we want
2308 # a new file.
2329 # a new file.
2309 if arg.endswith('.py'):
2330 if arg.endswith('.py'):
2310 filename = arg
2331 filename = arg
2311 else:
2332 else:
2312 filename = None
2333 filename = None
2313 return filename
2334 return filename
2314
2335
2315 # Set a few locals from the options for convenience:
2336 # Set a few locals from the options for convenience:
2316 opts_prev = 'p' in opts
2337 opts_prev = 'p' in opts
2317 opts_raw = 'r' in opts
2338 opts_raw = 'r' in opts
2318
2339
2319 # custom exceptions
2340 # custom exceptions
2320 class DataIsObject(Exception): pass
2341 class DataIsObject(Exception): pass
2321
2342
2322 # Default line number value
2343 # Default line number value
2323 lineno = opts.get('n',None)
2344 lineno = opts.get('n',None)
2324
2345
2325 if opts_prev:
2346 if opts_prev:
2326 args = '_%s' % last_call[0]
2347 args = '_%s' % last_call[0]
2327 if not self.shell.user_ns.has_key(args):
2348 if not self.shell.user_ns.has_key(args):
2328 args = last_call[1]
2349 args = last_call[1]
2329
2350
2330 # use last_call to remember the state of the previous call, but don't
2351 # use last_call to remember the state of the previous call, but don't
2331 # let it be clobbered by successive '-p' calls.
2352 # let it be clobbered by successive '-p' calls.
2332 try:
2353 try:
2333 last_call[0] = self.shell.displayhook.prompt_count
2354 last_call[0] = self.shell.displayhook.prompt_count
2334 if not opts_prev:
2355 if not opts_prev:
2335 last_call[1] = args
2356 last_call[1] = args
2336 except:
2357 except:
2337 pass
2358 pass
2338
2359
2339 # by default this is done with temp files, except when the given
2360 # by default this is done with temp files, except when the given
2340 # arg is a filename
2361 # arg is a filename
2341 use_temp = True
2362 use_temp = True
2342
2363
2343 data = ''
2364 data = ''
2344
2365
2345 # First, see if the arguments should be a filename.
2366 # First, see if the arguments should be a filename.
2346 filename = make_filename(args)
2367 filename = make_filename(args)
2347 if filename:
2368 if filename:
2348 use_temp = False
2369 use_temp = False
2349 elif args:
2370 elif args:
2350 # Mode where user specifies ranges of lines, like in %macro.
2371 # Mode where user specifies ranges of lines, like in %macro.
2351 data = self.extract_input_lines(args, opts_raw)
2372 data = self.extract_input_lines(args, opts_raw)
2352 if not data:
2373 if not data:
2353 try:
2374 try:
2354 # Load the parameter given as a variable. If not a string,
2375 # Load the parameter given as a variable. If not a string,
2355 # process it as an object instead (below)
2376 # process it as an object instead (below)
2356
2377
2357 #print '*** args',args,'type',type(args) # dbg
2378 #print '*** args',args,'type',type(args) # dbg
2358 data = eval(args, self.shell.user_ns)
2379 data = eval(args, self.shell.user_ns)
2359 if not isinstance(data, basestring):
2380 if not isinstance(data, basestring):
2360 raise DataIsObject
2381 raise DataIsObject
2361
2382
2362 except (NameError,SyntaxError):
2383 except (NameError,SyntaxError):
2363 # given argument is not a variable, try as a filename
2384 # given argument is not a variable, try as a filename
2364 filename = make_filename(args)
2385 filename = make_filename(args)
2365 if filename is None:
2386 if filename is None:
2366 warn("Argument given (%s) can't be found as a variable "
2387 warn("Argument given (%s) can't be found as a variable "
2367 "or as a filename." % args)
2388 "or as a filename." % args)
2368 return
2389 return
2369 use_temp = False
2390 use_temp = False
2370
2391
2371 except DataIsObject:
2392 except DataIsObject:
2372 # macros have a special edit function
2393 # macros have a special edit function
2373 if isinstance(data, Macro):
2394 if isinstance(data, Macro):
2374 raise MacroToEdit(data)
2395 raise MacroToEdit(data)
2375
2396
2376 # For objects, try to edit the file where they are defined
2397 # For objects, try to edit the file where they are defined
2377 try:
2398 try:
2378 filename = inspect.getabsfile(data)
2399 filename = inspect.getabsfile(data)
2379 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2400 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2380 # class created by %edit? Try to find source
2401 # class created by %edit? Try to find source
2381 # by looking for method definitions instead, the
2402 # by looking for method definitions instead, the
2382 # __module__ in those classes is FakeModule.
2403 # __module__ in those classes is FakeModule.
2383 attrs = [getattr(data, aname) for aname in dir(data)]
2404 attrs = [getattr(data, aname) for aname in dir(data)]
2384 for attr in attrs:
2405 for attr in attrs:
2385 if not inspect.ismethod(attr):
2406 if not inspect.ismethod(attr):
2386 continue
2407 continue
2387 filename = inspect.getabsfile(attr)
2408 filename = inspect.getabsfile(attr)
2388 if filename and 'fakemodule' not in filename.lower():
2409 if filename and 'fakemodule' not in filename.lower():
2389 # change the attribute to be the edit target instead
2410 # change the attribute to be the edit target instead
2390 data = attr
2411 data = attr
2391 break
2412 break
2392
2413
2393 datafile = 1
2414 datafile = 1
2394 except TypeError:
2415 except TypeError:
2395 filename = make_filename(args)
2416 filename = make_filename(args)
2396 datafile = 1
2417 datafile = 1
2397 warn('Could not find file where `%s` is defined.\n'
2418 warn('Could not find file where `%s` is defined.\n'
2398 'Opening a file named `%s`' % (args,filename))
2419 'Opening a file named `%s`' % (args,filename))
2399 # Now, make sure we can actually read the source (if it was in
2420 # Now, make sure we can actually read the source (if it was in
2400 # a temp file it's gone by now).
2421 # a temp file it's gone by now).
2401 if datafile:
2422 if datafile:
2402 try:
2423 try:
2403 if lineno is None:
2424 if lineno is None:
2404 lineno = inspect.getsourcelines(data)[1]
2425 lineno = inspect.getsourcelines(data)[1]
2405 except IOError:
2426 except IOError:
2406 filename = make_filename(args)
2427 filename = make_filename(args)
2407 if filename is None:
2428 if filename is None:
2408 warn('The file `%s` where `%s` was defined cannot '
2429 warn('The file `%s` where `%s` was defined cannot '
2409 'be read.' % (filename,data))
2430 'be read.' % (filename,data))
2410 return
2431 return
2411 use_temp = False
2432 use_temp = False
2412
2433
2413 if use_temp:
2434 if use_temp:
2414 filename = self.shell.mktempfile(data)
2435 filename = self.shell.mktempfile(data)
2415 print 'IPython will make a temporary file named:',filename
2436 print 'IPython will make a temporary file named:',filename
2416
2437
2417 return filename, lineno, use_temp
2438 return filename, lineno, use_temp
2418
2439
2419 def _edit_macro(self,mname,macro):
2440 def _edit_macro(self,mname,macro):
2420 """open an editor with the macro data in a file"""
2441 """open an editor with the macro data in a file"""
2421 filename = self.shell.mktempfile(macro.value)
2442 filename = self.shell.mktempfile(macro.value)
2422 self.shell.hooks.editor(filename)
2443 self.shell.hooks.editor(filename)
2423
2444
2424 # and make a new macro object, to replace the old one
2445 # and make a new macro object, to replace the old one
2425 mfile = open(filename)
2446 mfile = open(filename)
2426 mvalue = mfile.read()
2447 mvalue = mfile.read()
2427 mfile.close()
2448 mfile.close()
2428 self.shell.user_ns[mname] = Macro(mvalue)
2449 self.shell.user_ns[mname] = Macro(mvalue)
2429
2450
2430 def magic_ed(self,parameter_s=''):
2451 def magic_ed(self,parameter_s=''):
2431 """Alias to %edit."""
2452 """Alias to %edit."""
2432 return self.magic_edit(parameter_s)
2453 return self.magic_edit(parameter_s)
2433
2454
2434 @skip_doctest
2455 @skip_doctest
2435 def magic_edit(self,parameter_s='',last_call=['','']):
2456 def magic_edit(self,parameter_s='',last_call=['','']):
2436 """Bring up an editor and execute the resulting code.
2457 """Bring up an editor and execute the resulting code.
2437
2458
2438 Usage:
2459 Usage:
2439 %edit [options] [args]
2460 %edit [options] [args]
2440
2461
2441 %edit runs IPython's editor hook. The default version of this hook is
2462 %edit runs IPython's editor hook. The default version of this hook is
2442 set to call the editor specified by your $EDITOR environment variable.
2463 set to call the editor specified by your $EDITOR environment variable.
2443 If this isn't found, it will default to vi under Linux/Unix and to
2464 If this isn't found, it will default to vi under Linux/Unix and to
2444 notepad under Windows. See the end of this docstring for how to change
2465 notepad under Windows. See the end of this docstring for how to change
2445 the editor hook.
2466 the editor hook.
2446
2467
2447 You can also set the value of this editor via the
2468 You can also set the value of this editor via the
2448 ``TerminalInteractiveShell.editor`` option in your configuration file.
2469 ``TerminalInteractiveShell.editor`` option in your configuration file.
2449 This is useful if you wish to use a different editor from your typical
2470 This is useful if you wish to use a different editor from your typical
2450 default with IPython (and for Windows users who typically don't set
2471 default with IPython (and for Windows users who typically don't set
2451 environment variables).
2472 environment variables).
2452
2473
2453 This command allows you to conveniently edit multi-line code right in
2474 This command allows you to conveniently edit multi-line code right in
2454 your IPython session.
2475 your IPython session.
2455
2476
2456 If called without arguments, %edit opens up an empty editor with a
2477 If called without arguments, %edit opens up an empty editor with a
2457 temporary file and will execute the contents of this file when you
2478 temporary file and will execute the contents of this file when you
2458 close it (don't forget to save it!).
2479 close it (don't forget to save it!).
2459
2480
2460
2481
2461 Options:
2482 Options:
2462
2483
2463 -n <number>: open the editor at a specified line number. By default,
2484 -n <number>: open the editor at a specified line number. By default,
2464 the IPython editor hook uses the unix syntax 'editor +N filename', but
2485 the IPython editor hook uses the unix syntax 'editor +N filename', but
2465 you can configure this by providing your own modified hook if your
2486 you can configure this by providing your own modified hook if your
2466 favorite editor supports line-number specifications with a different
2487 favorite editor supports line-number specifications with a different
2467 syntax.
2488 syntax.
2468
2489
2469 -p: this will call the editor with the same data as the previous time
2490 -p: this will call the editor with the same data as the previous time
2470 it was used, regardless of how long ago (in your current session) it
2491 it was used, regardless of how long ago (in your current session) it
2471 was.
2492 was.
2472
2493
2473 -r: use 'raw' input. This option only applies to input taken from the
2494 -r: use 'raw' input. This option only applies to input taken from the
2474 user's history. By default, the 'processed' history is used, so that
2495 user's history. By default, the 'processed' history is used, so that
2475 magics are loaded in their transformed version to valid Python. If
2496 magics are loaded in their transformed version to valid Python. If
2476 this option is given, the raw input as typed as the command line is
2497 this option is given, the raw input as typed as the command line is
2477 used instead. When you exit the editor, it will be executed by
2498 used instead. When you exit the editor, it will be executed by
2478 IPython's own processor.
2499 IPython's own processor.
2479
2500
2480 -x: do not execute the edited code immediately upon exit. This is
2501 -x: do not execute the edited code immediately upon exit. This is
2481 mainly useful if you are editing programs which need to be called with
2502 mainly useful if you are editing programs which need to be called with
2482 command line arguments, which you can then do using %run.
2503 command line arguments, which you can then do using %run.
2483
2504
2484
2505
2485 Arguments:
2506 Arguments:
2486
2507
2487 If arguments are given, the following possibilities exist:
2508 If arguments are given, the following possibilities exist:
2488
2509
2489 - If the argument is a filename, IPython will load that into the
2510 - If the argument is a filename, IPython will load that into the
2490 editor. It will execute its contents with execfile() when you exit,
2511 editor. It will execute its contents with execfile() when you exit,
2491 loading any code in the file into your interactive namespace.
2512 loading any code in the file into your interactive namespace.
2492
2513
2493 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
2514 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
2494 The syntax is the same as in the %history magic.
2515 The syntax is the same as in the %history magic.
2495
2516
2496 - If the argument is a string variable, its contents are loaded
2517 - If the argument is a string variable, its contents are loaded
2497 into the editor. You can thus edit any string which contains
2518 into the editor. You can thus edit any string which contains
2498 python code (including the result of previous edits).
2519 python code (including the result of previous edits).
2499
2520
2500 - If the argument is the name of an object (other than a string),
2521 - If the argument is the name of an object (other than a string),
2501 IPython will try to locate the file where it was defined and open the
2522 IPython will try to locate the file where it was defined and open the
2502 editor at the point where it is defined. You can use `%edit function`
2523 editor at the point where it is defined. You can use `%edit function`
2503 to load an editor exactly at the point where 'function' is defined,
2524 to load an editor exactly at the point where 'function' is defined,
2504 edit it and have the file be executed automatically.
2525 edit it and have the file be executed automatically.
2505
2526
2506 - If the object is a macro (see %macro for details), this opens up your
2527 - If the object is a macro (see %macro for details), this opens up your
2507 specified editor with a temporary file containing the macro's data.
2528 specified editor with a temporary file containing the macro's data.
2508 Upon exit, the macro is reloaded with the contents of the file.
2529 Upon exit, the macro is reloaded with the contents of the file.
2509
2530
2510 Note: opening at an exact line is only supported under Unix, and some
2531 Note: opening at an exact line is only supported under Unix, and some
2511 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2532 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2512 '+NUMBER' parameter necessary for this feature. Good editors like
2533 '+NUMBER' parameter necessary for this feature. Good editors like
2513 (X)Emacs, vi, jed, pico and joe all do.
2534 (X)Emacs, vi, jed, pico and joe all do.
2514
2535
2515 After executing your code, %edit will return as output the code you
2536 After executing your code, %edit will return as output the code you
2516 typed in the editor (except when it was an existing file). This way
2537 typed in the editor (except when it was an existing file). This way
2517 you can reload the code in further invocations of %edit as a variable,
2538 you can reload the code in further invocations of %edit as a variable,
2518 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2539 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2519 the output.
2540 the output.
2520
2541
2521 Note that %edit is also available through the alias %ed.
2542 Note that %edit is also available through the alias %ed.
2522
2543
2523 This is an example of creating a simple function inside the editor and
2544 This is an example of creating a simple function inside the editor and
2524 then modifying it. First, start up the editor::
2545 then modifying it. First, start up the editor::
2525
2546
2526 In [1]: ed
2547 In [1]: ed
2527 Editing... done. Executing edited code...
2548 Editing... done. Executing edited code...
2528 Out[1]: 'def foo():\\n print "foo() was defined in an editing
2549 Out[1]: 'def foo():\\n print "foo() was defined in an editing
2529 session"\\n'
2550 session"\\n'
2530
2551
2531 We can then call the function foo()::
2552 We can then call the function foo()::
2532
2553
2533 In [2]: foo()
2554 In [2]: foo()
2534 foo() was defined in an editing session
2555 foo() was defined in an editing session
2535
2556
2536 Now we edit foo. IPython automatically loads the editor with the
2557 Now we edit foo. IPython automatically loads the editor with the
2537 (temporary) file where foo() was previously defined::
2558 (temporary) file where foo() was previously defined::
2538
2559
2539 In [3]: ed foo
2560 In [3]: ed foo
2540 Editing... done. Executing edited code...
2561 Editing... done. Executing edited code...
2541
2562
2542 And if we call foo() again we get the modified version::
2563 And if we call foo() again we get the modified version::
2543
2564
2544 In [4]: foo()
2565 In [4]: foo()
2545 foo() has now been changed!
2566 foo() has now been changed!
2546
2567
2547 Here is an example of how to edit a code snippet successive
2568 Here is an example of how to edit a code snippet successive
2548 times. First we call the editor::
2569 times. First we call the editor::
2549
2570
2550 In [5]: ed
2571 In [5]: ed
2551 Editing... done. Executing edited code...
2572 Editing... done. Executing edited code...
2552 hello
2573 hello
2553 Out[5]: "print 'hello'\\n"
2574 Out[5]: "print 'hello'\\n"
2554
2575
2555 Now we call it again with the previous output (stored in _)::
2576 Now we call it again with the previous output (stored in _)::
2556
2577
2557 In [6]: ed _
2578 In [6]: ed _
2558 Editing... done. Executing edited code...
2579 Editing... done. Executing edited code...
2559 hello world
2580 hello world
2560 Out[6]: "print 'hello world'\\n"
2581 Out[6]: "print 'hello world'\\n"
2561
2582
2562 Now we call it with the output #8 (stored in _8, also as Out[8])::
2583 Now we call it with the output #8 (stored in _8, also as Out[8])::
2563
2584
2564 In [7]: ed _8
2585 In [7]: ed _8
2565 Editing... done. Executing edited code...
2586 Editing... done. Executing edited code...
2566 hello again
2587 hello again
2567 Out[7]: "print 'hello again'\\n"
2588 Out[7]: "print 'hello again'\\n"
2568
2589
2569
2590
2570 Changing the default editor hook:
2591 Changing the default editor hook:
2571
2592
2572 If you wish to write your own editor hook, you can put it in a
2593 If you wish to write your own editor hook, you can put it in a
2573 configuration file which you load at startup time. The default hook
2594 configuration file which you load at startup time. The default hook
2574 is defined in the IPython.core.hooks module, and you can use that as a
2595 is defined in the IPython.core.hooks module, and you can use that as a
2575 starting example for further modifications. That file also has
2596 starting example for further modifications. That file also has
2576 general instructions on how to set a new hook for use once you've
2597 general instructions on how to set a new hook for use once you've
2577 defined it."""
2598 defined it."""
2578 opts,args = self.parse_options(parameter_s,'prxn:')
2599 opts,args = self.parse_options(parameter_s,'prxn:')
2579
2600
2580 try:
2601 try:
2581 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
2602 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
2582 except MacroToEdit as e:
2603 except MacroToEdit as e:
2583 self._edit_macro(args, e.args[0])
2604 self._edit_macro(args, e.args[0])
2584 return
2605 return
2585
2606
2586 # do actual editing here
2607 # do actual editing here
2587 print 'Editing...',
2608 print 'Editing...',
2588 sys.stdout.flush()
2609 sys.stdout.flush()
2589 try:
2610 try:
2590 # Quote filenames that may have spaces in them
2611 # Quote filenames that may have spaces in them
2591 if ' ' in filename:
2612 if ' ' in filename:
2592 filename = "'%s'" % filename
2613 filename = "'%s'" % filename
2593 self.shell.hooks.editor(filename,lineno)
2614 self.shell.hooks.editor(filename,lineno)
2594 except TryNext:
2615 except TryNext:
2595 warn('Could not open editor')
2616 warn('Could not open editor')
2596 return
2617 return
2597
2618
2598 # XXX TODO: should this be generalized for all string vars?
2619 # XXX TODO: should this be generalized for all string vars?
2599 # For now, this is special-cased to blocks created by cpaste
2620 # For now, this is special-cased to blocks created by cpaste
2600 if args.strip() == 'pasted_block':
2621 if args.strip() == 'pasted_block':
2601 self.shell.user_ns['pasted_block'] = file_read(filename)
2622 self.shell.user_ns['pasted_block'] = file_read(filename)
2602
2623
2603 if 'x' in opts: # -x prevents actual execution
2624 if 'x' in opts: # -x prevents actual execution
2604 print
2625 print
2605 else:
2626 else:
2606 print 'done. Executing edited code...'
2627 print 'done. Executing edited code...'
2607 if 'r' in opts: # Untranslated IPython code
2628 if 'r' in opts: # Untranslated IPython code
2608 self.shell.run_cell(file_read(filename),
2629 self.shell.run_cell(file_read(filename),
2609 store_history=False)
2630 store_history=False)
2610 else:
2631 else:
2611 self.shell.safe_execfile(filename,self.shell.user_ns,
2632 self.shell.safe_execfile(filename,self.shell.user_ns,
2612 self.shell.user_ns)
2633 self.shell.user_ns)
2613
2634
2614 if is_temp:
2635 if is_temp:
2615 try:
2636 try:
2616 return open(filename).read()
2637 return open(filename).read()
2617 except IOError,msg:
2638 except IOError,msg:
2618 if msg.filename == filename:
2639 if msg.filename == filename:
2619 warn('File not found. Did you forget to save?')
2640 warn('File not found. Did you forget to save?')
2620 return
2641 return
2621 else:
2642 else:
2622 self.shell.showtraceback()
2643 self.shell.showtraceback()
2623
2644
2624 def magic_xmode(self,parameter_s = ''):
2645 def magic_xmode(self,parameter_s = ''):
2625 """Switch modes for the exception handlers.
2646 """Switch modes for the exception handlers.
2626
2647
2627 Valid modes: Plain, Context and Verbose.
2648 Valid modes: Plain, Context and Verbose.
2628
2649
2629 If called without arguments, acts as a toggle."""
2650 If called without arguments, acts as a toggle."""
2630
2651
2631 def xmode_switch_err(name):
2652 def xmode_switch_err(name):
2632 warn('Error changing %s exception modes.\n%s' %
2653 warn('Error changing %s exception modes.\n%s' %
2633 (name,sys.exc_info()[1]))
2654 (name,sys.exc_info()[1]))
2634
2655
2635 shell = self.shell
2656 shell = self.shell
2636 new_mode = parameter_s.strip().capitalize()
2657 new_mode = parameter_s.strip().capitalize()
2637 try:
2658 try:
2638 shell.InteractiveTB.set_mode(mode=new_mode)
2659 shell.InteractiveTB.set_mode(mode=new_mode)
2639 print 'Exception reporting mode:',shell.InteractiveTB.mode
2660 print 'Exception reporting mode:',shell.InteractiveTB.mode
2640 except:
2661 except:
2641 xmode_switch_err('user')
2662 xmode_switch_err('user')
2642
2663
2643 def magic_colors(self,parameter_s = ''):
2664 def magic_colors(self,parameter_s = ''):
2644 """Switch color scheme for prompts, info system and exception handlers.
2665 """Switch color scheme for prompts, info system and exception handlers.
2645
2666
2646 Currently implemented schemes: NoColor, Linux, LightBG.
2667 Currently implemented schemes: NoColor, Linux, LightBG.
2647
2668
2648 Color scheme names are not case-sensitive.
2669 Color scheme names are not case-sensitive.
2649
2670
2650 Examples
2671 Examples
2651 --------
2672 --------
2652 To get a plain black and white terminal::
2673 To get a plain black and white terminal::
2653
2674
2654 %colors nocolor
2675 %colors nocolor
2655 """
2676 """
2656
2677
2657 def color_switch_err(name):
2678 def color_switch_err(name):
2658 warn('Error changing %s color schemes.\n%s' %
2679 warn('Error changing %s color schemes.\n%s' %
2659 (name,sys.exc_info()[1]))
2680 (name,sys.exc_info()[1]))
2660
2681
2661
2682
2662 new_scheme = parameter_s.strip()
2683 new_scheme = parameter_s.strip()
2663 if not new_scheme:
2684 if not new_scheme:
2664 raise UsageError(
2685 raise UsageError(
2665 "%colors: you must specify a color scheme. See '%colors?'")
2686 "%colors: you must specify a color scheme. See '%colors?'")
2666 return
2687 return
2667 # local shortcut
2688 # local shortcut
2668 shell = self.shell
2689 shell = self.shell
2669
2690
2670 import IPython.utils.rlineimpl as readline
2691 import IPython.utils.rlineimpl as readline
2671
2692
2672 if not shell.colors_force and \
2693 if not shell.colors_force and \
2673 not readline.have_readline and sys.platform == "win32":
2694 not readline.have_readline and sys.platform == "win32":
2674 msg = """\
2695 msg = """\
2675 Proper color support under MS Windows requires the pyreadline library.
2696 Proper color support under MS Windows requires the pyreadline library.
2676 You can find it at:
2697 You can find it at:
2677 http://ipython.org/pyreadline.html
2698 http://ipython.org/pyreadline.html
2678 Gary's readline needs the ctypes module, from:
2699 Gary's readline needs the ctypes module, from:
2679 http://starship.python.net/crew/theller/ctypes
2700 http://starship.python.net/crew/theller/ctypes
2680 (Note that ctypes is already part of Python versions 2.5 and newer).
2701 (Note that ctypes is already part of Python versions 2.5 and newer).
2681
2702
2682 Defaulting color scheme to 'NoColor'"""
2703 Defaulting color scheme to 'NoColor'"""
2683 new_scheme = 'NoColor'
2704 new_scheme = 'NoColor'
2684 warn(msg)
2705 warn(msg)
2685
2706
2686 # readline option is 0
2707 # readline option is 0
2687 if not shell.colors_force and not shell.has_readline:
2708 if not shell.colors_force and not shell.has_readline:
2688 new_scheme = 'NoColor'
2709 new_scheme = 'NoColor'
2689
2710
2690 # Set prompt colors
2711 # Set prompt colors
2691 try:
2712 try:
2692 shell.prompt_manager.color_scheme = new_scheme
2713 shell.prompt_manager.color_scheme = new_scheme
2693 except:
2714 except:
2694 color_switch_err('prompt')
2715 color_switch_err('prompt')
2695 else:
2716 else:
2696 shell.colors = \
2717 shell.colors = \
2697 shell.prompt_manager.color_scheme_table.active_scheme_name
2718 shell.prompt_manager.color_scheme_table.active_scheme_name
2698 # Set exception colors
2719 # Set exception colors
2699 try:
2720 try:
2700 shell.InteractiveTB.set_colors(scheme = new_scheme)
2721 shell.InteractiveTB.set_colors(scheme = new_scheme)
2701 shell.SyntaxTB.set_colors(scheme = new_scheme)
2722 shell.SyntaxTB.set_colors(scheme = new_scheme)
2702 except:
2723 except:
2703 color_switch_err('exception')
2724 color_switch_err('exception')
2704
2725
2705 # Set info (for 'object?') colors
2726 # Set info (for 'object?') colors
2706 if shell.color_info:
2727 if shell.color_info:
2707 try:
2728 try:
2708 shell.inspector.set_active_scheme(new_scheme)
2729 shell.inspector.set_active_scheme(new_scheme)
2709 except:
2730 except:
2710 color_switch_err('object inspector')
2731 color_switch_err('object inspector')
2711 else:
2732 else:
2712 shell.inspector.set_active_scheme('NoColor')
2733 shell.inspector.set_active_scheme('NoColor')
2713
2734
2714 def magic_pprint(self, parameter_s=''):
2735 def magic_pprint(self, parameter_s=''):
2715 """Toggle pretty printing on/off."""
2736 """Toggle pretty printing on/off."""
2716 ptformatter = self.shell.display_formatter.formatters['text/plain']
2737 ptformatter = self.shell.display_formatter.formatters['text/plain']
2717 ptformatter.pprint = bool(1 - ptformatter.pprint)
2738 ptformatter.pprint = bool(1 - ptformatter.pprint)
2718 print 'Pretty printing has been turned', \
2739 print 'Pretty printing has been turned', \
2719 ['OFF','ON'][ptformatter.pprint]
2740 ['OFF','ON'][ptformatter.pprint]
2720
2741
2721 #......................................................................
2742 #......................................................................
2722 # Functions to implement unix shell-type things
2743 # Functions to implement unix shell-type things
2723
2744
2724 @skip_doctest
2745 @skip_doctest
2725 def magic_alias(self, parameter_s = ''):
2746 def magic_alias(self, parameter_s = ''):
2726 """Define an alias for a system command.
2747 """Define an alias for a system command.
2727
2748
2728 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2749 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2729
2750
2730 Then, typing 'alias_name params' will execute the system command 'cmd
2751 Then, typing 'alias_name params' will execute the system command 'cmd
2731 params' (from your underlying operating system).
2752 params' (from your underlying operating system).
2732
2753
2733 Aliases have lower precedence than magic functions and Python normal
2754 Aliases have lower precedence than magic functions and Python normal
2734 variables, so if 'foo' is both a Python variable and an alias, the
2755 variables, so if 'foo' is both a Python variable and an alias, the
2735 alias can not be executed until 'del foo' removes the Python variable.
2756 alias can not be executed until 'del foo' removes the Python variable.
2736
2757
2737 You can use the %l specifier in an alias definition to represent the
2758 You can use the %l specifier in an alias definition to represent the
2738 whole line when the alias is called. For example::
2759 whole line when the alias is called. For example::
2739
2760
2740 In [2]: alias bracket echo "Input in brackets: <%l>"
2761 In [2]: alias bracket echo "Input in brackets: <%l>"
2741 In [3]: bracket hello world
2762 In [3]: bracket hello world
2742 Input in brackets: <hello world>
2763 Input in brackets: <hello world>
2743
2764
2744 You can also define aliases with parameters using %s specifiers (one
2765 You can also define aliases with parameters using %s specifiers (one
2745 per parameter)::
2766 per parameter)::
2746
2767
2747 In [1]: alias parts echo first %s second %s
2768 In [1]: alias parts echo first %s second %s
2748 In [2]: %parts A B
2769 In [2]: %parts A B
2749 first A second B
2770 first A second B
2750 In [3]: %parts A
2771 In [3]: %parts A
2751 Incorrect number of arguments: 2 expected.
2772 Incorrect number of arguments: 2 expected.
2752 parts is an alias to: 'echo first %s second %s'
2773 parts is an alias to: 'echo first %s second %s'
2753
2774
2754 Note that %l and %s are mutually exclusive. You can only use one or
2775 Note that %l and %s are mutually exclusive. You can only use one or
2755 the other in your aliases.
2776 the other in your aliases.
2756
2777
2757 Aliases expand Python variables just like system calls using ! or !!
2778 Aliases expand Python variables just like system calls using ! or !!
2758 do: all expressions prefixed with '$' get expanded. For details of
2779 do: all expressions prefixed with '$' get expanded. For details of
2759 the semantic rules, see PEP-215:
2780 the semantic rules, see PEP-215:
2760 http://www.python.org/peps/pep-0215.html. This is the library used by
2781 http://www.python.org/peps/pep-0215.html. This is the library used by
2761 IPython for variable expansion. If you want to access a true shell
2782 IPython for variable expansion. If you want to access a true shell
2762 variable, an extra $ is necessary to prevent its expansion by
2783 variable, an extra $ is necessary to prevent its expansion by
2763 IPython::
2784 IPython::
2764
2785
2765 In [6]: alias show echo
2786 In [6]: alias show echo
2766 In [7]: PATH='A Python string'
2787 In [7]: PATH='A Python string'
2767 In [8]: show $PATH
2788 In [8]: show $PATH
2768 A Python string
2789 A Python string
2769 In [9]: show $$PATH
2790 In [9]: show $$PATH
2770 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2791 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2771
2792
2772 You can use the alias facility to acess all of $PATH. See the %rehash
2793 You can use the alias facility to acess all of $PATH. See the %rehash
2773 and %rehashx functions, which automatically create aliases for the
2794 and %rehashx functions, which automatically create aliases for the
2774 contents of your $PATH.
2795 contents of your $PATH.
2775
2796
2776 If called with no parameters, %alias prints the current alias table."""
2797 If called with no parameters, %alias prints the current alias table."""
2777
2798
2778 par = parameter_s.strip()
2799 par = parameter_s.strip()
2779 if not par:
2800 if not par:
2780 stored = self.db.get('stored_aliases', {} )
2801 stored = self.db.get('stored_aliases', {} )
2781 aliases = sorted(self.shell.alias_manager.aliases)
2802 aliases = sorted(self.shell.alias_manager.aliases)
2782 # for k, v in stored:
2803 # for k, v in stored:
2783 # atab.append(k, v[0])
2804 # atab.append(k, v[0])
2784
2805
2785 print "Total number of aliases:", len(aliases)
2806 print "Total number of aliases:", len(aliases)
2786 sys.stdout.flush()
2807 sys.stdout.flush()
2787 return aliases
2808 return aliases
2788
2809
2789 # Now try to define a new one
2810 # Now try to define a new one
2790 try:
2811 try:
2791 alias,cmd = par.split(None, 1)
2812 alias,cmd = par.split(None, 1)
2792 except:
2813 except:
2793 print oinspect.getdoc(self.magic_alias)
2814 print oinspect.getdoc(self.magic_alias)
2794 else:
2815 else:
2795 self.shell.alias_manager.soft_define_alias(alias, cmd)
2816 self.shell.alias_manager.soft_define_alias(alias, cmd)
2796 # end magic_alias
2817 # end magic_alias
2797
2818
2798 def magic_unalias(self, parameter_s = ''):
2819 def magic_unalias(self, parameter_s = ''):
2799 """Remove an alias"""
2820 """Remove an alias"""
2800
2821
2801 aname = parameter_s.strip()
2822 aname = parameter_s.strip()
2802 self.shell.alias_manager.undefine_alias(aname)
2823 self.shell.alias_manager.undefine_alias(aname)
2803 stored = self.db.get('stored_aliases', {} )
2824 stored = self.db.get('stored_aliases', {} )
2804 if aname in stored:
2825 if aname in stored:
2805 print "Removing %stored alias",aname
2826 print "Removing %stored alias",aname
2806 del stored[aname]
2827 del stored[aname]
2807 self.db['stored_aliases'] = stored
2828 self.db['stored_aliases'] = stored
2808
2829
2809 def magic_rehashx(self, parameter_s = ''):
2830 def magic_rehashx(self, parameter_s = ''):
2810 """Update the alias table with all executable files in $PATH.
2831 """Update the alias table with all executable files in $PATH.
2811
2832
2812 This version explicitly checks that every entry in $PATH is a file
2833 This version explicitly checks that every entry in $PATH is a file
2813 with execute access (os.X_OK), so it is much slower than %rehash.
2834 with execute access (os.X_OK), so it is much slower than %rehash.
2814
2835
2815 Under Windows, it checks executability as a match against a
2836 Under Windows, it checks executability as a match against a
2816 '|'-separated string of extensions, stored in the IPython config
2837 '|'-separated string of extensions, stored in the IPython config
2817 variable win_exec_ext. This defaults to 'exe|com|bat'.
2838 variable win_exec_ext. This defaults to 'exe|com|bat'.
2818
2839
2819 This function also resets the root module cache of module completer,
2840 This function also resets the root module cache of module completer,
2820 used on slow filesystems.
2841 used on slow filesystems.
2821 """
2842 """
2822 from IPython.core.alias import InvalidAliasError
2843 from IPython.core.alias import InvalidAliasError
2823
2844
2824 # for the benefit of module completer in ipy_completers.py
2845 # for the benefit of module completer in ipy_completers.py
2825 del self.shell.db['rootmodules']
2846 del self.shell.db['rootmodules']
2826
2847
2827 path = [os.path.abspath(os.path.expanduser(p)) for p in
2848 path = [os.path.abspath(os.path.expanduser(p)) for p in
2828 os.environ.get('PATH','').split(os.pathsep)]
2849 os.environ.get('PATH','').split(os.pathsep)]
2829 path = filter(os.path.isdir,path)
2850 path = filter(os.path.isdir,path)
2830
2851
2831 syscmdlist = []
2852 syscmdlist = []
2832 # Now define isexec in a cross platform manner.
2853 # Now define isexec in a cross platform manner.
2833 if os.name == 'posix':
2854 if os.name == 'posix':
2834 isexec = lambda fname:os.path.isfile(fname) and \
2855 isexec = lambda fname:os.path.isfile(fname) and \
2835 os.access(fname,os.X_OK)
2856 os.access(fname,os.X_OK)
2836 else:
2857 else:
2837 try:
2858 try:
2838 winext = os.environ['pathext'].replace(';','|').replace('.','')
2859 winext = os.environ['pathext'].replace(';','|').replace('.','')
2839 except KeyError:
2860 except KeyError:
2840 winext = 'exe|com|bat|py'
2861 winext = 'exe|com|bat|py'
2841 if 'py' not in winext:
2862 if 'py' not in winext:
2842 winext += '|py'
2863 winext += '|py'
2843 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2864 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2844 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2865 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2845 savedir = os.getcwdu()
2866 savedir = os.getcwdu()
2846
2867
2847 # Now walk the paths looking for executables to alias.
2868 # Now walk the paths looking for executables to alias.
2848 try:
2869 try:
2849 # write the whole loop for posix/Windows so we don't have an if in
2870 # write the whole loop for posix/Windows so we don't have an if in
2850 # the innermost part
2871 # the innermost part
2851 if os.name == 'posix':
2872 if os.name == 'posix':
2852 for pdir in path:
2873 for pdir in path:
2853 os.chdir(pdir)
2874 os.chdir(pdir)
2854 for ff in os.listdir(pdir):
2875 for ff in os.listdir(pdir):
2855 if isexec(ff):
2876 if isexec(ff):
2856 try:
2877 try:
2857 # Removes dots from the name since ipython
2878 # Removes dots from the name since ipython
2858 # will assume names with dots to be python.
2879 # will assume names with dots to be python.
2859 self.shell.alias_manager.define_alias(
2880 self.shell.alias_manager.define_alias(
2860 ff.replace('.',''), ff)
2881 ff.replace('.',''), ff)
2861 except InvalidAliasError:
2882 except InvalidAliasError:
2862 pass
2883 pass
2863 else:
2884 else:
2864 syscmdlist.append(ff)
2885 syscmdlist.append(ff)
2865 else:
2886 else:
2866 no_alias = self.shell.alias_manager.no_alias
2887 no_alias = self.shell.alias_manager.no_alias
2867 for pdir in path:
2888 for pdir in path:
2868 os.chdir(pdir)
2889 os.chdir(pdir)
2869 for ff in os.listdir(pdir):
2890 for ff in os.listdir(pdir):
2870 base, ext = os.path.splitext(ff)
2891 base, ext = os.path.splitext(ff)
2871 if isexec(ff) and base.lower() not in no_alias:
2892 if isexec(ff) and base.lower() not in no_alias:
2872 if ext.lower() == '.exe':
2893 if ext.lower() == '.exe':
2873 ff = base
2894 ff = base
2874 try:
2895 try:
2875 # Removes dots from the name since ipython
2896 # Removes dots from the name since ipython
2876 # will assume names with dots to be python.
2897 # will assume names with dots to be python.
2877 self.shell.alias_manager.define_alias(
2898 self.shell.alias_manager.define_alias(
2878 base.lower().replace('.',''), ff)
2899 base.lower().replace('.',''), ff)
2879 except InvalidAliasError:
2900 except InvalidAliasError:
2880 pass
2901 pass
2881 syscmdlist.append(ff)
2902 syscmdlist.append(ff)
2882 self.shell.db['syscmdlist'] = syscmdlist
2903 self.shell.db['syscmdlist'] = syscmdlist
2883 finally:
2904 finally:
2884 os.chdir(savedir)
2905 os.chdir(savedir)
2885
2906
2886 @skip_doctest
2907 @skip_doctest
2887 def magic_pwd(self, parameter_s = ''):
2908 def magic_pwd(self, parameter_s = ''):
2888 """Return the current working directory path.
2909 """Return the current working directory path.
2889
2910
2890 Examples
2911 Examples
2891 --------
2912 --------
2892 ::
2913 ::
2893
2914
2894 In [9]: pwd
2915 In [9]: pwd
2895 Out[9]: '/home/tsuser/sprint/ipython'
2916 Out[9]: '/home/tsuser/sprint/ipython'
2896 """
2917 """
2897 return os.getcwdu()
2918 return os.getcwdu()
2898
2919
2899 @skip_doctest
2920 @skip_doctest
2900 def magic_cd(self, parameter_s=''):
2921 def magic_cd(self, parameter_s=''):
2901 """Change the current working directory.
2922 """Change the current working directory.
2902
2923
2903 This command automatically maintains an internal list of directories
2924 This command automatically maintains an internal list of directories
2904 you visit during your IPython session, in the variable _dh. The
2925 you visit during your IPython session, in the variable _dh. The
2905 command %dhist shows this history nicely formatted. You can also
2926 command %dhist shows this history nicely formatted. You can also
2906 do 'cd -<tab>' to see directory history conveniently.
2927 do 'cd -<tab>' to see directory history conveniently.
2907
2928
2908 Usage:
2929 Usage:
2909
2930
2910 cd 'dir': changes to directory 'dir'.
2931 cd 'dir': changes to directory 'dir'.
2911
2932
2912 cd -: changes to the last visited directory.
2933 cd -: changes to the last visited directory.
2913
2934
2914 cd -<n>: changes to the n-th directory in the directory history.
2935 cd -<n>: changes to the n-th directory in the directory history.
2915
2936
2916 cd --foo: change to directory that matches 'foo' in history
2937 cd --foo: change to directory that matches 'foo' in history
2917
2938
2918 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2939 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2919 (note: cd <bookmark_name> is enough if there is no
2940 (note: cd <bookmark_name> is enough if there is no
2920 directory <bookmark_name>, but a bookmark with the name exists.)
2941 directory <bookmark_name>, but a bookmark with the name exists.)
2921 'cd -b <tab>' allows you to tab-complete bookmark names.
2942 'cd -b <tab>' allows you to tab-complete bookmark names.
2922
2943
2923 Options:
2944 Options:
2924
2945
2925 -q: quiet. Do not print the working directory after the cd command is
2946 -q: quiet. Do not print the working directory after the cd command is
2926 executed. By default IPython's cd command does print this directory,
2947 executed. By default IPython's cd command does print this directory,
2927 since the default prompts do not display path information.
2948 since the default prompts do not display path information.
2928
2949
2929 Note that !cd doesn't work for this purpose because the shell where
2950 Note that !cd doesn't work for this purpose because the shell where
2930 !command runs is immediately discarded after executing 'command'.
2951 !command runs is immediately discarded after executing 'command'.
2931
2952
2932 Examples
2953 Examples
2933 --------
2954 --------
2934 ::
2955 ::
2935
2956
2936 In [10]: cd parent/child
2957 In [10]: cd parent/child
2937 /home/tsuser/parent/child
2958 /home/tsuser/parent/child
2938 """
2959 """
2939
2960
2940 parameter_s = parameter_s.strip()
2961 parameter_s = parameter_s.strip()
2941 #bkms = self.shell.persist.get("bookmarks",{})
2962 #bkms = self.shell.persist.get("bookmarks",{})
2942
2963
2943 oldcwd = os.getcwdu()
2964 oldcwd = os.getcwdu()
2944 numcd = re.match(r'(-)(\d+)$',parameter_s)
2965 numcd = re.match(r'(-)(\d+)$',parameter_s)
2945 # jump in directory history by number
2966 # jump in directory history by number
2946 if numcd:
2967 if numcd:
2947 nn = int(numcd.group(2))
2968 nn = int(numcd.group(2))
2948 try:
2969 try:
2949 ps = self.shell.user_ns['_dh'][nn]
2970 ps = self.shell.user_ns['_dh'][nn]
2950 except IndexError:
2971 except IndexError:
2951 print 'The requested directory does not exist in history.'
2972 print 'The requested directory does not exist in history.'
2952 return
2973 return
2953 else:
2974 else:
2954 opts = {}
2975 opts = {}
2955 elif parameter_s.startswith('--'):
2976 elif parameter_s.startswith('--'):
2956 ps = None
2977 ps = None
2957 fallback = None
2978 fallback = None
2958 pat = parameter_s[2:]
2979 pat = parameter_s[2:]
2959 dh = self.shell.user_ns['_dh']
2980 dh = self.shell.user_ns['_dh']
2960 # first search only by basename (last component)
2981 # first search only by basename (last component)
2961 for ent in reversed(dh):
2982 for ent in reversed(dh):
2962 if pat in os.path.basename(ent) and os.path.isdir(ent):
2983 if pat in os.path.basename(ent) and os.path.isdir(ent):
2963 ps = ent
2984 ps = ent
2964 break
2985 break
2965
2986
2966 if fallback is None and pat in ent and os.path.isdir(ent):
2987 if fallback is None and pat in ent and os.path.isdir(ent):
2967 fallback = ent
2988 fallback = ent
2968
2989
2969 # if we have no last part match, pick the first full path match
2990 # if we have no last part match, pick the first full path match
2970 if ps is None:
2991 if ps is None:
2971 ps = fallback
2992 ps = fallback
2972
2993
2973 if ps is None:
2994 if ps is None:
2974 print "No matching entry in directory history"
2995 print "No matching entry in directory history"
2975 return
2996 return
2976 else:
2997 else:
2977 opts = {}
2998 opts = {}
2978
2999
2979
3000
2980 else:
3001 else:
2981 #turn all non-space-escaping backslashes to slashes,
3002 #turn all non-space-escaping backslashes to slashes,
2982 # for c:\windows\directory\names\
3003 # for c:\windows\directory\names\
2983 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
3004 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2984 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
3005 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2985 # jump to previous
3006 # jump to previous
2986 if ps == '-':
3007 if ps == '-':
2987 try:
3008 try:
2988 ps = self.shell.user_ns['_dh'][-2]
3009 ps = self.shell.user_ns['_dh'][-2]
2989 except IndexError:
3010 except IndexError:
2990 raise UsageError('%cd -: No previous directory to change to.')
3011 raise UsageError('%cd -: No previous directory to change to.')
2991 # jump to bookmark if needed
3012 # jump to bookmark if needed
2992 else:
3013 else:
2993 if not os.path.isdir(ps) or opts.has_key('b'):
3014 if not os.path.isdir(ps) or opts.has_key('b'):
2994 bkms = self.db.get('bookmarks', {})
3015 bkms = self.db.get('bookmarks', {})
2995
3016
2996 if bkms.has_key(ps):
3017 if bkms.has_key(ps):
2997 target = bkms[ps]
3018 target = bkms[ps]
2998 print '(bookmark:%s) -> %s' % (ps,target)
3019 print '(bookmark:%s) -> %s' % (ps,target)
2999 ps = target
3020 ps = target
3000 else:
3021 else:
3001 if opts.has_key('b'):
3022 if opts.has_key('b'):
3002 raise UsageError("Bookmark '%s' not found. "
3023 raise UsageError("Bookmark '%s' not found. "
3003 "Use '%%bookmark -l' to see your bookmarks." % ps)
3024 "Use '%%bookmark -l' to see your bookmarks." % ps)
3004
3025
3005 # strip extra quotes on Windows, because os.chdir doesn't like them
3026 # strip extra quotes on Windows, because os.chdir doesn't like them
3006 ps = unquote_filename(ps)
3027 ps = unquote_filename(ps)
3007 # at this point ps should point to the target dir
3028 # at this point ps should point to the target dir
3008 if ps:
3029 if ps:
3009 try:
3030 try:
3010 os.chdir(os.path.expanduser(ps))
3031 os.chdir(os.path.expanduser(ps))
3011 if hasattr(self.shell, 'term_title') and self.shell.term_title:
3032 if hasattr(self.shell, 'term_title') and self.shell.term_title:
3012 set_term_title('IPython: ' + abbrev_cwd())
3033 set_term_title('IPython: ' + abbrev_cwd())
3013 except OSError:
3034 except OSError:
3014 print sys.exc_info()[1]
3035 print sys.exc_info()[1]
3015 else:
3036 else:
3016 cwd = os.getcwdu()
3037 cwd = os.getcwdu()
3017 dhist = self.shell.user_ns['_dh']
3038 dhist = self.shell.user_ns['_dh']
3018 if oldcwd != cwd:
3039 if oldcwd != cwd:
3019 dhist.append(cwd)
3040 dhist.append(cwd)
3020 self.db['dhist'] = compress_dhist(dhist)[-100:]
3041 self.db['dhist'] = compress_dhist(dhist)[-100:]
3021
3042
3022 else:
3043 else:
3023 os.chdir(self.shell.home_dir)
3044 os.chdir(self.shell.home_dir)
3024 if hasattr(self.shell, 'term_title') and self.shell.term_title:
3045 if hasattr(self.shell, 'term_title') and self.shell.term_title:
3025 set_term_title('IPython: ' + '~')
3046 set_term_title('IPython: ' + '~')
3026 cwd = os.getcwdu()
3047 cwd = os.getcwdu()
3027 dhist = self.shell.user_ns['_dh']
3048 dhist = self.shell.user_ns['_dh']
3028
3049
3029 if oldcwd != cwd:
3050 if oldcwd != cwd:
3030 dhist.append(cwd)
3051 dhist.append(cwd)
3031 self.db['dhist'] = compress_dhist(dhist)[-100:]
3052 self.db['dhist'] = compress_dhist(dhist)[-100:]
3032 if not 'q' in opts and self.shell.user_ns['_dh']:
3053 if not 'q' in opts and self.shell.user_ns['_dh']:
3033 print self.shell.user_ns['_dh'][-1]
3054 print self.shell.user_ns['_dh'][-1]
3034
3055
3035
3056
3036 def magic_env(self, parameter_s=''):
3057 def magic_env(self, parameter_s=''):
3037 """List environment variables."""
3058 """List environment variables."""
3038
3059
3039 return dict(os.environ)
3060 return dict(os.environ)
3040
3061
3041 def magic_pushd(self, parameter_s=''):
3062 def magic_pushd(self, parameter_s=''):
3042 """Place the current dir on stack and change directory.
3063 """Place the current dir on stack and change directory.
3043
3064
3044 Usage:\\
3065 Usage:\\
3045 %pushd ['dirname']
3066 %pushd ['dirname']
3046 """
3067 """
3047
3068
3048 dir_s = self.shell.dir_stack
3069 dir_s = self.shell.dir_stack
3049 tgt = os.path.expanduser(unquote_filename(parameter_s))
3070 tgt = os.path.expanduser(unquote_filename(parameter_s))
3050 cwd = os.getcwdu().replace(self.home_dir,'~')
3071 cwd = os.getcwdu().replace(self.home_dir,'~')
3051 if tgt:
3072 if tgt:
3052 self.magic_cd(parameter_s)
3073 self.magic_cd(parameter_s)
3053 dir_s.insert(0,cwd)
3074 dir_s.insert(0,cwd)
3054 return self.magic_dirs()
3075 return self.magic_dirs()
3055
3076
3056 def magic_popd(self, parameter_s=''):
3077 def magic_popd(self, parameter_s=''):
3057 """Change to directory popped off the top of the stack.
3078 """Change to directory popped off the top of the stack.
3058 """
3079 """
3059 if not self.shell.dir_stack:
3080 if not self.shell.dir_stack:
3060 raise UsageError("%popd on empty stack")
3081 raise UsageError("%popd on empty stack")
3061 top = self.shell.dir_stack.pop(0)
3082 top = self.shell.dir_stack.pop(0)
3062 self.magic_cd(top)
3083 self.magic_cd(top)
3063 print "popd ->",top
3084 print "popd ->",top
3064
3085
3065 def magic_dirs(self, parameter_s=''):
3086 def magic_dirs(self, parameter_s=''):
3066 """Return the current directory stack."""
3087 """Return the current directory stack."""
3067
3088
3068 return self.shell.dir_stack
3089 return self.shell.dir_stack
3069
3090
3070 def magic_dhist(self, parameter_s=''):
3091 def magic_dhist(self, parameter_s=''):
3071 """Print your history of visited directories.
3092 """Print your history of visited directories.
3072
3093
3073 %dhist -> print full history\\
3094 %dhist -> print full history\\
3074 %dhist n -> print last n entries only\\
3095 %dhist n -> print last n entries only\\
3075 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
3096 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
3076
3097
3077 This history is automatically maintained by the %cd command, and
3098 This history is automatically maintained by the %cd command, and
3078 always available as the global list variable _dh. You can use %cd -<n>
3099 always available as the global list variable _dh. You can use %cd -<n>
3079 to go to directory number <n>.
3100 to go to directory number <n>.
3080
3101
3081 Note that most of time, you should view directory history by entering
3102 Note that most of time, you should view directory history by entering
3082 cd -<TAB>.
3103 cd -<TAB>.
3083
3104
3084 """
3105 """
3085
3106
3086 dh = self.shell.user_ns['_dh']
3107 dh = self.shell.user_ns['_dh']
3087 if parameter_s:
3108 if parameter_s:
3088 try:
3109 try:
3089 args = map(int,parameter_s.split())
3110 args = map(int,parameter_s.split())
3090 except:
3111 except:
3091 self.arg_err(Magic.magic_dhist)
3112 self.arg_err(Magic.magic_dhist)
3092 return
3113 return
3093 if len(args) == 1:
3114 if len(args) == 1:
3094 ini,fin = max(len(dh)-(args[0]),0),len(dh)
3115 ini,fin = max(len(dh)-(args[0]),0),len(dh)
3095 elif len(args) == 2:
3116 elif len(args) == 2:
3096 ini,fin = args
3117 ini,fin = args
3097 else:
3118 else:
3098 self.arg_err(Magic.magic_dhist)
3119 self.arg_err(Magic.magic_dhist)
3099 return
3120 return
3100 else:
3121 else:
3101 ini,fin = 0,len(dh)
3122 ini,fin = 0,len(dh)
3102 nlprint(dh,
3123 nlprint(dh,
3103 header = 'Directory history (kept in _dh)',
3124 header = 'Directory history (kept in _dh)',
3104 start=ini,stop=fin)
3125 start=ini,stop=fin)
3105
3126
3106 @skip_doctest
3127 @skip_doctest
3107 def magic_sc(self, parameter_s=''):
3128 def magic_sc(self, parameter_s=''):
3108 """Shell capture - execute a shell command and capture its output.
3129 """Shell capture - execute a shell command and capture its output.
3109
3130
3110 DEPRECATED. Suboptimal, retained for backwards compatibility.
3131 DEPRECATED. Suboptimal, retained for backwards compatibility.
3111
3132
3112 You should use the form 'var = !command' instead. Example:
3133 You should use the form 'var = !command' instead. Example:
3113
3134
3114 "%sc -l myfiles = ls ~" should now be written as
3135 "%sc -l myfiles = ls ~" should now be written as
3115
3136
3116 "myfiles = !ls ~"
3137 "myfiles = !ls ~"
3117
3138
3118 myfiles.s, myfiles.l and myfiles.n still apply as documented
3139 myfiles.s, myfiles.l and myfiles.n still apply as documented
3119 below.
3140 below.
3120
3141
3121 --
3142 --
3122 %sc [options] varname=command
3143 %sc [options] varname=command
3123
3144
3124 IPython will run the given command using commands.getoutput(), and
3145 IPython will run the given command using commands.getoutput(), and
3125 will then update the user's interactive namespace with a variable
3146 will then update the user's interactive namespace with a variable
3126 called varname, containing the value of the call. Your command can
3147 called varname, containing the value of the call. Your command can
3127 contain shell wildcards, pipes, etc.
3148 contain shell wildcards, pipes, etc.
3128
3149
3129 The '=' sign in the syntax is mandatory, and the variable name you
3150 The '=' sign in the syntax is mandatory, and the variable name you
3130 supply must follow Python's standard conventions for valid names.
3151 supply must follow Python's standard conventions for valid names.
3131
3152
3132 (A special format without variable name exists for internal use)
3153 (A special format without variable name exists for internal use)
3133
3154
3134 Options:
3155 Options:
3135
3156
3136 -l: list output. Split the output on newlines into a list before
3157 -l: list output. Split the output on newlines into a list before
3137 assigning it to the given variable. By default the output is stored
3158 assigning it to the given variable. By default the output is stored
3138 as a single string.
3159 as a single string.
3139
3160
3140 -v: verbose. Print the contents of the variable.
3161 -v: verbose. Print the contents of the variable.
3141
3162
3142 In most cases you should not need to split as a list, because the
3163 In most cases you should not need to split as a list, because the
3143 returned value is a special type of string which can automatically
3164 returned value is a special type of string which can automatically
3144 provide its contents either as a list (split on newlines) or as a
3165 provide its contents either as a list (split on newlines) or as a
3145 space-separated string. These are convenient, respectively, either
3166 space-separated string. These are convenient, respectively, either
3146 for sequential processing or to be passed to a shell command.
3167 for sequential processing or to be passed to a shell command.
3147
3168
3148 For example::
3169 For example::
3149
3170
3150 # Capture into variable a
3171 # Capture into variable a
3151 In [1]: sc a=ls *py
3172 In [1]: sc a=ls *py
3152
3173
3153 # a is a string with embedded newlines
3174 # a is a string with embedded newlines
3154 In [2]: a
3175 In [2]: a
3155 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
3176 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
3156
3177
3157 # which can be seen as a list:
3178 # which can be seen as a list:
3158 In [3]: a.l
3179 In [3]: a.l
3159 Out[3]: ['setup.py', 'win32_manual_post_install.py']
3180 Out[3]: ['setup.py', 'win32_manual_post_install.py']
3160
3181
3161 # or as a whitespace-separated string:
3182 # or as a whitespace-separated string:
3162 In [4]: a.s
3183 In [4]: a.s
3163 Out[4]: 'setup.py win32_manual_post_install.py'
3184 Out[4]: 'setup.py win32_manual_post_install.py'
3164
3185
3165 # a.s is useful to pass as a single command line:
3186 # a.s is useful to pass as a single command line:
3166 In [5]: !wc -l $a.s
3187 In [5]: !wc -l $a.s
3167 146 setup.py
3188 146 setup.py
3168 130 win32_manual_post_install.py
3189 130 win32_manual_post_install.py
3169 276 total
3190 276 total
3170
3191
3171 # while the list form is useful to loop over:
3192 # while the list form is useful to loop over:
3172 In [6]: for f in a.l:
3193 In [6]: for f in a.l:
3173 ...: !wc -l $f
3194 ...: !wc -l $f
3174 ...:
3195 ...:
3175 146 setup.py
3196 146 setup.py
3176 130 win32_manual_post_install.py
3197 130 win32_manual_post_install.py
3177
3198
3178 Similarly, the lists returned by the -l option are also special, in
3199 Similarly, the lists returned by the -l option are also special, in
3179 the sense that you can equally invoke the .s attribute on them to
3200 the sense that you can equally invoke the .s attribute on them to
3180 automatically get a whitespace-separated string from their contents::
3201 automatically get a whitespace-separated string from their contents::
3181
3202
3182 In [7]: sc -l b=ls *py
3203 In [7]: sc -l b=ls *py
3183
3204
3184 In [8]: b
3205 In [8]: b
3185 Out[8]: ['setup.py', 'win32_manual_post_install.py']
3206 Out[8]: ['setup.py', 'win32_manual_post_install.py']
3186
3207
3187 In [9]: b.s
3208 In [9]: b.s
3188 Out[9]: 'setup.py win32_manual_post_install.py'
3209 Out[9]: 'setup.py win32_manual_post_install.py'
3189
3210
3190 In summary, both the lists and strings used for output capture have
3211 In summary, both the lists and strings used for output capture have
3191 the following special attributes::
3212 the following special attributes::
3192
3213
3193 .l (or .list) : value as list.
3214 .l (or .list) : value as list.
3194 .n (or .nlstr): value as newline-separated string.
3215 .n (or .nlstr): value as newline-separated string.
3195 .s (or .spstr): value as space-separated string.
3216 .s (or .spstr): value as space-separated string.
3196 """
3217 """
3197
3218
3198 opts,args = self.parse_options(parameter_s,'lv')
3219 opts,args = self.parse_options(parameter_s,'lv')
3199 # Try to get a variable name and command to run
3220 # Try to get a variable name and command to run
3200 try:
3221 try:
3201 # the variable name must be obtained from the parse_options
3222 # the variable name must be obtained from the parse_options
3202 # output, which uses shlex.split to strip options out.
3223 # output, which uses shlex.split to strip options out.
3203 var,_ = args.split('=',1)
3224 var,_ = args.split('=',1)
3204 var = var.strip()
3225 var = var.strip()
3205 # But the command has to be extracted from the original input
3226 # But the command has to be extracted from the original input
3206 # parameter_s, not on what parse_options returns, to avoid the
3227 # parameter_s, not on what parse_options returns, to avoid the
3207 # quote stripping which shlex.split performs on it.
3228 # quote stripping which shlex.split performs on it.
3208 _,cmd = parameter_s.split('=',1)
3229 _,cmd = parameter_s.split('=',1)
3209 except ValueError:
3230 except ValueError:
3210 var,cmd = '',''
3231 var,cmd = '',''
3211 # If all looks ok, proceed
3232 # If all looks ok, proceed
3212 split = 'l' in opts
3233 split = 'l' in opts
3213 out = self.shell.getoutput(cmd, split=split)
3234 out = self.shell.getoutput(cmd, split=split)
3214 if opts.has_key('v'):
3235 if opts.has_key('v'):
3215 print '%s ==\n%s' % (var,pformat(out))
3236 print '%s ==\n%s' % (var,pformat(out))
3216 if var:
3237 if var:
3217 self.shell.user_ns.update({var:out})
3238 self.shell.user_ns.update({var:out})
3218 else:
3239 else:
3219 return out
3240 return out
3220
3241
3221 def magic_sx(self, parameter_s=''):
3242 def magic_sx(self, parameter_s=''):
3222 """Shell execute - run a shell command and capture its output.
3243 """Shell execute - run a shell command and capture its output.
3223
3244
3224 %sx command
3245 %sx command
3225
3246
3226 IPython will run the given command using commands.getoutput(), and
3247 IPython will run the given command using commands.getoutput(), and
3227 return the result formatted as a list (split on '\\n'). Since the
3248 return the result formatted as a list (split on '\\n'). Since the
3228 output is _returned_, it will be stored in ipython's regular output
3249 output is _returned_, it will be stored in ipython's regular output
3229 cache Out[N] and in the '_N' automatic variables.
3250 cache Out[N] and in the '_N' automatic variables.
3230
3251
3231 Notes:
3252 Notes:
3232
3253
3233 1) If an input line begins with '!!', then %sx is automatically
3254 1) If an input line begins with '!!', then %sx is automatically
3234 invoked. That is, while::
3255 invoked. That is, while::
3235
3256
3236 !ls
3257 !ls
3237
3258
3238 causes ipython to simply issue system('ls'), typing::
3259 causes ipython to simply issue system('ls'), typing::
3239
3260
3240 !!ls
3261 !!ls
3241
3262
3242 is a shorthand equivalent to::
3263 is a shorthand equivalent to::
3243
3264
3244 %sx ls
3265 %sx ls
3245
3266
3246 2) %sx differs from %sc in that %sx automatically splits into a list,
3267 2) %sx differs from %sc in that %sx automatically splits into a list,
3247 like '%sc -l'. The reason for this is to make it as easy as possible
3268 like '%sc -l'. The reason for this is to make it as easy as possible
3248 to process line-oriented shell output via further python commands.
3269 to process line-oriented shell output via further python commands.
3249 %sc is meant to provide much finer control, but requires more
3270 %sc is meant to provide much finer control, but requires more
3250 typing.
3271 typing.
3251
3272
3252 3) Just like %sc -l, this is a list with special attributes:
3273 3) Just like %sc -l, this is a list with special attributes:
3253 ::
3274 ::
3254
3275
3255 .l (or .list) : value as list.
3276 .l (or .list) : value as list.
3256 .n (or .nlstr): value as newline-separated string.
3277 .n (or .nlstr): value as newline-separated string.
3257 .s (or .spstr): value as whitespace-separated string.
3278 .s (or .spstr): value as whitespace-separated string.
3258
3279
3259 This is very useful when trying to use such lists as arguments to
3280 This is very useful when trying to use such lists as arguments to
3260 system commands."""
3281 system commands."""
3261
3282
3262 if parameter_s:
3283 if parameter_s:
3263 return self.shell.getoutput(parameter_s)
3284 return self.shell.getoutput(parameter_s)
3264
3285
3265
3286
3266 def magic_bookmark(self, parameter_s=''):
3287 def magic_bookmark(self, parameter_s=''):
3267 """Manage IPython's bookmark system.
3288 """Manage IPython's bookmark system.
3268
3289
3269 %bookmark <name> - set bookmark to current dir
3290 %bookmark <name> - set bookmark to current dir
3270 %bookmark <name> <dir> - set bookmark to <dir>
3291 %bookmark <name> <dir> - set bookmark to <dir>
3271 %bookmark -l - list all bookmarks
3292 %bookmark -l - list all bookmarks
3272 %bookmark -d <name> - remove bookmark
3293 %bookmark -d <name> - remove bookmark
3273 %bookmark -r - remove all bookmarks
3294 %bookmark -r - remove all bookmarks
3274
3295
3275 You can later on access a bookmarked folder with::
3296 You can later on access a bookmarked folder with::
3276
3297
3277 %cd -b <name>
3298 %cd -b <name>
3278
3299
3279 or simply '%cd <name>' if there is no directory called <name> AND
3300 or simply '%cd <name>' if there is no directory called <name> AND
3280 there is such a bookmark defined.
3301 there is such a bookmark defined.
3281
3302
3282 Your bookmarks persist through IPython sessions, but they are
3303 Your bookmarks persist through IPython sessions, but they are
3283 associated with each profile."""
3304 associated with each profile."""
3284
3305
3285 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3306 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3286 if len(args) > 2:
3307 if len(args) > 2:
3287 raise UsageError("%bookmark: too many arguments")
3308 raise UsageError("%bookmark: too many arguments")
3288
3309
3289 bkms = self.db.get('bookmarks',{})
3310 bkms = self.db.get('bookmarks',{})
3290
3311
3291 if opts.has_key('d'):
3312 if opts.has_key('d'):
3292 try:
3313 try:
3293 todel = args[0]
3314 todel = args[0]
3294 except IndexError:
3315 except IndexError:
3295 raise UsageError(
3316 raise UsageError(
3296 "%bookmark -d: must provide a bookmark to delete")
3317 "%bookmark -d: must provide a bookmark to delete")
3297 else:
3318 else:
3298 try:
3319 try:
3299 del bkms[todel]
3320 del bkms[todel]
3300 except KeyError:
3321 except KeyError:
3301 raise UsageError(
3322 raise UsageError(
3302 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3323 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3303
3324
3304 elif opts.has_key('r'):
3325 elif opts.has_key('r'):
3305 bkms = {}
3326 bkms = {}
3306 elif opts.has_key('l'):
3327 elif opts.has_key('l'):
3307 bks = bkms.keys()
3328 bks = bkms.keys()
3308 bks.sort()
3329 bks.sort()
3309 if bks:
3330 if bks:
3310 size = max(map(len,bks))
3331 size = max(map(len,bks))
3311 else:
3332 else:
3312 size = 0
3333 size = 0
3313 fmt = '%-'+str(size)+'s -> %s'
3334 fmt = '%-'+str(size)+'s -> %s'
3314 print 'Current bookmarks:'
3335 print 'Current bookmarks:'
3315 for bk in bks:
3336 for bk in bks:
3316 print fmt % (bk,bkms[bk])
3337 print fmt % (bk,bkms[bk])
3317 else:
3338 else:
3318 if not args:
3339 if not args:
3319 raise UsageError("%bookmark: You must specify the bookmark name")
3340 raise UsageError("%bookmark: You must specify the bookmark name")
3320 elif len(args)==1:
3341 elif len(args)==1:
3321 bkms[args[0]] = os.getcwdu()
3342 bkms[args[0]] = os.getcwdu()
3322 elif len(args)==2:
3343 elif len(args)==2:
3323 bkms[args[0]] = args[1]
3344 bkms[args[0]] = args[1]
3324 self.db['bookmarks'] = bkms
3345 self.db['bookmarks'] = bkms
3325
3346
3347
3326 def magic_pycat(self, parameter_s=''):
3348 def magic_pycat(self, parameter_s=''):
3327 """Show a syntax-highlighted file through a pager.
3349 """Show a syntax-highlighted file through a pager.
3328
3350
3329 This magic is similar to the cat utility, but it will assume the file
3351 This magic is similar to the cat utility, but it will assume the file
3330 to be Python source and will show it with syntax highlighting. """
3352 to be Python source and will show it with syntax highlighting.
3331
3353
3332 try:
3354 This magic command can either take a local filename, an url,
3333 filename = get_py_filename(parameter_s)
3355 an history range (see %history) or a macro as argument ::
3334 cont = file_read(filename)
3356
3335 except IOError:
3357 %pycat myscript.py
3336 try:
3358 %pycat 7-27
3337 cont = eval(parameter_s,self.user_ns)
3359 %pycat myMacro
3338 except NameError:
3360 %pycat http://www.example.com/myscript.py
3339 cont = None
3361 """
3340 if cont is None:
3362
3341 print "Error: no such file or variable"
3363 try :
3364 cont = self.shell.find_user_code(parameter_s)
3365 except ValueError, IOError:
3366 print "Error: no such file, variable, URL, history range or macro"
3342 return
3367 return
3343
3368
3344 page.page(self.shell.pycolorize(cont))
3369 page.page(self.shell.pycolorize(cont))
3345
3370
3346 def magic_quickref(self,arg):
3371 def magic_quickref(self,arg):
3347 """ Show a quick reference sheet """
3372 """ Show a quick reference sheet """
3348 import IPython.core.usage
3373 import IPython.core.usage
3349 qr = IPython.core.usage.quick_reference + self.magic_magic('-brief')
3374 qr = IPython.core.usage.quick_reference + self.magic_magic('-brief')
3350
3375
3351 page.page(qr)
3376 page.page(qr)
3352
3377
3353 def magic_doctest_mode(self,parameter_s=''):
3378 def magic_doctest_mode(self,parameter_s=''):
3354 """Toggle doctest mode on and off.
3379 """Toggle doctest mode on and off.
3355
3380
3356 This mode is intended to make IPython behave as much as possible like a
3381 This mode is intended to make IPython behave as much as possible like a
3357 plain Python shell, from the perspective of how its prompts, exceptions
3382 plain Python shell, from the perspective of how its prompts, exceptions
3358 and output look. This makes it easy to copy and paste parts of a
3383 and output look. This makes it easy to copy and paste parts of a
3359 session into doctests. It does so by:
3384 session into doctests. It does so by:
3360
3385
3361 - Changing the prompts to the classic ``>>>`` ones.
3386 - Changing the prompts to the classic ``>>>`` ones.
3362 - Changing the exception reporting mode to 'Plain'.
3387 - Changing the exception reporting mode to 'Plain'.
3363 - Disabling pretty-printing of output.
3388 - Disabling pretty-printing of output.
3364
3389
3365 Note that IPython also supports the pasting of code snippets that have
3390 Note that IPython also supports the pasting of code snippets that have
3366 leading '>>>' and '...' prompts in them. This means that you can paste
3391 leading '>>>' and '...' prompts in them. This means that you can paste
3367 doctests from files or docstrings (even if they have leading
3392 doctests from files or docstrings (even if they have leading
3368 whitespace), and the code will execute correctly. You can then use
3393 whitespace), and the code will execute correctly. You can then use
3369 '%history -t' to see the translated history; this will give you the
3394 '%history -t' to see the translated history; this will give you the
3370 input after removal of all the leading prompts and whitespace, which
3395 input after removal of all the leading prompts and whitespace, which
3371 can be pasted back into an editor.
3396 can be pasted back into an editor.
3372
3397
3373 With these features, you can switch into this mode easily whenever you
3398 With these features, you can switch into this mode easily whenever you
3374 need to do testing and changes to doctests, without having to leave
3399 need to do testing and changes to doctests, without having to leave
3375 your existing IPython session.
3400 your existing IPython session.
3376 """
3401 """
3377
3402
3378 from IPython.utils.ipstruct import Struct
3403 from IPython.utils.ipstruct import Struct
3379
3404
3380 # Shorthands
3405 # Shorthands
3381 shell = self.shell
3406 shell = self.shell
3382 pm = shell.prompt_manager
3407 pm = shell.prompt_manager
3383 meta = shell.meta
3408 meta = shell.meta
3384 disp_formatter = self.shell.display_formatter
3409 disp_formatter = self.shell.display_formatter
3385 ptformatter = disp_formatter.formatters['text/plain']
3410 ptformatter = disp_formatter.formatters['text/plain']
3386 # dstore is a data store kept in the instance metadata bag to track any
3411 # dstore is a data store kept in the instance metadata bag to track any
3387 # changes we make, so we can undo them later.
3412 # changes we make, so we can undo them later.
3388 dstore = meta.setdefault('doctest_mode',Struct())
3413 dstore = meta.setdefault('doctest_mode',Struct())
3389 save_dstore = dstore.setdefault
3414 save_dstore = dstore.setdefault
3390
3415
3391 # save a few values we'll need to recover later
3416 # save a few values we'll need to recover later
3392 mode = save_dstore('mode',False)
3417 mode = save_dstore('mode',False)
3393 save_dstore('rc_pprint',ptformatter.pprint)
3418 save_dstore('rc_pprint',ptformatter.pprint)
3394 save_dstore('xmode',shell.InteractiveTB.mode)
3419 save_dstore('xmode',shell.InteractiveTB.mode)
3395 save_dstore('rc_separate_out',shell.separate_out)
3420 save_dstore('rc_separate_out',shell.separate_out)
3396 save_dstore('rc_separate_out2',shell.separate_out2)
3421 save_dstore('rc_separate_out2',shell.separate_out2)
3397 save_dstore('rc_prompts_pad_left',pm.justify)
3422 save_dstore('rc_prompts_pad_left',pm.justify)
3398 save_dstore('rc_separate_in',shell.separate_in)
3423 save_dstore('rc_separate_in',shell.separate_in)
3399 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
3424 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
3400 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
3425 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
3401
3426
3402 if mode == False:
3427 if mode == False:
3403 # turn on
3428 # turn on
3404 pm.in_template = '>>> '
3429 pm.in_template = '>>> '
3405 pm.in2_template = '... '
3430 pm.in2_template = '... '
3406 pm.out_template = ''
3431 pm.out_template = ''
3407
3432
3408 # Prompt separators like plain python
3433 # Prompt separators like plain python
3409 shell.separate_in = ''
3434 shell.separate_in = ''
3410 shell.separate_out = ''
3435 shell.separate_out = ''
3411 shell.separate_out2 = ''
3436 shell.separate_out2 = ''
3412
3437
3413 pm.justify = False
3438 pm.justify = False
3414
3439
3415 ptformatter.pprint = False
3440 ptformatter.pprint = False
3416 disp_formatter.plain_text_only = True
3441 disp_formatter.plain_text_only = True
3417
3442
3418 shell.magic_xmode('Plain')
3443 shell.magic_xmode('Plain')
3419 else:
3444 else:
3420 # turn off
3445 # turn off
3421 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
3446 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
3422
3447
3423 shell.separate_in = dstore.rc_separate_in
3448 shell.separate_in = dstore.rc_separate_in
3424
3449
3425 shell.separate_out = dstore.rc_separate_out
3450 shell.separate_out = dstore.rc_separate_out
3426 shell.separate_out2 = dstore.rc_separate_out2
3451 shell.separate_out2 = dstore.rc_separate_out2
3427
3452
3428 pm.justify = dstore.rc_prompts_pad_left
3453 pm.justify = dstore.rc_prompts_pad_left
3429
3454
3430 ptformatter.pprint = dstore.rc_pprint
3455 ptformatter.pprint = dstore.rc_pprint
3431 disp_formatter.plain_text_only = dstore.rc_plain_text_only
3456 disp_formatter.plain_text_only = dstore.rc_plain_text_only
3432
3457
3433 shell.magic_xmode(dstore.xmode)
3458 shell.magic_xmode(dstore.xmode)
3434
3459
3435 # Store new mode and inform
3460 # Store new mode and inform
3436 dstore.mode = bool(1-int(mode))
3461 dstore.mode = bool(1-int(mode))
3437 mode_label = ['OFF','ON'][dstore.mode]
3462 mode_label = ['OFF','ON'][dstore.mode]
3438 print 'Doctest mode is:', mode_label
3463 print 'Doctest mode is:', mode_label
3439
3464
3440 def magic_gui(self, parameter_s=''):
3465 def magic_gui(self, parameter_s=''):
3441 """Enable or disable IPython GUI event loop integration.
3466 """Enable or disable IPython GUI event loop integration.
3442
3467
3443 %gui [GUINAME]
3468 %gui [GUINAME]
3444
3469
3445 This magic replaces IPython's threaded shells that were activated
3470 This magic replaces IPython's threaded shells that were activated
3446 using the (pylab/wthread/etc.) command line flags. GUI toolkits
3471 using the (pylab/wthread/etc.) command line flags. GUI toolkits
3447 can now be enabled at runtime and keyboard
3472 can now be enabled at runtime and keyboard
3448 interrupts should work without any problems. The following toolkits
3473 interrupts should work without any problems. The following toolkits
3449 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
3474 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
3450
3475
3451 %gui wx # enable wxPython event loop integration
3476 %gui wx # enable wxPython event loop integration
3452 %gui qt4|qt # enable PyQt4 event loop integration
3477 %gui qt4|qt # enable PyQt4 event loop integration
3453 %gui gtk # enable PyGTK event loop integration
3478 %gui gtk # enable PyGTK event loop integration
3454 %gui gtk3 # enable Gtk3 event loop integration
3479 %gui gtk3 # enable Gtk3 event loop integration
3455 %gui tk # enable Tk event loop integration
3480 %gui tk # enable Tk event loop integration
3456 %gui OSX # enable Cocoa event loop integration
3481 %gui OSX # enable Cocoa event loop integration
3457 # (requires %matplotlib 1.1)
3482 # (requires %matplotlib 1.1)
3458 %gui # disable all event loop integration
3483 %gui # disable all event loop integration
3459
3484
3460 WARNING: after any of these has been called you can simply create
3485 WARNING: after any of these has been called you can simply create
3461 an application object, but DO NOT start the event loop yourself, as
3486 an application object, but DO NOT start the event loop yourself, as
3462 we have already handled that.
3487 we have already handled that.
3463 """
3488 """
3464 opts, arg = self.parse_options(parameter_s, '')
3489 opts, arg = self.parse_options(parameter_s, '')
3465 if arg=='': arg = None
3490 if arg=='': arg = None
3466 try:
3491 try:
3467 return self.enable_gui(arg)
3492 return self.enable_gui(arg)
3468 except Exception as e:
3493 except Exception as e:
3469 # print simple error message, rather than traceback if we can't
3494 # print simple error message, rather than traceback if we can't
3470 # hook up the GUI
3495 # hook up the GUI
3471 error(str(e))
3496 error(str(e))
3472
3497
3473 def magic_install_ext(self, parameter_s):
3498 def magic_install_ext(self, parameter_s):
3474 """Download and install an extension from a URL, e.g.::
3499 """Download and install an extension from a URL, e.g.::
3475
3500
3476 %install_ext https://bitbucket.org/birkenfeld/ipython-physics/raw/d1310a2ab15d/physics.py
3501 %install_ext https://bitbucket.org/birkenfeld/ipython-physics/raw/d1310a2ab15d/physics.py
3477
3502
3478 The URL should point to an importable Python module - either a .py file
3503 The URL should point to an importable Python module - either a .py file
3479 or a .zip file.
3504 or a .zip file.
3480
3505
3481 Parameters:
3506 Parameters:
3482
3507
3483 -n filename : Specify a name for the file, rather than taking it from
3508 -n filename : Specify a name for the file, rather than taking it from
3484 the URL.
3509 the URL.
3485 """
3510 """
3486 opts, args = self.parse_options(parameter_s, 'n:')
3511 opts, args = self.parse_options(parameter_s, 'n:')
3487 try:
3512 try:
3488 filename = self.extension_manager.install_extension(args, opts.get('n'))
3513 filename = self.extension_manager.install_extension(args, opts.get('n'))
3489 except ValueError as e:
3514 except ValueError as e:
3490 print e
3515 print e
3491 return
3516 return
3492
3517
3493 filename = os.path.basename(filename)
3518 filename = os.path.basename(filename)
3494 print "Installed %s. To use it, type:" % filename
3519 print "Installed %s. To use it, type:" % filename
3495 print " %%load_ext %s" % os.path.splitext(filename)[0]
3520 print " %%load_ext %s" % os.path.splitext(filename)[0]
3496
3521
3497
3522
3498 def magic_load_ext(self, module_str):
3523 def magic_load_ext(self, module_str):
3499 """Load an IPython extension by its module name."""
3524 """Load an IPython extension by its module name."""
3500 return self.extension_manager.load_extension(module_str)
3525 return self.extension_manager.load_extension(module_str)
3501
3526
3502 def magic_unload_ext(self, module_str):
3527 def magic_unload_ext(self, module_str):
3503 """Unload an IPython extension by its module name."""
3528 """Unload an IPython extension by its module name."""
3504 self.extension_manager.unload_extension(module_str)
3529 self.extension_manager.unload_extension(module_str)
3505
3530
3506 def magic_reload_ext(self, module_str):
3531 def magic_reload_ext(self, module_str):
3507 """Reload an IPython extension by its module name."""
3532 """Reload an IPython extension by its module name."""
3508 self.extension_manager.reload_extension(module_str)
3533 self.extension_manager.reload_extension(module_str)
3509
3534
3510 def magic_install_profiles(self, s):
3535 def magic_install_profiles(self, s):
3511 """%install_profiles has been deprecated."""
3536 """%install_profiles has been deprecated."""
3512 print '\n'.join([
3537 print '\n'.join([
3513 "%install_profiles has been deprecated.",
3538 "%install_profiles has been deprecated.",
3514 "Use `ipython profile list` to view available profiles.",
3539 "Use `ipython profile list` to view available profiles.",
3515 "Requesting a profile with `ipython profile create <name>`",
3540 "Requesting a profile with `ipython profile create <name>`",
3516 "or `ipython --profile=<name>` will start with the bundled",
3541 "or `ipython --profile=<name>` will start with the bundled",
3517 "profile of that name if it exists."
3542 "profile of that name if it exists."
3518 ])
3543 ])
3519
3544
3520 def magic_install_default_config(self, s):
3545 def magic_install_default_config(self, s):
3521 """%install_default_config has been deprecated."""
3546 """%install_default_config has been deprecated."""
3522 print '\n'.join([
3547 print '\n'.join([
3523 "%install_default_config has been deprecated.",
3548 "%install_default_config has been deprecated.",
3524 "Use `ipython profile create <name>` to initialize a profile",
3549 "Use `ipython profile create <name>` to initialize a profile",
3525 "with the default config files.",
3550 "with the default config files.",
3526 "Add `--reset` to overwrite already existing config files with defaults."
3551 "Add `--reset` to overwrite already existing config files with defaults."
3527 ])
3552 ])
3528
3553
3529 # Pylab support: simple wrappers that activate pylab, load gui input
3554 # Pylab support: simple wrappers that activate pylab, load gui input
3530 # handling and modify slightly %run
3555 # handling and modify slightly %run
3531
3556
3532 @skip_doctest
3557 @skip_doctest
3533 def _pylab_magic_run(self, parameter_s=''):
3558 def _pylab_magic_run(self, parameter_s=''):
3534 Magic.magic_run(self, parameter_s,
3559 Magic.magic_run(self, parameter_s,
3535 runner=mpl_runner(self.shell.safe_execfile))
3560 runner=mpl_runner(self.shell.safe_execfile))
3536
3561
3537 _pylab_magic_run.__doc__ = magic_run.__doc__
3562 _pylab_magic_run.__doc__ = magic_run.__doc__
3538
3563
3539 @skip_doctest
3564 @skip_doctest
3540 def magic_pylab(self, s):
3565 def magic_pylab(self, s):
3541 """Load numpy and matplotlib to work interactively.
3566 """Load numpy and matplotlib to work interactively.
3542
3567
3543 %pylab [GUINAME]
3568 %pylab [GUINAME]
3544
3569
3545 This function lets you activate pylab (matplotlib, numpy and
3570 This function lets you activate pylab (matplotlib, numpy and
3546 interactive support) at any point during an IPython session.
3571 interactive support) at any point during an IPython session.
3547
3572
3548 It will import at the top level numpy as np, pyplot as plt, matplotlib,
3573 It will import at the top level numpy as np, pyplot as plt, matplotlib,
3549 pylab and mlab, as well as all names from numpy and pylab.
3574 pylab and mlab, as well as all names from numpy and pylab.
3550
3575
3551 If you are using the inline matplotlib backend for embedded figures,
3576 If you are using the inline matplotlib backend for embedded figures,
3552 you can adjust its behavior via the %config magic::
3577 you can adjust its behavior via the %config magic::
3553
3578
3554 # enable SVG figures, necessary for SVG+XHTML export in the qtconsole
3579 # enable SVG figures, necessary for SVG+XHTML export in the qtconsole
3555 In [1]: %config InlineBackend.figure_format = 'svg'
3580 In [1]: %config InlineBackend.figure_format = 'svg'
3556
3581
3557 # change the behavior of closing all figures at the end of each
3582 # change the behavior of closing all figures at the end of each
3558 # execution (cell), or allowing reuse of active figures across
3583 # execution (cell), or allowing reuse of active figures across
3559 # cells:
3584 # cells:
3560 In [2]: %config InlineBackend.close_figures = False
3585 In [2]: %config InlineBackend.close_figures = False
3561
3586
3562 Parameters
3587 Parameters
3563 ----------
3588 ----------
3564 guiname : optional
3589 guiname : optional
3565 One of the valid arguments to the %gui magic ('qt', 'wx', 'gtk',
3590 One of the valid arguments to the %gui magic ('qt', 'wx', 'gtk',
3566 'osx' or 'tk'). If given, the corresponding Matplotlib backend is
3591 'osx' or 'tk'). If given, the corresponding Matplotlib backend is
3567 used, otherwise matplotlib's default (which you can override in your
3592 used, otherwise matplotlib's default (which you can override in your
3568 matplotlib config file) is used.
3593 matplotlib config file) is used.
3569
3594
3570 Examples
3595 Examples
3571 --------
3596 --------
3572 In this case, where the MPL default is TkAgg::
3597 In this case, where the MPL default is TkAgg::
3573
3598
3574 In [2]: %pylab
3599 In [2]: %pylab
3575
3600
3576 Welcome to pylab, a matplotlib-based Python environment.
3601 Welcome to pylab, a matplotlib-based Python environment.
3577 Backend in use: TkAgg
3602 Backend in use: TkAgg
3578 For more information, type 'help(pylab)'.
3603 For more information, type 'help(pylab)'.
3579
3604
3580 But you can explicitly request a different backend::
3605 But you can explicitly request a different backend::
3581
3606
3582 In [3]: %pylab qt
3607 In [3]: %pylab qt
3583
3608
3584 Welcome to pylab, a matplotlib-based Python environment.
3609 Welcome to pylab, a matplotlib-based Python environment.
3585 Backend in use: Qt4Agg
3610 Backend in use: Qt4Agg
3586 For more information, type 'help(pylab)'.
3611 For more information, type 'help(pylab)'.
3587 """
3612 """
3588
3613
3589 if Application.initialized():
3614 if Application.initialized():
3590 app = Application.instance()
3615 app = Application.instance()
3591 try:
3616 try:
3592 import_all_status = app.pylab_import_all
3617 import_all_status = app.pylab_import_all
3593 except AttributeError:
3618 except AttributeError:
3594 import_all_status = True
3619 import_all_status = True
3595 else:
3620 else:
3596 import_all_status = True
3621 import_all_status = True
3597
3622
3598 self.shell.enable_pylab(s, import_all=import_all_status)
3623 self.shell.enable_pylab(s, import_all=import_all_status)
3599
3624
3600 def magic_tb(self, s):
3625 def magic_tb(self, s):
3601 """Print the last traceback with the currently active exception mode.
3626 """Print the last traceback with the currently active exception mode.
3602
3627
3603 See %xmode for changing exception reporting modes."""
3628 See %xmode for changing exception reporting modes."""
3604 self.shell.showtraceback()
3629 self.shell.showtraceback()
3605
3630
3606 @skip_doctest
3631 @skip_doctest
3607 def magic_precision(self, s=''):
3632 def magic_precision(self, s=''):
3608 """Set floating point precision for pretty printing.
3633 """Set floating point precision for pretty printing.
3609
3634
3610 Can set either integer precision or a format string.
3635 Can set either integer precision or a format string.
3611
3636
3612 If numpy has been imported and precision is an int,
3637 If numpy has been imported and precision is an int,
3613 numpy display precision will also be set, via ``numpy.set_printoptions``.
3638 numpy display precision will also be set, via ``numpy.set_printoptions``.
3614
3639
3615 If no argument is given, defaults will be restored.
3640 If no argument is given, defaults will be restored.
3616
3641
3617 Examples
3642 Examples
3618 --------
3643 --------
3619 ::
3644 ::
3620
3645
3621 In [1]: from math import pi
3646 In [1]: from math import pi
3622
3647
3623 In [2]: %precision 3
3648 In [2]: %precision 3
3624 Out[2]: u'%.3f'
3649 Out[2]: u'%.3f'
3625
3650
3626 In [3]: pi
3651 In [3]: pi
3627 Out[3]: 3.142
3652 Out[3]: 3.142
3628
3653
3629 In [4]: %precision %i
3654 In [4]: %precision %i
3630 Out[4]: u'%i'
3655 Out[4]: u'%i'
3631
3656
3632 In [5]: pi
3657 In [5]: pi
3633 Out[5]: 3
3658 Out[5]: 3
3634
3659
3635 In [6]: %precision %e
3660 In [6]: %precision %e
3636 Out[6]: u'%e'
3661 Out[6]: u'%e'
3637
3662
3638 In [7]: pi**10
3663 In [7]: pi**10
3639 Out[7]: 9.364805e+04
3664 Out[7]: 9.364805e+04
3640
3665
3641 In [8]: %precision
3666 In [8]: %precision
3642 Out[8]: u'%r'
3667 Out[8]: u'%r'
3643
3668
3644 In [9]: pi**10
3669 In [9]: pi**10
3645 Out[9]: 93648.047476082982
3670 Out[9]: 93648.047476082982
3646
3671
3647 """
3672 """
3648
3673
3649 ptformatter = self.shell.display_formatter.formatters['text/plain']
3674 ptformatter = self.shell.display_formatter.formatters['text/plain']
3650 ptformatter.float_precision = s
3675 ptformatter.float_precision = s
3651 return ptformatter.float_format
3676 return ptformatter.float_format
3652
3677
3653
3678
3654 @magic_arguments.magic_arguments()
3679 @magic_arguments.magic_arguments()
3655 @magic_arguments.argument(
3680 @magic_arguments.argument(
3656 '-e', '--export', action='store_true', default=False,
3681 '-e', '--export', action='store_true', default=False,
3657 help='Export IPython history as a notebook. The filename argument '
3682 help='Export IPython history as a notebook. The filename argument '
3658 'is used to specify the notebook name and format. For example '
3683 'is used to specify the notebook name and format. For example '
3659 'a filename of notebook.ipynb will result in a notebook name '
3684 'a filename of notebook.ipynb will result in a notebook name '
3660 'of "notebook" and a format of "xml". Likewise using a ".json" '
3685 'of "notebook" and a format of "xml". Likewise using a ".json" '
3661 'or ".py" file extension will write the notebook in the json '
3686 'or ".py" file extension will write the notebook in the json '
3662 'or py formats.'
3687 'or py formats.'
3663 )
3688 )
3664 @magic_arguments.argument(
3689 @magic_arguments.argument(
3665 '-f', '--format',
3690 '-f', '--format',
3666 help='Convert an existing IPython notebook to a new format. This option '
3691 help='Convert an existing IPython notebook to a new format. This option '
3667 'specifies the new format and can have the values: xml, json, py. '
3692 'specifies the new format and can have the values: xml, json, py. '
3668 'The target filename is chosen automatically based on the new '
3693 'The target filename is chosen automatically based on the new '
3669 'format. The filename argument gives the name of the source file.'
3694 'format. The filename argument gives the name of the source file.'
3670 )
3695 )
3671 @magic_arguments.argument(
3696 @magic_arguments.argument(
3672 'filename', type=unicode,
3697 'filename', type=unicode,
3673 help='Notebook name or filename'
3698 help='Notebook name or filename'
3674 )
3699 )
3675 def magic_notebook(self, s):
3700 def magic_notebook(self, s):
3676 """Export and convert IPython notebooks.
3701 """Export and convert IPython notebooks.
3677
3702
3678 This function can export the current IPython history to a notebook file
3703 This function can export the current IPython history to a notebook file
3679 or can convert an existing notebook file into a different format. For
3704 or can convert an existing notebook file into a different format. For
3680 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
3705 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
3681 To export the history to "foo.py" do "%notebook -e foo.py". To convert
3706 To export the history to "foo.py" do "%notebook -e foo.py". To convert
3682 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
3707 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
3683 formats include (json/ipynb, py).
3708 formats include (json/ipynb, py).
3684 """
3709 """
3685 args = magic_arguments.parse_argstring(self.magic_notebook, s)
3710 args = magic_arguments.parse_argstring(self.magic_notebook, s)
3686
3711
3687 from IPython.nbformat import current
3712 from IPython.nbformat import current
3688 args.filename = unquote_filename(args.filename)
3713 args.filename = unquote_filename(args.filename)
3689 if args.export:
3714 if args.export:
3690 fname, name, format = current.parse_filename(args.filename)
3715 fname, name, format = current.parse_filename(args.filename)
3691 cells = []
3716 cells = []
3692 hist = list(self.history_manager.get_range())
3717 hist = list(self.history_manager.get_range())
3693 for session, prompt_number, input in hist[:-1]:
3718 for session, prompt_number, input in hist[:-1]:
3694 cells.append(current.new_code_cell(prompt_number=prompt_number, input=input))
3719 cells.append(current.new_code_cell(prompt_number=prompt_number, input=input))
3695 worksheet = current.new_worksheet(cells=cells)
3720 worksheet = current.new_worksheet(cells=cells)
3696 nb = current.new_notebook(name=name,worksheets=[worksheet])
3721 nb = current.new_notebook(name=name,worksheets=[worksheet])
3697 with io.open(fname, 'w', encoding='utf-8') as f:
3722 with io.open(fname, 'w', encoding='utf-8') as f:
3698 current.write(nb, f, format);
3723 current.write(nb, f, format);
3699 elif args.format is not None:
3724 elif args.format is not None:
3700 old_fname, old_name, old_format = current.parse_filename(args.filename)
3725 old_fname, old_name, old_format = current.parse_filename(args.filename)
3701 new_format = args.format
3726 new_format = args.format
3702 if new_format == u'xml':
3727 if new_format == u'xml':
3703 raise ValueError('Notebooks cannot be written as xml.')
3728 raise ValueError('Notebooks cannot be written as xml.')
3704 elif new_format == u'ipynb' or new_format == u'json':
3729 elif new_format == u'ipynb' or new_format == u'json':
3705 new_fname = old_name + u'.ipynb'
3730 new_fname = old_name + u'.ipynb'
3706 new_format = u'json'
3731 new_format = u'json'
3707 elif new_format == u'py':
3732 elif new_format == u'py':
3708 new_fname = old_name + u'.py'
3733 new_fname = old_name + u'.py'
3709 else:
3734 else:
3710 raise ValueError('Invalid notebook format: %s' % new_format)
3735 raise ValueError('Invalid notebook format: %s' % new_format)
3711 with io.open(old_fname, 'r', encoding='utf-8') as f:
3736 with io.open(old_fname, 'r', encoding='utf-8') as f:
3712 nb = current.read(f, old_format)
3737 nb = current.read(f, old_format)
3713 with io.open(new_fname, 'w', encoding='utf-8') as f:
3738 with io.open(new_fname, 'w', encoding='utf-8') as f:
3714 current.write(nb, f, new_format)
3739 current.write(nb, f, new_format)
3715
3740
3716 def magic_config(self, s):
3741 def magic_config(self, s):
3717 """configure IPython
3742 """configure IPython
3718
3743
3719 %config Class[.trait=value]
3744 %config Class[.trait=value]
3720
3745
3721 This magic exposes most of the IPython config system. Any
3746 This magic exposes most of the IPython config system. Any
3722 Configurable class should be able to be configured with the simple
3747 Configurable class should be able to be configured with the simple
3723 line::
3748 line::
3724
3749
3725 %config Class.trait=value
3750 %config Class.trait=value
3726
3751
3727 Where `value` will be resolved in the user's namespace, if it is an
3752 Where `value` will be resolved in the user's namespace, if it is an
3728 expression or variable name.
3753 expression or variable name.
3729
3754
3730 Examples
3755 Examples
3731 --------
3756 --------
3732
3757
3733 To see what classes are available for config, pass no arguments::
3758 To see what classes are available for config, pass no arguments::
3734
3759
3735 In [1]: %config
3760 In [1]: %config
3736 Available objects for config:
3761 Available objects for config:
3737 TerminalInteractiveShell
3762 TerminalInteractiveShell
3738 HistoryManager
3763 HistoryManager
3739 PrefilterManager
3764 PrefilterManager
3740 AliasManager
3765 AliasManager
3741 IPCompleter
3766 IPCompleter
3742 PromptManager
3767 PromptManager
3743 DisplayFormatter
3768 DisplayFormatter
3744
3769
3745 To view what is configurable on a given class, just pass the class
3770 To view what is configurable on a given class, just pass the class
3746 name::
3771 name::
3747
3772
3748 In [2]: %config IPCompleter
3773 In [2]: %config IPCompleter
3749 IPCompleter options
3774 IPCompleter options
3750 -----------------
3775 -----------------
3751 IPCompleter.omit__names=<Enum>
3776 IPCompleter.omit__names=<Enum>
3752 Current: 2
3777 Current: 2
3753 Choices: (0, 1, 2)
3778 Choices: (0, 1, 2)
3754 Instruct the completer to omit private method names
3779 Instruct the completer to omit private method names
3755 Specifically, when completing on ``object.<tab>``.
3780 Specifically, when completing on ``object.<tab>``.
3756 When 2 [default]: all names that start with '_' will be excluded.
3781 When 2 [default]: all names that start with '_' will be excluded.
3757 When 1: all 'magic' names (``__foo__``) will be excluded.
3782 When 1: all 'magic' names (``__foo__``) will be excluded.
3758 When 0: nothing will be excluded.
3783 When 0: nothing will be excluded.
3759 IPCompleter.merge_completions=<CBool>
3784 IPCompleter.merge_completions=<CBool>
3760 Current: True
3785 Current: True
3761 Whether to merge completion results into a single list
3786 Whether to merge completion results into a single list
3762 If False, only the completion results from the first non-empty completer
3787 If False, only the completion results from the first non-empty completer
3763 will be returned.
3788 will be returned.
3764 IPCompleter.limit_to__all__=<CBool>
3789 IPCompleter.limit_to__all__=<CBool>
3765 Current: False
3790 Current: False
3766 Instruct the completer to use __all__ for the completion
3791 Instruct the completer to use __all__ for the completion
3767 Specifically, when completing on ``object.<tab>``.
3792 Specifically, when completing on ``object.<tab>``.
3768 When True: only those names in obj.__all__ will be included.
3793 When True: only those names in obj.__all__ will be included.
3769 When False [default]: the __all__ attribute is ignored
3794 When False [default]: the __all__ attribute is ignored
3770 IPCompleter.greedy=<CBool>
3795 IPCompleter.greedy=<CBool>
3771 Current: False
3796 Current: False
3772 Activate greedy completion
3797 Activate greedy completion
3773 This will enable completion on elements of lists, results of function calls,
3798 This will enable completion on elements of lists, results of function calls,
3774 etc., but can be unsafe because the code is actually evaluated on TAB.
3799 etc., but can be unsafe because the code is actually evaluated on TAB.
3775
3800
3776 but the real use is in setting values::
3801 but the real use is in setting values::
3777
3802
3778 In [3]: %config IPCompleter.greedy = True
3803 In [3]: %config IPCompleter.greedy = True
3779
3804
3780 and these values are read from the user_ns if they are variables::
3805 and these values are read from the user_ns if they are variables::
3781
3806
3782 In [4]: feeling_greedy=False
3807 In [4]: feeling_greedy=False
3783
3808
3784 In [5]: %config IPCompleter.greedy = feeling_greedy
3809 In [5]: %config IPCompleter.greedy = feeling_greedy
3785
3810
3786 """
3811 """
3787 from IPython.config.loader import Config
3812 from IPython.config.loader import Config
3788 # some IPython objects are Configurable, but do not yet have
3813 # some IPython objects are Configurable, but do not yet have
3789 # any configurable traits. Exclude them from the effects of
3814 # any configurable traits. Exclude them from the effects of
3790 # this magic, as their presence is just noise:
3815 # this magic, as their presence is just noise:
3791 configurables = [ c for c in self.configurables if c.__class__.class_traits(config=True) ]
3816 configurables = [ c for c in self.configurables if c.__class__.class_traits(config=True) ]
3792 classnames = [ c.__class__.__name__ for c in configurables ]
3817 classnames = [ c.__class__.__name__ for c in configurables ]
3793
3818
3794 line = s.strip()
3819 line = s.strip()
3795 if not line:
3820 if not line:
3796 # print available configurable names
3821 # print available configurable names
3797 print "Available objects for config:"
3822 print "Available objects for config:"
3798 for name in classnames:
3823 for name in classnames:
3799 print " ", name
3824 print " ", name
3800 return
3825 return
3801 elif line in classnames:
3826 elif line in classnames:
3802 # `%config TerminalInteractiveShell` will print trait info for
3827 # `%config TerminalInteractiveShell` will print trait info for
3803 # TerminalInteractiveShell
3828 # TerminalInteractiveShell
3804 c = configurables[classnames.index(line)]
3829 c = configurables[classnames.index(line)]
3805 cls = c.__class__
3830 cls = c.__class__
3806 help = cls.class_get_help(c)
3831 help = cls.class_get_help(c)
3807 # strip leading '--' from cl-args:
3832 # strip leading '--' from cl-args:
3808 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
3833 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
3809 print help
3834 print help
3810 return
3835 return
3811 elif '=' not in line:
3836 elif '=' not in line:
3812 raise UsageError("Invalid config statement: %r, should be Class.trait = value" % line)
3837 raise UsageError("Invalid config statement: %r, should be Class.trait = value" % line)
3813
3838
3814
3839
3815 # otherwise, assume we are setting configurables.
3840 # otherwise, assume we are setting configurables.
3816 # leave quotes on args when splitting, because we want
3841 # leave quotes on args when splitting, because we want
3817 # unquoted args to eval in user_ns
3842 # unquoted args to eval in user_ns
3818 cfg = Config()
3843 cfg = Config()
3819 exec "cfg."+line in locals(), self.user_ns
3844 exec "cfg."+line in locals(), self.user_ns
3820
3845
3821 for configurable in configurables:
3846 for configurable in configurables:
3822 try:
3847 try:
3823 configurable.update_config(cfg)
3848 configurable.update_config(cfg)
3824 except Exception as e:
3849 except Exception as e:
3825 error(e)
3850 error(e)
3826
3851
3827 # end Magic
3852 # end Magic
@@ -1,275 +1,275 b''
1 """A notebook manager that uses the local file system for storage.
1 """A notebook manager that uses the local file system for storage.
2
2
3 Authors:
3 Authors:
4
4
5 * Brian Granger
5 * Brian Granger
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import datetime
19 import datetime
20 import io
20 import io
21 import os
21 import os
22 import uuid
22 import uuid
23 import glob
23 import glob
24
24
25 from tornado import web
25 from tornado import web
26
26
27 from IPython.config.configurable import LoggingConfigurable
27 from IPython.config.configurable import LoggingConfigurable
28 from IPython.nbformat import current
28 from IPython.nbformat import current
29 from IPython.utils.traitlets import Unicode, List, Dict, Bool
29 from IPython.utils.traitlets import Unicode, List, Dict, Bool
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # Classes
32 # Classes
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35 class NotebookManager(LoggingConfigurable):
35 class NotebookManager(LoggingConfigurable):
36
36
37 notebook_dir = Unicode(os.getcwdu(), config=True, help="""
37 notebook_dir = Unicode(os.getcwdu(), config=True, help="""
38 The directory to use for notebooks.
38 The directory to use for notebooks.
39 """)
39 """)
40
40
41 save_script = Bool(False, config=True,
41 save_script = Bool(False, config=True,
42 help="""Automatically create a Python script when saving the notebook.
42 help="""Automatically create a Python script when saving the notebook.
43
43
44 For easier use of import, %run and %loadpy across notebooks, a
44 For easier use of import, %run and %load across notebooks, a
45 <notebook-name>.py script will be created next to any
45 <notebook-name>.py script will be created next to any
46 <notebook-name>.ipynb on each save. This can also be set with the
46 <notebook-name>.ipynb on each save. This can also be set with the
47 short `--script` flag.
47 short `--script` flag.
48 """
48 """
49 )
49 )
50
50
51 filename_ext = Unicode(u'.ipynb')
51 filename_ext = Unicode(u'.ipynb')
52 allowed_formats = List([u'json',u'py'])
52 allowed_formats = List([u'json',u'py'])
53
53
54 # Map notebook_ids to notebook names
54 # Map notebook_ids to notebook names
55 mapping = Dict()
55 mapping = Dict()
56 # Map notebook names to notebook_ids
56 # Map notebook names to notebook_ids
57 rev_mapping = Dict()
57 rev_mapping = Dict()
58
58
59 def list_notebooks(self):
59 def list_notebooks(self):
60 """List all notebooks in the notebook dir.
60 """List all notebooks in the notebook dir.
61
61
62 This returns a list of dicts of the form::
62 This returns a list of dicts of the form::
63
63
64 dict(notebook_id=notebook,name=name)
64 dict(notebook_id=notebook,name=name)
65 """
65 """
66 names = glob.glob(os.path.join(self.notebook_dir,
66 names = glob.glob(os.path.join(self.notebook_dir,
67 '*' + self.filename_ext))
67 '*' + self.filename_ext))
68 names = [os.path.splitext(os.path.basename(name))[0]
68 names = [os.path.splitext(os.path.basename(name))[0]
69 for name in names]
69 for name in names]
70
70
71 data = []
71 data = []
72 for name in names:
72 for name in names:
73 if name not in self.rev_mapping:
73 if name not in self.rev_mapping:
74 notebook_id = self.new_notebook_id(name)
74 notebook_id = self.new_notebook_id(name)
75 else:
75 else:
76 notebook_id = self.rev_mapping[name]
76 notebook_id = self.rev_mapping[name]
77 data.append(dict(notebook_id=notebook_id,name=name))
77 data.append(dict(notebook_id=notebook_id,name=name))
78 data = sorted(data, key=lambda item: item['name'])
78 data = sorted(data, key=lambda item: item['name'])
79 return data
79 return data
80
80
81 def new_notebook_id(self, name):
81 def new_notebook_id(self, name):
82 """Generate a new notebook_id for a name and store its mappings."""
82 """Generate a new notebook_id for a name and store its mappings."""
83 # TODO: the following will give stable urls for notebooks, but unless
83 # TODO: the following will give stable urls for notebooks, but unless
84 # the notebooks are immediately redirected to their new urls when their
84 # the notebooks are immediately redirected to their new urls when their
85 # filemname changes, nasty inconsistencies result. So for now it's
85 # filemname changes, nasty inconsistencies result. So for now it's
86 # disabled and instead we use a random uuid4() call. But we leave the
86 # disabled and instead we use a random uuid4() call. But we leave the
87 # logic here so that we can later reactivate it, whhen the necessary
87 # logic here so that we can later reactivate it, whhen the necessary
88 # url redirection code is written.
88 # url redirection code is written.
89 #notebook_id = unicode(uuid.uuid5(uuid.NAMESPACE_URL,
89 #notebook_id = unicode(uuid.uuid5(uuid.NAMESPACE_URL,
90 # 'file://'+self.get_path_by_name(name).encode('utf-8')))
90 # 'file://'+self.get_path_by_name(name).encode('utf-8')))
91
91
92 notebook_id = unicode(uuid.uuid4())
92 notebook_id = unicode(uuid.uuid4())
93
93
94 self.mapping[notebook_id] = name
94 self.mapping[notebook_id] = name
95 self.rev_mapping[name] = notebook_id
95 self.rev_mapping[name] = notebook_id
96 return notebook_id
96 return notebook_id
97
97
98 def delete_notebook_id(self, notebook_id):
98 def delete_notebook_id(self, notebook_id):
99 """Delete a notebook's id only. This doesn't delete the actual notebook."""
99 """Delete a notebook's id only. This doesn't delete the actual notebook."""
100 name = self.mapping[notebook_id]
100 name = self.mapping[notebook_id]
101 del self.mapping[notebook_id]
101 del self.mapping[notebook_id]
102 del self.rev_mapping[name]
102 del self.rev_mapping[name]
103
103
104 def notebook_exists(self, notebook_id):
104 def notebook_exists(self, notebook_id):
105 """Does a notebook exist?"""
105 """Does a notebook exist?"""
106 if notebook_id not in self.mapping:
106 if notebook_id not in self.mapping:
107 return False
107 return False
108 path = self.get_path_by_name(self.mapping[notebook_id])
108 path = self.get_path_by_name(self.mapping[notebook_id])
109 return os.path.isfile(path)
109 return os.path.isfile(path)
110
110
111 def find_path(self, notebook_id):
111 def find_path(self, notebook_id):
112 """Return a full path to a notebook given its notebook_id."""
112 """Return a full path to a notebook given its notebook_id."""
113 try:
113 try:
114 name = self.mapping[notebook_id]
114 name = self.mapping[notebook_id]
115 except KeyError:
115 except KeyError:
116 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
116 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
117 return self.get_path_by_name(name)
117 return self.get_path_by_name(name)
118
118
119 def get_path_by_name(self, name):
119 def get_path_by_name(self, name):
120 """Return a full path to a notebook given its name."""
120 """Return a full path to a notebook given its name."""
121 filename = name + self.filename_ext
121 filename = name + self.filename_ext
122 path = os.path.join(self.notebook_dir, filename)
122 path = os.path.join(self.notebook_dir, filename)
123 return path
123 return path
124
124
125 def get_notebook(self, notebook_id, format=u'json'):
125 def get_notebook(self, notebook_id, format=u'json'):
126 """Get the representation of a notebook in format by notebook_id."""
126 """Get the representation of a notebook in format by notebook_id."""
127 format = unicode(format)
127 format = unicode(format)
128 if format not in self.allowed_formats:
128 if format not in self.allowed_formats:
129 raise web.HTTPError(415, u'Invalid notebook format: %s' % format)
129 raise web.HTTPError(415, u'Invalid notebook format: %s' % format)
130 last_modified, nb = self.get_notebook_object(notebook_id)
130 last_modified, nb = self.get_notebook_object(notebook_id)
131 kwargs = {}
131 kwargs = {}
132 if format == 'json':
132 if format == 'json':
133 # don't split lines for sending over the wire, because it
133 # don't split lines for sending over the wire, because it
134 # should match the Python in-memory format.
134 # should match the Python in-memory format.
135 kwargs['split_lines'] = False
135 kwargs['split_lines'] = False
136 data = current.writes(nb, format, **kwargs)
136 data = current.writes(nb, format, **kwargs)
137 name = nb.get('name','notebook')
137 name = nb.get('name','notebook')
138 return last_modified, name, data
138 return last_modified, name, data
139
139
140 def get_notebook_object(self, notebook_id):
140 def get_notebook_object(self, notebook_id):
141 """Get the NotebookNode representation of a notebook by notebook_id."""
141 """Get the NotebookNode representation of a notebook by notebook_id."""
142 path = self.find_path(notebook_id)
142 path = self.find_path(notebook_id)
143 if not os.path.isfile(path):
143 if not os.path.isfile(path):
144 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
144 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
145 info = os.stat(path)
145 info = os.stat(path)
146 last_modified = datetime.datetime.utcfromtimestamp(info.st_mtime)
146 last_modified = datetime.datetime.utcfromtimestamp(info.st_mtime)
147 with open(path,'r') as f:
147 with open(path,'r') as f:
148 s = f.read()
148 s = f.read()
149 try:
149 try:
150 # v1 and v2 and json in the .ipynb files.
150 # v1 and v2 and json in the .ipynb files.
151 nb = current.reads(s, u'json')
151 nb = current.reads(s, u'json')
152 except:
152 except:
153 raise web.HTTPError(500, u'Unreadable JSON notebook.')
153 raise web.HTTPError(500, u'Unreadable JSON notebook.')
154 if 'name' not in nb:
154 if 'name' not in nb:
155 nb.name = os.path.split(path)[-1].split(u'.')[0]
155 nb.name = os.path.split(path)[-1].split(u'.')[0]
156 return last_modified, nb
156 return last_modified, nb
157
157
158 def save_new_notebook(self, data, name=None, format=u'json'):
158 def save_new_notebook(self, data, name=None, format=u'json'):
159 """Save a new notebook and return its notebook_id.
159 """Save a new notebook and return its notebook_id.
160
160
161 If a name is passed in, it overrides any values in the notebook data
161 If a name is passed in, it overrides any values in the notebook data
162 and the value in the data is updated to use that value.
162 and the value in the data is updated to use that value.
163 """
163 """
164 if format not in self.allowed_formats:
164 if format not in self.allowed_formats:
165 raise web.HTTPError(415, u'Invalid notebook format: %s' % format)
165 raise web.HTTPError(415, u'Invalid notebook format: %s' % format)
166
166
167 try:
167 try:
168 nb = current.reads(data.decode('utf-8'), format)
168 nb = current.reads(data.decode('utf-8'), format)
169 except:
169 except:
170 raise web.HTTPError(400, u'Invalid JSON data')
170 raise web.HTTPError(400, u'Invalid JSON data')
171
171
172 if name is None:
172 if name is None:
173 try:
173 try:
174 name = nb.metadata.name
174 name = nb.metadata.name
175 except AttributeError:
175 except AttributeError:
176 raise web.HTTPError(400, u'Missing notebook name')
176 raise web.HTTPError(400, u'Missing notebook name')
177 nb.metadata.name = name
177 nb.metadata.name = name
178
178
179 notebook_id = self.new_notebook_id(name)
179 notebook_id = self.new_notebook_id(name)
180 self.save_notebook_object(notebook_id, nb)
180 self.save_notebook_object(notebook_id, nb)
181 return notebook_id
181 return notebook_id
182
182
183 def save_notebook(self, notebook_id, data, name=None, format=u'json'):
183 def save_notebook(self, notebook_id, data, name=None, format=u'json'):
184 """Save an existing notebook by notebook_id."""
184 """Save an existing notebook by notebook_id."""
185 if format not in self.allowed_formats:
185 if format not in self.allowed_formats:
186 raise web.HTTPError(415, u'Invalid notebook format: %s' % format)
186 raise web.HTTPError(415, u'Invalid notebook format: %s' % format)
187
187
188 try:
188 try:
189 nb = current.reads(data.decode('utf-8'), format)
189 nb = current.reads(data.decode('utf-8'), format)
190 except:
190 except:
191 raise web.HTTPError(400, u'Invalid JSON data')
191 raise web.HTTPError(400, u'Invalid JSON data')
192
192
193 if name is not None:
193 if name is not None:
194 nb.metadata.name = name
194 nb.metadata.name = name
195 self.save_notebook_object(notebook_id, nb)
195 self.save_notebook_object(notebook_id, nb)
196
196
197 def save_notebook_object(self, notebook_id, nb):
197 def save_notebook_object(self, notebook_id, nb):
198 """Save an existing notebook object by notebook_id."""
198 """Save an existing notebook object by notebook_id."""
199 if notebook_id not in self.mapping:
199 if notebook_id not in self.mapping:
200 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
200 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
201 old_name = self.mapping[notebook_id]
201 old_name = self.mapping[notebook_id]
202 try:
202 try:
203 new_name = nb.metadata.name
203 new_name = nb.metadata.name
204 except AttributeError:
204 except AttributeError:
205 raise web.HTTPError(400, u'Missing notebook name')
205 raise web.HTTPError(400, u'Missing notebook name')
206 path = self.get_path_by_name(new_name)
206 path = self.get_path_by_name(new_name)
207 try:
207 try:
208 with open(path,'w') as f:
208 with open(path,'w') as f:
209 current.write(nb, f, u'json')
209 current.write(nb, f, u'json')
210 except Exception as e:
210 except Exception as e:
211 raise web.HTTPError(400, u'Unexpected error while saving notebook: %s' % e)
211 raise web.HTTPError(400, u'Unexpected error while saving notebook: %s' % e)
212 # save .py script as well
212 # save .py script as well
213 if self.save_script:
213 if self.save_script:
214 pypath = os.path.splitext(path)[0] + '.py'
214 pypath = os.path.splitext(path)[0] + '.py'
215 try:
215 try:
216 with io.open(pypath,'w', encoding='utf-8') as f:
216 with io.open(pypath,'w', encoding='utf-8') as f:
217 current.write(nb, f, u'py')
217 current.write(nb, f, u'py')
218 except Exception as e:
218 except Exception as e:
219 raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s' % e)
219 raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s' % e)
220
220
221 if old_name != new_name:
221 if old_name != new_name:
222 old_path = self.get_path_by_name(old_name)
222 old_path = self.get_path_by_name(old_name)
223 if os.path.isfile(old_path):
223 if os.path.isfile(old_path):
224 os.unlink(old_path)
224 os.unlink(old_path)
225 if self.save_script:
225 if self.save_script:
226 old_pypath = os.path.splitext(old_path)[0] + '.py'
226 old_pypath = os.path.splitext(old_path)[0] + '.py'
227 if os.path.isfile(old_pypath):
227 if os.path.isfile(old_pypath):
228 os.unlink(old_pypath)
228 os.unlink(old_pypath)
229 self.mapping[notebook_id] = new_name
229 self.mapping[notebook_id] = new_name
230 self.rev_mapping[new_name] = notebook_id
230 self.rev_mapping[new_name] = notebook_id
231
231
232 def delete_notebook(self, notebook_id):
232 def delete_notebook(self, notebook_id):
233 """Delete notebook by notebook_id."""
233 """Delete notebook by notebook_id."""
234 path = self.find_path(notebook_id)
234 path = self.find_path(notebook_id)
235 if not os.path.isfile(path):
235 if not os.path.isfile(path):
236 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
236 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
237 os.unlink(path)
237 os.unlink(path)
238 self.delete_notebook_id(notebook_id)
238 self.delete_notebook_id(notebook_id)
239
239
240 def increment_filename(self, basename):
240 def increment_filename(self, basename):
241 """Return a non-used filename of the form basename<int>.
241 """Return a non-used filename of the form basename<int>.
242
242
243 This searches through the filenames (basename0, basename1, ...)
243 This searches through the filenames (basename0, basename1, ...)
244 until is find one that is not already being used. It is used to
244 until is find one that is not already being used. It is used to
245 create Untitled and Copy names that are unique.
245 create Untitled and Copy names that are unique.
246 """
246 """
247 i = 0
247 i = 0
248 while True:
248 while True:
249 name = u'%s%i' % (basename,i)
249 name = u'%s%i' % (basename,i)
250 path = self.get_path_by_name(name)
250 path = self.get_path_by_name(name)
251 if not os.path.isfile(path):
251 if not os.path.isfile(path):
252 break
252 break
253 else:
253 else:
254 i = i+1
254 i = i+1
255 return path, name
255 return path, name
256
256
257 def new_notebook(self):
257 def new_notebook(self):
258 """Create a new notebook and return its notebook_id."""
258 """Create a new notebook and return its notebook_id."""
259 path, name = self.increment_filename('Untitled')
259 path, name = self.increment_filename('Untitled')
260 notebook_id = self.new_notebook_id(name)
260 notebook_id = self.new_notebook_id(name)
261 metadata = current.new_metadata(name=name)
261 metadata = current.new_metadata(name=name)
262 nb = current.new_notebook(metadata=metadata)
262 nb = current.new_notebook(metadata=metadata)
263 with open(path,'w') as f:
263 with open(path,'w') as f:
264 current.write(nb, f, u'json')
264 current.write(nb, f, u'json')
265 return notebook_id
265 return notebook_id
266
266
267 def copy_notebook(self, notebook_id):
267 def copy_notebook(self, notebook_id):
268 """Copy an existing notebook and return its notebook_id."""
268 """Copy an existing notebook and return its notebook_id."""
269 last_mod, nb = self.get_notebook_object(notebook_id)
269 last_mod, nb = self.get_notebook_object(notebook_id)
270 name = nb.metadata.name + '-Copy'
270 name = nb.metadata.name + '-Copy'
271 path, name = self.increment_filename(name)
271 path, name = self.increment_filename(name)
272 nb.metadata.name = name
272 nb.metadata.name = name
273 notebook_id = self.new_notebook_id(name)
273 notebook_id = self.new_notebook_id(name)
274 self.save_notebook_object(notebook_id, nb)
274 self.save_notebook_object(notebook_id, nb)
275 return notebook_id
275 return notebook_id
@@ -1,910 +1,910 b''
1 """The Qt MainWindow for the QtConsole
1 """The Qt MainWindow for the QtConsole
2
2
3 This is a tabbed pseudo-terminal of IPython sessions, with a menu bar for
3 This is a tabbed pseudo-terminal of IPython sessions, with a menu bar for
4 common actions.
4 common actions.
5
5
6 Authors:
6 Authors:
7
7
8 * Evan Patterson
8 * Evan Patterson
9 * Min RK
9 * Min RK
10 * Erik Tollerud
10 * Erik Tollerud
11 * Fernando Perez
11 * Fernando Perez
12 * Bussonnier Matthias
12 * Bussonnier Matthias
13 * Thomas Kluyver
13 * Thomas Kluyver
14
14
15 """
15 """
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 # stdlib imports
21 # stdlib imports
22 import sys
22 import sys
23 import re
23 import re
24 import webbrowser
24 import webbrowser
25 from threading import Thread
25 from threading import Thread
26
26
27 # System library imports
27 # System library imports
28 from IPython.external.qt import QtGui,QtCore
28 from IPython.external.qt import QtGui,QtCore
29
29
30 def background(f):
30 def background(f):
31 """call a function in a simple thread, to prevent blocking"""
31 """call a function in a simple thread, to prevent blocking"""
32 t = Thread(target=f)
32 t = Thread(target=f)
33 t.start()
33 t.start()
34 return t
34 return t
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # Classes
37 # Classes
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 class MainWindow(QtGui.QMainWindow):
40 class MainWindow(QtGui.QMainWindow):
41
41
42 #---------------------------------------------------------------------------
42 #---------------------------------------------------------------------------
43 # 'object' interface
43 # 'object' interface
44 #---------------------------------------------------------------------------
44 #---------------------------------------------------------------------------
45
45
46 def __init__(self, app,
46 def __init__(self, app,
47 confirm_exit=True,
47 confirm_exit=True,
48 new_frontend_factory=None, slave_frontend_factory=None,
48 new_frontend_factory=None, slave_frontend_factory=None,
49 ):
49 ):
50 """ Create a tabbed MainWindow for managing IPython FrontendWidgets
50 """ Create a tabbed MainWindow for managing IPython FrontendWidgets
51
51
52 Parameters
52 Parameters
53 ----------
53 ----------
54
54
55 app : reference to QApplication parent
55 app : reference to QApplication parent
56 confirm_exit : bool, optional
56 confirm_exit : bool, optional
57 Whether we should prompt on close of tabs
57 Whether we should prompt on close of tabs
58 new_frontend_factory : callable
58 new_frontend_factory : callable
59 A callable that returns a new IPythonWidget instance, attached to
59 A callable that returns a new IPythonWidget instance, attached to
60 its own running kernel.
60 its own running kernel.
61 slave_frontend_factory : callable
61 slave_frontend_factory : callable
62 A callable that takes an existing IPythonWidget, and returns a new
62 A callable that takes an existing IPythonWidget, and returns a new
63 IPythonWidget instance, attached to the same kernel.
63 IPythonWidget instance, attached to the same kernel.
64 """
64 """
65
65
66 super(MainWindow, self).__init__()
66 super(MainWindow, self).__init__()
67 self._kernel_counter = 0
67 self._kernel_counter = 0
68 self._app = app
68 self._app = app
69 self.confirm_exit = confirm_exit
69 self.confirm_exit = confirm_exit
70 self.new_frontend_factory = new_frontend_factory
70 self.new_frontend_factory = new_frontend_factory
71 self.slave_frontend_factory = slave_frontend_factory
71 self.slave_frontend_factory = slave_frontend_factory
72
72
73 self.tab_widget = QtGui.QTabWidget(self)
73 self.tab_widget = QtGui.QTabWidget(self)
74 self.tab_widget.setDocumentMode(True)
74 self.tab_widget.setDocumentMode(True)
75 self.tab_widget.setTabsClosable(True)
75 self.tab_widget.setTabsClosable(True)
76 self.tab_widget.tabCloseRequested[int].connect(self.close_tab)
76 self.tab_widget.tabCloseRequested[int].connect(self.close_tab)
77
77
78 self.setCentralWidget(self.tab_widget)
78 self.setCentralWidget(self.tab_widget)
79 # hide tab bar at first, since we have no tabs:
79 # hide tab bar at first, since we have no tabs:
80 self.tab_widget.tabBar().setVisible(False)
80 self.tab_widget.tabBar().setVisible(False)
81 # prevent focus in tab bar
81 # prevent focus in tab bar
82 self.tab_widget.setFocusPolicy(QtCore.Qt.NoFocus)
82 self.tab_widget.setFocusPolicy(QtCore.Qt.NoFocus)
83
83
84 def update_tab_bar_visibility(self):
84 def update_tab_bar_visibility(self):
85 """ update visibility of the tabBar depending of the number of tab
85 """ update visibility of the tabBar depending of the number of tab
86
86
87 0 or 1 tab, tabBar hidden
87 0 or 1 tab, tabBar hidden
88 2+ tabs, tabBar visible
88 2+ tabs, tabBar visible
89
89
90 send a self.close if number of tab ==0
90 send a self.close if number of tab ==0
91
91
92 need to be called explicitely, or be connected to tabInserted/tabRemoved
92 need to be called explicitely, or be connected to tabInserted/tabRemoved
93 """
93 """
94 if self.tab_widget.count() <= 1:
94 if self.tab_widget.count() <= 1:
95 self.tab_widget.tabBar().setVisible(False)
95 self.tab_widget.tabBar().setVisible(False)
96 else:
96 else:
97 self.tab_widget.tabBar().setVisible(True)
97 self.tab_widget.tabBar().setVisible(True)
98 if self.tab_widget.count()==0 :
98 if self.tab_widget.count()==0 :
99 self.close()
99 self.close()
100
100
101 @property
101 @property
102 def next_kernel_id(self):
102 def next_kernel_id(self):
103 """constantly increasing counter for kernel IDs"""
103 """constantly increasing counter for kernel IDs"""
104 c = self._kernel_counter
104 c = self._kernel_counter
105 self._kernel_counter += 1
105 self._kernel_counter += 1
106 return c
106 return c
107
107
108 @property
108 @property
109 def active_frontend(self):
109 def active_frontend(self):
110 return self.tab_widget.currentWidget()
110 return self.tab_widget.currentWidget()
111
111
112 def create_tab_with_new_frontend(self):
112 def create_tab_with_new_frontend(self):
113 """create a new frontend and attach it to a new tab"""
113 """create a new frontend and attach it to a new tab"""
114 widget = self.new_frontend_factory()
114 widget = self.new_frontend_factory()
115 self.add_tab_with_frontend(widget)
115 self.add_tab_with_frontend(widget)
116
116
117 def create_tab_with_current_kernel(self):
117 def create_tab_with_current_kernel(self):
118 """create a new frontend attached to the same kernel as the current tab"""
118 """create a new frontend attached to the same kernel as the current tab"""
119 current_widget = self.tab_widget.currentWidget()
119 current_widget = self.tab_widget.currentWidget()
120 current_widget_index = self.tab_widget.indexOf(current_widget)
120 current_widget_index = self.tab_widget.indexOf(current_widget)
121 current_widget_name = self.tab_widget.tabText(current_widget_index)
121 current_widget_name = self.tab_widget.tabText(current_widget_index)
122 widget = self.slave_frontend_factory(current_widget)
122 widget = self.slave_frontend_factory(current_widget)
123 if 'slave' in current_widget_name:
123 if 'slave' in current_widget_name:
124 # don't keep stacking slaves
124 # don't keep stacking slaves
125 name = current_widget_name
125 name = current_widget_name
126 else:
126 else:
127 name = '(%s) slave' % current_widget_name
127 name = '(%s) slave' % current_widget_name
128 self.add_tab_with_frontend(widget,name=name)
128 self.add_tab_with_frontend(widget,name=name)
129
129
130 def close_tab(self,current_tab):
130 def close_tab(self,current_tab):
131 """ Called when you need to try to close a tab.
131 """ Called when you need to try to close a tab.
132
132
133 It takes the number of the tab to be closed as argument, or a referece
133 It takes the number of the tab to be closed as argument, or a referece
134 to the wiget insite this tab
134 to the wiget insite this tab
135 """
135 """
136
136
137 # let's be sure "tab" and "closing widget are respectivey the index of the tab to close
137 # let's be sure "tab" and "closing widget are respectivey the index of the tab to close
138 # and a reference to the trontend to close
138 # and a reference to the trontend to close
139 if type(current_tab) is not int :
139 if type(current_tab) is not int :
140 current_tab = self.tab_widget.indexOf(current_tab)
140 current_tab = self.tab_widget.indexOf(current_tab)
141 closing_widget=self.tab_widget.widget(current_tab)
141 closing_widget=self.tab_widget.widget(current_tab)
142
142
143
143
144 # when trying to be closed, widget might re-send a request to be closed again, but will
144 # when trying to be closed, widget might re-send a request to be closed again, but will
145 # be deleted when event will be processed. So need to check that widget still exist and
145 # be deleted when event will be processed. So need to check that widget still exist and
146 # skip if not. One example of this is when 'exit' is send in a slave tab. 'exit' will be
146 # skip if not. One example of this is when 'exit' is send in a slave tab. 'exit' will be
147 # re-send by this fonction on the master widget, which ask all slaves widget to exit
147 # re-send by this fonction on the master widget, which ask all slaves widget to exit
148 if closing_widget==None:
148 if closing_widget==None:
149 return
149 return
150
150
151 #get a list of all slave widgets on the same kernel.
151 #get a list of all slave widgets on the same kernel.
152 slave_tabs = self.find_slave_widgets(closing_widget)
152 slave_tabs = self.find_slave_widgets(closing_widget)
153
153
154 keepkernel = None #Use the prompt by default
154 keepkernel = None #Use the prompt by default
155 if hasattr(closing_widget,'_keep_kernel_on_exit'): #set by exit magic
155 if hasattr(closing_widget,'_keep_kernel_on_exit'): #set by exit magic
156 keepkernel = closing_widget._keep_kernel_on_exit
156 keepkernel = closing_widget._keep_kernel_on_exit
157 # If signal sent by exit magic (_keep_kernel_on_exit, exist and not None)
157 # If signal sent by exit magic (_keep_kernel_on_exit, exist and not None)
158 # we set local slave tabs._hidden to True to avoid prompting for kernel
158 # we set local slave tabs._hidden to True to avoid prompting for kernel
159 # restart when they get the signal. and then "forward" the 'exit'
159 # restart when they get the signal. and then "forward" the 'exit'
160 # to the main window
160 # to the main window
161 if keepkernel is not None:
161 if keepkernel is not None:
162 for tab in slave_tabs:
162 for tab in slave_tabs:
163 tab._hidden = True
163 tab._hidden = True
164 if closing_widget in slave_tabs:
164 if closing_widget in slave_tabs:
165 try :
165 try :
166 self.find_master_tab(closing_widget).execute('exit')
166 self.find_master_tab(closing_widget).execute('exit')
167 except AttributeError:
167 except AttributeError:
168 self.log.info("Master already closed or not local, closing only current tab")
168 self.log.info("Master already closed or not local, closing only current tab")
169 self.tab_widget.removeTab(current_tab)
169 self.tab_widget.removeTab(current_tab)
170 self.update_tab_bar_visibility()
170 self.update_tab_bar_visibility()
171 return
171 return
172
172
173 kernel_manager = closing_widget.kernel_manager
173 kernel_manager = closing_widget.kernel_manager
174
174
175 if keepkernel is None and not closing_widget._confirm_exit:
175 if keepkernel is None and not closing_widget._confirm_exit:
176 # don't prompt, just terminate the kernel if we own it
176 # don't prompt, just terminate the kernel if we own it
177 # or leave it alone if we don't
177 # or leave it alone if we don't
178 keepkernel = closing_widget._existing
178 keepkernel = closing_widget._existing
179 if keepkernel is None: #show prompt
179 if keepkernel is None: #show prompt
180 if kernel_manager and kernel_manager.channels_running:
180 if kernel_manager and kernel_manager.channels_running:
181 title = self.window().windowTitle()
181 title = self.window().windowTitle()
182 cancel = QtGui.QMessageBox.Cancel
182 cancel = QtGui.QMessageBox.Cancel
183 okay = QtGui.QMessageBox.Ok
183 okay = QtGui.QMessageBox.Ok
184 if closing_widget._may_close:
184 if closing_widget._may_close:
185 msg = "You are closing the tab : "+'"'+self.tab_widget.tabText(current_tab)+'"'
185 msg = "You are closing the tab : "+'"'+self.tab_widget.tabText(current_tab)+'"'
186 info = "Would you like to quit the Kernel and close all attached Consoles as well?"
186 info = "Would you like to quit the Kernel and close all attached Consoles as well?"
187 justthis = QtGui.QPushButton("&No, just this Tab", self)
187 justthis = QtGui.QPushButton("&No, just this Tab", self)
188 justthis.setShortcut('N')
188 justthis.setShortcut('N')
189 closeall = QtGui.QPushButton("&Yes, close all", self)
189 closeall = QtGui.QPushButton("&Yes, close all", self)
190 closeall.setShortcut('Y')
190 closeall.setShortcut('Y')
191 # allow ctrl-d ctrl-d exit, like in terminal
191 # allow ctrl-d ctrl-d exit, like in terminal
192 closeall.setShortcut('Ctrl+D')
192 closeall.setShortcut('Ctrl+D')
193 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
193 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
194 title, msg)
194 title, msg)
195 box.setInformativeText(info)
195 box.setInformativeText(info)
196 box.addButton(cancel)
196 box.addButton(cancel)
197 box.addButton(justthis, QtGui.QMessageBox.NoRole)
197 box.addButton(justthis, QtGui.QMessageBox.NoRole)
198 box.addButton(closeall, QtGui.QMessageBox.YesRole)
198 box.addButton(closeall, QtGui.QMessageBox.YesRole)
199 box.setDefaultButton(closeall)
199 box.setDefaultButton(closeall)
200 box.setEscapeButton(cancel)
200 box.setEscapeButton(cancel)
201 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
201 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
202 box.setIconPixmap(pixmap)
202 box.setIconPixmap(pixmap)
203 reply = box.exec_()
203 reply = box.exec_()
204 if reply == 1: # close All
204 if reply == 1: # close All
205 for slave in slave_tabs:
205 for slave in slave_tabs:
206 background(slave.kernel_manager.stop_channels)
206 background(slave.kernel_manager.stop_channels)
207 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
207 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
208 closing_widget.execute("exit")
208 closing_widget.execute("exit")
209 self.tab_widget.removeTab(current_tab)
209 self.tab_widget.removeTab(current_tab)
210 background(kernel_manager.stop_channels)
210 background(kernel_manager.stop_channels)
211 elif reply == 0: # close Console
211 elif reply == 0: # close Console
212 if not closing_widget._existing:
212 if not closing_widget._existing:
213 # Have kernel: don't quit, just close the tab
213 # Have kernel: don't quit, just close the tab
214 closing_widget.execute("exit True")
214 closing_widget.execute("exit True")
215 self.tab_widget.removeTab(current_tab)
215 self.tab_widget.removeTab(current_tab)
216 background(kernel_manager.stop_channels)
216 background(kernel_manager.stop_channels)
217 else:
217 else:
218 reply = QtGui.QMessageBox.question(self, title,
218 reply = QtGui.QMessageBox.question(self, title,
219 "Are you sure you want to close this Console?"+
219 "Are you sure you want to close this Console?"+
220 "\nThe Kernel and other Consoles will remain active.",
220 "\nThe Kernel and other Consoles will remain active.",
221 okay|cancel,
221 okay|cancel,
222 defaultButton=okay
222 defaultButton=okay
223 )
223 )
224 if reply == okay:
224 if reply == okay:
225 self.tab_widget.removeTab(current_tab)
225 self.tab_widget.removeTab(current_tab)
226 elif keepkernel: #close console but leave kernel running (no prompt)
226 elif keepkernel: #close console but leave kernel running (no prompt)
227 self.tab_widget.removeTab(current_tab)
227 self.tab_widget.removeTab(current_tab)
228 background(kernel_manager.stop_channels)
228 background(kernel_manager.stop_channels)
229 else: #close console and kernel (no prompt)
229 else: #close console and kernel (no prompt)
230 self.tab_widget.removeTab(current_tab)
230 self.tab_widget.removeTab(current_tab)
231 if kernel_manager and kernel_manager.channels_running:
231 if kernel_manager and kernel_manager.channels_running:
232 for slave in slave_tabs:
232 for slave in slave_tabs:
233 background(slave.kernel_manager.stop_channels)
233 background(slave.kernel_manager.stop_channels)
234 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
234 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
235 kernel_manager.shutdown_kernel()
235 kernel_manager.shutdown_kernel()
236 background(kernel_manager.stop_channels)
236 background(kernel_manager.stop_channels)
237
237
238 self.update_tab_bar_visibility()
238 self.update_tab_bar_visibility()
239
239
240 def add_tab_with_frontend(self,frontend,name=None):
240 def add_tab_with_frontend(self,frontend,name=None):
241 """ insert a tab with a given frontend in the tab bar, and give it a name
241 """ insert a tab with a given frontend in the tab bar, and give it a name
242
242
243 """
243 """
244 if not name:
244 if not name:
245 name = 'kernel %i' % self.next_kernel_id
245 name = 'kernel %i' % self.next_kernel_id
246 self.tab_widget.addTab(frontend,name)
246 self.tab_widget.addTab(frontend,name)
247 self.update_tab_bar_visibility()
247 self.update_tab_bar_visibility()
248 self.make_frontend_visible(frontend)
248 self.make_frontend_visible(frontend)
249 frontend.exit_requested.connect(self.close_tab)
249 frontend.exit_requested.connect(self.close_tab)
250
250
251 def next_tab(self):
251 def next_tab(self):
252 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()+1))
252 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()+1))
253
253
254 def prev_tab(self):
254 def prev_tab(self):
255 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()-1))
255 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()-1))
256
256
257 def make_frontend_visible(self,frontend):
257 def make_frontend_visible(self,frontend):
258 widget_index=self.tab_widget.indexOf(frontend)
258 widget_index=self.tab_widget.indexOf(frontend)
259 if widget_index > 0 :
259 if widget_index > 0 :
260 self.tab_widget.setCurrentIndex(widget_index)
260 self.tab_widget.setCurrentIndex(widget_index)
261
261
262 def find_master_tab(self,tab,as_list=False):
262 def find_master_tab(self,tab,as_list=False):
263 """
263 """
264 Try to return the frontend that own the kernel attached to the given widget/tab.
264 Try to return the frontend that own the kernel attached to the given widget/tab.
265
265
266 Only find frontend owed by the current application. Selection
266 Only find frontend owed by the current application. Selection
267 based on port of the kernel, might be inacurate if several kernel
267 based on port of the kernel, might be inacurate if several kernel
268 on different ip use same port number.
268 on different ip use same port number.
269
269
270 This fonction does the conversion tabNumber/widget if needed.
270 This fonction does the conversion tabNumber/widget if needed.
271 Might return None if no master widget (non local kernel)
271 Might return None if no master widget (non local kernel)
272 Will crash IPython if more than 1 masterWidget
272 Will crash IPython if more than 1 masterWidget
273
273
274 When asList set to True, always return a list of widget(s) owning
274 When asList set to True, always return a list of widget(s) owning
275 the kernel. The list might be empty or containing several Widget.
275 the kernel. The list might be empty or containing several Widget.
276 """
276 """
277
277
278 #convert from/to int/richIpythonWidget if needed
278 #convert from/to int/richIpythonWidget if needed
279 if isinstance(tab, int):
279 if isinstance(tab, int):
280 tab = self.tab_widget.widget(tab)
280 tab = self.tab_widget.widget(tab)
281 km=tab.kernel_manager
281 km=tab.kernel_manager
282
282
283 #build list of all widgets
283 #build list of all widgets
284 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
284 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
285
285
286 # widget that are candidate to be the owner of the kernel does have all the same port of the curent widget
286 # widget that are candidate to be the owner of the kernel does have all the same port of the curent widget
287 # And should have a _may_close attribute
287 # And should have a _may_close attribute
288 filtered_widget_list = [ widget for widget in widget_list if
288 filtered_widget_list = [ widget for widget in widget_list if
289 widget.kernel_manager.connection_file == km.connection_file and
289 widget.kernel_manager.connection_file == km.connection_file and
290 hasattr(widget,'_may_close') ]
290 hasattr(widget,'_may_close') ]
291 # the master widget is the one that may close the kernel
291 # the master widget is the one that may close the kernel
292 master_widget= [ widget for widget in filtered_widget_list if widget._may_close]
292 master_widget= [ widget for widget in filtered_widget_list if widget._may_close]
293 if as_list:
293 if as_list:
294 return master_widget
294 return master_widget
295 assert(len(master_widget)<=1 )
295 assert(len(master_widget)<=1 )
296 if len(master_widget)==0:
296 if len(master_widget)==0:
297 return None
297 return None
298
298
299 return master_widget[0]
299 return master_widget[0]
300
300
301 def find_slave_widgets(self,tab):
301 def find_slave_widgets(self,tab):
302 """return all the frontends that do not own the kernel attached to the given widget/tab.
302 """return all the frontends that do not own the kernel attached to the given widget/tab.
303
303
304 Only find frontends owned by the current application. Selection
304 Only find frontends owned by the current application. Selection
305 based on connection file of the kernel.
305 based on connection file of the kernel.
306
306
307 This function does the conversion tabNumber/widget if needed.
307 This function does the conversion tabNumber/widget if needed.
308 """
308 """
309 #convert from/to int/richIpythonWidget if needed
309 #convert from/to int/richIpythonWidget if needed
310 if isinstance(tab, int):
310 if isinstance(tab, int):
311 tab = self.tab_widget.widget(tab)
311 tab = self.tab_widget.widget(tab)
312 km=tab.kernel_manager
312 km=tab.kernel_manager
313
313
314 #build list of all widgets
314 #build list of all widgets
315 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
315 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
316
316
317 # widget that are candidate not to be the owner of the kernel does have all the same port of the curent widget
317 # widget that are candidate not to be the owner of the kernel does have all the same port of the curent widget
318 filtered_widget_list = ( widget for widget in widget_list if
318 filtered_widget_list = ( widget for widget in widget_list if
319 widget.kernel_manager.connection_file == km.connection_file)
319 widget.kernel_manager.connection_file == km.connection_file)
320 # Get a list of all widget owning the same kernel and removed it from
320 # Get a list of all widget owning the same kernel and removed it from
321 # the previous cadidate. (better using sets ?)
321 # the previous cadidate. (better using sets ?)
322 master_widget_list = self.find_master_tab(tab, as_list=True)
322 master_widget_list = self.find_master_tab(tab, as_list=True)
323 slave_list = [widget for widget in filtered_widget_list if widget not in master_widget_list]
323 slave_list = [widget for widget in filtered_widget_list if widget not in master_widget_list]
324
324
325 return slave_list
325 return slave_list
326
326
327 # Populate the menu bar with common actions and shortcuts
327 # Populate the menu bar with common actions and shortcuts
328 def add_menu_action(self, menu, action, defer_shortcut=False):
328 def add_menu_action(self, menu, action, defer_shortcut=False):
329 """Add action to menu as well as self
329 """Add action to menu as well as self
330
330
331 So that when the menu bar is invisible, its actions are still available.
331 So that when the menu bar is invisible, its actions are still available.
332
332
333 If defer_shortcut is True, set the shortcut context to widget-only,
333 If defer_shortcut is True, set the shortcut context to widget-only,
334 where it will avoid conflict with shortcuts already bound to the
334 where it will avoid conflict with shortcuts already bound to the
335 widgets themselves.
335 widgets themselves.
336 """
336 """
337 menu.addAction(action)
337 menu.addAction(action)
338 self.addAction(action)
338 self.addAction(action)
339
339
340 if defer_shortcut:
340 if defer_shortcut:
341 action.setShortcutContext(QtCore.Qt.WidgetShortcut)
341 action.setShortcutContext(QtCore.Qt.WidgetShortcut)
342
342
343 def init_menu_bar(self):
343 def init_menu_bar(self):
344 #create menu in the order they should appear in the menu bar
344 #create menu in the order they should appear in the menu bar
345 self.init_file_menu()
345 self.init_file_menu()
346 self.init_edit_menu()
346 self.init_edit_menu()
347 self.init_view_menu()
347 self.init_view_menu()
348 self.init_kernel_menu()
348 self.init_kernel_menu()
349 self.init_magic_menu()
349 self.init_magic_menu()
350 self.init_window_menu()
350 self.init_window_menu()
351 self.init_help_menu()
351 self.init_help_menu()
352
352
353 def init_file_menu(self):
353 def init_file_menu(self):
354 self.file_menu = self.menuBar().addMenu("&File")
354 self.file_menu = self.menuBar().addMenu("&File")
355
355
356 self.new_kernel_tab_act = QtGui.QAction("New Tab with &New kernel",
356 self.new_kernel_tab_act = QtGui.QAction("New Tab with &New kernel",
357 self,
357 self,
358 shortcut="Ctrl+T",
358 shortcut="Ctrl+T",
359 triggered=self.create_tab_with_new_frontend)
359 triggered=self.create_tab_with_new_frontend)
360 self.add_menu_action(self.file_menu, self.new_kernel_tab_act)
360 self.add_menu_action(self.file_menu, self.new_kernel_tab_act)
361
361
362 self.slave_kernel_tab_act = QtGui.QAction("New Tab with Sa&me kernel",
362 self.slave_kernel_tab_act = QtGui.QAction("New Tab with Sa&me kernel",
363 self,
363 self,
364 shortcut="Ctrl+Shift+T",
364 shortcut="Ctrl+Shift+T",
365 triggered=self.create_tab_with_current_kernel)
365 triggered=self.create_tab_with_current_kernel)
366 self.add_menu_action(self.file_menu, self.slave_kernel_tab_act)
366 self.add_menu_action(self.file_menu, self.slave_kernel_tab_act)
367
367
368 self.file_menu.addSeparator()
368 self.file_menu.addSeparator()
369
369
370 self.close_action=QtGui.QAction("&Close Tab",
370 self.close_action=QtGui.QAction("&Close Tab",
371 self,
371 self,
372 shortcut=QtGui.QKeySequence.Close,
372 shortcut=QtGui.QKeySequence.Close,
373 triggered=self.close_active_frontend
373 triggered=self.close_active_frontend
374 )
374 )
375 self.add_menu_action(self.file_menu, self.close_action)
375 self.add_menu_action(self.file_menu, self.close_action)
376
376
377 self.export_action=QtGui.QAction("&Save to HTML/XHTML",
377 self.export_action=QtGui.QAction("&Save to HTML/XHTML",
378 self,
378 self,
379 shortcut=QtGui.QKeySequence.Save,
379 shortcut=QtGui.QKeySequence.Save,
380 triggered=self.export_action_active_frontend
380 triggered=self.export_action_active_frontend
381 )
381 )
382 self.add_menu_action(self.file_menu, self.export_action, True)
382 self.add_menu_action(self.file_menu, self.export_action, True)
383
383
384 self.file_menu.addSeparator()
384 self.file_menu.addSeparator()
385
385
386 printkey = QtGui.QKeySequence(QtGui.QKeySequence.Print)
386 printkey = QtGui.QKeySequence(QtGui.QKeySequence.Print)
387 if printkey.matches("Ctrl+P") and sys.platform != 'darwin':
387 if printkey.matches("Ctrl+P") and sys.platform != 'darwin':
388 # Only override the default if there is a collision.
388 # Only override the default if there is a collision.
389 # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
389 # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
390 printkey = "Ctrl+Shift+P"
390 printkey = "Ctrl+Shift+P"
391 self.print_action = QtGui.QAction("&Print",
391 self.print_action = QtGui.QAction("&Print",
392 self,
392 self,
393 shortcut=printkey,
393 shortcut=printkey,
394 triggered=self.print_action_active_frontend)
394 triggered=self.print_action_active_frontend)
395 self.add_menu_action(self.file_menu, self.print_action, True)
395 self.add_menu_action(self.file_menu, self.print_action, True)
396
396
397 if sys.platform != 'darwin':
397 if sys.platform != 'darwin':
398 # OSX always has Quit in the Application menu, only add it
398 # OSX always has Quit in the Application menu, only add it
399 # to the File menu elsewhere.
399 # to the File menu elsewhere.
400
400
401 self.file_menu.addSeparator()
401 self.file_menu.addSeparator()
402
402
403 self.quit_action = QtGui.QAction("&Quit",
403 self.quit_action = QtGui.QAction("&Quit",
404 self,
404 self,
405 shortcut=QtGui.QKeySequence.Quit,
405 shortcut=QtGui.QKeySequence.Quit,
406 triggered=self.close,
406 triggered=self.close,
407 )
407 )
408 self.add_menu_action(self.file_menu, self.quit_action)
408 self.add_menu_action(self.file_menu, self.quit_action)
409
409
410
410
411 def init_edit_menu(self):
411 def init_edit_menu(self):
412 self.edit_menu = self.menuBar().addMenu("&Edit")
412 self.edit_menu = self.menuBar().addMenu("&Edit")
413
413
414 self.undo_action = QtGui.QAction("&Undo",
414 self.undo_action = QtGui.QAction("&Undo",
415 self,
415 self,
416 shortcut=QtGui.QKeySequence.Undo,
416 shortcut=QtGui.QKeySequence.Undo,
417 statusTip="Undo last action if possible",
417 statusTip="Undo last action if possible",
418 triggered=self.undo_active_frontend
418 triggered=self.undo_active_frontend
419 )
419 )
420 self.add_menu_action(self.edit_menu, self.undo_action)
420 self.add_menu_action(self.edit_menu, self.undo_action)
421
421
422 self.redo_action = QtGui.QAction("&Redo",
422 self.redo_action = QtGui.QAction("&Redo",
423 self,
423 self,
424 shortcut=QtGui.QKeySequence.Redo,
424 shortcut=QtGui.QKeySequence.Redo,
425 statusTip="Redo last action if possible",
425 statusTip="Redo last action if possible",
426 triggered=self.redo_active_frontend)
426 triggered=self.redo_active_frontend)
427 self.add_menu_action(self.edit_menu, self.redo_action)
427 self.add_menu_action(self.edit_menu, self.redo_action)
428
428
429 self.edit_menu.addSeparator()
429 self.edit_menu.addSeparator()
430
430
431 self.cut_action = QtGui.QAction("&Cut",
431 self.cut_action = QtGui.QAction("&Cut",
432 self,
432 self,
433 shortcut=QtGui.QKeySequence.Cut,
433 shortcut=QtGui.QKeySequence.Cut,
434 triggered=self.cut_active_frontend
434 triggered=self.cut_active_frontend
435 )
435 )
436 self.add_menu_action(self.edit_menu, self.cut_action, True)
436 self.add_menu_action(self.edit_menu, self.cut_action, True)
437
437
438 self.copy_action = QtGui.QAction("&Copy",
438 self.copy_action = QtGui.QAction("&Copy",
439 self,
439 self,
440 shortcut=QtGui.QKeySequence.Copy,
440 shortcut=QtGui.QKeySequence.Copy,
441 triggered=self.copy_active_frontend
441 triggered=self.copy_active_frontend
442 )
442 )
443 self.add_menu_action(self.edit_menu, self.copy_action, True)
443 self.add_menu_action(self.edit_menu, self.copy_action, True)
444
444
445 self.copy_raw_action = QtGui.QAction("Copy (&Raw Text)",
445 self.copy_raw_action = QtGui.QAction("Copy (&Raw Text)",
446 self,
446 self,
447 shortcut="Ctrl+Shift+C",
447 shortcut="Ctrl+Shift+C",
448 triggered=self.copy_raw_active_frontend
448 triggered=self.copy_raw_active_frontend
449 )
449 )
450 self.add_menu_action(self.edit_menu, self.copy_raw_action, True)
450 self.add_menu_action(self.edit_menu, self.copy_raw_action, True)
451
451
452 self.paste_action = QtGui.QAction("&Paste",
452 self.paste_action = QtGui.QAction("&Paste",
453 self,
453 self,
454 shortcut=QtGui.QKeySequence.Paste,
454 shortcut=QtGui.QKeySequence.Paste,
455 triggered=self.paste_active_frontend
455 triggered=self.paste_active_frontend
456 )
456 )
457 self.add_menu_action(self.edit_menu, self.paste_action, True)
457 self.add_menu_action(self.edit_menu, self.paste_action, True)
458
458
459 self.edit_menu.addSeparator()
459 self.edit_menu.addSeparator()
460
460
461 selectall = QtGui.QKeySequence(QtGui.QKeySequence.SelectAll)
461 selectall = QtGui.QKeySequence(QtGui.QKeySequence.SelectAll)
462 if selectall.matches("Ctrl+A") and sys.platform != 'darwin':
462 if selectall.matches("Ctrl+A") and sys.platform != 'darwin':
463 # Only override the default if there is a collision.
463 # Only override the default if there is a collision.
464 # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
464 # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
465 selectall = "Ctrl+Shift+A"
465 selectall = "Ctrl+Shift+A"
466 self.select_all_action = QtGui.QAction("Select &All",
466 self.select_all_action = QtGui.QAction("Select &All",
467 self,
467 self,
468 shortcut=selectall,
468 shortcut=selectall,
469 triggered=self.select_all_active_frontend
469 triggered=self.select_all_active_frontend
470 )
470 )
471 self.add_menu_action(self.edit_menu, self.select_all_action, True)
471 self.add_menu_action(self.edit_menu, self.select_all_action, True)
472
472
473
473
474 def init_view_menu(self):
474 def init_view_menu(self):
475 self.view_menu = self.menuBar().addMenu("&View")
475 self.view_menu = self.menuBar().addMenu("&View")
476
476
477 if sys.platform != 'darwin':
477 if sys.platform != 'darwin':
478 # disable on OSX, where there is always a menu bar
478 # disable on OSX, where there is always a menu bar
479 self.toggle_menu_bar_act = QtGui.QAction("Toggle &Menu Bar",
479 self.toggle_menu_bar_act = QtGui.QAction("Toggle &Menu Bar",
480 self,
480 self,
481 shortcut="Ctrl+Shift+M",
481 shortcut="Ctrl+Shift+M",
482 statusTip="Toggle visibility of menubar",
482 statusTip="Toggle visibility of menubar",
483 triggered=self.toggle_menu_bar)
483 triggered=self.toggle_menu_bar)
484 self.add_menu_action(self.view_menu, self.toggle_menu_bar_act)
484 self.add_menu_action(self.view_menu, self.toggle_menu_bar_act)
485
485
486 fs_key = "Ctrl+Meta+F" if sys.platform == 'darwin' else "F11"
486 fs_key = "Ctrl+Meta+F" if sys.platform == 'darwin' else "F11"
487 self.full_screen_act = QtGui.QAction("&Full Screen",
487 self.full_screen_act = QtGui.QAction("&Full Screen",
488 self,
488 self,
489 shortcut=fs_key,
489 shortcut=fs_key,
490 statusTip="Toggle between Fullscreen and Normal Size",
490 statusTip="Toggle between Fullscreen and Normal Size",
491 triggered=self.toggleFullScreen)
491 triggered=self.toggleFullScreen)
492 self.add_menu_action(self.view_menu, self.full_screen_act)
492 self.add_menu_action(self.view_menu, self.full_screen_act)
493
493
494 self.view_menu.addSeparator()
494 self.view_menu.addSeparator()
495
495
496 self.increase_font_size = QtGui.QAction("Zoom &In",
496 self.increase_font_size = QtGui.QAction("Zoom &In",
497 self,
497 self,
498 shortcut=QtGui.QKeySequence.ZoomIn,
498 shortcut=QtGui.QKeySequence.ZoomIn,
499 triggered=self.increase_font_size_active_frontend
499 triggered=self.increase_font_size_active_frontend
500 )
500 )
501 self.add_menu_action(self.view_menu, self.increase_font_size, True)
501 self.add_menu_action(self.view_menu, self.increase_font_size, True)
502
502
503 self.decrease_font_size = QtGui.QAction("Zoom &Out",
503 self.decrease_font_size = QtGui.QAction("Zoom &Out",
504 self,
504 self,
505 shortcut=QtGui.QKeySequence.ZoomOut,
505 shortcut=QtGui.QKeySequence.ZoomOut,
506 triggered=self.decrease_font_size_active_frontend
506 triggered=self.decrease_font_size_active_frontend
507 )
507 )
508 self.add_menu_action(self.view_menu, self.decrease_font_size, True)
508 self.add_menu_action(self.view_menu, self.decrease_font_size, True)
509
509
510 self.reset_font_size = QtGui.QAction("Zoom &Reset",
510 self.reset_font_size = QtGui.QAction("Zoom &Reset",
511 self,
511 self,
512 shortcut="Ctrl+0",
512 shortcut="Ctrl+0",
513 triggered=self.reset_font_size_active_frontend
513 triggered=self.reset_font_size_active_frontend
514 )
514 )
515 self.add_menu_action(self.view_menu, self.reset_font_size, True)
515 self.add_menu_action(self.view_menu, self.reset_font_size, True)
516
516
517 self.view_menu.addSeparator()
517 self.view_menu.addSeparator()
518
518
519 self.clear_action = QtGui.QAction("&Clear Screen",
519 self.clear_action = QtGui.QAction("&Clear Screen",
520 self,
520 self,
521 shortcut='Ctrl+L',
521 shortcut='Ctrl+L',
522 statusTip="Clear the console",
522 statusTip="Clear the console",
523 triggered=self.clear_magic_active_frontend)
523 triggered=self.clear_magic_active_frontend)
524 self.add_menu_action(self.view_menu, self.clear_action)
524 self.add_menu_action(self.view_menu, self.clear_action)
525
525
526 def init_kernel_menu(self):
526 def init_kernel_menu(self):
527 self.kernel_menu = self.menuBar().addMenu("&Kernel")
527 self.kernel_menu = self.menuBar().addMenu("&Kernel")
528 # Qt on OSX maps Ctrl to Cmd, and Meta to Ctrl
528 # Qt on OSX maps Ctrl to Cmd, and Meta to Ctrl
529 # keep the signal shortcuts to ctrl, rather than
529 # keep the signal shortcuts to ctrl, rather than
530 # platform-default like we do elsewhere.
530 # platform-default like we do elsewhere.
531
531
532 ctrl = "Meta" if sys.platform == 'darwin' else "Ctrl"
532 ctrl = "Meta" if sys.platform == 'darwin' else "Ctrl"
533
533
534 self.interrupt_kernel_action = QtGui.QAction("Interrupt current Kernel",
534 self.interrupt_kernel_action = QtGui.QAction("Interrupt current Kernel",
535 self,
535 self,
536 triggered=self.interrupt_kernel_active_frontend,
536 triggered=self.interrupt_kernel_active_frontend,
537 shortcut=ctrl+"+C",
537 shortcut=ctrl+"+C",
538 )
538 )
539 self.add_menu_action(self.kernel_menu, self.interrupt_kernel_action)
539 self.add_menu_action(self.kernel_menu, self.interrupt_kernel_action)
540
540
541 self.restart_kernel_action = QtGui.QAction("Restart current Kernel",
541 self.restart_kernel_action = QtGui.QAction("Restart current Kernel",
542 self,
542 self,
543 triggered=self.restart_kernel_active_frontend,
543 triggered=self.restart_kernel_active_frontend,
544 shortcut=ctrl+"+.",
544 shortcut=ctrl+"+.",
545 )
545 )
546 self.add_menu_action(self.kernel_menu, self.restart_kernel_action)
546 self.add_menu_action(self.kernel_menu, self.restart_kernel_action)
547
547
548 self.kernel_menu.addSeparator()
548 self.kernel_menu.addSeparator()
549
549
550 def _make_dynamic_magic(self,magic):
550 def _make_dynamic_magic(self,magic):
551 """Return a function `fun` that will execute `magic` on active frontend.
551 """Return a function `fun` that will execute `magic` on active frontend.
552
552
553 Parameters
553 Parameters
554 ----------
554 ----------
555 magic : string
555 magic : string
556 string that will be executed as is when the returned function is called
556 string that will be executed as is when the returned function is called
557
557
558 Returns
558 Returns
559 -------
559 -------
560 fun : function
560 fun : function
561 function with no parameters, when called will execute `magic` on the
561 function with no parameters, when called will execute `magic` on the
562 current active frontend at call time
562 current active frontend at call time
563
563
564 See Also
564 See Also
565 --------
565 --------
566 populate_all_magic_menu : generate the "All Magics..." menu
566 populate_all_magic_menu : generate the "All Magics..." menu
567
567
568 Notes
568 Notes
569 -----
569 -----
570 `fun` execute `magic` an active frontend at the moment it is triggerd,
570 `fun` execute `magic` an active frontend at the moment it is triggerd,
571 not the active frontend at the moment it has been created.
571 not the active frontend at the moment it has been created.
572
572
573 This function is mostly used to create the "All Magics..." Menu at run time.
573 This function is mostly used to create the "All Magics..." Menu at run time.
574 """
574 """
575 # need to level nested function to be sure to past magic
575 # need to level nested function to be sure to past magic
576 # on active frontend **at run time**.
576 # on active frontend **at run time**.
577 def inner_dynamic_magic():
577 def inner_dynamic_magic():
578 self.active_frontend.execute(magic)
578 self.active_frontend.execute(magic)
579 inner_dynamic_magic.__name__ = "dynamics_magic_s"
579 inner_dynamic_magic.__name__ = "dynamics_magic_s"
580 return inner_dynamic_magic
580 return inner_dynamic_magic
581
581
582 def populate_all_magic_menu(self, listofmagic=None):
582 def populate_all_magic_menu(self, listofmagic=None):
583 """Clean "All Magics..." menu and repopulate it with `listofmagic`
583 """Clean "All Magics..." menu and repopulate it with `listofmagic`
584
584
585 Parameters
585 Parameters
586 ----------
586 ----------
587 listofmagic : string,
587 listofmagic : string,
588 repr() of a list of strings, send back by the kernel
588 repr() of a list of strings, send back by the kernel
589
589
590 Notes
590 Notes
591 -----
591 -----
592 `listofmagic`is a repr() of list because it is fed with the result of
592 `listofmagic`is a repr() of list because it is fed with the result of
593 a 'user_expression'
593 a 'user_expression'
594 """
594 """
595 alm_magic_menu = self.all_magic_menu
595 alm_magic_menu = self.all_magic_menu
596 alm_magic_menu.clear()
596 alm_magic_menu.clear()
597
597
598 # list of protected magic that don't like to be called without argument
598 # list of protected magic that don't like to be called without argument
599 # append '?' to the end to print the docstring when called from the menu
599 # append '?' to the end to print the docstring when called from the menu
600 protected_magic = set(["more","less","load_ext","pycat","loadpy","save"])
600 protected_magic = set(["more","less","load_ext","pycat","loadpy","load","save"])
601 magics=re.findall('\w+', listofmagic)
601 magics=re.findall('\w+', listofmagic)
602 for magic in magics:
602 for magic in magics:
603 if magic in protected_magic:
603 if magic in protected_magic:
604 pmagic = '%s%s%s'%('%',magic,'?')
604 pmagic = '%s%s%s'%('%',magic,'?')
605 else:
605 else:
606 pmagic = '%s%s'%('%',magic)
606 pmagic = '%s%s'%('%',magic)
607 xaction = QtGui.QAction(pmagic,
607 xaction = QtGui.QAction(pmagic,
608 self,
608 self,
609 triggered=self._make_dynamic_magic(pmagic)
609 triggered=self._make_dynamic_magic(pmagic)
610 )
610 )
611 alm_magic_menu.addAction(xaction)
611 alm_magic_menu.addAction(xaction)
612
612
613 def update_all_magic_menu(self):
613 def update_all_magic_menu(self):
614 """ Update the list on magic in the "All Magics..." Menu
614 """ Update the list on magic in the "All Magics..." Menu
615
615
616 Request the kernel with the list of availlable magic and populate the
616 Request the kernel with the list of availlable magic and populate the
617 menu with the list received back
617 menu with the list received back
618
618
619 """
619 """
620 # first define a callback which will get the list of all magic and put it in the menu.
620 # first define a callback which will get the list of all magic and put it in the menu.
621 self.active_frontend._silent_exec_callback('get_ipython().lsmagic()', self.populate_all_magic_menu)
621 self.active_frontend._silent_exec_callback('get_ipython().lsmagic()', self.populate_all_magic_menu)
622
622
623 def init_magic_menu(self):
623 def init_magic_menu(self):
624 self.magic_menu = self.menuBar().addMenu("&Magic")
624 self.magic_menu = self.menuBar().addMenu("&Magic")
625 self.all_magic_menu = self.magic_menu.addMenu("&All Magics")
625 self.all_magic_menu = self.magic_menu.addMenu("&All Magics")
626
626
627 # This action should usually not appear as it will be cleared when menu
627 # This action should usually not appear as it will be cleared when menu
628 # is updated at first kernel response. Though, it is necessary when
628 # is updated at first kernel response. Though, it is necessary when
629 # connecting through X-forwarding, as in this case, the menu is not
629 # connecting through X-forwarding, as in this case, the menu is not
630 # auto updated, SO DO NOT DELETE.
630 # auto updated, SO DO NOT DELETE.
631 self.pop = QtGui.QAction("&Update All Magic Menu ",
631 self.pop = QtGui.QAction("&Update All Magic Menu ",
632 self, triggered=self.update_all_magic_menu)
632 self, triggered=self.update_all_magic_menu)
633 self.add_menu_action(self.all_magic_menu, self.pop)
633 self.add_menu_action(self.all_magic_menu, self.pop)
634 # we need to populate the 'Magic Menu' once the kernel has answer at
634 # we need to populate the 'Magic Menu' once the kernel has answer at
635 # least once let's do it immedialy, but it's assured to works
635 # least once let's do it immedialy, but it's assured to works
636 self.pop.trigger()
636 self.pop.trigger()
637
637
638 self.reset_action = QtGui.QAction("&Reset",
638 self.reset_action = QtGui.QAction("&Reset",
639 self,
639 self,
640 statusTip="Clear all varible from workspace",
640 statusTip="Clear all varible from workspace",
641 triggered=self.reset_magic_active_frontend)
641 triggered=self.reset_magic_active_frontend)
642 self.add_menu_action(self.magic_menu, self.reset_action)
642 self.add_menu_action(self.magic_menu, self.reset_action)
643
643
644 self.history_action = QtGui.QAction("&History",
644 self.history_action = QtGui.QAction("&History",
645 self,
645 self,
646 statusTip="show command history",
646 statusTip="show command history",
647 triggered=self.history_magic_active_frontend)
647 triggered=self.history_magic_active_frontend)
648 self.add_menu_action(self.magic_menu, self.history_action)
648 self.add_menu_action(self.magic_menu, self.history_action)
649
649
650 self.save_action = QtGui.QAction("E&xport History ",
650 self.save_action = QtGui.QAction("E&xport History ",
651 self,
651 self,
652 statusTip="Export History as Python File",
652 statusTip="Export History as Python File",
653 triggered=self.save_magic_active_frontend)
653 triggered=self.save_magic_active_frontend)
654 self.add_menu_action(self.magic_menu, self.save_action)
654 self.add_menu_action(self.magic_menu, self.save_action)
655
655
656 self.who_action = QtGui.QAction("&Who",
656 self.who_action = QtGui.QAction("&Who",
657 self,
657 self,
658 statusTip="List interactive variable",
658 statusTip="List interactive variable",
659 triggered=self.who_magic_active_frontend)
659 triggered=self.who_magic_active_frontend)
660 self.add_menu_action(self.magic_menu, self.who_action)
660 self.add_menu_action(self.magic_menu, self.who_action)
661
661
662 self.who_ls_action = QtGui.QAction("Wh&o ls",
662 self.who_ls_action = QtGui.QAction("Wh&o ls",
663 self,
663 self,
664 statusTip="Return a list of interactive variable",
664 statusTip="Return a list of interactive variable",
665 triggered=self.who_ls_magic_active_frontend)
665 triggered=self.who_ls_magic_active_frontend)
666 self.add_menu_action(self.magic_menu, self.who_ls_action)
666 self.add_menu_action(self.magic_menu, self.who_ls_action)
667
667
668 self.whos_action = QtGui.QAction("Who&s",
668 self.whos_action = QtGui.QAction("Who&s",
669 self,
669 self,
670 statusTip="List interactive variable with detail",
670 statusTip="List interactive variable with detail",
671 triggered=self.whos_magic_active_frontend)
671 triggered=self.whos_magic_active_frontend)
672 self.add_menu_action(self.magic_menu, self.whos_action)
672 self.add_menu_action(self.magic_menu, self.whos_action)
673
673
674 def init_window_menu(self):
674 def init_window_menu(self):
675 self.window_menu = self.menuBar().addMenu("&Window")
675 self.window_menu = self.menuBar().addMenu("&Window")
676 if sys.platform == 'darwin':
676 if sys.platform == 'darwin':
677 # add min/maximize actions to OSX, which lacks default bindings.
677 # add min/maximize actions to OSX, which lacks default bindings.
678 self.minimizeAct = QtGui.QAction("Mini&mize",
678 self.minimizeAct = QtGui.QAction("Mini&mize",
679 self,
679 self,
680 shortcut="Ctrl+m",
680 shortcut="Ctrl+m",
681 statusTip="Minimize the window/Restore Normal Size",
681 statusTip="Minimize the window/Restore Normal Size",
682 triggered=self.toggleMinimized)
682 triggered=self.toggleMinimized)
683 # maximize is called 'Zoom' on OSX for some reason
683 # maximize is called 'Zoom' on OSX for some reason
684 self.maximizeAct = QtGui.QAction("&Zoom",
684 self.maximizeAct = QtGui.QAction("&Zoom",
685 self,
685 self,
686 shortcut="Ctrl+Shift+M",
686 shortcut="Ctrl+Shift+M",
687 statusTip="Maximize the window/Restore Normal Size",
687 statusTip="Maximize the window/Restore Normal Size",
688 triggered=self.toggleMaximized)
688 triggered=self.toggleMaximized)
689
689
690 self.add_menu_action(self.window_menu, self.minimizeAct)
690 self.add_menu_action(self.window_menu, self.minimizeAct)
691 self.add_menu_action(self.window_menu, self.maximizeAct)
691 self.add_menu_action(self.window_menu, self.maximizeAct)
692 self.window_menu.addSeparator()
692 self.window_menu.addSeparator()
693
693
694 prev_key = "Ctrl+Shift+Left" if sys.platform == 'darwin' else "Ctrl+PgUp"
694 prev_key = "Ctrl+Shift+Left" if sys.platform == 'darwin' else "Ctrl+PgUp"
695 self.prev_tab_act = QtGui.QAction("Pre&vious Tab",
695 self.prev_tab_act = QtGui.QAction("Pre&vious Tab",
696 self,
696 self,
697 shortcut=prev_key,
697 shortcut=prev_key,
698 statusTip="Select previous tab",
698 statusTip="Select previous tab",
699 triggered=self.prev_tab)
699 triggered=self.prev_tab)
700 self.add_menu_action(self.window_menu, self.prev_tab_act)
700 self.add_menu_action(self.window_menu, self.prev_tab_act)
701
701
702 next_key = "Ctrl+Shift+Right" if sys.platform == 'darwin' else "Ctrl+PgDown"
702 next_key = "Ctrl+Shift+Right" if sys.platform == 'darwin' else "Ctrl+PgDown"
703 self.next_tab_act = QtGui.QAction("Ne&xt Tab",
703 self.next_tab_act = QtGui.QAction("Ne&xt Tab",
704 self,
704 self,
705 shortcut=next_key,
705 shortcut=next_key,
706 statusTip="Select next tab",
706 statusTip="Select next tab",
707 triggered=self.next_tab)
707 triggered=self.next_tab)
708 self.add_menu_action(self.window_menu, self.next_tab_act)
708 self.add_menu_action(self.window_menu, self.next_tab_act)
709
709
710 def init_help_menu(self):
710 def init_help_menu(self):
711 # please keep the Help menu in Mac Os even if empty. It will
711 # please keep the Help menu in Mac Os even if empty. It will
712 # automatically contain a search field to search inside menus and
712 # automatically contain a search field to search inside menus and
713 # please keep it spelled in English, as long as Qt Doesn't support
713 # please keep it spelled in English, as long as Qt Doesn't support
714 # a QAction.MenuRole like HelpMenuRole otherwise it will loose
714 # a QAction.MenuRole like HelpMenuRole otherwise it will loose
715 # this search field fonctionality
715 # this search field fonctionality
716
716
717 self.help_menu = self.menuBar().addMenu("&Help")
717 self.help_menu = self.menuBar().addMenu("&Help")
718
718
719
719
720 # Help Menu
720 # Help Menu
721
721
722 self.intro_active_frontend_action = QtGui.QAction("&Intro to IPython",
722 self.intro_active_frontend_action = QtGui.QAction("&Intro to IPython",
723 self,
723 self,
724 triggered=self.intro_active_frontend
724 triggered=self.intro_active_frontend
725 )
725 )
726 self.add_menu_action(self.help_menu, self.intro_active_frontend_action)
726 self.add_menu_action(self.help_menu, self.intro_active_frontend_action)
727
727
728 self.quickref_active_frontend_action = QtGui.QAction("IPython &Cheat Sheet",
728 self.quickref_active_frontend_action = QtGui.QAction("IPython &Cheat Sheet",
729 self,
729 self,
730 triggered=self.quickref_active_frontend
730 triggered=self.quickref_active_frontend
731 )
731 )
732 self.add_menu_action(self.help_menu, self.quickref_active_frontend_action)
732 self.add_menu_action(self.help_menu, self.quickref_active_frontend_action)
733
733
734 self.guiref_active_frontend_action = QtGui.QAction("&Qt Console",
734 self.guiref_active_frontend_action = QtGui.QAction("&Qt Console",
735 self,
735 self,
736 triggered=self.guiref_active_frontend
736 triggered=self.guiref_active_frontend
737 )
737 )
738 self.add_menu_action(self.help_menu, self.guiref_active_frontend_action)
738 self.add_menu_action(self.help_menu, self.guiref_active_frontend_action)
739
739
740 self.onlineHelpAct = QtGui.QAction("Open Online &Help",
740 self.onlineHelpAct = QtGui.QAction("Open Online &Help",
741 self,
741 self,
742 triggered=self._open_online_help)
742 triggered=self._open_online_help)
743 self.add_menu_action(self.help_menu, self.onlineHelpAct)
743 self.add_menu_action(self.help_menu, self.onlineHelpAct)
744
744
745 # minimize/maximize/fullscreen actions:
745 # minimize/maximize/fullscreen actions:
746
746
747 def toggle_menu_bar(self):
747 def toggle_menu_bar(self):
748 menu_bar = self.menuBar()
748 menu_bar = self.menuBar()
749 if menu_bar.isVisible():
749 if menu_bar.isVisible():
750 menu_bar.setVisible(False)
750 menu_bar.setVisible(False)
751 else:
751 else:
752 menu_bar.setVisible(True)
752 menu_bar.setVisible(True)
753
753
754 def toggleMinimized(self):
754 def toggleMinimized(self):
755 if not self.isMinimized():
755 if not self.isMinimized():
756 self.showMinimized()
756 self.showMinimized()
757 else:
757 else:
758 self.showNormal()
758 self.showNormal()
759
759
760 def _open_online_help(self):
760 def _open_online_help(self):
761 filename="http://ipython.org/ipython-doc/stable/index.html"
761 filename="http://ipython.org/ipython-doc/stable/index.html"
762 webbrowser.open(filename, new=1, autoraise=True)
762 webbrowser.open(filename, new=1, autoraise=True)
763
763
764 def toggleMaximized(self):
764 def toggleMaximized(self):
765 if not self.isMaximized():
765 if not self.isMaximized():
766 self.showMaximized()
766 self.showMaximized()
767 else:
767 else:
768 self.showNormal()
768 self.showNormal()
769
769
770 # Min/Max imizing while in full screen give a bug
770 # Min/Max imizing while in full screen give a bug
771 # when going out of full screen, at least on OSX
771 # when going out of full screen, at least on OSX
772 def toggleFullScreen(self):
772 def toggleFullScreen(self):
773 if not self.isFullScreen():
773 if not self.isFullScreen():
774 self.showFullScreen()
774 self.showFullScreen()
775 if sys.platform == 'darwin':
775 if sys.platform == 'darwin':
776 self.maximizeAct.setEnabled(False)
776 self.maximizeAct.setEnabled(False)
777 self.minimizeAct.setEnabled(False)
777 self.minimizeAct.setEnabled(False)
778 else:
778 else:
779 self.showNormal()
779 self.showNormal()
780 if sys.platform == 'darwin':
780 if sys.platform == 'darwin':
781 self.maximizeAct.setEnabled(True)
781 self.maximizeAct.setEnabled(True)
782 self.minimizeAct.setEnabled(True)
782 self.minimizeAct.setEnabled(True)
783
783
784 def close_active_frontend(self):
784 def close_active_frontend(self):
785 self.close_tab(self.active_frontend)
785 self.close_tab(self.active_frontend)
786
786
787 def restart_kernel_active_frontend(self):
787 def restart_kernel_active_frontend(self):
788 self.active_frontend.request_restart_kernel()
788 self.active_frontend.request_restart_kernel()
789
789
790 def interrupt_kernel_active_frontend(self):
790 def interrupt_kernel_active_frontend(self):
791 self.active_frontend.request_interrupt_kernel()
791 self.active_frontend.request_interrupt_kernel()
792
792
793 def cut_active_frontend(self):
793 def cut_active_frontend(self):
794 widget = self.active_frontend
794 widget = self.active_frontend
795 if widget.can_cut():
795 if widget.can_cut():
796 widget.cut()
796 widget.cut()
797
797
798 def copy_active_frontend(self):
798 def copy_active_frontend(self):
799 widget = self.active_frontend
799 widget = self.active_frontend
800 widget.copy()
800 widget.copy()
801
801
802 def copy_raw_active_frontend(self):
802 def copy_raw_active_frontend(self):
803 self.active_frontend._copy_raw_action.trigger()
803 self.active_frontend._copy_raw_action.trigger()
804
804
805 def paste_active_frontend(self):
805 def paste_active_frontend(self):
806 widget = self.active_frontend
806 widget = self.active_frontend
807 if widget.can_paste():
807 if widget.can_paste():
808 widget.paste()
808 widget.paste()
809
809
810 def undo_active_frontend(self):
810 def undo_active_frontend(self):
811 self.active_frontend.undo()
811 self.active_frontend.undo()
812
812
813 def redo_active_frontend(self):
813 def redo_active_frontend(self):
814 self.active_frontend.redo()
814 self.active_frontend.redo()
815
815
816 def reset_magic_active_frontend(self):
816 def reset_magic_active_frontend(self):
817 self.active_frontend.execute("%reset")
817 self.active_frontend.execute("%reset")
818
818
819 def history_magic_active_frontend(self):
819 def history_magic_active_frontend(self):
820 self.active_frontend.execute("%history")
820 self.active_frontend.execute("%history")
821
821
822 def save_magic_active_frontend(self):
822 def save_magic_active_frontend(self):
823 self.active_frontend.save_magic()
823 self.active_frontend.save_magic()
824
824
825 def clear_magic_active_frontend(self):
825 def clear_magic_active_frontend(self):
826 self.active_frontend.execute("%clear")
826 self.active_frontend.execute("%clear")
827
827
828 def who_magic_active_frontend(self):
828 def who_magic_active_frontend(self):
829 self.active_frontend.execute("%who")
829 self.active_frontend.execute("%who")
830
830
831 def who_ls_magic_active_frontend(self):
831 def who_ls_magic_active_frontend(self):
832 self.active_frontend.execute("%who_ls")
832 self.active_frontend.execute("%who_ls")
833
833
834 def whos_magic_active_frontend(self):
834 def whos_magic_active_frontend(self):
835 self.active_frontend.execute("%whos")
835 self.active_frontend.execute("%whos")
836
836
837 def print_action_active_frontend(self):
837 def print_action_active_frontend(self):
838 self.active_frontend.print_action.trigger()
838 self.active_frontend.print_action.trigger()
839
839
840 def export_action_active_frontend(self):
840 def export_action_active_frontend(self):
841 self.active_frontend.export_action.trigger()
841 self.active_frontend.export_action.trigger()
842
842
843 def select_all_active_frontend(self):
843 def select_all_active_frontend(self):
844 self.active_frontend.select_all_action.trigger()
844 self.active_frontend.select_all_action.trigger()
845
845
846 def increase_font_size_active_frontend(self):
846 def increase_font_size_active_frontend(self):
847 self.active_frontend.increase_font_size.trigger()
847 self.active_frontend.increase_font_size.trigger()
848
848
849 def decrease_font_size_active_frontend(self):
849 def decrease_font_size_active_frontend(self):
850 self.active_frontend.decrease_font_size.trigger()
850 self.active_frontend.decrease_font_size.trigger()
851
851
852 def reset_font_size_active_frontend(self):
852 def reset_font_size_active_frontend(self):
853 self.active_frontend.reset_font_size.trigger()
853 self.active_frontend.reset_font_size.trigger()
854
854
855 def guiref_active_frontend(self):
855 def guiref_active_frontend(self):
856 self.active_frontend.execute("%guiref")
856 self.active_frontend.execute("%guiref")
857
857
858 def intro_active_frontend(self):
858 def intro_active_frontend(self):
859 self.active_frontend.execute("?")
859 self.active_frontend.execute("?")
860
860
861 def quickref_active_frontend(self):
861 def quickref_active_frontend(self):
862 self.active_frontend.execute("%quickref")
862 self.active_frontend.execute("%quickref")
863 #---------------------------------------------------------------------------
863 #---------------------------------------------------------------------------
864 # QWidget interface
864 # QWidget interface
865 #---------------------------------------------------------------------------
865 #---------------------------------------------------------------------------
866
866
867 def closeEvent(self, event):
867 def closeEvent(self, event):
868 """ Forward the close event to every tabs contained by the windows
868 """ Forward the close event to every tabs contained by the windows
869 """
869 """
870 if self.tab_widget.count() == 0:
870 if self.tab_widget.count() == 0:
871 # no tabs, just close
871 # no tabs, just close
872 event.accept()
872 event.accept()
873 return
873 return
874 # Do Not loop on the widget count as it change while closing
874 # Do Not loop on the widget count as it change while closing
875 title = self.window().windowTitle()
875 title = self.window().windowTitle()
876 cancel = QtGui.QMessageBox.Cancel
876 cancel = QtGui.QMessageBox.Cancel
877 okay = QtGui.QMessageBox.Ok
877 okay = QtGui.QMessageBox.Ok
878
878
879 if self.confirm_exit:
879 if self.confirm_exit:
880 if self.tab_widget.count() > 1:
880 if self.tab_widget.count() > 1:
881 msg = "Close all tabs, stop all kernels, and Quit?"
881 msg = "Close all tabs, stop all kernels, and Quit?"
882 else:
882 else:
883 msg = "Close console, stop kernel, and Quit?"
883 msg = "Close console, stop kernel, and Quit?"
884 info = "Kernels not started here (e.g. notebooks) will be left alone."
884 info = "Kernels not started here (e.g. notebooks) will be left alone."
885 closeall = QtGui.QPushButton("&Quit", self)
885 closeall = QtGui.QPushButton("&Quit", self)
886 closeall.setShortcut('Q')
886 closeall.setShortcut('Q')
887 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
887 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
888 title, msg)
888 title, msg)
889 box.setInformativeText(info)
889 box.setInformativeText(info)
890 box.addButton(cancel)
890 box.addButton(cancel)
891 box.addButton(closeall, QtGui.QMessageBox.YesRole)
891 box.addButton(closeall, QtGui.QMessageBox.YesRole)
892 box.setDefaultButton(closeall)
892 box.setDefaultButton(closeall)
893 box.setEscapeButton(cancel)
893 box.setEscapeButton(cancel)
894 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
894 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
895 box.setIconPixmap(pixmap)
895 box.setIconPixmap(pixmap)
896 reply = box.exec_()
896 reply = box.exec_()
897 else:
897 else:
898 reply = okay
898 reply = okay
899
899
900 if reply == cancel:
900 if reply == cancel:
901 event.ignore()
901 event.ignore()
902 return
902 return
903 if reply == okay:
903 if reply == okay:
904 while self.tab_widget.count() >= 1:
904 while self.tab_widget.count() >= 1:
905 # prevent further confirmations:
905 # prevent further confirmations:
906 widget = self.active_frontend
906 widget = self.active_frontend
907 widget._confirm_exit = False
907 widget._confirm_exit = False
908 self.close_tab(widget)
908 self.close_tab(widget)
909 event.accept()
909 event.accept()
910
910
@@ -1,192 +1,192 b''
1 """
1 """
2 Tools to open .py files as Unicode, using the encoding specified within the file,
2 Tools to open .py files as Unicode, using the encoding specified within the file,
3 as per PEP 263.
3 as per PEP 263.
4
4
5 Much of the code is taken from the tokenize module in Python 3.2.
5 Much of the code is taken from the tokenize module in Python 3.2.
6 """
6 """
7 from __future__ import absolute_import
7 from __future__ import absolute_import
8
8
9 import __builtin__
10 import io
9 import io
11 from io import TextIOWrapper
10 from io import TextIOWrapper
12 import re
11 import re
13 import urllib
12 import urllib
14
13
15 cookie_re = re.compile(ur"coding[:=]\s*([-\w.]+)", re.UNICODE)
14 cookie_re = re.compile(ur"coding[:=]\s*([-\w.]+)", re.UNICODE)
16 cookie_comment_re = re.compile(ur"^\s*#.*coding[:=]\s*([-\w.]+)", re.UNICODE)
15 cookie_comment_re = re.compile(ur"^\s*#.*coding[:=]\s*([-\w.]+)", re.UNICODE)
17
16
18 try:
17 try:
19 # Available in Python 3
18 # Available in Python 3
20 from tokenize import detect_encoding
19 from tokenize import detect_encoding
21 except ImportError:
20 except ImportError:
22 from codecs import lookup, BOM_UTF8
21 from codecs import lookup, BOM_UTF8
23
22
24 # Copied from Python 3.2 tokenize
23 # Copied from Python 3.2 tokenize
25 def _get_normal_name(orig_enc):
24 def _get_normal_name(orig_enc):
26 """Imitates get_normal_name in tokenizer.c."""
25 """Imitates get_normal_name in tokenizer.c."""
27 # Only care about the first 12 characters.
26 # Only care about the first 12 characters.
28 enc = orig_enc[:12].lower().replace("_", "-")
27 enc = orig_enc[:12].lower().replace("_", "-")
29 if enc == "utf-8" or enc.startswith("utf-8-"):
28 if enc == "utf-8" or enc.startswith("utf-8-"):
30 return "utf-8"
29 return "utf-8"
31 if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
30 if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
32 enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
31 enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
33 return "iso-8859-1"
32 return "iso-8859-1"
34 return orig_enc
33 return orig_enc
35
34
36 # Copied from Python 3.2 tokenize
35 # Copied from Python 3.2 tokenize
37 def detect_encoding(readline):
36 def detect_encoding(readline):
38 """
37 """
39 The detect_encoding() function is used to detect the encoding that should
38 The detect_encoding() function is used to detect the encoding that should
40 be used to decode a Python source file. It requires one argment, readline,
39 be used to decode a Python source file. It requires one argment, readline,
41 in the same way as the tokenize() generator.
40 in the same way as the tokenize() generator.
42
41
43 It will call readline a maximum of twice, and return the encoding used
42 It will call readline a maximum of twice, and return the encoding used
44 (as a string) and a list of any lines (left as bytes) it has read in.
43 (as a string) and a list of any lines (left as bytes) it has read in.
45
44
46 It detects the encoding from the presence of a utf-8 bom or an encoding
45 It detects the encoding from the presence of a utf-8 bom or an encoding
47 cookie as specified in pep-0263. If both a bom and a cookie are present,
46 cookie as specified in pep-0263. If both a bom and a cookie are present,
48 but disagree, a SyntaxError will be raised. If the encoding cookie is an
47 but disagree, a SyntaxError will be raised. If the encoding cookie is an
49 invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
48 invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
50 'utf-8-sig' is returned.
49 'utf-8-sig' is returned.
51
50
52 If no encoding is specified, then the default of 'utf-8' will be returned.
51 If no encoding is specified, then the default of 'utf-8' will be returned.
53 """
52 """
54 bom_found = False
53 bom_found = False
55 encoding = None
54 encoding = None
56 default = 'utf-8'
55 default = 'utf-8'
57 def read_or_stop():
56 def read_or_stop():
58 try:
57 try:
59 return readline()
58 return readline()
60 except StopIteration:
59 except StopIteration:
61 return b''
60 return b''
62
61
63 def find_cookie(line):
62 def find_cookie(line):
64 try:
63 try:
65 line_string = line.decode('ascii')
64 line_string = line.decode('ascii')
66 except UnicodeDecodeError:
65 except UnicodeDecodeError:
67 return None
66 return None
68
67
69 matches = cookie_re.findall(line_string)
68 matches = cookie_re.findall(line_string)
70 if not matches:
69 if not matches:
71 return None
70 return None
72 encoding = _get_normal_name(matches[0])
71 encoding = _get_normal_name(matches[0])
73 try:
72 try:
74 codec = lookup(encoding)
73 codec = lookup(encoding)
75 except LookupError:
74 except LookupError:
76 # This behaviour mimics the Python interpreter
75 # This behaviour mimics the Python interpreter
77 raise SyntaxError("unknown encoding: " + encoding)
76 raise SyntaxError("unknown encoding: " + encoding)
78
77
79 if bom_found:
78 if bom_found:
80 if codec.name != 'utf-8':
79 if codec.name != 'utf-8':
81 # This behaviour mimics the Python interpreter
80 # This behaviour mimics the Python interpreter
82 raise SyntaxError('encoding problem: utf-8')
81 raise SyntaxError('encoding problem: utf-8')
83 encoding += '-sig'
82 encoding += '-sig'
84 return encoding
83 return encoding
85
84
86 first = read_or_stop()
85 first = read_or_stop()
87 if first.startswith(BOM_UTF8):
86 if first.startswith(BOM_UTF8):
88 bom_found = True
87 bom_found = True
89 first = first[3:]
88 first = first[3:]
90 default = 'utf-8-sig'
89 default = 'utf-8-sig'
91 if not first:
90 if not first:
92 return default, []
91 return default, []
93
92
94 encoding = find_cookie(first)
93 encoding = find_cookie(first)
95 if encoding:
94 if encoding:
96 return encoding, [first]
95 return encoding, [first]
97
96
98 second = read_or_stop()
97 second = read_or_stop()
99 if not second:
98 if not second:
100 return default, [first]
99 return default, [first]
101
100
102 encoding = find_cookie(second)
101 encoding = find_cookie(second)
103 if encoding:
102 if encoding:
104 return encoding, [first, second]
103 return encoding, [first, second]
105
104
106 return default, [first, second]
105 return default, [first, second]
107
106
108 try:
107 try:
109 # Available in Python 3.2 and above.
108 # Available in Python 3.2 and above.
110 from tokenize import open
109 from tokenize import open
111 except ImportError:
110 except ImportError:
112 # Copied from Python 3.2 tokenize
111 # Copied from Python 3.2 tokenize
113 def open(filename):
112 def open(filename):
114 """Open a file in read only mode using the encoding detected by
113 """Open a file in read only mode using the encoding detected by
115 detect_encoding().
114 detect_encoding().
116 """
115 """
117 buffer = io.open(filename, 'rb') # Tweaked to use io.open for Python 2
116 buffer = io.open(filename, 'rb') # Tweaked to use io.open for Python 2
118 encoding, lines = detect_encoding(buffer.readline)
117 encoding, lines = detect_encoding(buffer.readline)
119 buffer.seek(0)
118 buffer.seek(0)
120 text = TextIOWrapper(buffer, encoding, line_buffering=True)
119 text = TextIOWrapper(buffer, encoding, line_buffering=True)
121 text.mode = 'r'
120 text.mode = 'r'
122 return text
121 return text
123
122
124 def strip_encoding_cookie(filelike):
123 def strip_encoding_cookie(filelike):
125 """Generator to pull lines from a text-mode file, skipping the encoding
124 """Generator to pull lines from a text-mode file, skipping the encoding
126 cookie if it is found in the first two lines.
125 cookie if it is found in the first two lines.
127 """
126 """
128 it = iter(filelike)
127 it = iter(filelike)
129 try:
128 try:
130 first = next(it)
129 first = next(it)
131 if not cookie_comment_re.match(first):
130 if not cookie_comment_re.match(first):
132 yield first
131 yield first
133 second = next(it)
132 second = next(it)
134 if not cookie_comment_re.match(second):
133 if not cookie_comment_re.match(second):
135 yield second
134 yield second
136 except StopIteration:
135 except StopIteration:
137 return
136 return
138
137
139 for line in it:
138 for line in it:
140 yield line
139 yield line
141
140
142 def read_py_file(filename, skip_encoding_cookie=True):
141 def read_py_file(filename, skip_encoding_cookie=True):
143 """Read a Python file, using the encoding declared inside the file.
142 """Read a Python file, using the encoding declared inside the file.
144
143
145 Parameters
144 Parameters
146 ----------
145 ----------
147 filename : str
146 filename : str
148 The path to the file to read.
147 The path to the file to read.
149 skip_encoding_cookie : bool
148 skip_encoding_cookie : bool
150 If True (the default), and the encoding declaration is found in the first
149 If True (the default), and the encoding declaration is found in the first
151 two lines, that line will be excluded from the output - compiling a
150 two lines, that line will be excluded from the output - compiling a
152 unicode string with an encoding declaration is a SyntaxError in Python 2.
151 unicode string with an encoding declaration is a SyntaxError in Python 2.
153
152
154 Returns
153 Returns
155 -------
154 -------
156 A unicode string containing the contents of the file.
155 A unicode string containing the contents of the file.
157 """
156 """
158 with open(filename) as f: # the open function defined in this module.
157 with open(filename) as f: # the open function defined in this module.
159 if skip_encoding_cookie:
158 if skip_encoding_cookie:
160 return "".join(strip_encoding_cookie(f))
159 return "".join(strip_encoding_cookie(f))
161 else:
160 else:
162 return f.read()
161 return f.read()
163
162
164 def read_py_url(url, errors='replace', skip_encoding_cookie=True):
163 def read_py_url(url, errors='replace', skip_encoding_cookie=True):
165 """Read a Python file from a URL, using the encoding declared inside the file.
164 """Read a Python file from a URL, using the encoding declared inside the file.
166
165
167 Parameters
166 Parameters
168 ----------
167 ----------
169 url : str
168 url : str
170 The URL from which to fetch the file.
169 The URL from which to fetch the file.
171 errors : str
170 errors : str
172 How to handle decoding errors in the file. Options are the same as for
171 How to handle decoding errors in the file. Options are the same as for
173 bytes.decode(), but here 'replace' is the default.
172 bytes.decode(), but here 'replace' is the default.
174 skip_encoding_cookie : bool
173 skip_encoding_cookie : bool
175 If True (the default), and the encoding declaration is found in the first
174 If True (the default), and the encoding declaration is found in the first
176 two lines, that line will be excluded from the output - compiling a
175 two lines, that line will be excluded from the output - compiling a
177 unicode string with an encoding declaration is a SyntaxError in Python 2.
176 unicode string with an encoding declaration is a SyntaxError in Python 2.
178
177
179 Returns
178 Returns
180 -------
179 -------
181 A unicode string containing the contents of the file.
180 A unicode string containing the contents of the file.
182 """
181 """
183 response = urllib.urlopen(url)
182 response = urllib.urlopen(url)
184 buffer = io.BytesIO(response.read())
183 buffer = io.BytesIO(response.read())
185 encoding, lines = detect_encoding(buffer.readline)
184 encoding, lines = detect_encoding(buffer.readline)
186 buffer.seek(0)
185 buffer.seek(0)
187 text = TextIOWrapper(buffer, encoding, errors=errors, line_buffering=True)
186 text = TextIOWrapper(buffer, encoding, errors=errors, line_buffering=True)
188 text.mode = 'r'
187 text.mode = 'r'
189 if skip_encoding_cookie:
188 if skip_encoding_cookie:
190 return "".join(strip_encoding_cookie(text))
189 return "".join(strip_encoding_cookie(text))
191 else:
190 else:
192 return text.read()
191 return text.read()
192
@@ -1,1093 +1,1093 b''
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "name": "00_notebook_tour"
3 "name": "00_notebook_tour"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "worksheets": [
6 "worksheets": [
7 {
7 {
8 "cells": [
8 "cells": [
9 {
9 {
10 "cell_type": "markdown",
10 "cell_type": "markdown",
11 "source": [
11 "source": [
12 "# A brief tour of the IPython notebook",
12 "# A brief tour of the IPython notebook",
13 "",
13 "",
14 "This document will give you a brief tour of the capabilities of the IPython notebook. ",
14 "This document will give you a brief tour of the capabilities of the IPython notebook. ",
15 "You can view its contents by scrolling around, or execute each cell by typing `Shift-Enter`.",
15 "You can view its contents by scrolling around, or execute each cell by typing `Shift-Enter`.",
16 "After you conclude this brief high-level tour, you should read the accompanying notebook ",
16 "After you conclude this brief high-level tour, you should read the accompanying notebook ",
17 "titled `01_notebook_introduction`, which takes a more step-by-step approach to the features of the",
17 "titled `01_notebook_introduction`, which takes a more step-by-step approach to the features of the",
18 "system. ",
18 "system. ",
19 "",
19 "",
20 "The rest of the notebooks in this directory illustrate various other aspects and ",
20 "The rest of the notebooks in this directory illustrate various other aspects and ",
21 "capabilities of the IPython notebook; some of them may require additional libraries to be executed.",
21 "capabilities of the IPython notebook; some of them may require additional libraries to be executed.",
22 "",
22 "",
23 "**NOTE:** This notebook *must* be run from its own directory, so you must ``cd``",
23 "**NOTE:** This notebook *must* be run from its own directory, so you must ``cd``",
24 "to this directory and then start the notebook, but do *not* use the ``--notebook-dir``",
24 "to this directory and then start the notebook, but do *not* use the ``--notebook-dir``",
25 "option to run it from another location.",
25 "option to run it from another location.",
26 "",
26 "",
27 "The first thing you need to know is that you are still controlling the same old IPython you're used to,",
27 "The first thing you need to know is that you are still controlling the same old IPython you're used to,",
28 "so things like shell aliases and magic commands still work:"
28 "so things like shell aliases and magic commands still work:"
29 ]
29 ]
30 },
30 },
31 {
31 {
32 "cell_type": "code",
32 "cell_type": "code",
33 "collapsed": false,
33 "collapsed": false,
34 "input": [
34 "input": [
35 "pwd"
35 "pwd"
36 ],
36 ],
37 "language": "python",
37 "language": "python",
38 "outputs": [
38 "outputs": [
39 {
39 {
40 "output_type": "pyout",
40 "output_type": "pyout",
41 "prompt_number": 1,
41 "prompt_number": 1,
42 "text": [
42 "text": [
43 "u'/home/fperez/ipython/ipython/docs/examples/notebooks'"
43 "u'/home/fperez/ipython/ipython/docs/examples/notebooks'"
44 ]
44 ]
45 }
45 }
46 ],
46 ],
47 "prompt_number": 1
47 "prompt_number": 1
48 },
48 },
49 {
49 {
50 "cell_type": "code",
50 "cell_type": "code",
51 "collapsed": false,
51 "collapsed": false,
52 "input": [
52 "input": [
53 "ls"
53 "ls"
54 ],
54 ],
55 "language": "python",
55 "language": "python",
56 "outputs": [
56 "outputs": [
57 {
57 {
58 "output_type": "stream",
58 "output_type": "stream",
59 "stream": "stdout",
59 "stream": "stdout",
60 "text": [
60 "text": [
61 "00_notebook_tour.ipynb python-logo.svg",
61 "00_notebook_tour.ipynb python-logo.svg",
62 "01_notebook_introduction.ipynb sympy.ipynb",
62 "01_notebook_introduction.ipynb sympy.ipynb",
63 "animation.m4v sympy_quantum_computing.ipynb",
63 "animation.m4v sympy_quantum_computing.ipynb",
64 "display_protocol.ipynb trapezoid_rule.ipynb",
64 "display_protocol.ipynb trapezoid_rule.ipynb",
65 "formatting.ipynb"
65 "formatting.ipynb"
66 ]
66 ]
67 }
67 }
68 ],
68 ],
69 "prompt_number": 2
69 "prompt_number": 2
70 },
70 },
71 {
71 {
72 "cell_type": "code",
72 "cell_type": "code",
73 "collapsed": false,
73 "collapsed": false,
74 "input": [
74 "input": [
75 "message = 'The IPython notebook is great!'",
75 "message = 'The IPython notebook is great!'",
76 "# note: the echo command does not run on Windows, it's a unix command.",
76 "# note: the echo command does not run on Windows, it's a unix command.",
77 "!echo $message"
77 "!echo $message"
78 ],
78 ],
79 "language": "python",
79 "language": "python",
80 "outputs": [
80 "outputs": [
81 {
81 {
82 "output_type": "stream",
82 "output_type": "stream",
83 "stream": "stdout",
83 "stream": "stdout",
84 "text": [
84 "text": [
85 "The IPython notebook is great!"
85 "The IPython notebook is great!"
86 ]
86 ]
87 }
87 }
88 ],
88 ],
89 "prompt_number": 3
89 "prompt_number": 3
90 },
90 },
91 {
91 {
92 "cell_type": "markdown",
92 "cell_type": "markdown",
93 "source": [
93 "source": [
94 "Plots with matplotlib: do *not* execute the next below if you do not have matplotlib installed or didn't start up ",
94 "Plots with matplotlib: do *not* execute the next below if you do not have matplotlib installed or didn't start up ",
95 "this notebook with the `--pylab` option, as the code will not work."
95 "this notebook with the `--pylab` option, as the code will not work."
96 ]
96 ]
97 },
97 },
98 {
98 {
99 "cell_type": "code",
99 "cell_type": "code",
100 "collapsed": false,
100 "collapsed": false,
101 "input": [
101 "input": [
102 "x = linspace(0, 3*pi, 500)",
102 "x = linspace(0, 3*pi, 500)",
103 "plot(x, sin(x**2))",
103 "plot(x, sin(x**2))",
104 "title('A simple chirp');"
104 "title('A simple chirp');"
105 ],
105 ],
106 "language": "python",
106 "language": "python",
107 "outputs": [
107 "outputs": [
108 {
108 {
109 "output_type": "display_data",
109 "output_type": "display_data",
110 "png": "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\n"
110 "png": "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\n"
111 }
111 }
112 ],
112 ],
113 "prompt_number": 4
113 "prompt_number": 4
114 },
114 },
115 {
115 {
116 "cell_type": "markdown",
116 "cell_type": "markdown",
117 "source": [
117 "source": [
118 "You can paste blocks of input with prompt markers, such as those from",
118 "You can paste blocks of input with prompt markers, such as those from",
119 "[the official Python tutorial](http://docs.python.org/tutorial/interpreter.html#interactive-mode)"
119 "[the official Python tutorial](http://docs.python.org/tutorial/interpreter.html#interactive-mode)"
120 ]
120 ]
121 },
121 },
122 {
122 {
123 "cell_type": "code",
123 "cell_type": "code",
124 "collapsed": false,
124 "collapsed": false,
125 "input": [
125 "input": [
126 ">>> the_world_is_flat = 1",
126 ">>> the_world_is_flat = 1",
127 ">>> if the_world_is_flat:",
127 ">>> if the_world_is_flat:",
128 "... print \"Be careful not to fall off!\""
128 "... print \"Be careful not to fall off!\""
129 ],
129 ],
130 "language": "python",
130 "language": "python",
131 "outputs": [
131 "outputs": [
132 {
132 {
133 "output_type": "stream",
133 "output_type": "stream",
134 "stream": "stdout",
134 "stream": "stdout",
135 "text": [
135 "text": [
136 "Be careful not to fall off!"
136 "Be careful not to fall off!"
137 ]
137 ]
138 }
138 }
139 ],
139 ],
140 "prompt_number": 5
140 "prompt_number": 5
141 },
141 },
142 {
142 {
143 "cell_type": "markdown",
143 "cell_type": "markdown",
144 "source": [
144 "source": [
145 "Errors are shown in informative ways:"
145 "Errors are shown in informative ways:"
146 ]
146 ]
147 },
147 },
148 {
148 {
149 "cell_type": "code",
149 "cell_type": "code",
150 "collapsed": false,
150 "collapsed": false,
151 "input": [
151 "input": [
152 "%run non_existent_file"
152 "%run non_existent_file"
153 ],
153 ],
154 "language": "python",
154 "language": "python",
155 "outputs": [
155 "outputs": [
156 {
156 {
157 "output_type": "stream",
157 "output_type": "stream",
158 "stream": "stderr",
158 "stream": "stderr",
159 "text": [
159 "text": [
160 "ERROR: File `non_existent_file.py` not found."
160 "ERROR: File `non_existent_file.py` not found."
161 ]
161 ]
162 }
162 }
163 ],
163 ],
164 "prompt_number": 6
164 "prompt_number": 6
165 },
165 },
166 {
166 {
167 "cell_type": "code",
167 "cell_type": "code",
168 "collapsed": false,
168 "collapsed": false,
169 "input": [
169 "input": [
170 "x = 1",
170 "x = 1",
171 "y = 4",
171 "y = 4",
172 "z = y/(1-x)"
172 "z = y/(1-x)"
173 ],
173 ],
174 "language": "python",
174 "language": "python",
175 "outputs": [
175 "outputs": [
176 {
176 {
177 "ename": "ZeroDivisionError",
177 "ename": "ZeroDivisionError",
178 "evalue": "integer division or modulo by zero",
178 "evalue": "integer division or modulo by zero",
179 "output_type": "pyerr",
179 "output_type": "pyerr",
180 "traceback": [
180 "traceback": [
181 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
181 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
182 "\u001b[0;32m/home/fperez/ipython/ipython/docs/examples/notebooks/<ipython-input-7-dc39888fd1d2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mz\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
182 "\u001b[0;32m/home/fperez/ipython/ipython/docs/examples/notebooks/<ipython-input-7-dc39888fd1d2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mz\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
183 "\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
183 "\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
184 ]
184 ]
185 }
185 }
186 ],
186 ],
187 "prompt_number": 7
187 "prompt_number": 7
188 },
188 },
189 {
189 {
190 "cell_type": "markdown",
190 "cell_type": "markdown",
191 "source": [
191 "source": [
192 "When IPython needs to display additional information (such as providing details on an object via `x?`",
192 "When IPython needs to display additional information (such as providing details on an object via `x?`",
193 "it will automatically invoke a pager at the bottom of the screen:"
193 "it will automatically invoke a pager at the bottom of the screen:"
194 ]
194 ]
195 },
195 },
196 {
196 {
197 "cell_type": "code",
197 "cell_type": "code",
198 "collapsed": true,
198 "collapsed": true,
199 "input": [
199 "input": [
200 "magic"
200 "magic"
201 ],
201 ],
202 "language": "python",
202 "language": "python",
203 "outputs": [],
203 "outputs": [],
204 "prompt_number": 8
204 "prompt_number": 8
205 },
205 },
206 {
206 {
207 "cell_type": "markdown",
207 "cell_type": "markdown",
208 "source": [
208 "source": [
209 "## Non-blocking output of kernel",
209 "## Non-blocking output of kernel",
210 "",
210 "",
211 "If you execute the next cell, you will see the output arriving as it is generated, not all at the end."
211 "If you execute the next cell, you will see the output arriving as it is generated, not all at the end."
212 ]
212 ]
213 },
213 },
214 {
214 {
215 "cell_type": "code",
215 "cell_type": "code",
216 "collapsed": false,
216 "collapsed": false,
217 "input": [
217 "input": [
218 "import time, sys",
218 "import time, sys",
219 "for i in range(8):",
219 "for i in range(8):",
220 " print i,",
220 " print i,",
221 " time.sleep(0.5)"
221 " time.sleep(0.5)"
222 ],
222 ],
223 "language": "python",
223 "language": "python",
224 "outputs": [
224 "outputs": [
225 {
225 {
226 "output_type": "stream",
226 "output_type": "stream",
227 "stream": "stdout",
227 "stream": "stdout",
228 "text": [
228 "text": [
229 "0 "
229 "0 "
230 ]
230 ]
231 },
231 },
232 {
232 {
233 "output_type": "stream",
233 "output_type": "stream",
234 "stream": "stdout",
234 "stream": "stdout",
235 "text": [
235 "text": [
236 "1 "
236 "1 "
237 ]
237 ]
238 },
238 },
239 {
239 {
240 "output_type": "stream",
240 "output_type": "stream",
241 "stream": "stdout",
241 "stream": "stdout",
242 "text": [
242 "text": [
243 "2 "
243 "2 "
244 ]
244 ]
245 },
245 },
246 {
246 {
247 "output_type": "stream",
247 "output_type": "stream",
248 "stream": "stdout",
248 "stream": "stdout",
249 "text": [
249 "text": [
250 "3 "
250 "3 "
251 ]
251 ]
252 },
252 },
253 {
253 {
254 "output_type": "stream",
254 "output_type": "stream",
255 "stream": "stdout",
255 "stream": "stdout",
256 "text": [
256 "text": [
257 "4 "
257 "4 "
258 ]
258 ]
259 },
259 },
260 {
260 {
261 "output_type": "stream",
261 "output_type": "stream",
262 "stream": "stdout",
262 "stream": "stdout",
263 "text": [
263 "text": [
264 "5 "
264 "5 "
265 ]
265 ]
266 },
266 },
267 {
267 {
268 "output_type": "stream",
268 "output_type": "stream",
269 "stream": "stdout",
269 "stream": "stdout",
270 "text": [
270 "text": [
271 "6 "
271 "6 "
272 ]
272 ]
273 },
273 },
274 {
274 {
275 "output_type": "stream",
275 "output_type": "stream",
276 "stream": "stdout",
276 "stream": "stdout",
277 "text": [
277 "text": [
278 "7"
278 "7"
279 ]
279 ]
280 }
280 }
281 ],
281 ],
282 "prompt_number": 9
282 "prompt_number": 9
283 },
283 },
284 {
284 {
285 "cell_type": "markdown",
285 "cell_type": "markdown",
286 "source": [
286 "source": [
287 "## Clean crash and restart",
287 "## Clean crash and restart",
288 "",
288 "",
289 "We call the low-level system libc.time routine with the wrong argument via",
289 "We call the low-level system libc.time routine with the wrong argument via",
290 "ctypes to segfault the Python interpreter:"
290 "ctypes to segfault the Python interpreter:"
291 ]
291 ]
292 },
292 },
293 {
293 {
294 "cell_type": "code",
294 "cell_type": "code",
295 "collapsed": true,
295 "collapsed": true,
296 "input": [
296 "input": [
297 "from ctypes import CDLL",
297 "from ctypes import CDLL",
298 "# This will crash a linux system; equivalent calls can be made on Windows or Mac",
298 "# This will crash a linux system; equivalent calls can be made on Windows or Mac",
299 "libc = CDLL(\"libc.so.6\") ",
299 "libc = CDLL(\"libc.so.6\") ",
300 "libc.time(-1) # BOOM!!"
300 "libc.time(-1) # BOOM!!"
301 ],
301 ],
302 "language": "python",
302 "language": "python",
303 "outputs": [],
303 "outputs": [],
304 "prompt_number": "*"
304 "prompt_number": "*"
305 },
305 },
306 {
306 {
307 "cell_type": "markdown",
307 "cell_type": "markdown",
308 "source": [
308 "source": [
309 "## Markdown cells can contain formatted text and code",
309 "## Markdown cells can contain formatted text and code",
310 "",
310 "",
311 "You can *italicize*, **boldface**",
311 "You can *italicize*, **boldface**",
312 "",
312 "",
313 "* build",
313 "* build",
314 "* lists",
314 "* lists",
315 "",
315 "",
316 "and embed code meant for illustration instead of execution in Python:",
316 "and embed code meant for illustration instead of execution in Python:",
317 "",
317 "",
318 " def f(x):",
318 " def f(x):",
319 " \"\"\"a docstring\"\"\"",
319 " \"\"\"a docstring\"\"\"",
320 " return x**2",
320 " return x**2",
321 "",
321 "",
322 "or other languages:",
322 "or other languages:",
323 "",
323 "",
324 " if (i=0; i<n; i++) {",
324 " if (i=0; i<n; i++) {",
325 " printf(\"hello %d\\n\", i);",
325 " printf(\"hello %d\\n\", i);",
326 " x += 4;",
326 " x += 4;",
327 " }"
327 " }"
328 ]
328 ]
329 },
329 },
330 {
330 {
331 "cell_type": "markdown",
331 "cell_type": "markdown",
332 "source": [
332 "source": [
333 "Courtesy of MathJax, you can include mathematical expressions both inline: ",
333 "Courtesy of MathJax, you can include mathematical expressions both inline: ",
334 "$e^{i\\pi} + 1 = 0$ and displayed:",
334 "$e^{i\\pi} + 1 = 0$ and displayed:",
335 "",
335 "",
336 "$$e^x=\\sum_{i=0}^\\infty \\frac{1}{i!}x^i$$"
336 "$$e^x=\\sum_{i=0}^\\infty \\frac{1}{i!}x^i$$"
337 ]
337 ]
338 },
338 },
339 {
339 {
340 "cell_type": "markdown",
340 "cell_type": "markdown",
341 "source": [
341 "source": [
342 "## Rich displays: include anyting a browser can show",
342 "## Rich displays: include anyting a browser can show",
343 "",
343 "",
344 "Note that we have an actual protocol for this, see the `display_protocol` notebook for further details.",
344 "Note that we have an actual protocol for this, see the `display_protocol` notebook for further details.",
345 "",
345 "",
346 "### Images"
346 "### Images"
347 ]
347 ]
348 },
348 },
349 {
349 {
350 "cell_type": "code",
350 "cell_type": "code",
351 "collapsed": false,
351 "collapsed": false,
352 "input": [
352 "input": [
353 "from IPython.core.display import Image",
353 "from IPython.core.display import Image",
354 "Image(filename='../../source/_static/logo.png')"
354 "Image(filename='../../source/_static/logo.png')"
355 ],
355 ],
356 "language": "python",
356 "language": "python",
357 "outputs": [
357 "outputs": [
358 {
358 {
359 "output_type": "pyout",
359 "output_type": "pyout",
360 "png": "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\n",
360 "png": "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\n",
361 "prompt_number": 1,
361 "prompt_number": 1,
362 "text": [
362 "text": [
363 "&lt;IPython.core.display.Image at 0x41d4690&gt;"
363 "&lt;IPython.core.display.Image at 0x41d4690&gt;"
364 ]
364 ]
365 }
365 }
366 ],
366 ],
367 "prompt_number": 1
367 "prompt_number": 1
368 },
368 },
369 {
369 {
370 "cell_type": "markdown",
370 "cell_type": "markdown",
371 "source": [
371 "source": [
372 "An image can also be displayed from raw data or a url"
372 "An image can also be displayed from raw data or a url"
373 ]
373 ]
374 },
374 },
375 {
375 {
376 "cell_type": "code",
376 "cell_type": "code",
377 "collapsed": false,
377 "collapsed": false,
378 "input": [
378 "input": [
379 "Image('http://python.org/images/python-logo.gif')"
379 "Image('http://python.org/images/python-logo.gif')"
380 ],
380 ],
381 "language": "python",
381 "language": "python",
382 "outputs": [
382 "outputs": [
383 {
383 {
384 "html": [
384 "html": [
385 "<img src=\"http://python.org/images/python-logo.gif\" />"
385 "<img src=\"http://python.org/images/python-logo.gif\" />"
386 ],
386 ],
387 "output_type": "pyout",
387 "output_type": "pyout",
388 "prompt_number": 2,
388 "prompt_number": 2,
389 "text": [
389 "text": [
390 "&lt;IPython.core.display.Image at 0x41d4550&gt;"
390 "&lt;IPython.core.display.Image at 0x41d4550&gt;"
391 ]
391 ]
392 }
392 }
393 ],
393 ],
394 "prompt_number": 2
394 "prompt_number": 2
395 },
395 },
396 {
396 {
397 "cell_type": "markdown",
397 "cell_type": "markdown",
398 "source": [
398 "source": [
399 "SVG images are also supported out of the box (since modern browsers do a good job of rendering them):"
399 "SVG images are also supported out of the box (since modern browsers do a good job of rendering them):"
400 ]
400 ]
401 },
401 },
402 {
402 {
403 "cell_type": "code",
403 "cell_type": "code",
404 "collapsed": false,
404 "collapsed": false,
405 "input": [
405 "input": [
406 "from IPython.core.display import SVG",
406 "from IPython.core.display import SVG",
407 "SVG(filename='python-logo.svg')"
407 "SVG(filename='python-logo.svg')"
408 ],
408 ],
409 "language": "python",
409 "language": "python",
410 "outputs": [
410 "outputs": [
411 {
411 {
412 "output_type": "pyout",
412 "output_type": "pyout",
413 "prompt_number": 3,
413 "prompt_number": 3,
414 "svg": [
414 "svg": [
415 "<svg height=\"115.02pt\" id=\"svg2\" inkscape:version=\"0.43\" sodipodi:docbase=\"/home/sdeibel\" sodipodi:docname=\"logo-python-generic.svg\" sodipodi:version=\"0.32\" version=\"1.0\" width=\"388.84pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:cc=\"http://web.resource.org/cc/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:sodipodi=\"http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">",
415 "<svg height=\"115.02pt\" id=\"svg2\" inkscape:version=\"0.43\" sodipodi:docbase=\"/home/sdeibel\" sodipodi:docname=\"logo-python-generic.svg\" sodipodi:version=\"0.32\" version=\"1.0\" width=\"388.84pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:cc=\"http://web.resource.org/cc/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:sodipodi=\"http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">",
416 " <metadata id=\"metadata2193\">",
416 " <metadata id=\"metadata2193\">",
417 " <rdf:RDF>",
417 " <rdf:RDF>",
418 " <cc:Work rdf:about=\"\">",
418 " <cc:Work rdf:about=\"\">",
419 " <dc:format>image/svg+xml</dc:format>",
419 " <dc:format>image/svg+xml</dc:format>",
420 " <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>",
420 " <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>",
421 " </cc:Work>",
421 " </cc:Work>",
422 " </rdf:RDF>",
422 " </rdf:RDF>",
423 " </metadata>",
423 " </metadata>",
424 " <sodipodi:namedview bordercolor=\"#666666\" borderopacity=\"1.0\" id=\"base\" inkscape:current-layer=\"svg2\" inkscape:cx=\"243.02499\" inkscape:cy=\"71.887497\" inkscape:pageopacity=\"0.0\" inkscape:pageshadow=\"2\" inkscape:window-height=\"543\" inkscape:window-width=\"791\" inkscape:window-x=\"0\" inkscape:window-y=\"0\" inkscape:zoom=\"1.4340089\" pagecolor=\"#ffffff\"/>",
424 " <sodipodi:namedview bordercolor=\"#666666\" borderopacity=\"1.0\" id=\"base\" inkscape:current-layer=\"svg2\" inkscape:cx=\"243.02499\" inkscape:cy=\"71.887497\" inkscape:pageopacity=\"0.0\" inkscape:pageshadow=\"2\" inkscape:window-height=\"543\" inkscape:window-width=\"791\" inkscape:window-x=\"0\" inkscape:window-y=\"0\" inkscape:zoom=\"1.4340089\" pagecolor=\"#ffffff\"/>",
425 " <defs id=\"defs4\">",
425 " <defs id=\"defs4\">",
426 " <linearGradient id=\"linearGradient2795\">",
426 " <linearGradient id=\"linearGradient2795\">",
427 " <stop id=\"stop2797\" offset=\"0\" style=\"stop-color:#b8b8b8;stop-opacity:0.49803922\"/>",
427 " <stop id=\"stop2797\" offset=\"0\" style=\"stop-color:#b8b8b8;stop-opacity:0.49803922\"/>",
428 " <stop id=\"stop2799\" offset=\"1\" style=\"stop-color:#7f7f7f;stop-opacity:0\"/>",
428 " <stop id=\"stop2799\" offset=\"1\" style=\"stop-color:#7f7f7f;stop-opacity:0\"/>",
429 " </linearGradient>",
429 " </linearGradient>",
430 " <linearGradient id=\"linearGradient2787\">",
430 " <linearGradient id=\"linearGradient2787\">",
431 " <stop id=\"stop2789\" offset=\"0\" style=\"stop-color:#7f7f7f;stop-opacity:0.5\"/>",
431 " <stop id=\"stop2789\" offset=\"0\" style=\"stop-color:#7f7f7f;stop-opacity:0.5\"/>",
432 " <stop id=\"stop2791\" offset=\"1\" style=\"stop-color:#7f7f7f;stop-opacity:0\"/>",
432 " <stop id=\"stop2791\" offset=\"1\" style=\"stop-color:#7f7f7f;stop-opacity:0\"/>",
433 " </linearGradient>",
433 " </linearGradient>",
434 " <linearGradient id=\"linearGradient3676\">",
434 " <linearGradient id=\"linearGradient3676\">",
435 " <stop id=\"stop3678\" offset=\"0\" style=\"stop-color:#b2b2b2;stop-opacity:0.5\"/>",
435 " <stop id=\"stop3678\" offset=\"0\" style=\"stop-color:#b2b2b2;stop-opacity:0.5\"/>",
436 " <stop id=\"stop3680\" offset=\"1\" style=\"stop-color:#b3b3b3;stop-opacity:0\"/>",
436 " <stop id=\"stop3680\" offset=\"1\" style=\"stop-color:#b3b3b3;stop-opacity:0\"/>",
437 " </linearGradient>",
437 " </linearGradient>",
438 " <linearGradient id=\"linearGradient3236\">",
438 " <linearGradient id=\"linearGradient3236\">",
439 " <stop id=\"stop3244\" offset=\"0\" style=\"stop-color:#f4f4f4;stop-opacity:1\"/>",
439 " <stop id=\"stop3244\" offset=\"0\" style=\"stop-color:#f4f4f4;stop-opacity:1\"/>",
440 " <stop id=\"stop3240\" offset=\"1\" style=\"stop-color:#ffffff;stop-opacity:1\"/>",
440 " <stop id=\"stop3240\" offset=\"1\" style=\"stop-color:#ffffff;stop-opacity:1\"/>",
441 " </linearGradient>",
441 " </linearGradient>",
442 " <linearGradient id=\"linearGradient4671\">",
442 " <linearGradient id=\"linearGradient4671\">",
443 " <stop id=\"stop4673\" offset=\"0\" style=\"stop-color:#ffd43b;stop-opacity:1\"/>",
443 " <stop id=\"stop4673\" offset=\"0\" style=\"stop-color:#ffd43b;stop-opacity:1\"/>",
444 " <stop id=\"stop4675\" offset=\"1\" style=\"stop-color:#ffe873;stop-opacity:1\"/>",
444 " <stop id=\"stop4675\" offset=\"1\" style=\"stop-color:#ffe873;stop-opacity:1\"/>",
445 " </linearGradient>",
445 " </linearGradient>",
446 " <linearGradient id=\"linearGradient4689\">",
446 " <linearGradient id=\"linearGradient4689\">",
447 " <stop id=\"stop4691\" offset=\"0\" style=\"stop-color:#5a9fd4;stop-opacity:1\"/>",
447 " <stop id=\"stop4691\" offset=\"0\" style=\"stop-color:#5a9fd4;stop-opacity:1\"/>",
448 " <stop id=\"stop4693\" offset=\"1\" style=\"stop-color:#306998;stop-opacity:1\"/>",
448 " <stop id=\"stop4693\" offset=\"1\" style=\"stop-color:#306998;stop-opacity:1\"/>",
449 " </linearGradient>",
449 " </linearGradient>",
450 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2987\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
450 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2987\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
451 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2990\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"77.475983\" y2=\"76.313133\"/>",
451 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2990\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"77.475983\" y2=\"76.313133\"/>",
452 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2587\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"77.475983\" y2=\"76.313133\"/>",
452 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2587\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"77.475983\" y2=\"76.313133\"/>",
453 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2589\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
453 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2589\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
454 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2248\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"77.475983\" y2=\"76.313133\"/>",
454 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2248\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"77.475983\" y2=\"76.313133\"/>",
455 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2250\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
455 " <linearGradient gradientTransform=\"translate(100.2702,99.61116)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2250\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
456 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2255\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
456 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2255\" x1=\"224.23996\" x2=\"-65.308502\" xlink:href=\"#linearGradient4671\" y1=\"144.75717\" y2=\"144.75717\"/>",
457 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2258\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"76.176224\" y2=\"76.313133\"/>",
457 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient2258\" x1=\"172.94208\" x2=\"26.670298\" xlink:href=\"#linearGradient4689\" y1=\"76.176224\" y2=\"76.313133\"/>",
458 " <radialGradient cx=\"61.518883\" cy=\"132.28575\" fx=\"61.518883\" fy=\"132.28575\" gradientTransform=\"matrix(1,0,0,0.177966,0,108.7434)\" gradientUnits=\"userSpaceOnUse\" id=\"radialGradient2801\" r=\"29.036913\" xlink:href=\"#linearGradient2795\"/>",
458 " <radialGradient cx=\"61.518883\" cy=\"132.28575\" fx=\"61.518883\" fy=\"132.28575\" gradientTransform=\"matrix(1,0,0,0.177966,0,108.7434)\" gradientUnits=\"userSpaceOnUse\" id=\"radialGradient2801\" r=\"29.036913\" xlink:href=\"#linearGradient2795\"/>",
459 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient1475\" x1=\"150.96111\" x2=\"112.03144\" xlink:href=\"#linearGradient4671\" y1=\"192.35176\" y2=\"137.27299\"/>",
459 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient1475\" x1=\"150.96111\" x2=\"112.03144\" xlink:href=\"#linearGradient4671\" y1=\"192.35176\" y2=\"137.27299\"/>",
460 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient1478\" x1=\"26.648937\" x2=\"135.66525\" xlink:href=\"#linearGradient4689\" y1=\"20.603781\" y2=\"114.39767\"/>",
460 " <linearGradient gradientTransform=\"matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)\" gradientUnits=\"userSpaceOnUse\" id=\"linearGradient1478\" x1=\"26.648937\" x2=\"135.66525\" xlink:href=\"#linearGradient4689\" y1=\"20.603781\" y2=\"114.39767\"/>",
461 " <radialGradient cx=\"61.518883\" cy=\"132.28575\" fx=\"61.518883\" fy=\"132.28575\" gradientTransform=\"matrix(2.382716e-8,-0.296405,1.43676,4.683673e-7,-128.544,150.5202)\" gradientUnits=\"userSpaceOnUse\" id=\"radialGradient1480\" r=\"29.036913\" xlink:href=\"#linearGradient2795\"/>",
461 " <radialGradient cx=\"61.518883\" cy=\"132.28575\" fx=\"61.518883\" fy=\"132.28575\" gradientTransform=\"matrix(2.382716e-8,-0.296405,1.43676,4.683673e-7,-128.544,150.5202)\" gradientUnits=\"userSpaceOnUse\" id=\"radialGradient1480\" r=\"29.036913\" xlink:href=\"#linearGradient2795\"/>",
462 " </defs>",
462 " </defs>",
463 " <g id=\"g2303\">",
463 " <g id=\"g2303\">",
464 " <path d=\"M 184.61344,61.929363 C 184.61344,47.367213 180.46118,39.891193 172.15666,39.481813 C 168.85239,39.325863 165.62611,39.852203 162.48754,41.070593 C 159.98254,41.967323 158.2963,42.854313 157.40931,43.751043 L 157.40931,78.509163 C 162.72147,81.842673 167.43907,83.392453 171.55234,83.148783 C 180.25649,82.573703 184.61344,75.507063 184.61344,61.929363 z M 194.85763,62.533683 C 194.85763,69.931723 193.12265,76.072393 189.63319,80.955683 C 185.7441,86.482283 180.35396,89.328433 173.46277,89.484393 C 168.26757,89.650093 162.91642,88.022323 157.40931,84.610843 L 157.40931,116.20116 L 148.50047,113.02361 L 148.50047,42.903043 C 149.96253,41.109583 151.84372,39.569543 154.12454,38.263433 C 159.42696,35.173603 165.86978,33.584823 173.45302,33.506853 L 173.57973,33.633563 C 180.50991,33.545833 185.85132,36.391993 189.60395,42.162263 C 193.10315,47.454933 194.85763,54.238913 194.85763,62.533683 z \" id=\"path46\" style=\"fill:#646464;fill-opacity:1\"/>",
464 " <path d=\"M 184.61344,61.929363 C 184.61344,47.367213 180.46118,39.891193 172.15666,39.481813 C 168.85239,39.325863 165.62611,39.852203 162.48754,41.070593 C 159.98254,41.967323 158.2963,42.854313 157.40931,43.751043 L 157.40931,78.509163 C 162.72147,81.842673 167.43907,83.392453 171.55234,83.148783 C 180.25649,82.573703 184.61344,75.507063 184.61344,61.929363 z M 194.85763,62.533683 C 194.85763,69.931723 193.12265,76.072393 189.63319,80.955683 C 185.7441,86.482283 180.35396,89.328433 173.46277,89.484393 C 168.26757,89.650093 162.91642,88.022323 157.40931,84.610843 L 157.40931,116.20116 L 148.50047,113.02361 L 148.50047,42.903043 C 149.96253,41.109583 151.84372,39.569543 154.12454,38.263433 C 159.42696,35.173603 165.86978,33.584823 173.45302,33.506853 L 173.57973,33.633563 C 180.50991,33.545833 185.85132,36.391993 189.60395,42.162263 C 193.10315,47.454933 194.85763,54.238913 194.85763,62.533683 z \" id=\"path46\" style=\"fill:#646464;fill-opacity:1\"/>",
465 " <path d=\"M 249.30487,83.265743 C 249.30487,93.188283 248.31067,100.05998 246.32227,103.88084 C 244.32411,107.7017 240.52275,110.75254 234.90842,113.02361 C 230.35653,114.81707 225.43425,115.79178 220.15133,115.95748 L 218.67952,110.34316 C 224.05016,109.61213 227.83204,108.88109 230.02513,108.15006 C 234.34309,106.688 237.30621,104.44617 238.93397,101.44406 C 240.24008,98.997543 240.88339,94.328693 240.88339,87.418003 L 240.88339,85.098203 C 234.79146,87.866373 228.40711,89.240713 221.73036,89.240713 C 217.34417,89.240713 213.47457,87.866373 210.14107,85.098203 C 206.39818,82.086343 204.52674,78.265483 204.52674,73.635623 L 204.52674,36.557693 L 213.43558,33.506853 L 213.43558,70.828453 C 213.43558,74.815013 214.7222,77.885353 217.29543,80.039463 C 219.86866,82.193563 223.20217,83.226753 227.2862,83.148783 C 231.37023,83.061053 235.74667,81.482023 240.39603,78.392203 L 240.39603,34.851953 L 249.30487,34.851953 L 249.30487,83.265743 z \" id=\"path48\" style=\"fill:#646464;fill-opacity:1\"/>",
465 " <path d=\"M 249.30487,83.265743 C 249.30487,93.188283 248.31067,100.05998 246.32227,103.88084 C 244.32411,107.7017 240.52275,110.75254 234.90842,113.02361 C 230.35653,114.81707 225.43425,115.79178 220.15133,115.95748 L 218.67952,110.34316 C 224.05016,109.61213 227.83204,108.88109 230.02513,108.15006 C 234.34309,106.688 237.30621,104.44617 238.93397,101.44406 C 240.24008,98.997543 240.88339,94.328693 240.88339,87.418003 L 240.88339,85.098203 C 234.79146,87.866373 228.40711,89.240713 221.73036,89.240713 C 217.34417,89.240713 213.47457,87.866373 210.14107,85.098203 C 206.39818,82.086343 204.52674,78.265483 204.52674,73.635623 L 204.52674,36.557693 L 213.43558,33.506853 L 213.43558,70.828453 C 213.43558,74.815013 214.7222,77.885353 217.29543,80.039463 C 219.86866,82.193563 223.20217,83.226753 227.2862,83.148783 C 231.37023,83.061053 235.74667,81.482023 240.39603,78.392203 L 240.39603,34.851953 L 249.30487,34.851953 L 249.30487,83.265743 z \" id=\"path48\" style=\"fill:#646464;fill-opacity:1\"/>",
466 " <path d=\"M 284.08249,88.997033 C 283.02006,89.084753 282.04535,89.123743 281.14862,89.123743 C 276.10937,89.123743 272.18129,87.924853 269.37413,85.517323 C 266.57671,83.109793 265.17314,79.786033 265.17314,75.546053 L 265.17314,40.456523 L 259.07146,40.456523 L 259.07146,34.851953 L 265.17314,34.851953 L 265.17314,19.968143 L 274.07223,16.800333 L 274.07223,34.851953 L 284.08249,34.851953 L 284.08249,40.456523 L 274.07223,40.456523 L 274.07223,75.302373 C 274.07223,78.645623 274.96896,81.014163 276.76243,82.398253 C 278.30247,83.538663 280.74899,84.191723 284.08249,84.357423 L 284.08249,88.997033 z \" id=\"path50\" style=\"fill:#646464;fill-opacity:1\"/>",
466 " <path d=\"M 284.08249,88.997033 C 283.02006,89.084753 282.04535,89.123743 281.14862,89.123743 C 276.10937,89.123743 272.18129,87.924853 269.37413,85.517323 C 266.57671,83.109793 265.17314,79.786033 265.17314,75.546053 L 265.17314,40.456523 L 259.07146,40.456523 L 259.07146,34.851953 L 265.17314,34.851953 L 265.17314,19.968143 L 274.07223,16.800333 L 274.07223,34.851953 L 284.08249,34.851953 L 284.08249,40.456523 L 274.07223,40.456523 L 274.07223,75.302373 C 274.07223,78.645623 274.96896,81.014163 276.76243,82.398253 C 278.30247,83.538663 280.74899,84.191723 284.08249,84.357423 L 284.08249,88.997033 z \" id=\"path50\" style=\"fill:#646464;fill-opacity:1\"/>",
467 " <path d=\"M 338.02288,88.266003 L 329.11404,88.266003 L 329.11404,53.878273 C 329.11404,50.379063 328.29528,47.367213 326.66753,44.852463 C 324.78634,42.006313 322.17411,40.583233 318.82112,40.583233 C 314.73708,40.583233 309.6296,42.737343 303.4987,47.045563 L 303.4987,88.266003 L 294.58985,88.266003 L 294.58985,6.0687929 L 303.4987,3.2616329 L 303.4987,40.700203 C 309.191,36.557693 315.40963,34.481563 322.16436,34.481563 C 326.88196,34.481563 330.70282,36.070333 333.62694,39.238143 C 336.56082,42.405943 338.02288,46.353513 338.02288,51.071103 L 338.02288,88.266003 L 338.02288,88.266003 z \" id=\"path52\" style=\"fill:#646464;fill-opacity:1\"/>",
467 " <path d=\"M 338.02288,88.266003 L 329.11404,88.266003 L 329.11404,53.878273 C 329.11404,50.379063 328.29528,47.367213 326.66753,44.852463 C 324.78634,42.006313 322.17411,40.583233 318.82112,40.583233 C 314.73708,40.583233 309.6296,42.737343 303.4987,47.045563 L 303.4987,88.266003 L 294.58985,88.266003 L 294.58985,6.0687929 L 303.4987,3.2616329 L 303.4987,40.700203 C 309.191,36.557693 315.40963,34.481563 322.16436,34.481563 C 326.88196,34.481563 330.70282,36.070333 333.62694,39.238143 C 336.56082,42.405943 338.02288,46.353513 338.02288,51.071103 L 338.02288,88.266003 L 338.02288,88.266003 z \" id=\"path52\" style=\"fill:#646464;fill-opacity:1\"/>",
468 " <path d=\"M 385.37424,60.525783 C 385.37424,54.930953 384.31182,50.310833 382.19669,46.655673 C 379.68195,42.201253 375.77337,39.852203 370.49044,39.608523 C 360.72386,40.173863 355.85032,47.172273 355.85032,60.584263 C 355.85032,66.734683 356.86401,71.871393 358.91089,75.994413 C 361.52312,81.248093 365.44145,83.840823 370.66589,83.753103 C 380.47146,83.675123 385.37424,75.935933 385.37424,60.525783 z M 395.13109,60.584263 C 395.13109,68.547643 393.09395,75.175663 389.02941,80.468333 C 384.5555,86.394563 378.37584,89.367423 370.49044,89.367423 C 362.67328,89.367423 356.58135,86.394563 352.18541,80.468333 C 348.19885,75.175663 346.21044,68.547643 346.21044,60.584263 C 346.21044,53.098503 348.36455,46.801883 352.67276,41.674913 C 357.22466,36.236033 363.20937,33.506853 370.6074,33.506853 C 378.00545,33.506853 384.02914,36.236033 388.66877,41.674913 C 392.97697,46.801883 395.13109,53.098503 395.13109,60.584263 z \" id=\"path54\" style=\"fill:#646464;fill-opacity:1\"/>",
468 " <path d=\"M 385.37424,60.525783 C 385.37424,54.930953 384.31182,50.310833 382.19669,46.655673 C 379.68195,42.201253 375.77337,39.852203 370.49044,39.608523 C 360.72386,40.173863 355.85032,47.172273 355.85032,60.584263 C 355.85032,66.734683 356.86401,71.871393 358.91089,75.994413 C 361.52312,81.248093 365.44145,83.840823 370.66589,83.753103 C 380.47146,83.675123 385.37424,75.935933 385.37424,60.525783 z M 395.13109,60.584263 C 395.13109,68.547643 393.09395,75.175663 389.02941,80.468333 C 384.5555,86.394563 378.37584,89.367423 370.49044,89.367423 C 362.67328,89.367423 356.58135,86.394563 352.18541,80.468333 C 348.19885,75.175663 346.21044,68.547643 346.21044,60.584263 C 346.21044,53.098503 348.36455,46.801883 352.67276,41.674913 C 357.22466,36.236033 363.20937,33.506853 370.6074,33.506853 C 378.00545,33.506853 384.02914,36.236033 388.66877,41.674913 C 392.97697,46.801883 395.13109,53.098503 395.13109,60.584263 z \" id=\"path54\" style=\"fill:#646464;fill-opacity:1\"/>",
469 " <path d=\"M 446.20583,88.266003 L 437.29699,88.266003 L 437.29699,51.928853 C 437.29699,47.942293 436.0981,44.832973 433.70032,42.591133 C 431.30253,40.359053 428.10549,39.277123 424.11893,39.364853 C 419.8887,39.442833 415.86314,40.826913 412.04229,43.507363 L 412.04229,88.266003 L 403.13345,88.266003 L 403.13345,42.405943 C 408.26042,38.672813 412.97801,36.236033 417.28621,35.095623 C 421.35076,34.033193 424.93769,33.506853 428.02752,33.506853 C 430.14264,33.506853 432.13104,33.711543 434.00248,34.120913 C 437.50169,34.929923 440.34783,36.430973 442.54093,38.633823 C 444.98744,41.070593 446.20583,43.994723 446.20583,47.415943 L 446.20583,88.266003 z \" id=\"path56\" style=\"fill:#646464;fill-opacity:1\"/>",
469 " <path d=\"M 446.20583,88.266003 L 437.29699,88.266003 L 437.29699,51.928853 C 437.29699,47.942293 436.0981,44.832973 433.70032,42.591133 C 431.30253,40.359053 428.10549,39.277123 424.11893,39.364853 C 419.8887,39.442833 415.86314,40.826913 412.04229,43.507363 L 412.04229,88.266003 L 403.13345,88.266003 L 403.13345,42.405943 C 408.26042,38.672813 412.97801,36.236033 417.28621,35.095623 C 421.35076,34.033193 424.93769,33.506853 428.02752,33.506853 C 430.14264,33.506853 432.13104,33.711543 434.00248,34.120913 C 437.50169,34.929923 440.34783,36.430973 442.54093,38.633823 C 444.98744,41.070593 446.20583,43.994723 446.20583,47.415943 L 446.20583,88.266003 z \" id=\"path56\" style=\"fill:#646464;fill-opacity:1\"/>",
470 " <path d=\"M 60.510156,6.3979729 C 55.926503,6.4192712 51.549217,6.8101906 47.697656,7.4917229 C 36.35144,9.4962267 34.291407,13.691825 34.291406,21.429223 L 34.291406,31.647973 L 61.103906,31.647973 L 61.103906,35.054223 L 34.291406,35.054223 L 24.228906,35.054223 C 16.436447,35.054223 9.6131468,39.73794 7.4789058,48.647973 C 5.0170858,58.860939 4.9078907,65.233996 7.4789058,75.897973 C 9.3848341,83.835825 13.936449,89.491721 21.728906,89.491723 L 30.947656,89.491723 L 30.947656,77.241723 C 30.947656,68.391821 38.6048,60.585475 47.697656,60.585473 L 74.478906,60.585473 C 81.933857,60.585473 87.885159,54.447309 87.885156,46.960473 L 87.885156,21.429223 C 87.885156,14.162884 81.755176,8.7044455 74.478906,7.4917229 C 69.872919,6.7249976 65.093809,6.3766746 60.510156,6.3979729 z M 46.010156,14.616723 C 48.779703,14.616723 51.041406,16.915369 51.041406,19.741723 C 51.041404,22.558059 48.779703,24.835473 46.010156,24.835473 C 43.23068,24.835472 40.978906,22.558058 40.978906,19.741723 C 40.978905,16.91537 43.23068,14.616723 46.010156,14.616723 z \" id=\"path1948\" style=\"fill:url(#linearGradient1478);fill-opacity:1\"/>",
470 " <path d=\"M 60.510156,6.3979729 C 55.926503,6.4192712 51.549217,6.8101906 47.697656,7.4917229 C 36.35144,9.4962267 34.291407,13.691825 34.291406,21.429223 L 34.291406,31.647973 L 61.103906,31.647973 L 61.103906,35.054223 L 34.291406,35.054223 L 24.228906,35.054223 C 16.436447,35.054223 9.6131468,39.73794 7.4789058,48.647973 C 5.0170858,58.860939 4.9078907,65.233996 7.4789058,75.897973 C 9.3848341,83.835825 13.936449,89.491721 21.728906,89.491723 L 30.947656,89.491723 L 30.947656,77.241723 C 30.947656,68.391821 38.6048,60.585475 47.697656,60.585473 L 74.478906,60.585473 C 81.933857,60.585473 87.885159,54.447309 87.885156,46.960473 L 87.885156,21.429223 C 87.885156,14.162884 81.755176,8.7044455 74.478906,7.4917229 C 69.872919,6.7249976 65.093809,6.3766746 60.510156,6.3979729 z M 46.010156,14.616723 C 48.779703,14.616723 51.041406,16.915369 51.041406,19.741723 C 51.041404,22.558059 48.779703,24.835473 46.010156,24.835473 C 43.23068,24.835472 40.978906,22.558058 40.978906,19.741723 C 40.978905,16.91537 43.23068,14.616723 46.010156,14.616723 z \" id=\"path1948\" style=\"fill:url(#linearGradient1478);fill-opacity:1\"/>",
471 " <path d=\"M 91.228906,35.054223 L 91.228906,46.960473 C 91.228906,56.191228 83.403011,63.960472 74.478906,63.960473 L 47.697656,63.960473 C 40.361823,63.960473 34.291407,70.238956 34.291406,77.585473 L 34.291406,103.11672 C 34.291406,110.38306 40.609994,114.65704 47.697656,116.74172 C 56.184987,119.23733 64.323893,119.68835 74.478906,116.74172 C 81.229061,114.78733 87.885159,110.85411 87.885156,103.11672 L 87.885156,92.897973 L 61.103906,92.897973 L 61.103906,89.491723 L 87.885156,89.491723 L 101.29141,89.491723 C 109.08387,89.491723 111.98766,84.056315 114.69765,75.897973 C 117.49698,67.499087 117.37787,59.422197 114.69765,48.647973 C 112.77187,40.890532 109.09378,35.054223 101.29141,35.054223 L 91.228906,35.054223 z M 76.166406,99.710473 C 78.945884,99.710476 81.197656,101.98789 81.197656,104.80422 C 81.197654,107.63057 78.945881,109.92922 76.166406,109.92922 C 73.396856,109.92922 71.135156,107.63057 71.135156,104.80422 C 71.135158,101.98789 73.396853,99.710473 76.166406,99.710473 z \" id=\"path1950\" style=\"fill:url(#linearGradient1475);fill-opacity:1\"/>",
471 " <path d=\"M 91.228906,35.054223 L 91.228906,46.960473 C 91.228906,56.191228 83.403011,63.960472 74.478906,63.960473 L 47.697656,63.960473 C 40.361823,63.960473 34.291407,70.238956 34.291406,77.585473 L 34.291406,103.11672 C 34.291406,110.38306 40.609994,114.65704 47.697656,116.74172 C 56.184987,119.23733 64.323893,119.68835 74.478906,116.74172 C 81.229061,114.78733 87.885159,110.85411 87.885156,103.11672 L 87.885156,92.897973 L 61.103906,92.897973 L 61.103906,89.491723 L 87.885156,89.491723 L 101.29141,89.491723 C 109.08387,89.491723 111.98766,84.056315 114.69765,75.897973 C 117.49698,67.499087 117.37787,59.422197 114.69765,48.647973 C 112.77187,40.890532 109.09378,35.054223 101.29141,35.054223 L 91.228906,35.054223 z M 76.166406,99.710473 C 78.945884,99.710476 81.197656,101.98789 81.197656,104.80422 C 81.197654,107.63057 78.945881,109.92922 76.166406,109.92922 C 73.396856,109.92922 71.135156,107.63057 71.135156,104.80422 C 71.135158,101.98789 73.396853,99.710473 76.166406,99.710473 z \" id=\"path1950\" style=\"fill:url(#linearGradient1475);fill-opacity:1\"/>",
472 " <path d=\"M 463.5544,26.909383 L 465.11635,26.909383 L 465.11635,17.113143 L 468.81648,17.113143 L 468.81648,15.945483 L 459.85427,15.945483 L 459.85427,17.113143 L 463.5544,17.113143 L 463.5544,26.909383 M 470.20142,26.909383 L 471.53589,26.909383 L 471.53589,17.962353 L 474.4323,26.908259 L 475.91799,26.908259 L 478.93615,17.992683 L 478.93615,26.909383 L 480.39194,26.909383 L 480.39194,15.945483 L 478.46605,15.945483 L 475.16774,25.33834 L 472.35477,15.945483 L 470.20142,15.945483 L 470.20142,26.909383\" id=\"text3004\" style=\"font-size:15.16445827px;font-style:normal;font-weight:normal;line-height:125%;fill:#646464;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans\"/>",
472 " <path d=\"M 463.5544,26.909383 L 465.11635,26.909383 L 465.11635,17.113143 L 468.81648,17.113143 L 468.81648,15.945483 L 459.85427,15.945483 L 459.85427,17.113143 L 463.5544,17.113143 L 463.5544,26.909383 M 470.20142,26.909383 L 471.53589,26.909383 L 471.53589,17.962353 L 474.4323,26.908259 L 475.91799,26.908259 L 478.93615,17.992683 L 478.93615,26.909383 L 480.39194,26.909383 L 480.39194,15.945483 L 478.46605,15.945483 L 475.16774,25.33834 L 472.35477,15.945483 L 470.20142,15.945483 L 470.20142,26.909383\" id=\"text3004\" style=\"font-size:15.16445827px;font-style:normal;font-weight:normal;line-height:125%;fill:#646464;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans\"/>",
473 " <path d=\"M 110.46717 132.28575 A 48.948284 8.6066771 0 1 1 12.570599,132.28575 A 48.948284 8.6066771 0 1 1 110.46717 132.28575 z\" id=\"path1894\" style=\"opacity:0.44382019;fill:url(#radialGradient1480);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\" transform=\"matrix(0.73406,0,0,0.809524,16.24958,27.00935)\"/>",
473 " <path d=\"M 110.46717 132.28575 A 48.948284 8.6066771 0 1 1 12.570599,132.28575 A 48.948284 8.6066771 0 1 1 110.46717 132.28575 z\" id=\"path1894\" style=\"opacity:0.44382019;fill:url(#radialGradient1480);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\" transform=\"matrix(0.73406,0,0,0.809524,16.24958,27.00935)\"/>",
474 " </g>",
474 " </g>",
475 "</svg>"
475 "</svg>"
476 ],
476 ],
477 "text": [
477 "text": [
478 "&lt;IPython.core.display.SVG at 0x41d4910&gt;"
478 "&lt;IPython.core.display.SVG at 0x41d4910&gt;"
479 ]
479 ]
480 }
480 }
481 ],
481 ],
482 "prompt_number": 3
482 "prompt_number": 3
483 },
483 },
484 {
484 {
485 "cell_type": "markdown",
485 "cell_type": "markdown",
486 "source": [
486 "source": [
487 "#### Embedded vs Non-embedded Images"
487 "#### Embedded vs Non-embedded Images"
488 ]
488 ]
489 },
489 },
490 {
490 {
491 "cell_type": "markdown",
491 "cell_type": "markdown",
492 "source": [
492 "source": [
493 "As of IPython 0.13, images are embedded by default for compatibility with QtConsole, and the ability to still be displayed offline.",
493 "As of IPython 0.13, images are embedded by default for compatibility with QtConsole, and the ability to still be displayed offline.",
494 "",
494 "",
495 "Let's look at the differences:"
495 "Let's look at the differences:"
496 ]
496 ]
497 },
497 },
498 {
498 {
499 "cell_type": "code",
499 "cell_type": "code",
500 "collapsed": false,
500 "collapsed": false,
501 "input": [
501 "input": [
502 "# by default Image data are embedded",
502 "# by default Image data are embedded",
503 "Embed = Image( 'http://www.google.fr/images/srpr/logo3w.png')",
503 "Embed = Image( 'http://www.google.fr/images/srpr/logo3w.png')",
504 "",
504 "",
505 "# if kwarg `url` is given, the embedding is assumed to be false",
505 "# if kwarg `url` is given, the embedding is assumed to be false",
506 "SoftLinked = Image(url='http://www.google.fr/images/srpr/logo3w.png')",
506 "SoftLinked = Image(url='http://www.google.fr/images/srpr/logo3w.png')",
507 "",
507 "",
508 "# In each case, embed can be specified explicitly with the `embed` kwarg",
508 "# In each case, embed can be specified explicitly with the `embed` kwarg",
509 "# ForceEmbed = Image(url='http://www.google.fr/images/srpr/logo3w.png', embed=True)"
509 "# ForceEmbed = Image(url='http://www.google.fr/images/srpr/logo3w.png', embed=True)"
510 ],
510 ],
511 "language": "python",
511 "language": "python",
512 "outputs": [],
512 "outputs": [],
513 "prompt_number": 6
513 "prompt_number": 6
514 },
514 },
515 {
515 {
516 "cell_type": "markdown",
516 "cell_type": "markdown",
517 "source": [
517 "source": [
518 "Today's Google doodle, (at the time I created this notebook). This should also work in the Qtconsole.",
518 "Today's Google doodle, (at the time I created this notebook). This should also work in the Qtconsole.",
519 "Drawback is that the saved notebook will be larger, but the image will still be present offline."
519 "Drawback is that the saved notebook will be larger, but the image will still be present offline."
520 ]
520 ]
521 },
521 },
522 {
522 {
523 "cell_type": "code",
523 "cell_type": "code",
524 "collapsed": false,
524 "collapsed": false,
525 "input": [
525 "input": [
526 "Embed"
526 "Embed"
527 ],
527 ],
528 "language": "python",
528 "language": "python",
529 "outputs": [
529 "outputs": [
530 {
530 {
531 "jpeg": "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\nBoDQGgNAaA0H/9k=\n",
531 "jpeg": "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\nBoDQGgNAaA0H/9k=\n",
532 "output_type": "pyout",
532 "output_type": "pyout",
533 "prompt_number": 7,
533 "prompt_number": 7,
534 "text": [
534 "text": [
535 "<IPython.core.display.Image at 0x107deaad0>"
535 "<IPython.core.display.Image at 0x107deaad0>"
536 ]
536 ]
537 }
537 }
538 ],
538 ],
539 "prompt_number": 7
539 "prompt_number": 7
540 },
540 },
541 {
541 {
542 "cell_type": "markdown",
542 "cell_type": "markdown",
543 "source": [
543 "source": [
544 "Today's Google doodle, visible only with an active internet connexion, that should be different from the previous one. This will not work on Qtconsole.",
544 "Today's Google doodle, visible only with an active internet connexion, that should be different from the previous one. This will not work on Qtconsole.",
545 "Notebook saved with this kind of image will be lighter and always reflect the current version of the source, but the image won't display offline."
545 "Notebook saved with this kind of image will be lighter and always reflect the current version of the source, but the image won't display offline."
546 ]
546 ]
547 },
547 },
548 {
548 {
549 "cell_type": "code",
549 "cell_type": "code",
550 "collapsed": false,
550 "collapsed": false,
551 "input": [
551 "input": [
552 "SoftLinked"
552 "SoftLinked"
553 ],
553 ],
554 "language": "python",
554 "language": "python",
555 "outputs": [
555 "outputs": [
556 {
556 {
557 "html": [
557 "html": [
558 "<img src=\"http://www.google.fr/images/srpr/logo3w.png\" />"
558 "<img src=\"http://www.google.fr/images/srpr/logo3w.png\" />"
559 ],
559 ],
560 "output_type": "pyout",
560 "output_type": "pyout",
561 "prompt_number": 5,
561 "prompt_number": 5,
562 "text": [
562 "text": [
563 "<IPython.core.display.Image at 0x107dea890>"
563 "<IPython.core.display.Image at 0x107dea890>"
564 ]
564 ]
565 }
565 }
566 ],
566 ],
567 "prompt_number": 5
567 "prompt_number": 5
568 },
568 },
569 {
569 {
570 "cell_type": "markdown",
570 "cell_type": "markdown",
571 "source": [
571 "source": [
572 "Of course, if you re-run this notebook, the two doodles will be the same again.",
572 "Of course, if you re-run this notebook, the two doodles will be the same again.",
573 "<!-- well actually I cheated a little, by setting Embed Url to http://www.google.com/logos/2012/doisneau12-hp.jpg then editing the ipynb myself and replacing it by the other url -->"
573 "<!-- well actually I cheated a little, by setting Embed Url to http://www.google.com/logos/2012/doisneau12-hp.jpg then editing the ipynb myself and replacing it by the other url -->"
574 ]
574 ]
575 },
575 },
576 {
576 {
577 "cell_type": "markdown",
577 "cell_type": "markdown",
578 "source": [
578 "source": [
579 "### Video"
579 "### Video"
580 ]
580 ]
581 },
581 },
582 {
582 {
583 "cell_type": "markdown",
583 "cell_type": "markdown",
584 "source": [
584 "source": [
585 "And more exotic objects can also be displayed, as long as their representation supports ",
585 "And more exotic objects can also be displayed, as long as their representation supports ",
586 "the IPython display protocol.",
586 "the IPython display protocol.",
587 "",
587 "",
588 "For example, videos hosted externally on YouTube are easy to load (and writing a similar wrapper for other",
588 "For example, videos hosted externally on YouTube are easy to load (and writing a similar wrapper for other",
589 "hosted content is trivial):"
589 "hosted content is trivial):"
590 ]
590 ]
591 },
591 },
592 {
592 {
593 "cell_type": "code",
593 "cell_type": "code",
594 "collapsed": false,
594 "collapsed": false,
595 "input": [
595 "input": [
596 "from IPython.lib.display import YouTubeVideo",
596 "from IPython.lib.display import YouTubeVideo",
597 "# a talk about IPython at Sage Days at U. Washington, Seattle.",
597 "# a talk about IPython at Sage Days at U. Washington, Seattle.",
598 "# Video credit: William Stein.",
598 "# Video credit: William Stein.",
599 "YouTubeVideo('1j_HxD4iLn8')"
599 "YouTubeVideo('1j_HxD4iLn8')"
600 ],
600 ],
601 "language": "python",
601 "language": "python",
602 "outputs": [
602 "outputs": [
603 {
603 {
604 "html": [
604 "html": [
605 "",
605 "",
606 " <iframe",
606 " <iframe",
607 " width=\"400\"",
607 " width=\"400\"",
608 " height=\"300\"",
608 " height=\"300\"",
609 " src=\"http://www.youtube.com/embed/1j_HxD4iLn8\"",
609 " src=\"http://www.youtube.com/embed/1j_HxD4iLn8\"",
610 " frameborder=\"0\"",
610 " frameborder=\"0\"",
611 " allowfullscreen",
611 " allowfullscreen",
612 " ></iframe>",
612 " ></iframe>",
613 " "
613 " "
614 ],
614 ],
615 "output_type": "pyout",
615 "output_type": "pyout",
616 "prompt_number": 4,
616 "prompt_number": 4,
617 "text": [
617 "text": [
618 "&lt;IPython.lib.display.YouTubeVideo at 0x41d4310&gt;"
618 "&lt;IPython.lib.display.YouTubeVideo at 0x41d4310&gt;"
619 ]
619 ]
620 }
620 }
621 ],
621 ],
622 "prompt_number": 4
622 "prompt_number": 4
623 },
623 },
624 {
624 {
625 "cell_type": "markdown",
625 "cell_type": "markdown",
626 "source": [
626 "source": [
627 "Using the nascent video capabilities of modern browsers, you may also be able to display local",
627 "Using the nascent video capabilities of modern browsers, you may also be able to display local",
628 "videos. At the moment this doesn't work very well in all browsers, so it may or may not work for you;",
628 "videos. At the moment this doesn't work very well in all browsers, so it may or may not work for you;",
629 "we will continue testing this and looking for ways to make it more robust. ",
629 "we will continue testing this and looking for ways to make it more robust. ",
630 "",
630 "",
631 "The following cell loads a local file called `animation.m4v`, encodes the raw video as base64 for http",
631 "The following cell loads a local file called `animation.m4v`, encodes the raw video as base64 for http",
632 "transport, and uses the HTML5 video tag to load it. On Chrome 15 it works correctly, displaying a control",
632 "transport, and uses the HTML5 video tag to load it. On Chrome 15 it works correctly, displaying a control",
633 "bar at the bottom with a play/pause button and a location slider."
633 "bar at the bottom with a play/pause button and a location slider."
634 ]
634 ]
635 },
635 },
636 {
636 {
637 "cell_type": "code",
637 "cell_type": "code",
638 "collapsed": false,
638 "collapsed": false,
639 "input": [
639 "input": [
640 "from IPython.core.display import HTML",
640 "from IPython.core.display import HTML",
641 "video = open(\"animation.m4v\", \"rb\").read()",
641 "video = open(\"animation.m4v\", \"rb\").read()",
642 "video_encoded = video.encode(\"base64\")",
642 "video_encoded = video.encode(\"base64\")",
643 "video_tag = '<video controls alt=\"test\" src=\"data:video/x-m4v;base64,{0}\">'.format(video_encoded)",
643 "video_tag = '<video controls alt=\"test\" src=\"data:video/x-m4v;base64,{0}\">'.format(video_encoded)",
644 "HTML(data=video_tag)"
644 "HTML(data=video_tag)"
645 ],
645 ],
646 "language": "python",
646 "language": "python",
647 "outputs": [
647 "outputs": [
648 {
648 {
649 "html": [
649 "html": [
650 "<video controls alt=\"test\" src=\"data:video/x-m4v;base64,AAAAHGZ0eXBNNFYgAAACAGlzb21pc28yYXZjMQAAAAhmcmVlAAAqiW1kYXQAAAKMBgX//4jcRem9",
650 "<video controls alt=\"test\" src=\"data:video/x-m4v;base64,AAAAHGZ0eXBNNFYgAAACAGlzb21pc28yYXZjMQAAAAhmcmVlAAAqiW1kYXQAAAKMBgX//4jcRem9",
651 "5tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTE4IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENv",
651 "5tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTE4IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENv",
652 "cHlsZWZ0IDIwMDMtMjAxMSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9w",
652 "cHlsZWZ0IDIwMDMtMjAxMSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9w",
653 "dGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1o",
653 "dGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1o",
654 "ZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2",
654 "ZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2",
655 "IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MSBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0",
655 "IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MSBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0",
656 "X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTEgc2xpY2VkX3RocmVhZHM9MCBu",
656 "X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTEgc2xpY2VkX3RocmVhZHM9MCBu",
657 "cj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9p",
657 "cj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9p",
658 "bnRyYT0wIGJmcmFtZXM9MyBiX3B5cmFtaWQ9MiBiX2FkYXB0PTEgYl9iaWFzPTAgZGlyZWN0PTEg",
658 "bnRyYT0wIGJmcmFtZXM9MyBiX3B5cmFtaWQ9MiBiX2FkYXB0PTEgYl9iaWFzPTAgZGlyZWN0PTEg",
659 "d2VpZ2h0Yj0xIG9wZW5fZ29wPTAgd2VpZ2h0cD0yIGtleWludD0yNTAga2V5aW50X21pbj0yNSBz",
659 "d2VpZ2h0Yj0xIG9wZW5fZ29wPTAgd2VpZ2h0cD0yIGtleWludD0yNTAga2V5aW50X21pbj0yNSBz",
660 "Y2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmNfbG9va2FoZWFkPTQwIHJjPWNyZiBtYnRyZWU9",
660 "Y2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmNfbG9va2FoZWFkPTQwIHJjPWNyZiBtYnRyZWU9",
661 "MSBjcmY9MjMuMCBxY29tcD0wLjYwIHFwbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89",
661 "MSBjcmY9MjMuMCBxY29tcD0wLjYwIHFwbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89",
662 "MS40MCBhcT0xOjEuMDAAgAAACqVliIQAV/0TAAI/3gU2tIW7KawwaCmQGTGHKmuYAAADACBcshU+",
662 "MS40MCBhcT0xOjEuMDAAgAAACqVliIQAV/0TAAI/3gU2tIW7KawwaCmQGTGHKmuYAAADACBcshU+",
663 "yICkgAA14AHowiEeT6ei7v7h3Hu0i2fpUBLGBIkbCMP3Vfz+9BVGCDXnw9Uv5o3iN030tb7eq6rs",
663 "yICkgAA14AHowiEeT6ei7v7h3Hu0i2fpUBLGBIkbCMP3Vfz+9BVGCDXnw9Uv5o3iN030tb7eq6rs",
664 "EEhHs2azbdTiE9Csz5Zm6SiUWRdmB43hbD5i6syATuODUJd7LM3d9cbFpc7zFlu5y3vUmNGd6urp",
664 "EEhHs2azbdTiE9Csz5Zm6SiUWRdmB43hbD5i6syATuODUJd7LM3d9cbFpc7zFlu5y3vUmNGd6urp",
665 "vKKT9iyleIyTuR1sVS431DhevGfkUllVeIznYUe2USoMW1tufETjyRdmGldN6eNlhAOsGAH4z+Hk",
665 "vKKT9iyleIyTuR1sVS431DhevGfkUllVeIznYUe2USoMW1tufETjyRdmGldN6eNlhAOsGAH4z+Hk",
666 "rwKecPPU7Q5T4gDAIxj9hW84jVExMTSTHxkPTq1I4OotgUxURCGTsw60k/ezPNmNg38j1bqaGmPc",
666 "rwKecPPU7Q5T4gDAIxj9hW84jVExMTSTHxkPTq1I4OotgUxURCGTsw60k/ezPNmNg38j1bqaGmPc",
667 "ruDKEIBDsK5qEytFB90Q68s0h2wmlf2KXd5bleBefiK+/p47ZsyUO4IdlW25rRy+HLjt6wQXfYee",
667 "ruDKEIBDsK5qEytFB90Q68s0h2wmlf2KXd5bleBefiK+/p47ZsyUO4IdlW25rRy+HLjt6wQXfYee",
668 "3IkiQOoOK+U7u/lxcl78zfxwIoEMjUUSKNZjkp8clnmecDDJ3Kz+viF7bPklk7N6QRyizAKPIIpn",
668 "3IkiQOoOK+U7u/lxcl78zfxwIoEMjUUSKNZjkp8clnmecDDJ3Kz+viF7bPklk7N6QRyizAKPIIpn",
669 "NJUuMWQmqeL2Or6cr4D0/0tOym+4tficxmhuEONKUtO2pPn3hRjMllkd12tXp70fLTfxy0dwB70M",
669 "NJUuMWQmqeL2Or6cr4D0/0tOym+4tficxmhuEONKUtO2pPn3hRjMllkd12tXp70fLTfxy0dwB70M",
670 "L9iLEcItHb7zVupHlP5RxdvecpREw+OsIPr9KWilIesNE19jgIbT+TkiRBjOoKvUuwcQnKg7fOTH",
670 "L9iLEcItHb7zVupHlP5RxdvecpREw+OsIPr9KWilIesNE19jgIbT+TkiRBjOoKvUuwcQnKg7fOTH",
671 "VoLvnKuAfea+oujEdm1Rwd2tEOnkF+ZC11WaNQsiNR/eJ9EnUXjXDYGfhB+Oe7qj8nYTT+eOXg1c",
671 "VoLvnKuAfea+oujEdm1Rwd2tEOnkF+ZC11WaNQsiNR/eJ9EnUXjXDYGfhB+Oe7qj8nYTT+eOXg1c",
672 "uJNgLXEs4vOheWEjQOqfIWMQc3DmTof5s0ksBmUQ3PQ+UHPxZSnmOEZB+j6xT3wbm7HGzDjWtSg1",
672 "uJNgLXEs4vOheWEjQOqfIWMQc3DmTof5s0ksBmUQ3PQ+UHPxZSnmOEZB+j6xT3wbm7HGzDjWtSg1",
673 "SjTxd1EiJ8xA4SIxxR8WIKLg+TwFxJNS7Laxq7Uglu3AkXe82P1JCdJX5PsbFbxuDbuJgakzRcTw",
673 "SjTxd1EiJ8xA4SIxxR8WIKLg+TwFxJNS7Laxq7Uglu3AkXe82P1JCdJX5PsbFbxuDbuJgakzRcTw",
674 "MLLSKCiizS/eCW0uJed/lev9yb80kKlVET4S219cn/zhkpeDV83cHYOr+sJQKDRk/Wh2c7fsuxfx",
674 "MLLSKCiizS/eCW0uJed/lev9yb80kKlVET4S219cn/zhkpeDV83cHYOr+sJQKDRk/Wh2c7fsuxfx",
675 "aEH/6reSmvFDsAnXAyPXliJ3G4VG3OkEM5K5WyGGrBizZbTrdGsBnzj5VSGGOJdCKuRrUluw/8es",
675 "aEH/6reSmvFDsAnXAyPXliJ3G4VG3OkEM5K5WyGGrBizZbTrdGsBnzj5VSGGOJdCKuRrUluw/8es",
676 "2vYRPs9BcTqAqvHk9M52SSIf+1T6L53EZP8VbtXB+G29CMW4xVCK/B/YDjaNmqMwJ61dapugjnWJ",
676 "2vYRPs9BcTqAqvHk9M52SSIf+1T6L53EZP8VbtXB+G29CMW4xVCK/B/YDjaNmqMwJ61dapugjnWJ",
677 "fqeXlGGa3Ch3aA7gi30T8PucNRBjLK3lF67ZDDvkWXRQXd+VMnKWHkBbCkQ/F/fMuNpHO3C00Y2p",
677 "fqeXlGGa3Ch3aA7gi30T8PucNRBjLK3lF67ZDDvkWXRQXd+VMnKWHkBbCkQ/F/fMuNpHO3C00Y2p",
678 "ljna1qImBhVMvPe0F7Qx7G/YyxLRzhyUU8e23HGzp0agtNJRbydbrPV+TqJMSifJMNcZIf8wkdnC",
678 "ljna1qImBhVMvPe0F7Qx7G/YyxLRzhyUU8e23HGzp0agtNJRbydbrPV+TqJMSifJMNcZIf8wkdnC",
679 "3/xdpcXnLf2Ye3Kbd0o7utciTG+q5h6WTEk+PaNbXLLA0YyZ2VnLTcyV1QTS76aNCbV9Q1/OQ7QU",
679 "3/xdpcXnLf2Ye3Kbd0o7utciTG+q5h6WTEk+PaNbXLLA0YyZ2VnLTcyV1QTS76aNCbV9Q1/OQ7QU",
680 "81Gg0hPa9aSiscGary6jLVwDQaik4zLsi7jPqgPVdup7pwx7uJDqRCVcVi5QoZFp/GHdex5sJTF6",
680 "81Gg0hPa9aSiscGary6jLVwDQaik4zLsi7jPqgPVdup7pwx7uJDqRCVcVi5QoZFp/GHdex5sJTF6",
681 "9A6sja69/NLkFIWNSIeRcuGahXpF+wZeYIrqJv975s1TKYKAvp1WtzgtgWNkcbzCtROqf8rPtlAI",
681 "9A6sja69/NLkFIWNSIeRcuGahXpF+wZeYIrqJv975s1TKYKAvp1WtzgtgWNkcbzCtROqf8rPtlAI",
682 "xkX8GLcEo9zfExyfimeXQ64qfFxEy0IMy2Hsxau9fSMqUnIjntuVVjCQtBL+94gx1RZLndE6wROV",
682 "xkX8GLcEo9zfExyfimeXQ64qfFxEy0IMy2Hsxau9fSMqUnIjntuVVjCQtBL+94gx1RZLndE6wROV",
683 "Tq/wHwHrQzo9QL9cpPqPFJjiZ/NGZIFuudS+wsBFe6Hu8Oitf5zToLqLdtU4Smwh4ne3JsiT9lOz",
683 "Tq/wHwHrQzo9QL9cpPqPFJjiZ/NGZIFuudS+wsBFe6Hu8Oitf5zToLqLdtU4Smwh4ne3JsiT9lOz",
684 "N+4PPw3VSx9l5FppVwdKUWELw1dYpCOppyVWlJ3YQ8H4FQQM8EcYMG9N3Bxu79y1J1ikuvuhMmLQ",
684 "N+4PPw3VSx9l5FppVwdKUWELw1dYpCOppyVWlJ3YQ8H4FQQM8EcYMG9N3Bxu79y1J1ikuvuhMmLQ",
685 "lehLTbguhbix74hd1VIQC8EjHmOZSSWbssulYwPbr6FF49tifk6PymJvulR9/u+2585HkRfbxveG",
685 "lehLTbguhbix74hd1VIQC8EjHmOZSSWbssulYwPbr6FF49tifk6PymJvulR9/u+2585HkRfbxveG",
686 "eWCz0ix1pIVfaNpESKmtLy/0mcbMg9hYDz2werz9oe0lT2BiMV6uAin6RaQcT8Vk9MPctfwae+gk",
686 "eWCz0ix1pIVfaNpESKmtLy/0mcbMg9hYDz2werz9oe0lT2BiMV6uAin6RaQcT8Vk9MPctfwae+gk",
687 "vtnZA/sOBk8MbpylaHqc0KIVHhhLFMNnkOFiucjtGo/JWTa/F6g8wWeow5ZuIJUORaYHWqegZbTg",
687 "vtnZA/sOBk8MbpylaHqc0KIVHhhLFMNnkOFiucjtGo/JWTa/F6g8wWeow5ZuIJUORaYHWqegZbTg",
688 "M9dCsYYsfZGjjVMuSlDIvpYvIvFFooGPC7Ye2Jfawmq4Ut7EL/nv/dyAd2HRc5msmUhzeu/XpX3r",
688 "M9dCsYYsfZGjjVMuSlDIvpYvIvFFooGPC7Ye2Jfawmq4Ut7EL/nv/dyAd2HRc5msmUhzeu/XpX3r",
689 "VlzRmf9/Qan8Dbve3QfW1Ym0o5J/KAc3z1VBho7JBr5PgCL68RiD9jZHN0VvsT4gzsEjNlW3D91U",
689 "VlzRmf9/Qan8Dbve3QfW1Ym0o5J/KAc3z1VBho7JBr5PgCL68RiD9jZHN0VvsT4gzsEjNlW3D91U",
690 "y4RduaodBFoNTzXwlfUYULBzdiTbH75l/UmVMC4TKeTWhNzw2UezaqeGd8at3WSY7W/VR3+hvZHD",
690 "y4RduaodBFoNTzXwlfUYULBzdiTbH75l/UmVMC4TKeTWhNzw2UezaqeGd8at3WSY7W/VR3+hvZHD",
691 "pkIjgKuNNH0DsCRa/Kk56XQoHIyvvUH/eNekNvziReqS4qgLnXUT4BRGt2BOtCifI6+X/DGHUOmW",
691 "pkIjgKuNNH0DsCRa/Kk56XQoHIyvvUH/eNekNvziReqS4qgLnXUT4BRGt2BOtCifI6+X/DGHUOmW",
692 "lX7TN5b4pw5U7jwfwshtbhGZM49T8JMk15Mzrc7tM6J11TYxb5R3mQhZ8TZumJ0bMJXPM69HFyih",
692 "lX7TN5b4pw5U7jwfwshtbhGZM49T8JMk15Mzrc7tM6J11TYxb5R3mQhZ8TZumJ0bMJXPM69HFyih",
693 "r5dJSEJMycxJVUh6NTQALUOoRTHIOwE+FpWI6feTv1SiZ0YpYe5DbkYJJbN7zAHbAKw25XvqR2mA",
693 "r5dJSEJMycxJVUh6NTQALUOoRTHIOwE+FpWI6feTv1SiZ0YpYe5DbkYJJbN7zAHbAKw25XvqR2mA",
694 "jQmOlsfX/tK8DPjP/8h5/xgAF4EUbj1tOnQCBQL8jk9vHtfsXncsprww4Z+P/Z/UrKifuFyEpBWN",
694 "jQmOlsfX/tK8DPjP/8h5/xgAF4EUbj1tOnQCBQL8jk9vHtfsXncsprww4Z+P/Z/UrKifuFyEpBWN",
695 "8kLpF7yywE2iYdDruV9+/qKR8rC9ozNKyqQNIwtxrzYkWpE5t8K7gG4JFnrHona/Rp8dOX6VW41+",
695 "8kLpF7yywE2iYdDruV9+/qKR8rC9ozNKyqQNIwtxrzYkWpE5t8K7gG4JFnrHona/Rp8dOX6VW41+",
696 "jb5LB1LEtE8MwjLp3RCUOq/+6yLzaOEgBTqzvEjDeFpg/u9DMHMr4/2TOchfjg7dl+uQ6Gsx+4Ia",
696 "jb5LB1LEtE8MwjLp3RCUOq/+6yLzaOEgBTqzvEjDeFpg/u9DMHMr4/2TOchfjg7dl+uQ6Gsx+4Ia",
697 "9W7vivG95027p25eKL0nHvx/OqmAQEZYJL/JO58lOj0zPdJxrQ5dZksjMISzVZNn7DsxqE3zgBBu",
697 "9W7vivG95027p25eKL0nHvx/OqmAQEZYJL/JO58lOj0zPdJxrQ5dZksjMISzVZNn7DsxqE3zgBBu",
698 "Nzk50R8lTK3U8P12QiOAQYSTeGlYlkvfeofrfO1AitEj02m9aUkxTFd1ZZJoLQT2d3zEU5PmE4lx",
698 "Nzk50R8lTK3U8P12QiOAQYSTeGlYlkvfeofrfO1AitEj02m9aUkxTFd1ZZJoLQT2d3zEU5PmE4lx",
699 "MVfL5ttNnIbqfcIU2RJKNWqdw77xfjfrNc/eNpRKPZ/6z50LzBprgjzBHRfKgSWWkDxHrX0aTbgw",
699 "MVfL5ttNnIbqfcIU2RJKNWqdw77xfjfrNc/eNpRKPZ/6z50LzBprgjzBHRfKgSWWkDxHrX0aTbgw",
700 "QFwd51+PoUWH4DkQg26uGslF5Hn3hB58+fkeLTosTANOIBNAeFZtTc4PIaLHw759zae7scY55xcT",
700 "QFwd51+PoUWH4DkQg26uGslF5Hn3hB58+fkeLTosTANOIBNAeFZtTc4PIaLHw759zae7scY55xcT",
701 "abzlilYIftst2RZ6ntsRC3zFxduCKvL6wLfYT+TiIWJn5P7sTwZwXuSzXY+9Q3xMZ5o4Xcpz6vD9",
701 "abzlilYIftst2RZ6ntsRC3zFxduCKvL6wLfYT+TiIWJn5P7sTwZwXuSzXY+9Q3xMZ5o4Xcpz6vD9",
702 "FtTjzS69iefEYt4pXiDrZUo4ePGiLeoIFIwYB/v6GXdmG5VLLk+eKbOc9AmsX2zmvqtcvDRGQbzu",
702 "FtTjzS69iefEYt4pXiDrZUo4ePGiLeoIFIwYB/v6GXdmG5VLLk+eKbOc9AmsX2zmvqtcvDRGQbzu",
703 "gXbH/kTH/lkNPBTmqN3ZJODUEXVohPEJ6th0xna0EVleB73Q3eNvaVUvhlJbjs3D/T17FRCebN7A",
703 "gXbH/kTH/lkNPBTmqN3ZJODUEXVohPEJ6th0xna0EVleB73Q3eNvaVUvhlJbjs3D/T17FRCebN7A",
704 "OXvzzbLE/I5kNfEmJcv4dxtIeo2uQ/z9ohSpiZzbDj1u40nJRyJxUK60wEv0nA9f/NuJ6/PEyU0b",
704 "OXvzzbLE/I5kNfEmJcv4dxtIeo2uQ/z9ohSpiZzbDj1u40nJRyJxUK60wEv0nA9f/NuJ6/PEyU0b",
705 "kK16z2KH12k3Lc4+1f5fawIzkK2qJRB4wnj8VHhUW9mbJhs9vgfFmU3xrXSShY67Ygb+gYNPxxtn",
705 "kK16z2KH12k3Lc4+1f5fawIzkK2qJRB4wnj8VHhUW9mbJhs9vgfFmU3xrXSShY67Ygb+gYNPxxtn",
706 "4K/9eTSwIA9fv/nR33lA2lZoXALRUTmOZIl3R0gAM5h6oX1y1thIyqViBK95VZc8Pvy7G3O90M9S",
706 "4K/9eTSwIA9fv/nR33lA2lZoXALRUTmOZIl3R0gAM5h6oX1y1thIyqViBK95VZc8Pvy7G3O90M9S",
707 "4zkpyFQ36jrMazvMveMA4d39fvoaC7p90quiJfjI4yrl+ECVkCJL5MxRSa+iVcIL7Xbl0jVaGhZI",
707 "4zkpyFQ36jrMazvMveMA4d39fvoaC7p90quiJfjI4yrl+ECVkCJL5MxRSa+iVcIL7Xbl0jVaGhZI",
708 "cMYmcGOBbLzhJgloM1x1zFnnj3ggJRFAM8yNnXxhavk+mA18JC+y3lqGsp6vPReRxGlGHMou17L4",
708 "cMYmcGOBbLzhJgloM1x1zFnnj3ggJRFAM8yNnXxhavk+mA18JC+y3lqGsp6vPReRxGlGHMou17L4",
709 "It070LzkoeCzarpv8Apw59smdS5KN9qVN1WgeL7OSN8BHg94ubCvS7DW6H3/PbtRB62jFLsBhUV5",
709 "It070LzkoeCzarpv8Apw59smdS5KN9qVN1WgeL7OSN8BHg94ubCvS7DW6H3/PbtRB62jFLsBhUV5",
710 "YqCIbIN5VZ81AAACpUGaIWxFfwAru8x8uT3FuOjrAeSWXmAWqq9jCNGE+N5AOv//9//xjk4uBAcA",
710 "YqCIbIN5VZ81AAACpUGaIWxFfwAru8x8uT3FuOjrAeSWXmAWqq9jCNGE+N5AOv//9//xjk4uBAcA",
711 "DN96c97AVGmzRtnWwPsgcCbLrVdQJgbKp4QSmPwQnVhv0hXyBjeFWWlcvx70urEN3FK6/lvk2tQe",
711 "DN96c97AVGmzRtnWwPsgcCbLrVdQJgbKp4QSmPwQnVhv0hXyBjeFWWlcvx70urEN3FK6/lvk2tQe",
712 "ZgbtlbzXluvTfnSj/Ctz7vZ+O1FjhDzzdpL7uLzewzCIW5VWLAEKUVuS2J6wNk6MR7UblcEd4EtO",
712 "ZgbtlbzXluvTfnSj/Ctz7vZ+O1FjhDzzdpL7uLzewzCIW5VWLAEKUVuS2J6wNk6MR7UblcEd4EtO",
713 "Y+R4/qJgfojCsfRvA0oC5dc41Vd0erZbSkrmPTjLCn815bxlchUJMS8gQD5hJNwoKHvNLNwn7XKu",
713 "Y+R4/qJgfojCsfRvA0oC5dc41Vd0erZbSkrmPTjLCn815bxlchUJMS8gQD5hJNwoKHvNLNwn7XKu",
714 "TtYIhH2wVNZvDWgzCjlPeQajnrcMsb6bZYJvNJU8HuGHvm50r7VG8qifEwmuyegAZXojh5Ul5Vvj",
714 "TtYIhH2wVNZvDWgzCjlPeQajnrcMsb6bZYJvNJU8HuGHvm50r7VG8qifEwmuyegAZXojh5Ul5Vvj",
715 "DW7kSAZyw8a7I6mHY3FZHd+OA3V4JZMbNliI3Tj1L6+MKTmilVialmyZagRtEMeKRdtxUPd3vVEt",
715 "DW7kSAZyw8a7I6mHY3FZHd+OA3V4JZMbNliI3Tj1L6+MKTmilVialmyZagRtEMeKRdtxUPd3vVEt",
716 "rOBVIVYWdgAGA7HmZiHQUQNxLkWxbLyWVlrh5EM0Do2NdbclHxxArz90d+MSVeUOIXQ/4V9quq8C",
716 "rOBVIVYWdgAGA7HmZiHQUQNxLkWxbLyWVlrh5EM0Do2NdbclHxxArz90d+MSVeUOIXQ/4V9quq8C",
717 "8qVflo1gPtPMkjO2/UrdOYqhY404ReObOu/fdp4hAEDq6jhy64vOeT7XUK/Onq0rXTldtA6kvgQa",
717 "8qVflo1gPtPMkjO2/UrdOYqhY404ReObOu/fdp4hAEDq6jhy64vOeT7XUK/Onq0rXTldtA6kvgQa",
718 "Jg+mgYSR9hfXtMbOUSLgLj/RmBSO8aAMHuJJZqf1tCM5pZ9eYUsrHmy+/z2NGalon0//uF6+33bQ",
718 "Jg+mgYSR9hfXtMbOUSLgLj/RmBSO8aAMHuJJZqf1tCM5pZ9eYUsrHmy+/z2NGalon0//uF6+33bQ",
719 "zT/RLRfBbYTjy9QrJqHLlw46lggWPGkHuPKSqk/CB7U4pNPXUbR0DdcJy9Db00wCzVzxVc6h7jfC",
719 "zT/RLRfBbYTjy9QrJqHLlw46lggWPGkHuPKSqk/CB7U4pNPXUbR0DdcJy9Db00wCzVzxVc6h7jfC",
720 "FgiL2Y0HVqd6bgIaVUqn/gJCEyCDVplnzebv0gg3XwMJAGu639lHu7rEvxTp1smIYjWp9R5L4Ssp",
720 "FgiL2Y0HVqd6bgIaVUqn/gJCEyCDVplnzebv0gg3XwMJAGu639lHu7rEvxTp1smIYjWp9R5L4Ssp",
721 "VvS07Nb+Smk1FgsMp1K3EMUT8X2Fty4VG54/Ec6bE8tNVw4/QV1VzBw7Px2/2eEhhUS+FMfbHAlD",
721 "VvS07Nb+Smk1FgsMp1K3EMUT8X2Fty4VG54/Ec6bE8tNVw4/QV1VzBw7Px2/2eEhhUS+FMfbHAlD",
722 "28x00jRgAAACW0GaQjwhkymEVwArOUkEOhoFqiELtH8wgecFLiUq6WqmwAP7iGEwbYzfnHacfqUN",
722 "28x00jRgAAACW0GaQjwhkymEVwArOUkEOhoFqiELtH8wgecFLiUq6WqmwAP7iGEwbYzfnHacfqUN",
723 "XAfD+CGR2ap0lAHL25ipuYtd5j2O0PU/MpaWPG/n2y5OkfTzaOpotaR5tWjN55B2XblVVqsFfBC/",
723 "XAfD+CGR2ap0lAHL25ipuYtd5j2O0PU/MpaWPG/n2y5OkfTzaOpotaR5tWjN55B2XblVVqsFfBC/",
724 "mvsiPvCBWUHFChacdY5whj5mP5rqQ0dqLJCsWjrs4TWnIbL2V/Iwfj3hwI35jfo1JkTOeR+8GhOd",
724 "mvsiPvCBWUHFChacdY5whj5mP5rqQ0dqLJCsWjrs4TWnIbL2V/Iwfj3hwI35jfo1JkTOeR+8GhOd",
725 "ma9rgiKWafCbQyhYMTDmVdvhND60Flm97EDSTjF0OC+0gD9b8Yn4tNeHipCa/aWyt0n79bMmjfcj",
725 "ma9rgiKWafCbQyhYMTDmVdvhND60Flm97EDSTjF0OC+0gD9b8Yn4tNeHipCa/aWyt0n79bMmjfcj",
726 "ntBCPjrcB5ecRTpfGHbEHy1IRj2cjkGXKC+VYoYJXBp4rd4cMd8ygLCk5nBSd8/cTaKNRjdBscOe",
726 "ntBCPjrcB5ecRTpfGHbEHy1IRj2cjkGXKC+VYoYJXBp4rd4cMd8ygLCk5nBSd8/cTaKNRjdBscOe",
727 "TXG6QEjSxj9/2pVwx9DMRVtWQR0BSaAcQcZ8W2KPSaeRC4QwmNMu2xx25CSyrDiq2rFSK/JJtmvo",
727 "TXG6QEjSxj9/2pVwx9DMRVtWQR0BSaAcQcZ8W2KPSaeRC4QwmNMu2xx25CSyrDiq2rFSK/JJtmvo",
728 "IjAKq0ciEXoOgw+Ke+Ylb7ULKCS3k1p/613UNRp450uSq5b7CAHo7S0b7fBMLfNmwSjRYEhLlo0H",
728 "IjAKq0ciEXoOgw+Ke+Ylb7ULKCS3k1p/613UNRp450uSq5b7CAHo7S0b7fBMLfNmwSjRYEhLlo0H",
729 "UaRe/I+IX2Z6XdZH9Hty/399ZA1PwZGC6EfvUJIf7CBeaxv7cu6IT2/s0zPRGthpvXpYw6A7P4Ww",
729 "UaRe/I+IX2Z6XdZH9Hty/399ZA1PwZGC6EfvUJIf7CBeaxv7cu6IT2/s0zPRGthpvXpYw6A7P4Ww",
730 "z5C4V98KnIUNUanadqabKP6eXWhvbvcQHxAjiOOiKZgXZplZW2g+B2NNyJSLiR+g48DqvWR6t9S2",
730 "z5C4V98KnIUNUanadqabKP6eXWhvbvcQHxAjiOOiKZgXZplZW2g+B2NNyJSLiR+g48DqvWR6t9S2",
731 "aGfFjdOW1Gi6oTtZ1d4p5XIslAr8mryeZ6+htSSQe4AcfVt7k+V6mOthBCYtr/LEU4ZHtl0mW987",
731 "aGfFjdOW1Gi6oTtZ1d4p5XIslAr8mryeZ6+htSSQe4AcfVt7k+V6mOthBCYtr/LEU4ZHtl0mW987",
732 "6PK8mRFAaT8DJOUFVz1lPfzRApuPggkkyq+UMvyfKTUbCk7/DpfX8Y4s4QAAAg9BmmNJ4Q8mUwIr",
732 "6PK8mRFAaT8DJOUFVz1lPfzRApuPggkkyq+UMvyfKTUbCk7/DpfX8Y4s4QAAAg9BmmNJ4Q8mUwIr",
733 "/wAsWUPjZw3ksgRsxZ6n4fQjprPbkj2aUh30y0bZJnLmiXnWskvOGnCPwBnG9dEhatwX3hoxk7BN",
733 "/wAsWUPjZw3ksgRsxZ6n4fQjprPbkj2aUh30y0bZJnLmiXnWskvOGnCPwBnG9dEhatwX3hoxk7BN",
734 "yG+wQ4emZUpcVzcWl2T9nKQB1euucuZWHTg7TCtM/iHyfPO2vbmGsfzs70b/egIbywUH4y4BQSL1",
734 "yG+wQ4emZUpcVzcWl2T9nKQB1euucuZWHTg7TCtM/iHyfPO2vbmGsfzs70b/egIbywUH4y4BQSL1",
735 "nWc1SmpHm2zHMBcUjYLDZ5gL5vdfxn0V8FFw66G88c/LN4I5icUa7xf4fcSBKywU0ajbp1P+aJYj",
735 "nWc1SmpHm2zHMBcUjYLDZ5gL5vdfxn0V8FFw66G88c/LN4I5icUa7xf4fcSBKywU0ajbp1P+aJYj",
736 "BgWT6Ggu0MDLDNl54tfqd42lKosQtM1aif4WXAZFP5Ww3vrQ1rH9+utSYxqZd6N6gGtNbSNMcVia",
736 "BgWT6Ggu0MDLDNl54tfqd42lKosQtM1aif4WXAZFP5Ww3vrQ1rH9+utSYxqZd6N6gGtNbSNMcVia",
737 "Kn5LcnjsbBi3T3EmGqshEbcme8VHKwR3kSfBOAprrIsv6K8R+X6az+MD23rWka/2v64m1qM69D7X",
737 "Kn5LcnjsbBi3T3EmGqshEbcme8VHKwR3kSfBOAprrIsv6K8R+X6az+MD23rWka/2v64m1qM69D7X",
738 "a+Kcs/n0KLCJdTilyaGadopLeaAn3eYvWTeHcucMM1Fp1KgHD1tiFeO6HvobLkZlRximsA3/7Mio",
738 "a+Kcs/n0KLCJdTilyaGadopLeaAn3eYvWTeHcucMM1Fp1KgHD1tiFeO6HvobLkZlRximsA3/7Mio",
739 "hYklLIcJrZL22BH+6W9d6kZsYIsej9RM681nU6mWNjepBAfAfTbrGRrVB/h2DxC5B8YyRjgSIzQj",
739 "hYklLIcJrZL22BH+6W9d6kZsYIsej9RM681nU6mWNjepBAfAfTbrGRrVB/h2DxC5B8YyRjgSIzQj",
740 "NYrse0rzChqbrsLl7mQ7W+1bsNKze5//9ZIa8rSsF+BXh/vgoRTDkPW/ws95B7VPCZEFChfX0icw",
740 "NYrse0rzChqbrsLl7mQ7W+1bsNKze5//9ZIa8rSsF+BXh/vgoRTDkPW/ws95B7VPCZEFChfX0icw",
741 "+tpcpN/q7NY87tUn4vESdSiMMlyhKklMjQu/G51J69ZRQLs2oUO6YfoJFqliy4qCFCrf8SZE9Fc6",
741 "+tpcpN/q7NY87tUn4vESdSiMMlyhKklMjQu/G51J69ZRQLs2oUO6YfoJFqliy4qCFCrf8SZE9Fc6",
742 "DcCagAAAAodBmoRJ4Q8mUwIr/wArPWF/KOw78THwadfPqhJO0CnmR/M74/XYZLqVYKlNcEaYauf+",
742 "DcCagAAAAodBmoRJ4Q8mUwIr/wArPWF/KOw78THwadfPqhJO0CnmR/M74/XYZLqVYKlNcEaYauf+",
743 "vrRUDJPmu75sMKy2Y+Bnslc/iAISSyWtw/h/3CF8fE5ZrbrwSNst+MSyCoNWP+8imtoX2eyojpdC",
743 "vrRUDJPmu75sMKy2Y+Bnslc/iAISSyWtw/h/3CF8fE5ZrbrwSNst+MSyCoNWP+8imtoX2eyojpdC",
744 "k8YP5K+cbK4SJPCkZXbYqSXYk7hO8AdSemBHgXKWiZ+UOr802aJo+98ZOIjX9hWL9bo31Gqx7cy4",
744 "k8YP5K+cbK4SJPCkZXbYqSXYk7hO8AdSemBHgXKWiZ+UOr802aJo+98ZOIjX9hWL9bo31Gqx7cy4",
745 "ZG+W/ar/WGlzDa1xPWnPRsEdrIcZlEVGV/jGmbirkxw1lyUYoqj8Vv7Bxube9XPQlBkXOV6Lc1LT",
745 "ZG+W/ar/WGlzDa1xPWnPRsEdrIcZlEVGV/jGmbirkxw1lyUYoqj8Vv7Bxube9XPQlBkXOV6Lc1LT",
746 "2IzNq0V7WwVhF0kA6yxfAsFxc9krNEH8vGGntTWI608ovjatXc/CKKXw7AjJSftlTcLI0hIIGXbR",
746 "2IzNq0V7WwVhF0kA6yxfAsFxc9krNEH8vGGntTWI608ovjatXc/CKKXw7AjJSftlTcLI0hIIGXbR",
747 "Ur0NCYNp7M4cVd/n73Rjetnixz4SAKpcz/P47UsijZG7T3SxzK2D79WS42aEalc12hQwCZ01LfmF",
747 "Ur0NCYNp7M4cVd/n73Rjetnixz4SAKpcz/P47UsijZG7T3SxzK2D79WS42aEalc12hQwCZ01LfmF",
748 "/H2mmGEvOzPBie1D0YT7Jh19vxa4Dd3SQ1FrDfmSUpvv4DjbYcZ2PrPpFpWtMjWqHBeoyMiZf6RP",
748 "/H2mmGEvOzPBie1D0YT7Jh19vxa4Dd3SQ1FrDfmSUpvv4DjbYcZ2PrPpFpWtMjWqHBeoyMiZf6RP",
749 "3EfYR6z9jsVNIIHxM0bzzBQF8eeYkPgDySydxPXv9Izo+QUY94N8kWi16fI6eZSDc1G0Yo0L91jc",
749 "3EfYR6z9jsVNIIHxM0bzzBQF8eeYkPgDySydxPXv9Izo+QUY94N8kWi16fI6eZSDc1G0Yo0L91jc",
750 "RQuDMGGS7B2zuf/0GbJyRhUO48UbMrqnILMrbQg1LF00Q3pH9nbGEK/RRQpRN3T/J/4IZQjwW2Ft",
750 "RQuDMGGS7B2zuf/0GbJyRhUO48UbMrqnILMrbQg1LF00Q3pH9nbGEK/RRQpRN3T/J/4IZQjwW2Ft",
751 "2ipWGztg1Jn9I4DmffKS60QC+JQcyakdVON6zDcKttIKlqeTcmAi4xzmo4QXa2dRKleS+fs3EtTd",
751 "2ipWGztg1Jn9I4DmffKS60QC+JQcyakdVON6zDcKttIKlqeTcmAi4xzmo4QXa2dRKleS+fs3EtTd",
752 "BBtony2wK9T2Imj+NCziOSEL7Q7VuIU8kclUHrJJsSneFcxGRgIgGGUEQM8/pklwTOqab7mMmJeR",
752 "BBtony2wK9T2Imj+NCziOSEL7Q7VuIU8kclUHrJJsSneFcxGRgIgGGUEQM8/pklwTOqab7mMmJeR",
753 "iaBrjJDEnDpkR4Vz3qXxgyn4/5x24FuTMNVPwQAAAhtBmqVJ4Q8mUwIr/wApcLwPT0/Xh9UdWqWX",
753 "iaBrjJDEnDpkR4Vz3qXxgyn4/5x24FuTMNVPwQAAAhtBmqVJ4Q8mUwIr/wApcLwPT0/Xh9UdWqWX",
754 "Is8Wbj5K1hivmN6qIQnq+aolcegdlM/63MbHsdC6xYZC1e/Q8UjQCt9N/Ejqwms8DzeWv2qxskel",
754 "Is8Wbj5K1hivmN6qIQnq+aolcegdlM/63MbHsdC6xYZC1e/Q8UjQCt9N/Ejqwms8DzeWv2qxskel",
755 "iZH0kt1QWkErWSEodq7V0ZNksctLkMGWayX33gBT368EehfIeGDolBZoqIbJfb4nqcfU+ev4OzVv",
755 "iZH0kt1QWkErWSEodq7V0ZNksctLkMGWayX33gBT368EehfIeGDolBZoqIbJfb4nqcfU+ev4OzVv",
756 "9zVqWyLck315GFmXxQKIM8pICQc8Q5es34LH1+DmnMnW8kQpVGrztQcDXhjCU3F0fOgoSsXSVWCj",
756 "9zVqWyLck315GFmXxQKIM8pICQc8Q5es34LH1+DmnMnW8kQpVGrztQcDXhjCU3F0fOgoSsXSVWCj",
757 "c6XKqGbCwQDfJUxCfXfIT6YmQoPpVp1mpGy1wQypXus9z0bScDpyDu23hViYDntdj1O45ea0znKZ",
757 "c6XKqGbCwQDfJUxCfXfIT6YmQoPpVp1mpGy1wQypXus9z0bScDpyDu23hViYDntdj1O45ea0znKZ",
758 "kj1+tLHbBtqAGJ1WTcbGlF6Vya6hQhEsiiZUIC2fRxIj8/wEXCICIbr0gZ/m6gcOhE10tenvE7iy",
758 "kj1+tLHbBtqAGJ1WTcbGlF6Vya6hQhEsiiZUIC2fRxIj8/wEXCICIbr0gZ/m6gcOhE10tenvE7iy",
759 "+BKY81wLWrnzos3S6FWxYtmCRes+LLhNGOKWRuQo6SyePH2OZ90xZm8oA1MuTe3V59euVNxjAt0F",
759 "+BKY81wLWrnzos3S6FWxYtmCRes+LLhNGOKWRuQo6SyePH2OZ90xZm8oA1MuTe3V59euVNxjAt0F",
760 "LkAc9TEiFhP/8CB+gA8mF+A8h1U01f4DVX55GzCH51jHI2xUS0L9GtsHoBxLPLK/NNel8zcnwG4X",
760 "LkAc9TEiFhP/8CB+gA8mF+A8h1U01f4DVX55GzCH51jHI2xUS0L9GtsHoBxLPLK/NNel8zcnwG4X",
761 "+UusfcfEb5hh+ffnXteCE9vRGbs2n9wYW0xA3ZicklfadmWKUtMiHYBfkMSULWnkBQr4CXxjpYOs",
761 "+UusfcfEb5hh+ffnXteCE9vRGbs2n9wYW0xA3ZicklfadmWKUtMiHYBfkMSULWnkBQr4CXxjpYOs",
762 "6ygeEoA5+5B0B1SZObgZ42wWqddyyYE0NfwQAl75tfdJGqOa7OMHwBYNeatJaJK0zT2+bFaw2qWC",
762 "6ygeEoA5+5B0B1SZObgZ42wWqddyyYE0NfwQAl75tfdJGqOa7OMHwBYNeatJaJK0zT2+bFaw2qWC",
763 "WwAAAitBmsZJ4Q8mUwIr/wAstkdsayRXchoFk703izqzduZ5WsyXriI9cfUdMUWvm0iGHwYIrUuj",
763 "WwAAAitBmsZJ4Q8mUwIr/wAstkdsayRXchoFk703izqzduZ5WsyXriI9cfUdMUWvm0iGHwYIrUuj",
764 "vz3Yjou+JLwv9df2kt7MJo8u+3P5CjEKbwlz4vkE5AHTAbgXn3+Xc/MMJLgW5cm7iX3KiGNnBpbp",
764 "vz3Yjou+JLwv9df2kt7MJo8u+3P5CjEKbwlz4vkE5AHTAbgXn3+Xc/MMJLgW5cm7iX3KiGNnBpbp",
765 "hhwJRlb3u91NRDr0d1IR2up/z7lKxE7XPAPFe0siPMYVlIqWNSn5KqLABPeuxxbOsvMEb27/nH1L",
765 "hhwJRlb3u91NRDr0d1IR2up/z7lKxE7XPAPFe0siPMYVlIqWNSn5KqLABPeuxxbOsvMEb27/nH1L",
766 "UVM8I2F95c1I3Lv1SpkhZXjs1JsmS9X7gsoTxkXyShGC2+zRJSGUbhCPo/q1XSFMHQyMWJ79FKPQ",
766 "UVM8I2F95c1I3Lv1SpkhZXjs1JsmS9X7gsoTxkXyShGC2+zRJSGUbhCPo/q1XSFMHQyMWJ79FKPQ",
767 "SL/RpVsacN2bYwdKo4TFBw1SsKq/L1iOmqMI+4Gxnbbjojdk0ek0JIcDb4bHv1czxchF7FX1Ym8H",
767 "SL/RpVsacN2bYwdKo4TFBw1SsKq/L1iOmqMI+4Gxnbbjojdk0ek0JIcDb4bHv1czxchF7FX1Ym8H",
768 "6IpPuE8CeNKjzQ1a1wqhEu+wl1N0x3Y37ZryCCKJRkxj0FT7bOoH3L38/yMUuh/v3aCmxY4eCkyk",
768 "6IpPuE8CeNKjzQ1a1wqhEu+wl1N0x3Y37ZryCCKJRkxj0FT7bOoH3L38/yMUuh/v3aCmxY4eCkyk",
769 "b2p6ZrYMFE044anM/nMjmbErMibfRFuCz58Io1rBlF7JfkIz0R2/5vjUMVskcdbX2mm7DntncOsW",
769 "b2p6ZrYMFE044anM/nMjmbErMibfRFuCz58Io1rBlF7JfkIz0R2/5vjUMVskcdbX2mm7DntncOsW",
770 "DIdg/XVmgsC9CzVzUyq4VsS/sk97lJggcddpWLNw/29egz8iLyzWHOAXCvl2fTIPkviYAOQXfVhZ",
770 "DIdg/XVmgsC9CzVzUyq4VsS/sk97lJggcddpWLNw/29egz8iLyzWHOAXCvl2fTIPkviYAOQXfVhZ",
771 "UQdxsyJUNFMTiALrZCmoQLMp2LmDbfbW8JQriDeR3fVz6P1sjT8C2yEDvzkCn7sh0aTBK+sx7BKH",
771 "UQdxsyJUNFMTiALrZCmoQLMp2LmDbfbW8JQriDeR3fVz6P1sjT8C2yEDvzkCn7sh0aTBK+sx7BKH",
772 "1nb4320+caQepQj4TCJtCeNXjdrVcNEnjvwlcRJwFT1pT+Y7HREbHnT71XYNh4EAAAGEQZrnSeEP",
772 "1nb4320+caQepQj4TCJtCeNXjdrVcNEnjvwlcRJwFT1pT+Y7HREbHnT71XYNh4EAAAGEQZrnSeEP",
773 "JlMCK/8AKIjxcI58rm/ML255fOJW1zbznFna7lfgMQrka7OTPPsvVAV4EJXye/Uxiu9dlftmRypJ",
773 "JlMCK/8AKIjxcI58rm/ML255fOJW1zbznFna7lfgMQrka7OTPPsvVAV4EJXye/Uxiu9dlftmRypJ",
774 "qfDot3xwDe8lX/qAVf6pBkSlUsaLyBYtww/SUSa1bGl1JvrJCN7FXCCXbLd5R4PoYlPiDIm/DQH2",
774 "qfDot3xwDe8lX/qAVf6pBkSlUsaLyBYtww/SUSa1bGl1JvrJCN7FXCCXbLd5R4PoYlPiDIm/DQH2",
775 "puO0StIWmrR77Isc/J1pRvdu5+mQa/n0SEHUeM2KkoRzCznfD9zaaRO7BDtvC9SYIT0uYZxrwTjx",
775 "puO0StIWmrR77Isc/J1pRvdu5+mQa/n0SEHUeM2KkoRzCznfD9zaaRO7BDtvC9SYIT0uYZxrwTjx",
776 "Q7N7UERTrYG0P+vRLAhxkfohFIYl3HXyjPOvnlbUFP2oiiy6nkUFuaIyQcJawJv3GU8k4ObcKsC1",
776 "Q7N7UERTrYG0P+vRLAhxkfohFIYl3HXyjPOvnlbUFP2oiiy6nkUFuaIyQcJawJv3GU8k4ObcKsC1",
777 "cNDXjSpsyQRrxLFaCCjke4mikyt7vs0iN0bnrNWv9HXruG9zOFEOer1ggIFTsT1Eos5CXRkgja5H",
777 "cNDXjSpsyQRrxLFaCCjke4mikyt7vs0iN0bnrNWv9HXruG9zOFEOer1ggIFTsT1Eos5CXRkgja5H",
778 "N4QUM6MhWpc5du/HgBIH8ANFcoo2kJpqcadw9r/0qk25X91MQSDJQiH8Hny2dQhqR+LFWEawiW75",
778 "N4QUM6MhWpc5du/HgBIH8ANFcoo2kJpqcadw9r/0qk25X91MQSDJQiH8Hny2dQhqR+LFWEawiW75",
779 "3SJhn0ngZcv/mPj3mwcHv1SL9ErBqAjm4JGiDetPKYtFwANYY11OyQAAAVdBmwhJ4Q8mUwIr/wAr",
779 "3SJhn0ngZcv/mPj3mwcHv1SL9ErBqAjm4JGiDetPKYtFwANYY11OyQAAAVdBmwhJ4Q8mUwIr/wAr",
780 "Ox5HV2505jRePGgMxptW4PGIHEszV1xGZS+flSkF+aq30AaqO7u6XK9jJsuWXTfYCRQTn1bZfFQ2",
780 "Ox5HV2505jRePGgMxptW4PGIHEszV1xGZS+flSkF+aq30AaqO7u6XK9jJsuWXTfYCRQTn1bZfFQ2",
781 "2DbO5DXAxK/TUmbQleCflFzeS6/czxkL4PJ8AwOs2U+oehekgCZC8gZyHHaQSaKbNJ46gTjNsLy8",
781 "2DbO5DXAxK/TUmbQleCflFzeS6/czxkL4PJ8AwOs2U+oehekgCZC8gZyHHaQSaKbNJ46gTjNsLy8",
782 "4ACQ5uNt11TPuCPqPTuh+schdw9S+/lU/6m+EyaqGZ49wDFPiBFBYXglQQBjyP9k/rqq0xL7SiLj",
782 "4ACQ5uNt11TPuCPqPTuh+schdw9S+/lU/6m+EyaqGZ49wDFPiBFBYXglQQBjyP9k/rqq0xL7SiLj",
783 "pe4riYg8SFUuUtOzPdWHyvxnI7Ug/0VLPGAAhgMISUnqe01d5QFf36yHpwMAHexjAZFIGQHAFaut",
783 "pe4riYg8SFUuUtOzPdWHyvxnI7Ug/0VLPGAAhgMISUnqe01d5QFf36yHpwMAHexjAZFIGQHAFaut",
784 "uMuEw6HzUZVzNdeHYxvEYOGkTo007bLwbuf/nxzrywGOxlRTYJLRdYI0mk0SdN3+LeTv1RIJwv21",
784 "uMuEw6HzUZVzNdeHYxvEYOGkTo007bLwbuf/nxzrywGOxlRTYJLRdYI0mk0SdN3+LeTv1RIJwv21",
785 "+e9rT5iFOTCgzeQoekEWXLYz0X8YLq5bVCtijP7/T7w1Ck71j0aqfrEn6wtIAAABNUGbKUnhDyZT",
785 "+e9rT5iFOTCgzeQoekEWXLYz0X8YLq5bVCtijP7/T7w1Ck71j0aqfrEn6wtIAAABNUGbKUnhDyZT",
786 "Aiv/ACcySi7VBgOid6qZNXvhh/JsllHkMLLq0yNbQTqv/Wk2EBoSKICZwFwAD0WRzhvvReCGirep",
786 "Aiv/ACcySi7VBgOid6qZNXvhh/JsllHkMLLq0yNbQTqv/Wk2EBoSKICZwFwAD0WRzhvvReCGirep",
787 "1Fe4bxjm49/UR+OYrXRmHR18T0C83AUVeBk7KvDZmb/eHzuzEN4yfXucr/NWFJl+USVMY4r4UQ9C",
787 "1Fe4bxjm49/UR+OYrXRmHR18T0C83AUVeBk7KvDZmb/eHzuzEN4yfXucr/NWFJl+USVMY4r4UQ9C",
788 "ayrfEY9v6AQ6mzAdLy2UMfFxrRJ99g/Rfl8qx+m4jIZNjlrTaThzJ/3OpVmAliDfxVyg8+CVIlI3",
788 "ayrfEY9v6AQ6mzAdLy2UMfFxrRJ99g/Rfl8qx+m4jIZNjlrTaThzJ/3OpVmAliDfxVyg8+CVIlI3",
789 "1IykiwQrXcebgajG+av8XU1SfyAG5ibvwbtdSAxkGBcJWL387V+uTdY56w3KN2vBtoQpVKD2zb3y",
789 "1IykiwQrXcebgajG+av8XU1SfyAG5ibvwbtdSAxkGBcJWL387V+uTdY56w3KN2vBtoQpVKD2zb3y",
790 "azIcATZ02upwIytNcM/rpaLCdMb1myWcikE25agzLhDhOS+4zwjYz2DnW6VY0gFBAPsphhsUMnau",
790 "azIcATZ02upwIytNcM/rpaLCdMb1myWcikE25agzLhDhOS+4zwjYz2DnW6VY0gFBAPsphhsUMnau",
791 "VVdUVHzCTSdvzEve/H8q4AAAAVdBm0pJ4Q8mUwIr/wAo+x5XKuiN1am7SkJKSMonFZDPU3f5XFcD",
791 "VVdUVHzCTSdvzEve/H8q4AAAAVdBm0pJ4Q8mUwIr/wAo+x5XKuiN1am7SkJKSMonFZDPU3f5XFcD",
792 "QSs0FLVq2idfsKwuIkt1mxIq8NgMHpzofTnDHqs/WedvAmhBgL0N5azdQa5MNKG2rJ4IAvGQY/uF",
792 "QSs0FLVq2idfsKwuIkt1mxIq8NgMHpzofTnDHqs/WedvAmhBgL0N5azdQa5MNKG2rJ4IAvGQY/uF",
793 "m3jKQAKzvhSS01gO1oIfizF817z9IShS4QK2WT0PeFPELqLSpED8eNOpVTR96vmwpk/WBKRVJdTQ",
793 "m3jKQAKzvhSS01gO1oIfizF817z9IShS4QK2WT0PeFPELqLSpED8eNOpVTR96vmwpk/WBKRVJdTQ",
794 "JzjiCQ5pgEwjtvk7KqoS0+lwXSbvIrXkYm8DignEts3DLNoLHrPjXlQmbIop76JZSyJEtB+91GrL",
794 "JzjiCQ5pgEwjtvk7KqoS0+lwXSbvIrXkYm8DignEts3DLNoLHrPjXlQmbIop76JZSyJEtB+91GrL",
795 "wo6Km5GeebyA2E6qGL3xSkpppej/ruoFprSKrH60UMbrq/SK7eCo+1QFoySPQmqDFsMGiQFqvtld",
795 "wo6Km5GeebyA2E6qGL3xSkpppej/ruoFprSKrH60UMbrq/SK7eCo+1QFoySPQmqDFsMGiQFqvtld",
796 "5BXDYdVI4yRaoyN7Y7wi83HRC6eVazuHU9OtIY3xJJApBWq1aJOsYwc38aTC3ee863Aa/4n9Lk4D",
796 "5BXDYdVI4yRaoyN7Y7wi83HRC6eVazuHU9OtIY3xJJApBWq1aJOsYwc38aTC3ee863Aa/4n9Lk4D",
797 "AtyFYHNZjB5m2e2vk8G2Gny9YFlBAAABQEGba0nhDyZTAiv/ACoZSZQfHxhfQxEqOBQrP+L3Dmgv",
797 "AtyFYHNZjB5m2e2vk8G2Gny9YFlBAAABQEGba0nhDyZTAiv/ACoZSZQfHxhfQxEqOBQrP+L3Dmgv",
798 "HSJQtB1iVkcLTxm+vagLHBLG91OGnopwrr7gT/loDypIhoRxjcwAAOeg/jN4WBbXzCJtnWGGllUC",
798 "HSJQtB1iVkcLTxm+vagLHBLG91OGnopwrr7gT/loDypIhoRxjcwAAOeg/jN4WBbXzCJtnWGGllUC",
799 "SdtUZQzKOSp9iM4yX18C6jrY4Sq6R9PUV/lEGNveJR4gw4FMve7110XdEPL1O2VTdHvdqeANyaq0",
799 "SdtUZQzKOSp9iM4yX18C6jrY4Sq6R9PUV/lEGNveJR4gw4FMve7110XdEPL1O2VTdHvdqeANyaq0",
800 "nLdEmtXnrzvdrFlBaUvmaR4EdlkqGkvkZKWJej8Vq+msbKa7JdbxjwZtRufiyGfD/NVqMgSrYRzw",
800 "nLdEmtXnrzvdrFlBaUvmaR4EdlkqGkvkZKWJej8Vq+msbKa7JdbxjwZtRufiyGfD/NVqMgSrYRzw",
801 "9z/a8Zwbr+9+19CxlWD5bCuAEfPmjY6kZJE2L/CQI6+tnCBTXOmWZtZMBoCLGOf7G2uAC3+kFlbo",
801 "9z/a8Zwbr+9+19CxlWD5bCuAEfPmjY6kZJE2L/CQI6+tnCBTXOmWZtZMBoCLGOf7G2uAC3+kFlbo",
802 "h9as5WCkO6+iqXq29dyhKnsHInorRYsPlgxIXyU1Om/Kyhj1DJV0Am9WJK3Dln0zNUH0q6ZTOnZc",
802 "h9as5WCkO6+iqXq29dyhKnsHInorRYsPlgxIXyU1Om/Kyhj1DJV0Am9WJK3Dln0zNUH0q6ZTOnZc",
803 "FD36AAABYkGbjEnhDyZTAiv/ACcwdIOLRFfoGK2ZkKsvgMwG0m0qsY0vMLPSzefc+ebp/aztyF7M",
803 "FD36AAABYkGbjEnhDyZTAiv/ACcwdIOLRFfoGK2ZkKsvgMwG0m0qsY0vMLPSzefc+ebp/aztyF7M",
804 "lsBz/fBeNtxFBcsKgR4pf65GvdfOMHah0ltZ918sMDmXUEZMeRHy/xpnWpTLeGz6uTs/7MATPmU5",
804 "lsBz/fBeNtxFBcsKgR4pf65GvdfOMHah0ltZ918sMDmXUEZMeRHy/xpnWpTLeGz6uTs/7MATPmU5",
805 "BgHbT/DkD8QeaZnFAzidyFCXDz2l/jaKhEdgqipbB2pH0+fQ039r05z9axxEWGmaLQjg6x9+po1o",
805 "BgHbT/DkD8QeaZnFAzidyFCXDz2l/jaKhEdgqipbB2pH0+fQ039r05z9axxEWGmaLQjg6x9+po1o",
806 "24yhkVO7m03YwWmPyCgy8cOwrvRyJkXJpRN4m8ZBS1zwY80HeN/VyMQQJSMwsTo7R1XMerSFuyx0",
806 "24yhkVO7m03YwWmPyCgy8cOwrvRyJkXJpRN4m8ZBS1zwY80HeN/VyMQQJSMwsTo7R1XMerSFuyx0",
807 "nz+8qOuhiqykc2ohCCsXia/+kIKbJ5Vs+cbWtvkqBKIDSfU7FhAd3GjcY/xar0EVmi6wWFTugAog",
807 "nz+8qOuhiqykc2ohCCsXia/+kIKbJ5Vs+cbWtvkqBKIDSfU7FhAd3GjcY/xar0EVmi6wWFTugAog",
808 "R3I7mTrQDdlTAqYgqO7Gn5NMXQVHu2i1zhFSdo9GjMbeGnbkJwsFbQ2XkoKRIDpuW7AewC9AEBt0",
808 "R3I7mTrQDdlTAqYgqO7Gn5NMXQVHu2i1zhFSdo9GjMbeGnbkJwsFbQ2XkoKRIDpuW7AewC9AEBt0",
809 "Ox/Ah6dGXfXO1jl8pEApj2RFmgAAAPlBm61J4Q8mUwIr/wAlR+eW/VZ7bSrmwwMA62G05DZ7p/5F",
809 "Ox/Ah6dGXfXO1jl8pEApj2RFmgAAAPlBm61J4Q8mUwIr/wAlR+eW/VZ7bSrmwwMA62G05DZ7p/5F",
810 "UugsSsQdonUq6abtbU5hjFr+I1lPgoiV5c3CkTQZS+K5zivdo+Ti2P4K90xXANp8dSMAu85uJIOC",
810 "UugsSsQdonUq6abtbU5hjFr+I1lPgoiV5c3CkTQZS+K5zivdo+Ti2P4K90xXANp8dSMAu85uJIOC",
811 "Qn2TXbEnNDifLB+3V84ht5tj4lvTaZx317BcliV8D5v2zZQW8RO1mUbuJEBItst8E7hfE+ZXj7tf",
811 "Qn2TXbEnNDifLB+3V84ht5tj4lvTaZx317BcliV8D5v2zZQW8RO1mUbuJEBItst8E7hfE+ZXj7tf",
812 "DxNZPTvtpFyUv0fH1cTg1pr2VLy0d0zQLiA58dg+GkRvR1/hs2LyifBgHcj6eTWz0vsypVn9iPXR",
812 "DxNZPTvtpFyUv0fH1cTg1pr2VLy0d0zQLiA58dg+GkRvR1/hs2LyifBgHcj6eTWz0vsypVn9iPXR",
813 "H/unJ6i8cfFL69NO24tQ9QQB+nDFhoP2cRhkAvhHwn56n5PppBD/oxni2f8AAAE9QZvOSeEPJlMC",
813 "H/unJ6i8cfFL69NO24tQ9QQB+nDFhoP2cRhkAvhHwn56n5PppBD/oxni2f8AAAE9QZvOSeEPJlMC",
814 "K/8AJjAXVGf+Kj2XNJnFeKC/gr7dJDTC2ngpd4WeAHlg04GuJKnn9hAmiECxxo9qM1IYMRiB85t6",
814 "K/8AJjAXVGf+Kj2XNJnFeKC/gr7dJDTC2ngpd4WeAHlg04GuJKnn9hAmiECxxo9qM1IYMRiB85t6",
815 "gALnlm9sRqGmioyzAm18RJndc9Ah8RlpGzr+44a6ntRaPx0cIwNIWAA8buL2JP00dmfjNqEiAlCa",
815 "gALnlm9sRqGmioyzAm18RJndc9Ah8RlpGzr+44a6ntRaPx0cIwNIWAA8buL2JP00dmfjNqEiAlCa",
816 "8OdV8FQxjp1vDXsGcAGF3Qbd62KEpkimeI3wH2nuXpbDHm8/ZKOR49s5ifUCkxCoJpfp43aC0lTz",
816 "8OdV8FQxjp1vDXsGcAGF3Qbd62KEpkimeI3wH2nuXpbDHm8/ZKOR49s5ifUCkxCoJpfp43aC0lTz",
817 "h2NXpcfVw6h0QnK8G60R4ZAxOxaJB7c0nn8ixXSU2JVY24EtGMF53nxJnHfzUheewUfBOGYSxeo8",
817 "h2NXpcfVw6h0QnK8G60R4ZAxOxaJB7c0nn8ixXSU2JVY24EtGMF53nxJnHfzUheewUfBOGYSxeo8",
818 "oK7oUCqX4rztzDwoc2QywNqQUJUkFrqIN+sb5ecYvX24Zujn+ZzTW6UDAF3R6WdNyJyRAremgC8s",
818 "oK7oUCqX4rztzDwoc2QywNqQUJUkFrqIN+sb5ecYvX24Zujn+ZzTW6UDAF3R6WdNyJyRAremgC8s",
819 "pSflTqygQNGfHyGkfIEEJJaFo/pBCBkAAAEWQZvvSeEPJlMCK/8AKI41fuekXG59Knbw4Y6YJrit",
819 "pSflTqygQNGfHyGkfIEEJJaFo/pBCBkAAAEWQZvvSeEPJlMCK/8AKI41fuekXG59Knbw4Y6YJrit",
820 "sh9VtQgc3QKvVmxrzzo7f4aXn8N74eyP4b2lV1Z2Q+rohxps7EHTkOY9jLdqxI3MXe7je4g2qepz",
820 "sh9VtQgc3QKvVmxrzzo7f4aXn8N74eyP4b2lV1Z2Q+rohxps7EHTkOY9jLdqxI3MXe7je4g2qepz",
821 "71+hY+jYdX+9LO0kA0Zg3NfyAlIRX7k6c/YHAZNtNaGZgTBMqiPgmEjiJH9Luk7shbgr+srfwiYw",
821 "71+hY+jYdX+9LO0kA0Zg3NfyAlIRX7k6c/YHAZNtNaGZgTBMqiPgmEjiJH9Luk7shbgr+srfwiYw",
822 "BX9rdS3fQNNFwcT8orQC+F60LAY9+GbFo2Sw3Ld4Tw9jq9yJtrY8RtHAdzytyek/mv2+j2TbTvAQ",
822 "BX9rdS3fQNNFwcT8orQC+F60LAY9+GbFo2Sw3Ld4Tw9jq9yJtrY8RtHAdzytyek/mv2+j2TbTvAQ",
823 "KbbCYtdC8E/KtR4V5ZTSScr5Wb63vmbw7UpddEXYvl55pARyyvMxWNSh3Li4GF8Jk5JBi5B5ASQw",
823 "KbbCYtdC8E/KtR4V5ZTSScr5Wb63vmbw7UpddEXYvl55pARyyvMxWNSh3Li4GF8Jk5JBi5B5ASQw",
824 "xCMYpX5hkAMc+d8tl2bT+IEvUTsAAAElQZoQSeEPJlMCK/8AJIAzFZs00JJ0yfm8CZiew4xWdArL",
824 "xCMYpX5hkAMc+d8tl2bT+IEvUTsAAAElQZoQSeEPJlMCK/8AJIAzFZs00JJ0yfm8CZiew4xWdArL",
825 "klEvBVXo/+ukPLu3XP9HFOfsme3T6BJEKmPPgZw/Lxnraq6Sl2kLVW19YU1qmqgfv+80LkZaWU5g",
825 "klEvBVXo/+ukPLu3XP9HFOfsme3T6BJEKmPPgZw/Lxnraq6Sl2kLVW19YU1qmqgfv+80LkZaWU5g",
826 "RAH4hqyo3bFYcbuY2SC3IW5Wm69gtYyAXOdbAYSEHA16fvCeRQjHEsxKVndJdrRAlrGHsKgUBQ3U",
826 "RAH4hqyo3bFYcbuY2SC3IW5Wm69gtYyAXOdbAYSEHA16fvCeRQjHEsxKVndJdrRAlrGHsKgUBQ3U",
827 "p/ZXIy1vkdFOfKSjpuZnswkuqr8NZI5tJ/dnBSErBTNWPaNwWV7nNomC0EYVGo+geGBhLXzaLw0U",
827 "p/ZXIy1vkdFOfKSjpuZnswkuqr8NZI5tJ/dnBSErBTNWPaNwWV7nNomC0EYVGo+geGBhLXzaLw0U",
828 "AOCYGjiPc3803BDw1GLoLIXjrIFJxwRfBNIAXYZAglu30oYzhpAfRWSprkeULMWYJTlWvbUQ5CNe",
828 "AOCYGjiPc3803BDw1GLoLIXjrIFJxwRfBNIAXYZAglu30oYzhpAfRWSprkeULMWYJTlWvbUQ5CNe",
829 "wSZssuDWIRAc3w8AcFaywwn+YSGhtR8VI1OGjYkfBbcAAAD8QZoxSeEPJlMCK/8AJdokjCUETRw/",
829 "wSZssuDWIRAc3w8AcFaywwn+YSGhtR8VI1OGjYkfBbcAAAD8QZoxSeEPJlMCK/8AJdokjCUETRw/",
830 "nciVPtaZQSBP/VxAQSITASEzlJBl9Na1r0DJhLOz279+KQLtl/xHZ8vAKc528mTMTqtWs4sFbeVg",
830 "nciVPtaZQSBP/VxAQSITASEzlJBl9Na1r0DJhLOz279+KQLtl/xHZ8vAKc528mTMTqtWs4sFbeVg",
831 "HWyBpHcHEtgTzjIqEinp/MPuUXF5poo8YLSSMFn9Ozx2FbU5/Kh9A39oN9NHQflVxV1NA6yT/84H",
831 "HWyBpHcHEtgTzjIqEinp/MPuUXF5poo8YLSSMFn9Ozx2FbU5/Kh9A39oN9NHQflVxV1NA6yT/84H",
832 "HyfMtfdSMS8KTvAEE2lDs14VQayNs5ctjXboQT7xMBf5OLj6thhPvgaDrFB2o/PV9ouK147lruWT",
832 "HyfMtfdSMS8KTvAEE2lDs14VQayNs5ctjXboQT7xMBf5OLj6thhPvgaDrFB2o/PV9ouK147lruWT",
833 "P2mkoA9oDIMYW1pcBx4yyV/t9GOPZ3aXneMUb2fFmUCX43BjXfUDMaa4GO2/Ankj3UEQwDxA7ZlN",
833 "P2mkoA9oDIMYW1pcBx4yyV/t9GOPZ3aXneMUb2fFmUCX43BjXfUDMaa4GO2/Ankj3UEQwDxA7ZlN",
834 "UQK2AAAA4UGaUknhDyZTAiv/ACJHv33I08bkhybYiJ/JiiheW5zMPBu4n5CxGr3frhE7TkLh0vPk",
834 "UQK2AAAA4UGaUknhDyZTAiv/ACJHv33I08bkhybYiJ/JiiheW5zMPBu4n5CxGr3frhE7TkLh0vPk",
835 "tM8m/AhaDiJisdk5QXNe/4WmxEDSAyaVi4eUVu0iHT2ly/KNTGqiORqA2oKpTjh84nYbrpXwnGv9",
835 "tM8m/AhaDiJisdk5QXNe/4WmxEDSAyaVi4eUVu0iHT2ly/KNTGqiORqA2oKpTjh84nYbrpXwnGv9",
836 "SOf/34Z06xN6Yo3t35UZrP8nlcs/63GtnEmnUwVZHBYfPM6bs5M5AeBfAQ/9mIqu7vnEst+5O2wp",
836 "SOf/34Z06xN6Yo3t35UZrP8nlcs/63GtnEmnUwVZHBYfPM6bs5M5AeBfAQ/9mIqu7vnEst+5O2wp",
837 "PjzdItjwGCZ2ApHVjGnYYFomlA9nm6AXnxNIWHIsDgxCk3zx+6QbXipu/CWLG1Wf0WIbt4C0JPVl",
837 "PjzdItjwGCZ2ApHVjGnYYFomlA9nm6AXnxNIWHIsDgxCk3zx+6QbXipu/CWLG1Wf0WIbt4C0JPVl",
838 "3TEb0QAAAMlBmnNJ4Q8mUwIr/wAVV64OfTKmlktYOqZHH1W1DhPy/X/6sD4T6hRdzfOgNtTOX2Ic",
838 "3TEb0QAAAMlBmnNJ4Q8mUwIr/wAVV64OfTKmlktYOqZHH1W1DhPy/X/6sD4T6hRdzfOgNtTOX2Ic",
839 "kRJHshfBQVkJIzns079io6kpJFCcS3VD4zrWCn/dNaGV0kWTpFBRuusfn8F0C0R/EhsQeyTsdZft",
839 "kRJHshfBQVkJIzns079io6kpJFCcS3VD4zrWCn/dNaGV0kWTpFBRuusfn8F0C0R/EhsQeyTsdZft",
840 "EkLGb5tq+nrir3vfmeb7rjmWJRXkIrTEKu8pIuAd+4FBGp8ARgGe80Jqpp//s1433HqBFqXsIFJT",
840 "EkLGb5tq+nrir3vfmeb7rjmWJRXkIrTEKu8pIuAd+4FBGp8ARgGe80Jqpp//s1433HqBFqXsIFJT",
841 "mU8j/toF9HyueI1Ea4uvsQ6NANGcYCbOAKCmbNiwABMCFaiUTMAAAAPSbW9vdgAAAGxtdmhkAAAA",
841 "mU8j/toF9HyueI1Ea4uvsQ6NANGcYCbOAKCmbNiwABMCFaiUTMAAAAPSbW9vdgAAAGxtdmhkAAAA",
842 "AHwlsIB8JbCAAAAD6AAAAyAAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAA",
842 "AHwlsIB8JbCAAAAD6AAAAyAAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAA",
843 "AAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAv10cmFrAAAAXHRraGQA",
843 "AAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAv10cmFrAAAAXHRraGQA",
844 "AAAPfCWwgHwlsIAAAAABAAAAAAAAAyAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB",
844 "AAAPfCWwgHwlsIAAAAABAAAAAAAAAyAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB",
845 "AAAAAAAAAAAAAAAAAABAAAAAAY4AAAGGAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAMgAAAA",
845 "AAAAAAAAAAAAAAAAAABAAAAAAY4AAAGGAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAMgAAAA",
846 "AgABAAAAAAJ1bWRpYQAAACBtZGhkAAAAAHwlsIB8JbCAAAAAGQAAABRVxAAAAAAALWhkbHIAAAAA",
846 "AgABAAAAAAJ1bWRpYQAAACBtZGhkAAAAAHwlsIB8JbCAAAAAGQAAABRVxAAAAAAALWhkbHIAAAAA",
847 "AAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACIG1pbmYAAAAUdm1oZAAAAAEAAAAA",
847 "AAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACIG1pbmYAAAAUdm1oZAAAAAEAAAAA",
848 "AAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAeBzdGJsAAAAtHN0c2QA",
848 "AAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAeBzdGJsAAAAtHN0c2QA",
849 "AAAAAAAAAQAAAKRhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAY4BhgBIAAAASAAAAAAAAAAB",
849 "AAAAAAAAAQAAAKRhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAY4BhgBIAAAASAAAAAAAAAAB",
850 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAAMmF2Y0MBZAAV/+EAGWdkABWs",
850 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAAMmF2Y0MBZAAV/+EAGWdkABWs",
851 "2UGQz6mhAAADAAEAAAMAMg8WLZYBAAZo6+PLIsAAAAAcdXVpZGtoQPJfJE/FujmlG88DI/MAAAAA",
851 "2UGQz6mhAAADAAEAAAMAMg8WLZYBAAZo6+PLIsAAAAAcdXVpZGtoQPJfJE/FujmlG88DI/MAAAAA",
852 "AAAAGHN0dHMAAAAAAAAAAQAAABQAAAABAAAAFHN0c3MAAAAAAAAAAQAAAAEAAAAYY3R0cwAAAAAA",
852 "AAAAGHN0dHMAAAAAAAAAAQAAABQAAAABAAAAFHN0c3MAAAAAAAAAAQAAAAEAAAAYY3R0cwAAAAAA",
853 "AAABAAAAFAAAAAIAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAZHN0c3oAAAAAAAAAAAAA",
853 "AAABAAAAFAAAAAIAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAZHN0c3oAAAAAAAAAAAAA",
854 "ABQAAA05AAACqQAAAl8AAAITAAACiwAAAh8AAAIvAAABiAAAAVsAAAE5AAABWwAAAUQAAAFmAAAA",
854 "ABQAAA05AAACqQAAAl8AAAITAAACiwAAAh8AAAIvAAABiAAAAVsAAAE5AAABWwAAAUQAAAFmAAAA",
855 "/QAAAUEAAAEaAAABKQAAAQAAAADlAAAAzQAAAGBzdGNvAAAAAAAAABQAAAAsAAANZQAAEA4AABJt",
855 "/QAAAUEAAAEaAAABKQAAAQAAAADlAAAAzQAAAGBzdGNvAAAAAAAAABQAAAAsAAANZQAAEA4AABJt",
856 "AAAUgAAAFwsAABkqAAAbWQAAHOEAAB48AAAfdQAAINAAACIUAAAjegAAJHcAACW4AAAm0gAAJ/sA",
856 "AAAUgAAAFwsAABkqAAAbWQAAHOEAAB48AAAfdQAAINAAACIUAAAjegAAJHcAACW4AAAm0gAAJ/sA",
857 "ACj7AAAp4AAAAGF1ZHRhAAAAWW1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAA",
857 "ACj7AAAp4AAAAGF1ZHRhAAAAWW1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAA",
858 "AAAAAAAALGlsc3QAAAAkqXRvbwAAABxkYXRhAAAAAQAAAABMYXZmNTIuMTExLjA=",
858 "AAAAAAAALGlsc3QAAAAkqXRvbwAAABxkYXRhAAAAAQAAAABMYXZmNTIuMTExLjA=",
859 "\">"
859 "\">"
860 ],
860 ],
861 "output_type": "pyout",
861 "output_type": "pyout",
862 "prompt_number": 5,
862 "prompt_number": 5,
863 "text": [
863 "text": [
864 "&lt;IPython.core.display.HTML at 0x423a550&gt;"
864 "&lt;IPython.core.display.HTML at 0x423a550&gt;"
865 ]
865 ]
866 }
866 }
867 ],
867 ],
868 "prompt_number": 5
868 "prompt_number": 5
869 },
869 },
870 {
870 {
871 "cell_type": "markdown",
871 "cell_type": "markdown",
872 "source": [
872 "source": [
873 "## Local Files",
873 "## Local Files",
874 "",
874 "",
875 "The above examples embed images and video from the notebook filesystem in the output",
875 "The above examples embed images and video from the notebook filesystem in the output",
876 "areas of code cells. It is also possible to request these files directly in markdown cells",
876 "areas of code cells. It is also possible to request these files directly in markdown cells",
877 "if they reside in the notebook directory via relative urls prefixed with `files/`:",
877 "if they reside in the notebook directory via relative urls prefixed with `files/`:",
878 "",
878 "",
879 " files/[subdirectory/]<filename>",
879 " files/[subdirectory/]<filename>",
880 "",
880 "",
881 "",
881 "",
882 "For example, in the example notebook folder, we have the Python logo, addressed as:",
882 "For example, in the example notebook folder, we have the Python logo, addressed as:",
883 "",
883 "",
884 " <img src=\"files/python-logo.svg\" />",
884 " <img src=\"files/python-logo.svg\" />",
885 "",
885 "",
886 "<img src=\"/files/python-logo.svg\" />",
886 "<img src=\"/files/python-logo.svg\" />",
887 "",
887 "",
888 "and a video with the HTML5 video tag:",
888 "and a video with the HTML5 video tag:",
889 "",
889 "",
890 " <video controls src=\"files/animation.m4v\" />",
890 " <video controls src=\"files/animation.m4v\" />",
891 "",
891 "",
892 "<video controls src=\"/files/animation.m4v\" />",
892 "<video controls src=\"/files/animation.m4v\" />",
893 "",
893 "",
894 "These do not embed the data into the notebook file,",
894 "These do not embed the data into the notebook file,",
895 "and require that the files exist when you are viewing the notebook.",
895 "and require that the files exist when you are viewing the notebook.",
896 "",
896 "",
897 "### Security of local files",
897 "### Security of local files",
898 "",
898 "",
899 "Note that this means that the IPython notebook server also acts as a generic file server",
899 "Note that this means that the IPython notebook server also acts as a generic file server",
900 "for files inside the same tree as your notebooks. Access is not granted outside the",
900 "for files inside the same tree as your notebooks. Access is not granted outside the",
901 "notebook folder so you have strict control over what files are visible, but for this",
901 "notebook folder so you have strict control over what files are visible, but for this",
902 "reason it is highly recommended that you do not run the notebook server with a notebook",
902 "reason it is highly recommended that you do not run the notebook server with a notebook",
903 "directory at a high level in your filesystem (e.g. your home directory).",
903 "directory at a high level in your filesystem (e.g. your home directory).",
904 "",
904 "",
905 "When you run the notebook in a password-protected manner, local file access is restricted",
905 "When you run the notebook in a password-protected manner, local file access is restricted",
906 "to authenticated users unless read-only views are active."
906 "to authenticated users unless read-only views are active."
907 ]
907 ]
908 },
908 },
909 {
909 {
910 "cell_type": "markdown",
910 "cell_type": "markdown",
911 "source": [
911 "source": [
912 "### External sites",
912 "### External sites",
913 "",
913 "",
914 "You can even embed an entire page from another site in an iframe; for example this is today's Wikipedia",
914 "You can even embed an entire page from another site in an iframe; for example this is today's Wikipedia",
915 "page for mobile users:"
915 "page for mobile users:"
916 ]
916 ]
917 },
917 },
918 {
918 {
919 "cell_type": "code",
919 "cell_type": "code",
920 "collapsed": false,
920 "collapsed": false,
921 "input": [
921 "input": [
922 "HTML('<iframe src=http://en.mobile.wikipedia.org/?useformat=mobile width=700 height=350>')"
922 "HTML('<iframe src=http://en.mobile.wikipedia.org/?useformat=mobile width=700 height=350>')"
923 ],
923 ],
924 "language": "python",
924 "language": "python",
925 "outputs": [
925 "outputs": [
926 {
926 {
927 "html": [
927 "html": [
928 "<iframe src=http://en.mobile.wikipedia.org/?useformat=mobile width=700 height=350>"
928 "<iframe src=http://en.mobile.wikipedia.org/?useformat=mobile width=700 height=350>"
929 ],
929 ],
930 "output_type": "pyout",
930 "output_type": "pyout",
931 "prompt_number": 6,
931 "prompt_number": 6,
932 "text": [
932 "text": [
933 "&lt;IPython.core.display.HTML at 0x41d4710&gt;"
933 "&lt;IPython.core.display.HTML at 0x41d4710&gt;"
934 ]
934 ]
935 }
935 }
936 ],
936 ],
937 "prompt_number": 6
937 "prompt_number": 6
938 },
938 },
939 {
939 {
940 "cell_type": "markdown",
940 "cell_type": "markdown",
941 "source": [
941 "source": [
942 "### Mathematics",
942 "### Mathematics",
943 "",
943 "",
944 "And we also support the display of mathematical expressions typeset in LaTeX, which is rendered",
944 "And we also support the display of mathematical expressions typeset in LaTeX, which is rendered",
945 "in the browser thanks to the [MathJax library](http://mathjax.org). ",
945 "in the browser thanks to the [MathJax library](http://mathjax.org). ",
946 "",
946 "",
947 "Note that this is *different* from the above examples. Above we were typing mathematical expressions",
947 "Note that this is *different* from the above examples. Above we were typing mathematical expressions",
948 "in Markdown cells (along with normal text) and letting the browser render them; now we are displaying",
948 "in Markdown cells (along with normal text) and letting the browser render them; now we are displaying",
949 "the output of a Python computation as a LaTeX expression wrapped by the `Math()` object so the browser",
949 "the output of a Python computation as a LaTeX expression wrapped by the `Math()` object so the browser",
950 "renders it. The `Math` object will add the needed LaTeX delimiters (`$$`) if they are not provided:"
950 "renders it. The `Math` object will add the needed LaTeX delimiters (`$$`) if they are not provided:"
951 ]
951 ]
952 },
952 },
953 {
953 {
954 "cell_type": "code",
954 "cell_type": "code",
955 "collapsed": false,
955 "collapsed": false,
956 "input": [
956 "input": [
957 "from IPython.core.display import Math",
957 "from IPython.core.display import Math",
958 "Math(r'F(k) = \\int_{-\\infty}^{\\infty} f(x) e^{2\\pi i k} dx')"
958 "Math(r'F(k) = \\int_{-\\infty}^{\\infty} f(x) e^{2\\pi i k} dx')"
959 ],
959 ],
960 "language": "python",
960 "language": "python",
961 "outputs": [
961 "outputs": [
962 {
962 {
963 "latex": [
963 "latex": [
964 "$$F(k) = \\int_{-\\infty}^{\\infty} f(x) e^{2\\pi i k} dx$$"
964 "$$F(k) = \\int_{-\\infty}^{\\infty} f(x) e^{2\\pi i k} dx$$"
965 ],
965 ],
966 "output_type": "pyout",
966 "output_type": "pyout",
967 "prompt_number": 1,
967 "prompt_number": 1,
968 "text": [
968 "text": [
969 "<IPython.core.display.Math object at 0x10ad35e90>"
969 "<IPython.core.display.Math object at 0x10ad35e90>"
970 ]
970 ]
971 }
971 }
972 ],
972 ],
973 "prompt_number": 1
973 "prompt_number": 1
974 },
974 },
975 {
975 {
976 "cell_type": "markdown",
976 "cell_type": "markdown",
977 "source": [
977 "source": [
978 "With the `Latex` class, you have to include the delimiters yourself. This allows you to use other LaTeX modes such as `eqnarray`:"
978 "With the `Latex` class, you have to include the delimiters yourself. This allows you to use other LaTeX modes such as `eqnarray`:"
979 ]
979 ]
980 },
980 },
981 {
981 {
982 "cell_type": "code",
982 "cell_type": "code",
983 "collapsed": false,
983 "collapsed": false,
984 "input": [
984 "input": [
985 "from IPython.core.display import Latex",
985 "from IPython.core.display import Latex",
986 "Latex(r\"\"\"\\begin{eqnarray}",
986 "Latex(r\"\"\"\\begin{eqnarray}",
987 "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\",
987 "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\",
988 "\\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\",
988 "\\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\",
989 "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\",
989 "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\",
990 "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 ",
990 "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 ",
991 "\\end{eqnarray}\"\"\")"
991 "\\end{eqnarray}\"\"\")"
992 ],
992 ],
993 "language": "python",
993 "language": "python",
994 "outputs": [
994 "outputs": [
995 {
995 {
996 "latex": [
996 "latex": [
997 "\\begin{eqnarray}",
997 "\\begin{eqnarray}",
998 "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\ \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\",
998 "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\ \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\",
999 "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\",
999 "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\",
1000 "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 ",
1000 "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 ",
1001 "\\end{eqnarray}"
1001 "\\end{eqnarray}"
1002 ],
1002 ],
1003 "output_type": "pyout",
1003 "output_type": "pyout",
1004 "prompt_number": 5,
1004 "prompt_number": 5,
1005 "text": [
1005 "text": [
1006 "<IPython.core.display.Latex object at 0x109a38790>"
1006 "<IPython.core.display.Latex object at 0x109a38790>"
1007 ]
1007 ]
1008 }
1008 }
1009 ],
1009 ],
1010 "prompt_number": 5
1010 "prompt_number": 5
1011 },
1011 },
1012 {
1012 {
1013 "cell_type": "markdown",
1013 "cell_type": "markdown",
1014 "source": [
1014 "source": [
1015 "# Loading external codes",
1015 "# Loading external codes",
1016 "* Drag and drop a ``.py`` in the dashboard",
1016 "* Drag and drop a ``.py`` in the dashboard",
1017 "* Use ``%loadpy`` with any local or remote url: [the Matplotlib Gallery!](http://matplotlib.sourceforge.net/gallery.html)",
1017 "* Use ``%load`` with any local or remote url: [the Matplotlib Gallery!](http://matplotlib.sourceforge.net/gallery.html)",
1018 "",
1018 "",
1019 "In this notebook we've kept the output saved so you can see the result, but you should run the next",
1019 "In this notebook we've kept the output saved so you can see the result, but you should run the next",
1020 "cell yourself (with an active internet connection)."
1020 "cell yourself (with an active internet connection)."
1021 ]
1021 ]
1022 },
1022 },
1023 {
1023 {
1024 "cell_type": "code",
1024 "cell_type": "code",
1025 "collapsed": true,
1025 "collapsed": true,
1026 "input": [
1026 "input": [
1027 "%loadpy http://matplotlib.sourceforge.net/mpl_examples/pylab_examples/integral_demo.py"
1027 "%load http://matplotlib.sourceforge.net/mpl_examples/pylab_examples/integral_demo.py"
1028 ],
1028 ],
1029 "language": "python",
1029 "language": "python",
1030 "outputs": [],
1030 "outputs": [],
1031 "prompt_number": 8
1031 "prompt_number": 8
1032 },
1032 },
1033 {
1033 {
1034 "cell_type": "code",
1034 "cell_type": "code",
1035 "collapsed": false,
1035 "collapsed": false,
1036 "input": [
1036 "input": [
1037 "#!/usr/bin/env python",
1037 "#!/usr/bin/env python",
1038 "",
1038 "",
1039 "# implement the example graphs/integral from pyx",
1039 "# implement the example graphs/integral from pyx",
1040 "from pylab import *",
1040 "from pylab import *",
1041 "from matplotlib.patches import Polygon",
1041 "from matplotlib.patches import Polygon",
1042 "",
1042 "",
1043 "def func(x):",
1043 "def func(x):",
1044 " return (x-3)*(x-5)*(x-7)+85",
1044 " return (x-3)*(x-5)*(x-7)+85",
1045 "",
1045 "",
1046 "ax = subplot(111)",
1046 "ax = subplot(111)",
1047 "",
1047 "",
1048 "a, b = 2, 9 # integral area",
1048 "a, b = 2, 9 # integral area",
1049 "x = arange(0, 10, 0.01)",
1049 "x = arange(0, 10, 0.01)",
1050 "y = func(x)",
1050 "y = func(x)",
1051 "plot(x, y, linewidth=1)",
1051 "plot(x, y, linewidth=1)",
1052 "",
1052 "",
1053 "# make the shaded region",
1053 "# make the shaded region",
1054 "ix = arange(a, b, 0.01)",
1054 "ix = arange(a, b, 0.01)",
1055 "iy = func(ix)",
1055 "iy = func(ix)",
1056 "verts = [(a,0)] + zip(ix,iy) + [(b,0)]",
1056 "verts = [(a,0)] + zip(ix,iy) + [(b,0)]",
1057 "poly = Polygon(verts, facecolor='0.8', edgecolor='k')",
1057 "poly = Polygon(verts, facecolor='0.8', edgecolor='k')",
1058 "ax.add_patch(poly)",
1058 "ax.add_patch(poly)",
1059 "",
1059 "",
1060 "text(0.5 * (a + b), 30,",
1060 "text(0.5 * (a + b), 30,",
1061 " r\"$\\int_a^b f(x)\\mathrm{d}x$\", horizontalalignment='center',",
1061 " r\"$\\int_a^b f(x)\\mathrm{d}x$\", horizontalalignment='center',",
1062 " fontsize=20)",
1062 " fontsize=20)",
1063 "",
1063 "",
1064 "axis([0,10, 0, 180])",
1064 "axis([0,10, 0, 180])",
1065 "figtext(0.9, 0.05, 'x')",
1065 "figtext(0.9, 0.05, 'x')",
1066 "figtext(0.1, 0.9, 'y')",
1066 "figtext(0.1, 0.9, 'y')",
1067 "ax.set_xticks((a,b))",
1067 "ax.set_xticks((a,b))",
1068 "ax.set_xticklabels(('a','b'))",
1068 "ax.set_xticklabels(('a','b'))",
1069 "ax.set_yticks([])",
1069 "ax.set_yticks([])",
1070 "show()"
1070 "show()"
1071 ],
1071 ],
1072 "language": "python",
1072 "language": "python",
1073 "outputs": [
1073 "outputs": [
1074 {
1074 {
1075 "output_type": "display_data",
1075 "output_type": "display_data",
1076 "png": "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\nSUVORK5CYII=\n"
1076 "png": "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\nSUVORK5CYII=\n"
1077 }
1077 }
1078 ],
1078 ],
1079 "prompt_number": 9
1079 "prompt_number": 9
1080 },
1080 },
1081 {
1081 {
1082 "cell_type": "code",
1082 "cell_type": "code",
1083 "collapsed": true,
1083 "collapsed": true,
1084 "input": [
1084 "input": [
1085 ""
1085 ""
1086 ],
1086 ],
1087 "language": "python",
1087 "language": "python",
1088 "outputs": []
1088 "outputs": []
1089 }
1089 }
1090 ]
1090 ]
1091 }
1091 }
1092 ]
1092 ]
1093 }
1093 }
@@ -1,31 +1,31 b''
1 """
1 """
2 Run this script in the qtconsole with one of:
2 Run this script in the qtconsole with one of:
3
3
4 %loadpy hb_gil.py
4 %load hb_gil.py
5
5
6 or
6 or
7 %run hb_gil.py
7 %run hb_gil.py
8
8
9 Holding the GIL for too long could disrupt the heartbeat.
9 Holding the GIL for too long could disrupt the heartbeat.
10
10
11 See Issue #1260: https://github.com/ipython/ipython/issues/1260
11 See Issue #1260: https://github.com/ipython/ipython/issues/1260
12
12
13 """
13 """
14
14
15 import sys
15 import sys
16 import time
16 import time
17
17
18 from cython import inline
18 from cython import inline
19
19
20 def gilsleep(t):
20 def gilsleep(t):
21 """gil-holding sleep with cython.inline"""
21 """gil-holding sleep with cython.inline"""
22 code = '\n'.join([
22 code = '\n'.join([
23 'from posix cimport unistd',
23 'from posix cimport unistd',
24 'unistd.sleep(t)',
24 'unistd.sleep(t)',
25 ])
25 ])
26 while True:
26 while True:
27 inline(code, quiet=True, t=t)
27 inline(code, quiet=True, t=t)
28 print(time.time())
28 print(time.time())
29 sys.stdout.flush() # this is important
29 sys.stdout.flush() # this is important
30
30
31 gilsleep(5)
31 gilsleep(5)
@@ -1,609 +1,609 b''
1 .. _qtconsole:
1 .. _qtconsole:
2
2
3 =========================
3 =========================
4 A Qt Console for IPython
4 A Qt Console for IPython
5 =========================
5 =========================
6
6
7 We now have a version of IPython, using the new two-process :ref:`ZeroMQ Kernel
7 We now have a version of IPython, using the new two-process :ref:`ZeroMQ Kernel
8 <ipythonzmq>`, running in a PyQt_ GUI. This is a very lightweight widget that
8 <ipythonzmq>`, running in a PyQt_ GUI. This is a very lightweight widget that
9 largely feels like a terminal, but provides a number of enhancements only
9 largely feels like a terminal, but provides a number of enhancements only
10 possible in a GUI, such as inline figures, proper multiline editing with syntax
10 possible in a GUI, such as inline figures, proper multiline editing with syntax
11 highlighting, graphical calltips, and much more.
11 highlighting, graphical calltips, and much more.
12
12
13 .. figure:: ../_static/qtconsole.png
13 .. figure:: ../_static/qtconsole.png
14 :width: 400px
14 :width: 400px
15 :alt: IPython Qt console with embedded plots
15 :alt: IPython Qt console with embedded plots
16 :align: center
16 :align: center
17 :target: ../_static/qtconsole.png
17 :target: ../_static/qtconsole.png
18
18
19 The Qt console for IPython, using inline matplotlib plots.
19 The Qt console for IPython, using inline matplotlib plots.
20
20
21 To get acquainted with the Qt console, type `%guiref` to see a quick
21 To get acquainted with the Qt console, type `%guiref` to see a quick
22 introduction of its main features.
22 introduction of its main features.
23
23
24 The Qt frontend has hand-coded emacs-style bindings for text navigation. This
24 The Qt frontend has hand-coded emacs-style bindings for text navigation. This
25 is not yet configurable.
25 is not yet configurable.
26
26
27 .. tip::
27 .. tip::
28
28
29 Since the Qt console tries hard to behave like a terminal, by default it
29 Since the Qt console tries hard to behave like a terminal, by default it
30 immediately executes single lines of input that are complete. If you want
30 immediately executes single lines of input that are complete. If you want
31 to force multiline input, hit :kbd:`Ctrl-Enter` at the end of the first line
31 to force multiline input, hit :kbd:`Ctrl-Enter` at the end of the first line
32 instead of :kbd:`Enter`, and it will open a new line for input. At any
32 instead of :kbd:`Enter`, and it will open a new line for input. At any
33 point in a multiline block, you can force its execution (without having to
33 point in a multiline block, you can force its execution (without having to
34 go to the bottom) with :kbd:`Shift-Enter`.
34 go to the bottom) with :kbd:`Shift-Enter`.
35
35
36 ``%loadpy``
36 ``%load``
37 ===========
37 =========
38
38
39 The new ``%loadpy`` magic takes any python script (must end in '.py'), and
39 The new ``%load`` magic (previously ``%loadpy``) takes any script, and pastes
40 pastes its contents as your next input, so you can edit it before
40 its contents as your next input, so you can edit it before executing. The
41 executing. The script may be on your machine, but you can also specify a url,
41 script may be on your machine, but you can also specify an history range, or a
42 and it will download the script from the web. This is particularly useful for
42 url, and it will download the script from the web. This is particularly useful
43 playing with examples from documentation, such as matplotlib.
43 for playing with examples from documentation, such as matplotlib.
44
44
45 .. sourcecode:: ipython
45 .. sourcecode:: ipython
46
46
47 In [6]: %loadpy http://matplotlib.sourceforge.net/plot_directive/mpl_examples/mplot3d/contour3d_demo.py
47 In [6]: %load http://matplotlib.sourceforge.net/plot_directive/mpl_examples/mplot3d/contour3d_demo.py
48
48
49 In [7]: from mpl_toolkits.mplot3d import axes3d
49 In [7]: from mpl_toolkits.mplot3d import axes3d
50 ...: import matplotlib.pyplot as plt
50 ...: import matplotlib.pyplot as plt
51 ...:
51 ...:
52 ...: fig = plt.figure()
52 ...: fig = plt.figure()
53 ...: ax = fig.add_subplot(111, projection='3d')
53 ...: ax = fig.add_subplot(111, projection='3d')
54 ...: X, Y, Z = axes3d.get_test_data(0.05)
54 ...: X, Y, Z = axes3d.get_test_data(0.05)
55 ...: cset = ax.contour(X, Y, Z)
55 ...: cset = ax.contour(X, Y, Z)
56 ...: ax.clabel(cset, fontsize=9, inline=1)
56 ...: ax.clabel(cset, fontsize=9, inline=1)
57 ...:
57 ...:
58 ...: plt.show()
58 ...: plt.show()
59
59
60 Pylab
60 Pylab
61 =====
61 =====
62
62
63 One of the most exciting features of the new console is embedded matplotlib
63 One of the most exciting features of the new console is embedded matplotlib
64 figures. You can use any standard matplotlib GUI backend
64 figures. You can use any standard matplotlib GUI backend
65 to draw the figures, and since there is now a two-process model, there is no
65 to draw the figures, and since there is now a two-process model, there is no
66 longer a conflict between user input and the drawing eventloop.
66 longer a conflict between user input and the drawing eventloop.
67
67
68 .. image:: figs/besselj.png
68 .. image:: figs/besselj.png
69 :width: 519px
69 :width: 519px
70
70
71 .. display:
71 .. display:
72
72
73 :func:`display`
73 :func:`display`
74 ***************
74 ***************
75
75
76 An additional function, :func:`display`, will be added to the global namespace
76 An additional function, :func:`display`, will be added to the global namespace
77 if you specify the ``--pylab`` option at the command line. The IPython display
77 if you specify the ``--pylab`` option at the command line. The IPython display
78 system provides a mechanism for specifying PNG or SVG (and more)
78 system provides a mechanism for specifying PNG or SVG (and more)
79 representations of objects for GUI frontends. By default, IPython registers
79 representations of objects for GUI frontends. By default, IPython registers
80 convenient PNG and SVG renderers for matplotlib figures, so you can embed them
80 convenient PNG and SVG renderers for matplotlib figures, so you can embed them
81 in your document by calling :func:`display` on one or more of them. This is
81 in your document by calling :func:`display` on one or more of them. This is
82 especially useful for saving_ your work.
82 especially useful for saving_ your work.
83
83
84 .. sourcecode:: ipython
84 .. sourcecode:: ipython
85
85
86 In [5]: plot(range(5)) # plots in the matplotlib window
86 In [5]: plot(range(5)) # plots in the matplotlib window
87
87
88 In [6]: display(gcf()) # embeds the current figure in the qtconsole
88 In [6]: display(gcf()) # embeds the current figure in the qtconsole
89
89
90 In [7]: display(*getfigs()) # embeds all active figures in the qtconsole
90 In [7]: display(*getfigs()) # embeds all active figures in the qtconsole
91
91
92 If you have a reference to a matplotlib figure object, you can always display
92 If you have a reference to a matplotlib figure object, you can always display
93 that specific figure:
93 that specific figure:
94
94
95 .. sourcecode:: ipython
95 .. sourcecode:: ipython
96
96
97 In [1]: f = figure()
97 In [1]: f = figure()
98
98
99 In [2]: plot(rand(100))
99 In [2]: plot(rand(100))
100 Out[2]: [<matplotlib.lines.Line2D at 0x7fc6ac03dd90>]
100 Out[2]: [<matplotlib.lines.Line2D at 0x7fc6ac03dd90>]
101
101
102 In [3]: display(f)
102 In [3]: display(f)
103
103
104 # Plot is shown here
104 # Plot is shown here
105
105
106 In [4]: title('A title')
106 In [4]: title('A title')
107 Out[4]: <matplotlib.text.Text at 0x7fc6ac023450>
107 Out[4]: <matplotlib.text.Text at 0x7fc6ac023450>
108
108
109 In [5]: display(f)
109 In [5]: display(f)
110
110
111 # Updated plot with title is shown here.
111 # Updated plot with title is shown here.
112
112
113 .. _inline:
113 .. _inline:
114
114
115 ``--pylab=inline``
115 ``--pylab=inline``
116 ******************
116 ******************
117
117
118 If you want to have all of your figures embedded in your session, instead of
118 If you want to have all of your figures embedded in your session, instead of
119 calling :func:`display`, you can specify ``--pylab=inline`` when you start the
119 calling :func:`display`, you can specify ``--pylab=inline`` when you start the
120 console, and each time you make a plot, it will show up in your document, as if
120 console, and each time you make a plot, it will show up in your document, as if
121 you had called :func:`display(fig)`.
121 you had called :func:`display(fig)`.
122
122
123 The inline backend can use either SVG or PNG figures (PNG being the default).
123 The inline backend can use either SVG or PNG figures (PNG being the default).
124 To switch between them, set the ``InlineBackend.figure_format`` configurable
124 To switch between them, set the ``InlineBackend.figure_format`` configurable
125 in a config file, or via the ``%config`` magic:
125 in a config file, or via the ``%config`` magic:
126
126
127 .. sourcecode:: ipython
127 .. sourcecode:: ipython
128
128
129 In [10]: %config InlineBackend.figure_format = 'svg'
129 In [10]: %config InlineBackend.figure_format = 'svg'
130
130
131 .. note::
131 .. note::
132
132
133 Changing the inline figure format also affects calls to :func:`display` above,
133 Changing the inline figure format also affects calls to :func:`display` above,
134 even if you are not using the inline backend for all figures.
134 even if you are not using the inline backend for all figures.
135
135
136 By default, IPython closes all figures at the completion of each execution. This means you
136 By default, IPython closes all figures at the completion of each execution. This means you
137 don't have to manually close figures, which is less convenient when figures aren't attached
137 don't have to manually close figures, which is less convenient when figures aren't attached
138 to windows with an obvious close button. It also means that the first matplotlib call in
138 to windows with an obvious close button. It also means that the first matplotlib call in
139 each cell will always create a new figure:
139 each cell will always create a new figure:
140
140
141 .. sourcecode:: ipython
141 .. sourcecode:: ipython
142
142
143 In [11]: plot(range(100))
143 In [11]: plot(range(100))
144 <single-line plot>
144 <single-line plot>
145
145
146 In [12]: plot([1,3,2])
146 In [12]: plot([1,3,2])
147 <another single-line plot>
147 <another single-line plot>
148
148
149
149
150 However, it does prevent the list of active figures surviving from one input cell to the
150 However, it does prevent the list of active figures surviving from one input cell to the
151 next, so if you want to continue working with a figure, you must hold on to a reference to
151 next, so if you want to continue working with a figure, you must hold on to a reference to
152 it:
152 it:
153
153
154 .. sourcecode:: ipython
154 .. sourcecode:: ipython
155
155
156 In [11]: fig = gcf()
156 In [11]: fig = gcf()
157 ....: fig.plot(rand(100))
157 ....: fig.plot(rand(100))
158 <plot>
158 <plot>
159 In [12]: fig.title('Random Title')
159 In [12]: fig.title('Random Title')
160 <redraw plot with title>
160 <redraw plot with title>
161
161
162 This behavior is controlled by the :attr:`InlineBackend.close_figures` configurable, and
162 This behavior is controlled by the :attr:`InlineBackend.close_figures` configurable, and
163 if you set it to False, via %config or config file, then IPython will *not* close figures,
163 if you set it to False, via %config or config file, then IPython will *not* close figures,
164 and tools like :func:`gcf`, :func:`gca`, :func:`getfigs` will behave the same as they
164 and tools like :func:`gcf`, :func:`gca`, :func:`getfigs` will behave the same as they
165 do with other backends. You will, however, have to manually close figures:
165 do with other backends. You will, however, have to manually close figures:
166
166
167 .. sourcecode:: ipython
167 .. sourcecode:: ipython
168
168
169 # close all active figures:
169 # close all active figures:
170 In [13]: [ fig.close() for fig in getfigs() ]
170 In [13]: [ fig.close() for fig in getfigs() ]
171
171
172
172
173
173
174 .. _saving:
174 .. _saving:
175
175
176 Saving and Printing
176 Saving and Printing
177 ===================
177 ===================
178
178
179 IPythonQt has the ability to save your current session, as either HTML or
179 IPythonQt has the ability to save your current session, as either HTML or
180 XHTML. If you have been using :func:`display` or inline_ pylab, your figures
180 XHTML. If you have been using :func:`display` or inline_ pylab, your figures
181 will be PNG in HTML, or inlined as SVG in XHTML. PNG images have the option to
181 will be PNG in HTML, or inlined as SVG in XHTML. PNG images have the option to
182 be either in an external folder, as in many browsers' "Webpage, Complete"
182 be either in an external folder, as in many browsers' "Webpage, Complete"
183 option, or inlined as well, for a larger, but more portable file.
183 option, or inlined as well, for a larger, but more portable file.
184
184
185 .. note::
185 .. note::
186
186
187 Export to SVG+XHTML requires that you are using SVG figures, which is *not*
187 Export to SVG+XHTML requires that you are using SVG figures, which is *not*
188 the default. To switch the inline figure format to use SVG during an active
188 the default. To switch the inline figure format to use SVG during an active
189 session, do:
189 session, do:
190
190
191 .. sourcecode:: ipython
191 .. sourcecode:: ipython
192
192
193 In [10]: %config InlineBackend.figure_format = 'svg'
193 In [10]: %config InlineBackend.figure_format = 'svg'
194
194
195 Or, you can add the same line (c.Inline... instead of %config Inline...) to
195 Or, you can add the same line (c.Inline... instead of %config Inline...) to
196 your config files.
196 your config files.
197
197
198 This will only affect figures plotted after making this call
198 This will only affect figures plotted after making this call
199
199
200
200
201 The widget also exposes the ability to print directly, via the default print
201 The widget also exposes the ability to print directly, via the default print
202 shortcut or context menu.
202 shortcut or context menu.
203
203
204
204
205 .. Note::
205 .. Note::
206
206
207 Saving is only available to richtext Qt widgets, which are used by default,
207 Saving is only available to richtext Qt widgets, which are used by default,
208 but if you pass the ``--plain`` flag, saving will not be available to you.
208 but if you pass the ``--plain`` flag, saving will not be available to you.
209
209
210
210
211 See these examples of :download:`png/html<figs/jn.html>` and
211 See these examples of :download:`png/html<figs/jn.html>` and
212 :download:`svg/xhtml <figs/jn.xhtml>` output. Note that syntax highlighting
212 :download:`svg/xhtml <figs/jn.xhtml>` output. Note that syntax highlighting
213 does not survive export. This is a known issue, and is being investigated.
213 does not survive export. This is a known issue, and is being investigated.
214
214
215
215
216 Colors and Highlighting
216 Colors and Highlighting
217 =======================
217 =======================
218
218
219 Terminal IPython has always had some coloring, but never syntax
219 Terminal IPython has always had some coloring, but never syntax
220 highlighting. There are a few simple color choices, specified by the ``colors``
220 highlighting. There are a few simple color choices, specified by the ``colors``
221 flag or ``%colors`` magic:
221 flag or ``%colors`` magic:
222
222
223 * LightBG for light backgrounds
223 * LightBG for light backgrounds
224 * Linux for dark backgrounds
224 * Linux for dark backgrounds
225 * NoColor for a simple colorless terminal
225 * NoColor for a simple colorless terminal
226
226
227 The Qt widget has full support for the ``colors`` flag used in the terminal shell.
227 The Qt widget has full support for the ``colors`` flag used in the terminal shell.
228
228
229 The Qt widget, however, has full syntax highlighting as you type, handled by
229 The Qt widget, however, has full syntax highlighting as you type, handled by
230 the `pygments`_ library. The ``style`` argument exposes access to any style by
230 the `pygments`_ library. The ``style`` argument exposes access to any style by
231 name that can be found by pygments, and there are several already
231 name that can be found by pygments, and there are several already
232 installed. The ``colors`` argument, if unspecified, will be guessed based on
232 installed. The ``colors`` argument, if unspecified, will be guessed based on
233 the chosen style. Similarly, there are default styles associated with each
233 the chosen style. Similarly, there are default styles associated with each
234 ``colors`` option.
234 ``colors`` option.
235
235
236
236
237 Screenshot of ``ipython qtconsole --colors=linux``, which uses the 'monokai'
237 Screenshot of ``ipython qtconsole --colors=linux``, which uses the 'monokai'
238 theme by default:
238 theme by default:
239
239
240 .. image:: figs/colors_dark.png
240 .. image:: figs/colors_dark.png
241 :width: 627px
241 :width: 627px
242
242
243 .. Note::
243 .. Note::
244
244
245 Calling ``ipython qtconsole -h`` will show all the style names that
245 Calling ``ipython qtconsole -h`` will show all the style names that
246 pygments can find on your system.
246 pygments can find on your system.
247
247
248 You can also pass the filename of a custom CSS stylesheet, if you want to do
248 You can also pass the filename of a custom CSS stylesheet, if you want to do
249 your own coloring, via the ``stylesheet`` argument. The default LightBG
249 your own coloring, via the ``stylesheet`` argument. The default LightBG
250 stylesheet:
250 stylesheet:
251
251
252 .. sourcecode:: css
252 .. sourcecode:: css
253
253
254 QPlainTextEdit, QTextEdit { background-color: white;
254 QPlainTextEdit, QTextEdit { background-color: white;
255 color: black ;
255 color: black ;
256 selection-background-color: #ccc}
256 selection-background-color: #ccc}
257 .error { color: red; }
257 .error { color: red; }
258 .in-prompt { color: navy; }
258 .in-prompt { color: navy; }
259 .in-prompt-number { font-weight: bold; }
259 .in-prompt-number { font-weight: bold; }
260 .out-prompt { color: darkred; }
260 .out-prompt { color: darkred; }
261 .out-prompt-number { font-weight: bold; }
261 .out-prompt-number { font-weight: bold; }
262
262
263 Fonts
263 Fonts
264 =====
264 =====
265
265
266 The QtConsole has configurable via the ConsoleWidget. To change these, set the
266 The QtConsole has configurable via the ConsoleWidget. To change these, set the
267 ``font_family`` or ``font_size`` traits of the ConsoleWidget. For instance, to
267 ``font_family`` or ``font_size`` traits of the ConsoleWidget. For instance, to
268 use 9pt Anonymous Pro::
268 use 9pt Anonymous Pro::
269
269
270 $> ipython qtconsole --ConsoleWidget.font_family="Anonymous Pro" --ConsoleWidget.font_size=9
270 $> ipython qtconsole --ConsoleWidget.font_family="Anonymous Pro" --ConsoleWidget.font_size=9
271
271
272 Process Management
272 Process Management
273 ==================
273 ==================
274
274
275 With the two-process ZMQ model, the frontend does not block input during
275 With the two-process ZMQ model, the frontend does not block input during
276 execution. This means that actions can be taken by the frontend while the
276 execution. This means that actions can be taken by the frontend while the
277 Kernel is executing, or even after it crashes. The most basic such command is
277 Kernel is executing, or even after it crashes. The most basic such command is
278 via 'Ctrl-.', which restarts the kernel. This can be done in the middle of a
278 via 'Ctrl-.', which restarts the kernel. This can be done in the middle of a
279 blocking execution. The frontend can also know, via a heartbeat mechanism, that
279 blocking execution. The frontend can also know, via a heartbeat mechanism, that
280 the kernel has died. This means that the frontend can safely restart the
280 the kernel has died. This means that the frontend can safely restart the
281 kernel.
281 kernel.
282
282
283 .. _multiple_consoles:
283 .. _multiple_consoles:
284
284
285 Multiple Consoles
285 Multiple Consoles
286 *****************
286 *****************
287
287
288 Since the Kernel listens on the network, multiple frontends can connect to it.
288 Since the Kernel listens on the network, multiple frontends can connect to it.
289 These do not have to all be qt frontends - any IPython frontend can connect and
289 These do not have to all be qt frontends - any IPython frontend can connect and
290 run code. When you start ipython qtconsole, there will be an output line,
290 run code. When you start ipython qtconsole, there will be an output line,
291 like::
291 like::
292
292
293 [IPKernelApp] To connect another client to this kernel, use:
293 [IPKernelApp] To connect another client to this kernel, use:
294 [IPKernelApp] --existing kernel-12345.json
294 [IPKernelApp] --existing kernel-12345.json
295
295
296 Other frontends can connect to your kernel, and share in the execution. This is
296 Other frontends can connect to your kernel, and share in the execution. This is
297 great for collaboration. The ``--existing`` flag means connect to a kernel
297 great for collaboration. The ``--existing`` flag means connect to a kernel
298 that already exists. Starting other consoles
298 that already exists. Starting other consoles
299 with that flag will not try to start their own kernel, but rather connect to
299 with that flag will not try to start their own kernel, but rather connect to
300 yours. :file:`kernel-12345.json` is a small JSON file with the ip, port, and
300 yours. :file:`kernel-12345.json` is a small JSON file with the ip, port, and
301 authentication information necessary to connect to your kernel. By default, this file
301 authentication information necessary to connect to your kernel. By default, this file
302 will be in your default profile's security directory. If it is somewhere else,
302 will be in your default profile's security directory. If it is somewhere else,
303 the output line will print the full path of the connection file, rather than
303 the output line will print the full path of the connection file, rather than
304 just its filename.
304 just its filename.
305
305
306 If you need to find the connection info to send, and don't know where your connection file
306 If you need to find the connection info to send, and don't know where your connection file
307 lives, there are a couple of ways to get it. If you are already running an IPython console
307 lives, there are a couple of ways to get it. If you are already running an IPython console
308 connected to the kernel, you can use the ``%connect_info`` magic to display the information
308 connected to the kernel, you can use the ``%connect_info`` magic to display the information
309 necessary to connect another frontend to the kernel.
309 necessary to connect another frontend to the kernel.
310
310
311 .. sourcecode:: ipython
311 .. sourcecode:: ipython
312
312
313 In [2]: %connect_info
313 In [2]: %connect_info
314 {
314 {
315 "stdin_port":50255,
315 "stdin_port":50255,
316 "ip":"127.0.0.1",
316 "ip":"127.0.0.1",
317 "hb_port":50256,
317 "hb_port":50256,
318 "key":"70be6f0f-1564-4218-8cda-31be40a4d6aa",
318 "key":"70be6f0f-1564-4218-8cda-31be40a4d6aa",
319 "shell_port":50253,
319 "shell_port":50253,
320 "iopub_port":50254
320 "iopub_port":50254
321 }
321 }
322
322
323 Paste the above JSON into a file, and connect with:
323 Paste the above JSON into a file, and connect with:
324 $> ipython <app> --existing <file>
324 $> ipython <app> --existing <file>
325 or, if you are local, you can connect with just:
325 or, if you are local, you can connect with just:
326 $> ipython <app> --existing kernel-12345.json
326 $> ipython <app> --existing kernel-12345.json
327 or even just:
327 or even just:
328 $> ipython <app> --existing
328 $> ipython <app> --existing
329 if this is the most recent IPython session you have started.
329 if this is the most recent IPython session you have started.
330
330
331 Otherwise, you can find a connection file by name (and optionally profile) with
331 Otherwise, you can find a connection file by name (and optionally profile) with
332 :func:`IPython.lib.kernel.find_connection_file`:
332 :func:`IPython.lib.kernel.find_connection_file`:
333
333
334 .. sourcecode:: bash
334 .. sourcecode:: bash
335
335
336 $> python -c "from IPython.lib.kernel import find_connection_file;\
336 $> python -c "from IPython.lib.kernel import find_connection_file;\
337 print find_connection_file('kernel-12345.json')"
337 print find_connection_file('kernel-12345.json')"
338 /home/you/.ipython/profile_default/security/kernel-12345.json
338 /home/you/.ipython/profile_default/security/kernel-12345.json
339
339
340 And if you are using a particular IPython profile:
340 And if you are using a particular IPython profile:
341
341
342 .. sourcecode:: bash
342 .. sourcecode:: bash
343
343
344 $> python -c "from IPython.lib.kernel import find_connection_file;\
344 $> python -c "from IPython.lib.kernel import find_connection_file;\
345 print find_connection_file('kernel-12345.json', profile='foo')"
345 print find_connection_file('kernel-12345.json', profile='foo')"
346 /home/you/.ipython/profile_foo/security/kernel-12345.json
346 /home/you/.ipython/profile_foo/security/kernel-12345.json
347
347
348 You can even launch a standalone kernel, and connect and disconnect Qt Consoles
348 You can even launch a standalone kernel, and connect and disconnect Qt Consoles
349 from various machines. This lets you keep the same running IPython session
349 from various machines. This lets you keep the same running IPython session
350 on your work machine (with matplotlib plots and everything), logging in from home,
350 on your work machine (with matplotlib plots and everything), logging in from home,
351 cafΓ©s, etc.::
351 cafΓ©s, etc.::
352
352
353 $> ipython kernel
353 $> ipython kernel
354 [IPKernelApp] To connect another client to this kernel, use:
354 [IPKernelApp] To connect another client to this kernel, use:
355 [IPKernelApp] --existing kernel-12345.json
355 [IPKernelApp] --existing kernel-12345.json
356
356
357 This is actually exactly the same as the subprocess launched by the qtconsole, so
357 This is actually exactly the same as the subprocess launched by the qtconsole, so
358 all the information about connecting to a standalone kernel is identical to that
358 all the information about connecting to a standalone kernel is identical to that
359 of connecting to the kernel attached to a running console.
359 of connecting to the kernel attached to a running console.
360
360
361 .. _kernel_security:
361 .. _kernel_security:
362
362
363 Security
363 Security
364 --------
364 --------
365
365
366 .. warning::
366 .. warning::
367
367
368 Since the ZMQ code currently has no encryption, listening on an
368 Since the ZMQ code currently has no encryption, listening on an
369 external-facing IP is dangerous. You are giving any computer that can see
369 external-facing IP is dangerous. You are giving any computer that can see
370 you on the network the ability to connect to your kernel, and view your traffic.
370 you on the network the ability to connect to your kernel, and view your traffic.
371 Read the rest of this section before listening on external ports
371 Read the rest of this section before listening on external ports
372 or running an IPython kernel on a shared machine.
372 or running an IPython kernel on a shared machine.
373
373
374 By default (for security reasons), the kernel only listens on localhost, so you
374 By default (for security reasons), the kernel only listens on localhost, so you
375 can only connect multiple frontends to the kernel from your local machine. You
375 can only connect multiple frontends to the kernel from your local machine. You
376 can specify to listen on an external interface by specifying the ``ip``
376 can specify to listen on an external interface by specifying the ``ip``
377 argument::
377 argument::
378
378
379 $> ipython qtconsole --ip=192.168.1.123
379 $> ipython qtconsole --ip=192.168.1.123
380
380
381 If you specify the ip as 0.0.0.0 or '*', that means all interfaces, so any
381 If you specify the ip as 0.0.0.0 or '*', that means all interfaces, so any
382 computer that can see yours on the network can connect to the kernel.
382 computer that can see yours on the network can connect to the kernel.
383
383
384 Messages are not encrypted, so users with access to the ports your kernel is using will be
384 Messages are not encrypted, so users with access to the ports your kernel is using will be
385 able to see any output of the kernel. They will **NOT** be able to issue shell commands as
385 able to see any output of the kernel. They will **NOT** be able to issue shell commands as
386 you due to message signatures, which are enabled by default as of IPython 0.12.
386 you due to message signatures, which are enabled by default as of IPython 0.12.
387
387
388 .. warning::
388 .. warning::
389
389
390 If you disable message signatures, then any user with access to the ports your
390 If you disable message signatures, then any user with access to the ports your
391 kernel is listening on can issue arbitrary code as you. **DO NOT** disable message
391 kernel is listening on can issue arbitrary code as you. **DO NOT** disable message
392 signatures unless you have a lot of trust in your environment.
392 signatures unless you have a lot of trust in your environment.
393
393
394 The one security feature IPython does provide is protection from unauthorized execution.
394 The one security feature IPython does provide is protection from unauthorized execution.
395 IPython's messaging system will sign messages with HMAC digests using a shared-key. The key
395 IPython's messaging system will sign messages with HMAC digests using a shared-key. The key
396 is never sent over the network, it is only used to generate a unique hash for each message,
396 is never sent over the network, it is only used to generate a unique hash for each message,
397 based on its content. When IPython receives a message, it will check that the digest
397 based on its content. When IPython receives a message, it will check that the digest
398 matches, and discard the message. You can use any file that only you have access to to
398 matches, and discard the message. You can use any file that only you have access to to
399 generate this key, but the default is just to generate a new UUID. You can generate a random
399 generate this key, but the default is just to generate a new UUID. You can generate a random
400 private key with::
400 private key with::
401
401
402 # generate 1024b of random data, and store in a file only you can read:
402 # generate 1024b of random data, and store in a file only you can read:
403 # (assumes IPYTHONDIR is defined, otherwise use your IPython directory)
403 # (assumes IPYTHONDIR is defined, otherwise use your IPython directory)
404 $> python -c "import os; print os.urandom(128).encode('base64')" > $IPYTHONDIR/sessionkey
404 $> python -c "import os; print os.urandom(128).encode('base64')" > $IPYTHONDIR/sessionkey
405 $> chmod 600 $IPYTHONDIR/sessionkey
405 $> chmod 600 $IPYTHONDIR/sessionkey
406
406
407 The *contents* of this file will be stored in the JSON connection file, so that file
407 The *contents* of this file will be stored in the JSON connection file, so that file
408 contains everything you need to connect to and use a kernel.
408 contains everything you need to connect to and use a kernel.
409
409
410 To use this generated key, simply specify the ``Session.keyfile`` configurable
410 To use this generated key, simply specify the ``Session.keyfile`` configurable
411 in :file:`ipython_config.py` or at the command-line, as in::
411 in :file:`ipython_config.py` or at the command-line, as in::
412
412
413 # instruct IPython to sign messages with that key, instead of a new UUID
413 # instruct IPython to sign messages with that key, instead of a new UUID
414 $> ipython qtconsole --Session.keyfile=$IPYTHONDIR/sessionkey
414 $> ipython qtconsole --Session.keyfile=$IPYTHONDIR/sessionkey
415
415
416 .. _ssh_tunnels:
416 .. _ssh_tunnels:
417
417
418 SSH Tunnels
418 SSH Tunnels
419 -----------
419 -----------
420
420
421 Sometimes you want to connect to machines across the internet, or just across
421 Sometimes you want to connect to machines across the internet, or just across
422 a LAN that either doesn't permit open ports or you don't trust the other
422 a LAN that either doesn't permit open ports or you don't trust the other
423 machines on the network. To do this, you can use SSH tunnels. SSH tunnels
423 machines on the network. To do this, you can use SSH tunnels. SSH tunnels
424 are a way to securely forward ports on your local machine to ports on another
424 are a way to securely forward ports on your local machine to ports on another
425 machine, to which you have SSH access.
425 machine, to which you have SSH access.
426
426
427 In simple cases, IPython's tools can forward ports over ssh by simply adding the
427 In simple cases, IPython's tools can forward ports over ssh by simply adding the
428 ``--ssh=remote`` argument to the usual ``--existing...`` set of flags for connecting
428 ``--ssh=remote`` argument to the usual ``--existing...`` set of flags for connecting
429 to a running kernel, after copying the JSON connection file (or its contents) to
429 to a running kernel, after copying the JSON connection file (or its contents) to
430 the second computer.
430 the second computer.
431
431
432 .. warning::
432 .. warning::
433
433
434 Using SSH tunnels does *not* increase localhost security. In fact, when
434 Using SSH tunnels does *not* increase localhost security. In fact, when
435 tunneling from one machine to another *both* machines have open
435 tunneling from one machine to another *both* machines have open
436 ports on localhost available for connections to the kernel.
436 ports on localhost available for connections to the kernel.
437
437
438 There are two primary models for using SSH tunnels with IPython. The first
438 There are two primary models for using SSH tunnels with IPython. The first
439 is to have the Kernel listen only on localhost, and connect to it from
439 is to have the Kernel listen only on localhost, and connect to it from
440 another machine on the same LAN.
440 another machine on the same LAN.
441
441
442 First, let's start a kernel on machine **worker**, listening only
442 First, let's start a kernel on machine **worker**, listening only
443 on loopback::
443 on loopback::
444
444
445 user@worker $> ipython kernel
445 user@worker $> ipython kernel
446 [IPKernelApp] To connect another client to this kernel, use:
446 [IPKernelApp] To connect another client to this kernel, use:
447 [IPKernelApp] --existing kernel-12345.json
447 [IPKernelApp] --existing kernel-12345.json
448
448
449 In this case, the IP that you would connect
449 In this case, the IP that you would connect
450 to would still be 127.0.0.1, but you want to specify the additional ``--ssh`` argument
450 to would still be 127.0.0.1, but you want to specify the additional ``--ssh`` argument
451 with the hostname of the kernel (in this example, it's 'worker')::
451 with the hostname of the kernel (in this example, it's 'worker')::
452
452
453 user@client $> ipython qtconsole --ssh=worker --existing /path/to/kernel-12345.json
453 user@client $> ipython qtconsole --ssh=worker --existing /path/to/kernel-12345.json
454
454
455 Which will write a new connection file with the forwarded ports, so you can reuse them::
455 Which will write a new connection file with the forwarded ports, so you can reuse them::
456
456
457 [IPythonQtConsoleApp] To connect another client via this tunnel, use:
457 [IPythonQtConsoleApp] To connect another client via this tunnel, use:
458 [IPythonQtConsoleApp] --existing kernel-12345-ssh.json
458 [IPythonQtConsoleApp] --existing kernel-12345-ssh.json
459
459
460 Note again that this opens ports on the *client* machine that point to your kernel.
460 Note again that this opens ports on the *client* machine that point to your kernel.
461
461
462 .. note::
462 .. note::
463
463
464 the ssh argument is simply passed to openssh, so it can be fully specified ``user@host:port``
464 the ssh argument is simply passed to openssh, so it can be fully specified ``user@host:port``
465 but it will also respect your aliases, etc. in :file:`.ssh/config` if you have any.
465 but it will also respect your aliases, etc. in :file:`.ssh/config` if you have any.
466
466
467 The second pattern is for connecting to a machine behind a firewall across the internet
467 The second pattern is for connecting to a machine behind a firewall across the internet
468 (or otherwise wide network). This time, we have a machine **login** that you have ssh access
468 (or otherwise wide network). This time, we have a machine **login** that you have ssh access
469 to, which can see **kernel**, but **client** is on another network. The important difference
469 to, which can see **kernel**, but **client** is on another network. The important difference
470 now is that **client** can see **login**, but *not* **worker**. So we need to forward ports from
470 now is that **client** can see **login**, but *not* **worker**. So we need to forward ports from
471 client to worker *via* login. This means that the kernel must be started listening
471 client to worker *via* login. This means that the kernel must be started listening
472 on external interfaces, so that its ports are visible to `login`::
472 on external interfaces, so that its ports are visible to `login`::
473
473
474 user@worker $> ipython kernel --ip=0.0.0.0
474 user@worker $> ipython kernel --ip=0.0.0.0
475 [IPKernelApp] To connect another client to this kernel, use:
475 [IPKernelApp] To connect another client to this kernel, use:
476 [IPKernelApp] --existing kernel-12345.json
476 [IPKernelApp] --existing kernel-12345.json
477
477
478 Which we can connect to from the client with::
478 Which we can connect to from the client with::
479
479
480 user@client $> ipython qtconsole --ssh=login --ip=192.168.1.123 --existing /path/to/kernel-12345.json
480 user@client $> ipython qtconsole --ssh=login --ip=192.168.1.123 --existing /path/to/kernel-12345.json
481
481
482 .. note::
482 .. note::
483
483
484 The IP here is the address of worker as seen from *login*, and need only be specified if
484 The IP here is the address of worker as seen from *login*, and need only be specified if
485 the kernel used the ambiguous 0.0.0.0 (all interfaces) address. If it had used
485 the kernel used the ambiguous 0.0.0.0 (all interfaces) address. If it had used
486 192.168.1.123 to start with, it would not be needed.
486 192.168.1.123 to start with, it would not be needed.
487
487
488
488
489 Manual SSH tunnels
489 Manual SSH tunnels
490 ------------------
490 ------------------
491
491
492 It's possible that IPython's ssh helper functions won't work for you, for various
492 It's possible that IPython's ssh helper functions won't work for you, for various
493 reasons. You can still connect to remote machines, as long as you set up the tunnels
493 reasons. You can still connect to remote machines, as long as you set up the tunnels
494 yourself. The basic format of forwarding a local port to a remote one is::
494 yourself. The basic format of forwarding a local port to a remote one is::
495
495
496 [client] $> ssh <server> <localport>:<remoteip>:<remoteport> -f -N
496 [client] $> ssh <server> <localport>:<remoteip>:<remoteport> -f -N
497
497
498 This will forward local connections to **localport** on client to **remoteip:remoteport**
498 This will forward local connections to **localport** on client to **remoteip:remoteport**
499 *via* **server**. Note that remoteip is interpreted relative to *server*, not the client.
499 *via* **server**. Note that remoteip is interpreted relative to *server*, not the client.
500 So if you have direct ssh access to the machine to which you want to forward connections,
500 So if you have direct ssh access to the machine to which you want to forward connections,
501 then the server *is* the remote machine, and remoteip should be server's IP as seen from the
501 then the server *is* the remote machine, and remoteip should be server's IP as seen from the
502 server itself, i.e. 127.0.0.1. Thus, to forward local port 12345 to remote port 54321 on
502 server itself, i.e. 127.0.0.1. Thus, to forward local port 12345 to remote port 54321 on
503 a machine you can see, do::
503 a machine you can see, do::
504
504
505 [client] $> ssh machine 12345:127.0.0.1:54321 -f -N
505 [client] $> ssh machine 12345:127.0.0.1:54321 -f -N
506
506
507 But if your target is actually on a LAN at 192.168.1.123, behind another machine called **login**,
507 But if your target is actually on a LAN at 192.168.1.123, behind another machine called **login**,
508 then you would do::
508 then you would do::
509
509
510 [client] $> ssh login 12345:192.168.1.16:54321 -f -N
510 [client] $> ssh login 12345:192.168.1.16:54321 -f -N
511
511
512 The ``-f -N`` on the end are flags that tell ssh to run in the background,
512 The ``-f -N`` on the end are flags that tell ssh to run in the background,
513 and don't actually run any commands beyond creating the tunnel.
513 and don't actually run any commands beyond creating the tunnel.
514
514
515 .. seealso::
515 .. seealso::
516
516
517 A short discussion of ssh tunnels: http://www.revsys.com/writings/quicktips/ssh-tunnel.html
517 A short discussion of ssh tunnels: http://www.revsys.com/writings/quicktips/ssh-tunnel.html
518
518
519
519
520
520
521 Stopping Kernels and Consoles
521 Stopping Kernels and Consoles
522 *****************************
522 *****************************
523
523
524 Since there can be many consoles per kernel, the shutdown mechanism and dialog
524 Since there can be many consoles per kernel, the shutdown mechanism and dialog
525 are probably more complicated than you are used to. Since you don't always want
525 are probably more complicated than you are used to. Since you don't always want
526 to shutdown a kernel when you close a window, you are given the option to just
526 to shutdown a kernel when you close a window, you are given the option to just
527 close the console window or also close the Kernel and *all other windows*. Note
527 close the console window or also close the Kernel and *all other windows*. Note
528 that this only refers to all other *local* windows, as remote Consoles are not
528 that this only refers to all other *local* windows, as remote Consoles are not
529 allowed to shutdown the kernel, and shutdowns do not close Remote consoles (to
529 allowed to shutdown the kernel, and shutdowns do not close Remote consoles (to
530 allow for saving, etc.).
530 allow for saving, etc.).
531
531
532 Rules:
532 Rules:
533
533
534 * Restarting the kernel automatically clears all *local* Consoles, and prompts remote
534 * Restarting the kernel automatically clears all *local* Consoles, and prompts remote
535 Consoles about the reset.
535 Consoles about the reset.
536 * Shutdown closes all *local* Consoles, and notifies remotes that
536 * Shutdown closes all *local* Consoles, and notifies remotes that
537 the Kernel has been shutdown.
537 the Kernel has been shutdown.
538 * Remote Consoles may not restart or shutdown the kernel.
538 * Remote Consoles may not restart or shutdown the kernel.
539
539
540 Qt and the QtConsole
540 Qt and the QtConsole
541 ====================
541 ====================
542
542
543 An important part of working with the QtConsole when you are writing your own
543 An important part of working with the QtConsole when you are writing your own
544 Qt code is to remember that user code (in the kernel) is *not* in the same
544 Qt code is to remember that user code (in the kernel) is *not* in the same
545 process as the frontend. This means that there is not necessarily any Qt code
545 process as the frontend. This means that there is not necessarily any Qt code
546 running in the kernel, and under most normal circumstances there isn't. If,
546 running in the kernel, and under most normal circumstances there isn't. If,
547 however, you specify ``--pylab=qt`` at the command-line, then there *will* be a
547 however, you specify ``--pylab=qt`` at the command-line, then there *will* be a
548 :class:`QCoreApplication` instance running in the kernel process along with
548 :class:`QCoreApplication` instance running in the kernel process along with
549 user-code. To get a reference to this application, do:
549 user-code. To get a reference to this application, do:
550
550
551 .. sourcecode:: python
551 .. sourcecode:: python
552
552
553 from PyQt4 import QtCore
553 from PyQt4 import QtCore
554 app = QtCore.QCoreApplication.instance()
554 app = QtCore.QCoreApplication.instance()
555 # app will be None if there is no such instance
555 # app will be None if there is no such instance
556
556
557 A common problem listed in the PyQt4 Gotchas_ is the fact that Python's garbage
557 A common problem listed in the PyQt4 Gotchas_ is the fact that Python's garbage
558 collection will destroy Qt objects (Windows, etc.) once there is no longer a
558 collection will destroy Qt objects (Windows, etc.) once there is no longer a
559 Python reference to them, so you have to hold on to them. For instance, in:
559 Python reference to them, so you have to hold on to them. For instance, in:
560
560
561 .. sourcecode:: python
561 .. sourcecode:: python
562
562
563 def make_window():
563 def make_window():
564 win = QtGui.QMainWindow()
564 win = QtGui.QMainWindow()
565
565
566 def make_and_return_window():
566 def make_and_return_window():
567 win = QtGui.QMainWindow()
567 win = QtGui.QMainWindow()
568 return win
568 return win
569
569
570 :func:`make_window` will never draw a window, because garbage collection will
570 :func:`make_window` will never draw a window, because garbage collection will
571 destroy it before it is drawn, whereas :func:`make_and_return_window` lets the
571 destroy it before it is drawn, whereas :func:`make_and_return_window` lets the
572 caller decide when the window object should be destroyed. If, as a developer,
572 caller decide when the window object should be destroyed. If, as a developer,
573 you know that you always want your objects to last as long as the process, you
573 you know that you always want your objects to last as long as the process, you
574 can attach them to the QApplication instance itself:
574 can attach them to the QApplication instance itself:
575
575
576 .. sourcecode:: python
576 .. sourcecode:: python
577
577
578 # do this just once:
578 # do this just once:
579 app = QtCore.QCoreApplication.instance()
579 app = QtCore.QCoreApplication.instance()
580 app.references = set()
580 app.references = set()
581 # then when you create Windows, add them to the set
581 # then when you create Windows, add them to the set
582 def make_window():
582 def make_window():
583 win = QtGui.QMainWindow()
583 win = QtGui.QMainWindow()
584 app.references.add(win)
584 app.references.add(win)
585
585
586 Now the QApplication itself holds a reference to ``win``, so it will never be
586 Now the QApplication itself holds a reference to ``win``, so it will never be
587 garbage collected until the application itself is destroyed.
587 garbage collected until the application itself is destroyed.
588
588
589 .. _Gotchas: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/gotchas.html#garbage-collection
589 .. _Gotchas: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/gotchas.html#garbage-collection
590
590
591 Regressions
591 Regressions
592 ===========
592 ===========
593
593
594 There are some features, where the qt console lags behind the Terminal
594 There are some features, where the qt console lags behind the Terminal
595 frontend:
595 frontend:
596
596
597 * !cmd input: Due to our use of pexpect, we cannot pass input to subprocesses
597 * !cmd input: Due to our use of pexpect, we cannot pass input to subprocesses
598 launched using the '!' escape, so you should never call a command that
598 launched using the '!' escape, so you should never call a command that
599 requires interactive input. For such cases, use the terminal IPython. This
599 requires interactive input. For such cases, use the terminal IPython. This
600 will not be fixed, as abandoning pexpect would significantly degrade the
600 will not be fixed, as abandoning pexpect would significantly degrade the
601 console experience.
601 console experience.
602
602
603 * Use of ``\b`` and ``\r`` characters in the console: these are control
603 * Use of ``\b`` and ``\r`` characters in the console: these are control
604 characters that allow the cursor to move backwards on a line, and are used to
604 characters that allow the cursor to move backwards on a line, and are used to
605 display things like in-place progress bars in a terminal. We currently do
605 display things like in-place progress bars in a terminal. We currently do
606 not support this, but it is being tracked as issue :ghissue:`629`.
606 not support this, but it is being tracked as issue :ghissue:`629`.
607
607
608 .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/download
608 .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/download
609 .. _pygments: http://pygments.org/
609 .. _pygments: http://pygments.org/
General Comments 0
You need to be logged in to leave comments. Login now