##// END OF EJS Templates
Merge pull request #1 from ipython/master...
Gareth Elston -
r20633:d587f5ea merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,3388 +1,3389 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 from __future__ import absolute_import, print_function
13 from __future__ import absolute_import, print_function
14
14
15 import __future__
15 import __future__
16 import abc
16 import abc
17 import ast
17 import ast
18 import atexit
18 import atexit
19 import functools
19 import functools
20 import os
20 import os
21 import re
21 import re
22 import runpy
22 import runpy
23 import sys
23 import sys
24 import tempfile
24 import tempfile
25 import traceback
25 import traceback
26 import types
26 import types
27 import subprocess
27 import subprocess
28 from io import open as io_open
28 from io import open as io_open
29
29
30 from IPython.config.configurable import SingletonConfigurable
30 from IPython.config.configurable import SingletonConfigurable
31 from IPython.core import debugger, oinspect
31 from IPython.core import debugger, oinspect
32 from IPython.core import magic
32 from IPython.core import magic
33 from IPython.core import page
33 from IPython.core import page
34 from IPython.core import prefilter
34 from IPython.core import prefilter
35 from IPython.core import shadowns
35 from IPython.core import shadowns
36 from IPython.core import ultratb
36 from IPython.core import ultratb
37 from IPython.core.alias import AliasManager, AliasError
37 from IPython.core.alias import Alias, AliasManager
38 from IPython.core.autocall import ExitAutocall
38 from IPython.core.autocall import ExitAutocall
39 from IPython.core.builtin_trap import BuiltinTrap
39 from IPython.core.builtin_trap import BuiltinTrap
40 from IPython.core.events import EventManager, available_events
40 from IPython.core.events import EventManager, available_events
41 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
41 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
42 from IPython.core.display_trap import DisplayTrap
42 from IPython.core.display_trap import DisplayTrap
43 from IPython.core.displayhook import DisplayHook
43 from IPython.core.displayhook import DisplayHook
44 from IPython.core.displaypub import DisplayPublisher
44 from IPython.core.displaypub import DisplayPublisher
45 from IPython.core.error import InputRejected, UsageError
45 from IPython.core.error import InputRejected, UsageError
46 from IPython.core.extensions import ExtensionManager
46 from IPython.core.extensions import ExtensionManager
47 from IPython.core.formatters import DisplayFormatter
47 from IPython.core.formatters import DisplayFormatter
48 from IPython.core.history import HistoryManager
48 from IPython.core.history import HistoryManager
49 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
49 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
50 from IPython.core.logger import Logger
50 from IPython.core.logger import Logger
51 from IPython.core.macro import Macro
51 from IPython.core.macro import Macro
52 from IPython.core.payload import PayloadManager
52 from IPython.core.payload import PayloadManager
53 from IPython.core.prefilter import PrefilterManager
53 from IPython.core.prefilter import PrefilterManager
54 from IPython.core.profiledir import ProfileDir
54 from IPython.core.profiledir import ProfileDir
55 from IPython.core.prompts import PromptManager
55 from IPython.core.prompts import PromptManager
56 from IPython.core.usage import default_banner
56 from IPython.core.usage import default_banner
57 from IPython.testing.skipdoctest import skip_doctest
57 from IPython.testing.skipdoctest import skip_doctest
58 from IPython.utils import PyColorize
58 from IPython.utils import PyColorize
59 from IPython.utils import io
59 from IPython.utils import io
60 from IPython.utils import py3compat
60 from IPython.utils import py3compat
61 from IPython.utils import openpy
61 from IPython.utils import openpy
62 from IPython.utils.decorators import undoc
62 from IPython.utils.decorators import undoc
63 from IPython.utils.io import ask_yes_no
63 from IPython.utils.io import ask_yes_no
64 from IPython.utils.ipstruct import Struct
64 from IPython.utils.ipstruct import Struct
65 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename, ensure_dir_exists
65 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename, ensure_dir_exists
66 from IPython.utils.pickleshare import PickleShareDB
66 from IPython.utils.pickleshare import PickleShareDB
67 from IPython.utils.process import system, getoutput
67 from IPython.utils.process import system, getoutput
68 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
68 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
69 with_metaclass, iteritems)
69 with_metaclass, iteritems)
70 from IPython.utils.strdispatch import StrDispatch
70 from IPython.utils.strdispatch import StrDispatch
71 from IPython.utils.syspathcontext import prepended_to_syspath
71 from IPython.utils.syspathcontext import prepended_to_syspath
72 from IPython.utils.text import (format_screen, LSString, SList,
72 from IPython.utils.text import (format_screen, LSString, SList,
73 DollarFormatter)
73 DollarFormatter)
74 from IPython.utils.traitlets import (Integer, Bool, CBool, CaselessStrEnum, Enum,
74 from IPython.utils.traitlets import (Integer, Bool, CBool, CaselessStrEnum, Enum,
75 List, Unicode, Instance, Type)
75 List, Unicode, Instance, Type)
76 from IPython.utils.warn import warn, error
76 from IPython.utils.warn import warn, error
77 import IPython.core.hooks
77 import IPython.core.hooks
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 # Globals
80 # Globals
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82
82
83 # compiled regexps for autoindent management
83 # compiled regexps for autoindent management
84 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
84 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
85
85
86 #-----------------------------------------------------------------------------
86 #-----------------------------------------------------------------------------
87 # Utilities
87 # Utilities
88 #-----------------------------------------------------------------------------
88 #-----------------------------------------------------------------------------
89
89
90 @undoc
90 @undoc
91 def softspace(file, newvalue):
91 def softspace(file, newvalue):
92 """Copied from code.py, to remove the dependency"""
92 """Copied from code.py, to remove the dependency"""
93
93
94 oldvalue = 0
94 oldvalue = 0
95 try:
95 try:
96 oldvalue = file.softspace
96 oldvalue = file.softspace
97 except AttributeError:
97 except AttributeError:
98 pass
98 pass
99 try:
99 try:
100 file.softspace = newvalue
100 file.softspace = newvalue
101 except (AttributeError, TypeError):
101 except (AttributeError, TypeError):
102 # "attribute-less object" or "read-only attributes"
102 # "attribute-less object" or "read-only attributes"
103 pass
103 pass
104 return oldvalue
104 return oldvalue
105
105
106 @undoc
106 @undoc
107 def no_op(*a, **kw): pass
107 def no_op(*a, **kw): pass
108
108
109 @undoc
109 @undoc
110 class NoOpContext(object):
110 class NoOpContext(object):
111 def __enter__(self): pass
111 def __enter__(self): pass
112 def __exit__(self, type, value, traceback): pass
112 def __exit__(self, type, value, traceback): pass
113 no_op_context = NoOpContext()
113 no_op_context = NoOpContext()
114
114
115 class SpaceInInput(Exception): pass
115 class SpaceInInput(Exception): pass
116
116
117 @undoc
117 @undoc
118 class Bunch: pass
118 class Bunch: pass
119
119
120
120
121 def get_default_colors():
121 def get_default_colors():
122 if sys.platform=='darwin':
122 if sys.platform=='darwin':
123 return "LightBG"
123 return "LightBG"
124 elif os.name=='nt':
124 elif os.name=='nt':
125 return 'Linux'
125 return 'Linux'
126 else:
126 else:
127 return 'Linux'
127 return 'Linux'
128
128
129
129
130 class SeparateUnicode(Unicode):
130 class SeparateUnicode(Unicode):
131 r"""A Unicode subclass to validate separate_in, separate_out, etc.
131 r"""A Unicode subclass to validate separate_in, separate_out, etc.
132
132
133 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
133 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
134 """
134 """
135
135
136 def validate(self, obj, value):
136 def validate(self, obj, value):
137 if value == '0': value = ''
137 if value == '0': value = ''
138 value = value.replace('\\n','\n')
138 value = value.replace('\\n','\n')
139 return super(SeparateUnicode, self).validate(obj, value)
139 return super(SeparateUnicode, self).validate(obj, value)
140
140
141
141
142 class ReadlineNoRecord(object):
142 class ReadlineNoRecord(object):
143 """Context manager to execute some code, then reload readline history
143 """Context manager to execute some code, then reload readline history
144 so that interactive input to the code doesn't appear when pressing up."""
144 so that interactive input to the code doesn't appear when pressing up."""
145 def __init__(self, shell):
145 def __init__(self, shell):
146 self.shell = shell
146 self.shell = shell
147 self._nested_level = 0
147 self._nested_level = 0
148
148
149 def __enter__(self):
149 def __enter__(self):
150 if self._nested_level == 0:
150 if self._nested_level == 0:
151 try:
151 try:
152 self.orig_length = self.current_length()
152 self.orig_length = self.current_length()
153 self.readline_tail = self.get_readline_tail()
153 self.readline_tail = self.get_readline_tail()
154 except (AttributeError, IndexError): # Can fail with pyreadline
154 except (AttributeError, IndexError): # Can fail with pyreadline
155 self.orig_length, self.readline_tail = 999999, []
155 self.orig_length, self.readline_tail = 999999, []
156 self._nested_level += 1
156 self._nested_level += 1
157
157
158 def __exit__(self, type, value, traceback):
158 def __exit__(self, type, value, traceback):
159 self._nested_level -= 1
159 self._nested_level -= 1
160 if self._nested_level == 0:
160 if self._nested_level == 0:
161 # Try clipping the end if it's got longer
161 # Try clipping the end if it's got longer
162 try:
162 try:
163 e = self.current_length() - self.orig_length
163 e = self.current_length() - self.orig_length
164 if e > 0:
164 if e > 0:
165 for _ in range(e):
165 for _ in range(e):
166 self.shell.readline.remove_history_item(self.orig_length)
166 self.shell.readline.remove_history_item(self.orig_length)
167
167
168 # If it still doesn't match, just reload readline history.
168 # If it still doesn't match, just reload readline history.
169 if self.current_length() != self.orig_length \
169 if self.current_length() != self.orig_length \
170 or self.get_readline_tail() != self.readline_tail:
170 or self.get_readline_tail() != self.readline_tail:
171 self.shell.refill_readline_hist()
171 self.shell.refill_readline_hist()
172 except (AttributeError, IndexError):
172 except (AttributeError, IndexError):
173 pass
173 pass
174 # Returning False will cause exceptions to propagate
174 # Returning False will cause exceptions to propagate
175 return False
175 return False
176
176
177 def current_length(self):
177 def current_length(self):
178 return self.shell.readline.get_current_history_length()
178 return self.shell.readline.get_current_history_length()
179
179
180 def get_readline_tail(self, n=10):
180 def get_readline_tail(self, n=10):
181 """Get the last n items in readline history."""
181 """Get the last n items in readline history."""
182 end = self.shell.readline.get_current_history_length() + 1
182 end = self.shell.readline.get_current_history_length() + 1
183 start = max(end-n, 1)
183 start = max(end-n, 1)
184 ghi = self.shell.readline.get_history_item
184 ghi = self.shell.readline.get_history_item
185 return [ghi(x) for x in range(start, end)]
185 return [ghi(x) for x in range(start, end)]
186
186
187
187
188 @undoc
188 @undoc
189 class DummyMod(object):
189 class DummyMod(object):
190 """A dummy module used for IPython's interactive module when
190 """A dummy module used for IPython's interactive module when
191 a namespace must be assigned to the module's __dict__."""
191 a namespace must be assigned to the module's __dict__."""
192 pass
192 pass
193
193
194
194
195 class ExecutionResult(object):
195 class ExecutionResult(object):
196 """The result of a call to :meth:`InteractiveShell.run_cell`
196 """The result of a call to :meth:`InteractiveShell.run_cell`
197
197
198 Stores information about what took place.
198 Stores information about what took place.
199 """
199 """
200 execution_count = None
200 execution_count = None
201 error_before_exec = None
201 error_before_exec = None
202 error_in_exec = None
202 error_in_exec = None
203 result = None
203 result = None
204
204
205 @property
205 @property
206 def success(self):
206 def success(self):
207 return (self.error_before_exec is None) and (self.error_in_exec is None)
207 return (self.error_before_exec is None) and (self.error_in_exec is None)
208
208
209
209
210 class InteractiveShell(SingletonConfigurable):
210 class InteractiveShell(SingletonConfigurable):
211 """An enhanced, interactive shell for Python."""
211 """An enhanced, interactive shell for Python."""
212
212
213 _instance = None
213 _instance = None
214
214
215 ast_transformers = List([], config=True, help=
215 ast_transformers = List([], config=True, help=
216 """
216 """
217 A list of ast.NodeTransformer subclass instances, which will be applied
217 A list of ast.NodeTransformer subclass instances, which will be applied
218 to user input before code is run.
218 to user input before code is run.
219 """
219 """
220 )
220 )
221
221
222 autocall = Enum((0,1,2), default_value=0, config=True, help=
222 autocall = Enum((0,1,2), default_value=0, config=True, help=
223 """
223 """
224 Make IPython automatically call any callable object even if you didn't
224 Make IPython automatically call any callable object even if you didn't
225 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
225 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
226 automatically. The value can be '0' to disable the feature, '1' for
226 automatically. The value can be '0' to disable the feature, '1' for
227 'smart' autocall, where it is not applied if there are no more
227 'smart' autocall, where it is not applied if there are no more
228 arguments on the line, and '2' for 'full' autocall, where all callable
228 arguments on the line, and '2' for 'full' autocall, where all callable
229 objects are automatically called (even if no arguments are present).
229 objects are automatically called (even if no arguments are present).
230 """
230 """
231 )
231 )
232 # TODO: remove all autoindent logic and put into frontends.
232 # TODO: remove all autoindent logic and put into frontends.
233 # We can't do this yet because even runlines uses the autoindent.
233 # We can't do this yet because even runlines uses the autoindent.
234 autoindent = CBool(True, config=True, help=
234 autoindent = CBool(True, config=True, help=
235 """
235 """
236 Autoindent IPython code entered interactively.
236 Autoindent IPython code entered interactively.
237 """
237 """
238 )
238 )
239 automagic = CBool(True, config=True, help=
239 automagic = CBool(True, config=True, help=
240 """
240 """
241 Enable magic commands to be called without the leading %.
241 Enable magic commands to be called without the leading %.
242 """
242 """
243 )
243 )
244
244
245 banner1 = Unicode(default_banner, config=True,
245 banner1 = Unicode(default_banner, config=True,
246 help="""The part of the banner to be printed before the profile"""
246 help="""The part of the banner to be printed before the profile"""
247 )
247 )
248 banner2 = Unicode('', config=True,
248 banner2 = Unicode('', config=True,
249 help="""The part of the banner to be printed after the profile"""
249 help="""The part of the banner to be printed after the profile"""
250 )
250 )
251
251
252 cache_size = Integer(1000, config=True, help=
252 cache_size = Integer(1000, config=True, help=
253 """
253 """
254 Set the size of the output cache. The default is 1000, you can
254 Set the size of the output cache. The default is 1000, you can
255 change it permanently in your config file. Setting it to 0 completely
255 change it permanently in your config file. Setting it to 0 completely
256 disables the caching system, and the minimum value accepted is 20 (if
256 disables the caching system, and the minimum value accepted is 20 (if
257 you provide a value less than 20, it is reset to 0 and a warning is
257 you provide a value less than 20, it is reset to 0 and a warning is
258 issued). This limit is defined because otherwise you'll spend more
258 issued). This limit is defined because otherwise you'll spend more
259 time re-flushing a too small cache than working
259 time re-flushing a too small cache than working
260 """
260 """
261 )
261 )
262 color_info = CBool(True, config=True, help=
262 color_info = CBool(True, config=True, help=
263 """
263 """
264 Use colors for displaying information about objects. Because this
264 Use colors for displaying information about objects. Because this
265 information is passed through a pager (like 'less'), and some pagers
265 information is passed through a pager (like 'less'), and some pagers
266 get confused with color codes, this capability can be turned off.
266 get confused with color codes, this capability can be turned off.
267 """
267 """
268 )
268 )
269 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
269 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
270 default_value=get_default_colors(), config=True,
270 default_value=get_default_colors(), config=True,
271 help="Set the color scheme (NoColor, Linux, or LightBG)."
271 help="Set the color scheme (NoColor, Linux, or LightBG)."
272 )
272 )
273 colors_force = CBool(False, help=
273 colors_force = CBool(False, help=
274 """
274 """
275 Force use of ANSI color codes, regardless of OS and readline
275 Force use of ANSI color codes, regardless of OS and readline
276 availability.
276 availability.
277 """
277 """
278 # FIXME: This is essentially a hack to allow ZMQShell to show colors
278 # FIXME: This is essentially a hack to allow ZMQShell to show colors
279 # without readline on Win32. When the ZMQ formatting system is
279 # without readline on Win32. When the ZMQ formatting system is
280 # refactored, this should be removed.
280 # refactored, this should be removed.
281 )
281 )
282 debug = CBool(False, config=True)
282 debug = CBool(False, config=True)
283 deep_reload = CBool(False, config=True, help=
283 deep_reload = CBool(False, config=True, help=
284 """
284 """
285 Enable deep (recursive) reloading by default. IPython can use the
285 Enable deep (recursive) reloading by default. IPython can use the
286 deep_reload module which reloads changes in modules recursively (it
286 deep_reload module which reloads changes in modules recursively (it
287 replaces the reload() function, so you don't need to change anything to
287 replaces the reload() function, so you don't need to change anything to
288 use it). deep_reload() forces a full reload of modules whose code may
288 use it). deep_reload() forces a full reload of modules whose code may
289 have changed, which the default reload() function does not. When
289 have changed, which the default reload() function does not. When
290 deep_reload is off, IPython will use the normal reload(), but
290 deep_reload is off, IPython will use the normal reload(), but
291 deep_reload will still be available as dreload().
291 deep_reload will still be available as dreload().
292 """
292 """
293 )
293 )
294 disable_failing_post_execute = CBool(False, config=True,
294 disable_failing_post_execute = CBool(False, config=True,
295 help="Don't call post-execute functions that have failed in the past."
295 help="Don't call post-execute functions that have failed in the past."
296 )
296 )
297 display_formatter = Instance(DisplayFormatter)
297 display_formatter = Instance(DisplayFormatter)
298 displayhook_class = Type(DisplayHook)
298 displayhook_class = Type(DisplayHook)
299 display_pub_class = Type(DisplayPublisher)
299 display_pub_class = Type(DisplayPublisher)
300 data_pub_class = None
300 data_pub_class = None
301
301
302 exit_now = CBool(False)
302 exit_now = CBool(False)
303 exiter = Instance(ExitAutocall)
303 exiter = Instance(ExitAutocall)
304 def _exiter_default(self):
304 def _exiter_default(self):
305 return ExitAutocall(self)
305 return ExitAutocall(self)
306 # Monotonically increasing execution counter
306 # Monotonically increasing execution counter
307 execution_count = Integer(1)
307 execution_count = Integer(1)
308 filename = Unicode("<ipython console>")
308 filename = Unicode("<ipython console>")
309 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
309 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
310
310
311 # Input splitter, to transform input line by line and detect when a block
311 # Input splitter, to transform input line by line and detect when a block
312 # is ready to be executed.
312 # is ready to be executed.
313 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
313 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
314 (), {'line_input_checker': True})
314 (), {'line_input_checker': True})
315
315
316 # This InputSplitter instance is used to transform completed cells before
316 # This InputSplitter instance is used to transform completed cells before
317 # running them. It allows cell magics to contain blank lines.
317 # running them. It allows cell magics to contain blank lines.
318 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
318 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
319 (), {'line_input_checker': False})
319 (), {'line_input_checker': False})
320
320
321 logstart = CBool(False, config=True, help=
321 logstart = CBool(False, config=True, help=
322 """
322 """
323 Start logging to the default log file.
323 Start logging to the default log file.
324 """
324 """
325 )
325 )
326 logfile = Unicode('', config=True, help=
326 logfile = Unicode('', config=True, help=
327 """
327 """
328 The name of the logfile to use.
328 The name of the logfile to use.
329 """
329 """
330 )
330 )
331 logappend = Unicode('', config=True, help=
331 logappend = Unicode('', config=True, help=
332 """
332 """
333 Start logging to the given file in append mode.
333 Start logging to the given file in append mode.
334 """
334 """
335 )
335 )
336 object_info_string_level = Enum((0,1,2), default_value=0,
336 object_info_string_level = Enum((0,1,2), default_value=0,
337 config=True)
337 config=True)
338 pdb = CBool(False, config=True, help=
338 pdb = CBool(False, config=True, help=
339 """
339 """
340 Automatically call the pdb debugger after every exception.
340 Automatically call the pdb debugger after every exception.
341 """
341 """
342 )
342 )
343 multiline_history = CBool(sys.platform != 'win32', config=True,
343 multiline_history = CBool(sys.platform != 'win32', config=True,
344 help="Save multi-line entries as one entry in readline history"
344 help="Save multi-line entries as one entry in readline history"
345 )
345 )
346 display_page = Bool(False, config=True,
346 display_page = Bool(False, config=True,
347 help="""If True, anything that would be passed to the pager
347 help="""If True, anything that would be passed to the pager
348 will be displayed as regular output instead."""
348 will be displayed as regular output instead."""
349 )
349 )
350
350
351 # deprecated prompt traits:
351 # deprecated prompt traits:
352
352
353 prompt_in1 = Unicode('In [\\#]: ', config=True,
353 prompt_in1 = Unicode('In [\\#]: ', config=True,
354 help="Deprecated, use PromptManager.in_template")
354 help="Deprecated, use PromptManager.in_template")
355 prompt_in2 = Unicode(' .\\D.: ', config=True,
355 prompt_in2 = Unicode(' .\\D.: ', config=True,
356 help="Deprecated, use PromptManager.in2_template")
356 help="Deprecated, use PromptManager.in2_template")
357 prompt_out = Unicode('Out[\\#]: ', config=True,
357 prompt_out = Unicode('Out[\\#]: ', config=True,
358 help="Deprecated, use PromptManager.out_template")
358 help="Deprecated, use PromptManager.out_template")
359 prompts_pad_left = CBool(True, config=True,
359 prompts_pad_left = CBool(True, config=True,
360 help="Deprecated, use PromptManager.justify")
360 help="Deprecated, use PromptManager.justify")
361
361
362 def _prompt_trait_changed(self, name, old, new):
362 def _prompt_trait_changed(self, name, old, new):
363 table = {
363 table = {
364 'prompt_in1' : 'in_template',
364 'prompt_in1' : 'in_template',
365 'prompt_in2' : 'in2_template',
365 'prompt_in2' : 'in2_template',
366 'prompt_out' : 'out_template',
366 'prompt_out' : 'out_template',
367 'prompts_pad_left' : 'justify',
367 'prompts_pad_left' : 'justify',
368 }
368 }
369 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
369 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
370 name=name, newname=table[name])
370 name=name, newname=table[name])
371 )
371 )
372 # protect against weird cases where self.config may not exist:
372 # protect against weird cases where self.config may not exist:
373 if self.config is not None:
373 if self.config is not None:
374 # propagate to corresponding PromptManager trait
374 # propagate to corresponding PromptManager trait
375 setattr(self.config.PromptManager, table[name], new)
375 setattr(self.config.PromptManager, table[name], new)
376
376
377 _prompt_in1_changed = _prompt_trait_changed
377 _prompt_in1_changed = _prompt_trait_changed
378 _prompt_in2_changed = _prompt_trait_changed
378 _prompt_in2_changed = _prompt_trait_changed
379 _prompt_out_changed = _prompt_trait_changed
379 _prompt_out_changed = _prompt_trait_changed
380 _prompt_pad_left_changed = _prompt_trait_changed
380 _prompt_pad_left_changed = _prompt_trait_changed
381
381
382 show_rewritten_input = CBool(True, config=True,
382 show_rewritten_input = CBool(True, config=True,
383 help="Show rewritten input, e.g. for autocall."
383 help="Show rewritten input, e.g. for autocall."
384 )
384 )
385
385
386 quiet = CBool(False, config=True)
386 quiet = CBool(False, config=True)
387
387
388 history_length = Integer(10000, config=True)
388 history_length = Integer(10000, config=True)
389
389
390 # The readline stuff will eventually be moved to the terminal subclass
390 # The readline stuff will eventually be moved to the terminal subclass
391 # but for now, we can't do that as readline is welded in everywhere.
391 # but for now, we can't do that as readline is welded in everywhere.
392 readline_use = CBool(True, config=True)
392 readline_use = CBool(True, config=True)
393 readline_remove_delims = Unicode('-/~', config=True)
393 readline_remove_delims = Unicode('-/~', config=True)
394 readline_delims = Unicode() # set by init_readline()
394 readline_delims = Unicode() # set by init_readline()
395 # don't use \M- bindings by default, because they
395 # don't use \M- bindings by default, because they
396 # conflict with 8-bit encodings. See gh-58,gh-88
396 # conflict with 8-bit encodings. See gh-58,gh-88
397 readline_parse_and_bind = List([
397 readline_parse_and_bind = List([
398 'tab: complete',
398 'tab: complete',
399 '"\C-l": clear-screen',
399 '"\C-l": clear-screen',
400 'set show-all-if-ambiguous on',
400 'set show-all-if-ambiguous on',
401 '"\C-o": tab-insert',
401 '"\C-o": tab-insert',
402 '"\C-r": reverse-search-history',
402 '"\C-r": reverse-search-history',
403 '"\C-s": forward-search-history',
403 '"\C-s": forward-search-history',
404 '"\C-p": history-search-backward',
404 '"\C-p": history-search-backward',
405 '"\C-n": history-search-forward',
405 '"\C-n": history-search-forward',
406 '"\e[A": history-search-backward',
406 '"\e[A": history-search-backward',
407 '"\e[B": history-search-forward',
407 '"\e[B": history-search-forward',
408 '"\C-k": kill-line',
408 '"\C-k": kill-line',
409 '"\C-u": unix-line-discard',
409 '"\C-u": unix-line-discard',
410 ], config=True)
410 ], config=True)
411
411
412 _custom_readline_config = False
412 _custom_readline_config = False
413
413
414 def _readline_parse_and_bind_changed(self, name, old, new):
414 def _readline_parse_and_bind_changed(self, name, old, new):
415 # notice that readline config is customized
415 # notice that readline config is customized
416 # indicates that it should have higher priority than inputrc
416 # indicates that it should have higher priority than inputrc
417 self._custom_readline_config = True
417 self._custom_readline_config = True
418
418
419 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
419 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
420 default_value='last_expr', config=True,
420 default_value='last_expr', config=True,
421 help="""
421 help="""
422 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
422 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
423 run interactively (displaying output from expressions).""")
423 run interactively (displaying output from expressions).""")
424
424
425 # TODO: this part of prompt management should be moved to the frontends.
425 # TODO: this part of prompt management should be moved to the frontends.
426 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
426 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
427 separate_in = SeparateUnicode('\n', config=True)
427 separate_in = SeparateUnicode('\n', config=True)
428 separate_out = SeparateUnicode('', config=True)
428 separate_out = SeparateUnicode('', config=True)
429 separate_out2 = SeparateUnicode('', config=True)
429 separate_out2 = SeparateUnicode('', config=True)
430 wildcards_case_sensitive = CBool(True, config=True)
430 wildcards_case_sensitive = CBool(True, config=True)
431 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
431 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
432 default_value='Context', config=True)
432 default_value='Context', config=True)
433
433
434 # Subcomponents of InteractiveShell
434 # Subcomponents of InteractiveShell
435 alias_manager = Instance('IPython.core.alias.AliasManager')
435 alias_manager = Instance('IPython.core.alias.AliasManager')
436 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
436 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
437 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
437 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
438 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
438 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
439 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
439 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
440 payload_manager = Instance('IPython.core.payload.PayloadManager')
440 payload_manager = Instance('IPython.core.payload.PayloadManager')
441 history_manager = Instance('IPython.core.history.HistoryAccessorBase')
441 history_manager = Instance('IPython.core.history.HistoryAccessorBase')
442 magics_manager = Instance('IPython.core.magic.MagicsManager')
442 magics_manager = Instance('IPython.core.magic.MagicsManager')
443
443
444 profile_dir = Instance('IPython.core.application.ProfileDir')
444 profile_dir = Instance('IPython.core.application.ProfileDir')
445 @property
445 @property
446 def profile(self):
446 def profile(self):
447 if self.profile_dir is not None:
447 if self.profile_dir is not None:
448 name = os.path.basename(self.profile_dir.location)
448 name = os.path.basename(self.profile_dir.location)
449 return name.replace('profile_','')
449 return name.replace('profile_','')
450
450
451
451
452 # Private interface
452 # Private interface
453 _post_execute = Instance(dict)
453 _post_execute = Instance(dict)
454
454
455 # Tracks any GUI loop loaded for pylab
455 # Tracks any GUI loop loaded for pylab
456 pylab_gui_select = None
456 pylab_gui_select = None
457
457
458 def __init__(self, ipython_dir=None, profile_dir=None,
458 def __init__(self, ipython_dir=None, profile_dir=None,
459 user_module=None, user_ns=None,
459 user_module=None, user_ns=None,
460 custom_exceptions=((), None), **kwargs):
460 custom_exceptions=((), None), **kwargs):
461
461
462 # This is where traits with a config_key argument are updated
462 # This is where traits with a config_key argument are updated
463 # from the values on config.
463 # from the values on config.
464 super(InteractiveShell, self).__init__(**kwargs)
464 super(InteractiveShell, self).__init__(**kwargs)
465 self.configurables = [self]
465 self.configurables = [self]
466
466
467 # These are relatively independent and stateless
467 # These are relatively independent and stateless
468 self.init_ipython_dir(ipython_dir)
468 self.init_ipython_dir(ipython_dir)
469 self.init_profile_dir(profile_dir)
469 self.init_profile_dir(profile_dir)
470 self.init_instance_attrs()
470 self.init_instance_attrs()
471 self.init_environment()
471 self.init_environment()
472
472
473 # Check if we're in a virtualenv, and set up sys.path.
473 # Check if we're in a virtualenv, and set up sys.path.
474 self.init_virtualenv()
474 self.init_virtualenv()
475
475
476 # Create namespaces (user_ns, user_global_ns, etc.)
476 # Create namespaces (user_ns, user_global_ns, etc.)
477 self.init_create_namespaces(user_module, user_ns)
477 self.init_create_namespaces(user_module, user_ns)
478 # This has to be done after init_create_namespaces because it uses
478 # This has to be done after init_create_namespaces because it uses
479 # something in self.user_ns, but before init_sys_modules, which
479 # something in self.user_ns, but before init_sys_modules, which
480 # is the first thing to modify sys.
480 # is the first thing to modify sys.
481 # TODO: When we override sys.stdout and sys.stderr before this class
481 # TODO: When we override sys.stdout and sys.stderr before this class
482 # is created, we are saving the overridden ones here. Not sure if this
482 # is created, we are saving the overridden ones here. Not sure if this
483 # is what we want to do.
483 # is what we want to do.
484 self.save_sys_module_state()
484 self.save_sys_module_state()
485 self.init_sys_modules()
485 self.init_sys_modules()
486
486
487 # While we're trying to have each part of the code directly access what
487 # While we're trying to have each part of the code directly access what
488 # it needs without keeping redundant references to objects, we have too
488 # it needs without keeping redundant references to objects, we have too
489 # much legacy code that expects ip.db to exist.
489 # much legacy code that expects ip.db to exist.
490 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
490 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
491
491
492 self.init_history()
492 self.init_history()
493 self.init_encoding()
493 self.init_encoding()
494 self.init_prefilter()
494 self.init_prefilter()
495
495
496 self.init_syntax_highlighting()
496 self.init_syntax_highlighting()
497 self.init_hooks()
497 self.init_hooks()
498 self.init_events()
498 self.init_events()
499 self.init_pushd_popd_magic()
499 self.init_pushd_popd_magic()
500 # self.init_traceback_handlers use to be here, but we moved it below
500 # self.init_traceback_handlers use to be here, but we moved it below
501 # because it and init_io have to come after init_readline.
501 # because it and init_io have to come after init_readline.
502 self.init_user_ns()
502 self.init_user_ns()
503 self.init_logger()
503 self.init_logger()
504 self.init_builtins()
504 self.init_builtins()
505
505
506 # The following was in post_config_initialization
506 # The following was in post_config_initialization
507 self.init_inspector()
507 self.init_inspector()
508 # init_readline() must come before init_io(), because init_io uses
508 # init_readline() must come before init_io(), because init_io uses
509 # readline related things.
509 # readline related things.
510 self.init_readline()
510 self.init_readline()
511 # We save this here in case user code replaces raw_input, but it needs
511 # We save this here in case user code replaces raw_input, but it needs
512 # to be after init_readline(), because PyPy's readline works by replacing
512 # to be after init_readline(), because PyPy's readline works by replacing
513 # raw_input.
513 # raw_input.
514 if py3compat.PY3:
514 if py3compat.PY3:
515 self.raw_input_original = input
515 self.raw_input_original = input
516 else:
516 else:
517 self.raw_input_original = raw_input
517 self.raw_input_original = raw_input
518 # init_completer must come after init_readline, because it needs to
518 # init_completer must come after init_readline, because it needs to
519 # know whether readline is present or not system-wide to configure the
519 # know whether readline is present or not system-wide to configure the
520 # completers, since the completion machinery can now operate
520 # completers, since the completion machinery can now operate
521 # independently of readline (e.g. over the network)
521 # independently of readline (e.g. over the network)
522 self.init_completer()
522 self.init_completer()
523 # TODO: init_io() needs to happen before init_traceback handlers
523 # TODO: init_io() needs to happen before init_traceback handlers
524 # because the traceback handlers hardcode the stdout/stderr streams.
524 # because the traceback handlers hardcode the stdout/stderr streams.
525 # This logic in in debugger.Pdb and should eventually be changed.
525 # This logic in in debugger.Pdb and should eventually be changed.
526 self.init_io()
526 self.init_io()
527 self.init_traceback_handlers(custom_exceptions)
527 self.init_traceback_handlers(custom_exceptions)
528 self.init_prompts()
528 self.init_prompts()
529 self.init_display_formatter()
529 self.init_display_formatter()
530 self.init_display_pub()
530 self.init_display_pub()
531 self.init_data_pub()
531 self.init_data_pub()
532 self.init_displayhook()
532 self.init_displayhook()
533 self.init_magics()
533 self.init_magics()
534 self.init_alias()
534 self.init_alias()
535 self.init_logstart()
535 self.init_logstart()
536 self.init_pdb()
536 self.init_pdb()
537 self.init_extension_manager()
537 self.init_extension_manager()
538 self.init_payload()
538 self.init_payload()
539 self.hooks.late_startup_hook()
539 self.hooks.late_startup_hook()
540 self.events.trigger('shell_initialized', self)
540 self.events.trigger('shell_initialized', self)
541 atexit.register(self.atexit_operations)
541 atexit.register(self.atexit_operations)
542
542
543 def get_ipython(self):
543 def get_ipython(self):
544 """Return the currently running IPython instance."""
544 """Return the currently running IPython instance."""
545 return self
545 return self
546
546
547 #-------------------------------------------------------------------------
547 #-------------------------------------------------------------------------
548 # Trait changed handlers
548 # Trait changed handlers
549 #-------------------------------------------------------------------------
549 #-------------------------------------------------------------------------
550
550
551 def _ipython_dir_changed(self, name, new):
551 def _ipython_dir_changed(self, name, new):
552 ensure_dir_exists(new)
552 ensure_dir_exists(new)
553
553
554 def set_autoindent(self,value=None):
554 def set_autoindent(self,value=None):
555 """Set the autoindent flag, checking for readline support.
555 """Set the autoindent flag, checking for readline support.
556
556
557 If called with no arguments, it acts as a toggle."""
557 If called with no arguments, it acts as a toggle."""
558
558
559 if value != 0 and not self.has_readline:
559 if value != 0 and not self.has_readline:
560 if os.name == 'posix':
560 if os.name == 'posix':
561 warn("The auto-indent feature requires the readline library")
561 warn("The auto-indent feature requires the readline library")
562 self.autoindent = 0
562 self.autoindent = 0
563 return
563 return
564 if value is None:
564 if value is None:
565 self.autoindent = not self.autoindent
565 self.autoindent = not self.autoindent
566 else:
566 else:
567 self.autoindent = value
567 self.autoindent = value
568
568
569 #-------------------------------------------------------------------------
569 #-------------------------------------------------------------------------
570 # init_* methods called by __init__
570 # init_* methods called by __init__
571 #-------------------------------------------------------------------------
571 #-------------------------------------------------------------------------
572
572
573 def init_ipython_dir(self, ipython_dir):
573 def init_ipython_dir(self, ipython_dir):
574 if ipython_dir is not None:
574 if ipython_dir is not None:
575 self.ipython_dir = ipython_dir
575 self.ipython_dir = ipython_dir
576 return
576 return
577
577
578 self.ipython_dir = get_ipython_dir()
578 self.ipython_dir = get_ipython_dir()
579
579
580 def init_profile_dir(self, profile_dir):
580 def init_profile_dir(self, profile_dir):
581 if profile_dir is not None:
581 if profile_dir is not None:
582 self.profile_dir = profile_dir
582 self.profile_dir = profile_dir
583 return
583 return
584 self.profile_dir =\
584 self.profile_dir =\
585 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
585 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
586
586
587 def init_instance_attrs(self):
587 def init_instance_attrs(self):
588 self.more = False
588 self.more = False
589
589
590 # command compiler
590 # command compiler
591 self.compile = CachingCompiler()
591 self.compile = CachingCompiler()
592
592
593 # Make an empty namespace, which extension writers can rely on both
593 # Make an empty namespace, which extension writers can rely on both
594 # existing and NEVER being used by ipython itself. This gives them a
594 # existing and NEVER being used by ipython itself. This gives them a
595 # convenient location for storing additional information and state
595 # convenient location for storing additional information and state
596 # their extensions may require, without fear of collisions with other
596 # their extensions may require, without fear of collisions with other
597 # ipython names that may develop later.
597 # ipython names that may develop later.
598 self.meta = Struct()
598 self.meta = Struct()
599
599
600 # Temporary files used for various purposes. Deleted at exit.
600 # Temporary files used for various purposes. Deleted at exit.
601 self.tempfiles = []
601 self.tempfiles = []
602 self.tempdirs = []
602 self.tempdirs = []
603
603
604 # Keep track of readline usage (later set by init_readline)
604 # Keep track of readline usage (later set by init_readline)
605 self.has_readline = False
605 self.has_readline = False
606
606
607 # keep track of where we started running (mainly for crash post-mortem)
607 # keep track of where we started running (mainly for crash post-mortem)
608 # This is not being used anywhere currently.
608 # This is not being used anywhere currently.
609 self.starting_dir = py3compat.getcwd()
609 self.starting_dir = py3compat.getcwd()
610
610
611 # Indentation management
611 # Indentation management
612 self.indent_current_nsp = 0
612 self.indent_current_nsp = 0
613
613
614 # Dict to track post-execution functions that have been registered
614 # Dict to track post-execution functions that have been registered
615 self._post_execute = {}
615 self._post_execute = {}
616
616
617 def init_environment(self):
617 def init_environment(self):
618 """Any changes we need to make to the user's environment."""
618 """Any changes we need to make to the user's environment."""
619 pass
619 pass
620
620
621 def init_encoding(self):
621 def init_encoding(self):
622 # Get system encoding at startup time. Certain terminals (like Emacs
622 # Get system encoding at startup time. Certain terminals (like Emacs
623 # under Win32 have it set to None, and we need to have a known valid
623 # under Win32 have it set to None, and we need to have a known valid
624 # encoding to use in the raw_input() method
624 # encoding to use in the raw_input() method
625 try:
625 try:
626 self.stdin_encoding = sys.stdin.encoding or 'ascii'
626 self.stdin_encoding = sys.stdin.encoding or 'ascii'
627 except AttributeError:
627 except AttributeError:
628 self.stdin_encoding = 'ascii'
628 self.stdin_encoding = 'ascii'
629
629
630 def init_syntax_highlighting(self):
630 def init_syntax_highlighting(self):
631 # Python source parser/formatter for syntax highlighting
631 # Python source parser/formatter for syntax highlighting
632 pyformat = PyColorize.Parser().format
632 pyformat = PyColorize.Parser().format
633 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
633 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
634
634
635 def init_pushd_popd_magic(self):
635 def init_pushd_popd_magic(self):
636 # for pushd/popd management
636 # for pushd/popd management
637 self.home_dir = get_home_dir()
637 self.home_dir = get_home_dir()
638
638
639 self.dir_stack = []
639 self.dir_stack = []
640
640
641 def init_logger(self):
641 def init_logger(self):
642 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
642 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
643 logmode='rotate')
643 logmode='rotate')
644
644
645 def init_logstart(self):
645 def init_logstart(self):
646 """Initialize logging in case it was requested at the command line.
646 """Initialize logging in case it was requested at the command line.
647 """
647 """
648 if self.logappend:
648 if self.logappend:
649 self.magic('logstart %s append' % self.logappend)
649 self.magic('logstart %s append' % self.logappend)
650 elif self.logfile:
650 elif self.logfile:
651 self.magic('logstart %s' % self.logfile)
651 self.magic('logstart %s' % self.logfile)
652 elif self.logstart:
652 elif self.logstart:
653 self.magic('logstart')
653 self.magic('logstart')
654
654
655 def init_builtins(self):
655 def init_builtins(self):
656 # A single, static flag that we set to True. Its presence indicates
656 # A single, static flag that we set to True. Its presence indicates
657 # that an IPython shell has been created, and we make no attempts at
657 # that an IPython shell has been created, and we make no attempts at
658 # removing on exit or representing the existence of more than one
658 # removing on exit or representing the existence of more than one
659 # IPython at a time.
659 # IPython at a time.
660 builtin_mod.__dict__['__IPYTHON__'] = True
660 builtin_mod.__dict__['__IPYTHON__'] = True
661
661
662 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
662 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
663 # manage on enter/exit, but with all our shells it's virtually
663 # manage on enter/exit, but with all our shells it's virtually
664 # impossible to get all the cases right. We're leaving the name in for
664 # impossible to get all the cases right. We're leaving the name in for
665 # those who adapted their codes to check for this flag, but will
665 # those who adapted their codes to check for this flag, but will
666 # eventually remove it after a few more releases.
666 # eventually remove it after a few more releases.
667 builtin_mod.__dict__['__IPYTHON__active'] = \
667 builtin_mod.__dict__['__IPYTHON__active'] = \
668 'Deprecated, check for __IPYTHON__'
668 'Deprecated, check for __IPYTHON__'
669
669
670 self.builtin_trap = BuiltinTrap(shell=self)
670 self.builtin_trap = BuiltinTrap(shell=self)
671
671
672 def init_inspector(self):
672 def init_inspector(self):
673 # Object inspector
673 # Object inspector
674 self.inspector = oinspect.Inspector(oinspect.InspectColors,
674 self.inspector = oinspect.Inspector(oinspect.InspectColors,
675 PyColorize.ANSICodeColors,
675 PyColorize.ANSICodeColors,
676 'NoColor',
676 'NoColor',
677 self.object_info_string_level)
677 self.object_info_string_level)
678
678
679 def init_io(self):
679 def init_io(self):
680 # This will just use sys.stdout and sys.stderr. If you want to
680 # This will just use sys.stdout and sys.stderr. If you want to
681 # override sys.stdout and sys.stderr themselves, you need to do that
681 # override sys.stdout and sys.stderr themselves, you need to do that
682 # *before* instantiating this class, because io holds onto
682 # *before* instantiating this class, because io holds onto
683 # references to the underlying streams.
683 # references to the underlying streams.
684 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
684 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
685 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
685 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
686 else:
686 else:
687 io.stdout = io.IOStream(sys.stdout)
687 io.stdout = io.IOStream(sys.stdout)
688 io.stderr = io.IOStream(sys.stderr)
688 io.stderr = io.IOStream(sys.stderr)
689
689
690 def init_prompts(self):
690 def init_prompts(self):
691 self.prompt_manager = PromptManager(shell=self, parent=self)
691 self.prompt_manager = PromptManager(shell=self, parent=self)
692 self.configurables.append(self.prompt_manager)
692 self.configurables.append(self.prompt_manager)
693 # Set system prompts, so that scripts can decide if they are running
693 # Set system prompts, so that scripts can decide if they are running
694 # interactively.
694 # interactively.
695 sys.ps1 = 'In : '
695 sys.ps1 = 'In : '
696 sys.ps2 = '...: '
696 sys.ps2 = '...: '
697 sys.ps3 = 'Out: '
697 sys.ps3 = 'Out: '
698
698
699 def init_display_formatter(self):
699 def init_display_formatter(self):
700 self.display_formatter = DisplayFormatter(parent=self)
700 self.display_formatter = DisplayFormatter(parent=self)
701 self.configurables.append(self.display_formatter)
701 self.configurables.append(self.display_formatter)
702
702
703 def init_display_pub(self):
703 def init_display_pub(self):
704 self.display_pub = self.display_pub_class(parent=self)
704 self.display_pub = self.display_pub_class(parent=self)
705 self.configurables.append(self.display_pub)
705 self.configurables.append(self.display_pub)
706
706
707 def init_data_pub(self):
707 def init_data_pub(self):
708 if not self.data_pub_class:
708 if not self.data_pub_class:
709 self.data_pub = None
709 self.data_pub = None
710 return
710 return
711 self.data_pub = self.data_pub_class(parent=self)
711 self.data_pub = self.data_pub_class(parent=self)
712 self.configurables.append(self.data_pub)
712 self.configurables.append(self.data_pub)
713
713
714 def init_displayhook(self):
714 def init_displayhook(self):
715 # Initialize displayhook, set in/out prompts and printing system
715 # Initialize displayhook, set in/out prompts and printing system
716 self.displayhook = self.displayhook_class(
716 self.displayhook = self.displayhook_class(
717 parent=self,
717 parent=self,
718 shell=self,
718 shell=self,
719 cache_size=self.cache_size,
719 cache_size=self.cache_size,
720 )
720 )
721 self.configurables.append(self.displayhook)
721 self.configurables.append(self.displayhook)
722 # This is a context manager that installs/revmoes the displayhook at
722 # This is a context manager that installs/revmoes the displayhook at
723 # the appropriate time.
723 # the appropriate time.
724 self.display_trap = DisplayTrap(hook=self.displayhook)
724 self.display_trap = DisplayTrap(hook=self.displayhook)
725
725
726 def init_virtualenv(self):
726 def init_virtualenv(self):
727 """Add a virtualenv to sys.path so the user can import modules from it.
727 """Add a virtualenv to sys.path so the user can import modules from it.
728 This isn't perfect: it doesn't use the Python interpreter with which the
728 This isn't perfect: it doesn't use the Python interpreter with which the
729 virtualenv was built, and it ignores the --no-site-packages option. A
729 virtualenv was built, and it ignores the --no-site-packages option. A
730 warning will appear suggesting the user installs IPython in the
730 warning will appear suggesting the user installs IPython in the
731 virtualenv, but for many cases, it probably works well enough.
731 virtualenv, but for many cases, it probably works well enough.
732
732
733 Adapted from code snippets online.
733 Adapted from code snippets online.
734
734
735 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
735 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
736 """
736 """
737 if 'VIRTUAL_ENV' not in os.environ:
737 if 'VIRTUAL_ENV' not in os.environ:
738 # Not in a virtualenv
738 # Not in a virtualenv
739 return
739 return
740
740
741 # venv detection:
741 # venv detection:
742 # stdlib venv may symlink sys.executable, so we can't use realpath.
742 # stdlib venv may symlink sys.executable, so we can't use realpath.
743 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
743 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
744 # So we just check every item in the symlink tree (generally <= 3)
744 # So we just check every item in the symlink tree (generally <= 3)
745 p = os.path.normcase(sys.executable)
745 p = os.path.normcase(sys.executable)
746 paths = [p]
746 paths = [p]
747 while os.path.islink(p):
747 while os.path.islink(p):
748 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
748 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
749 paths.append(p)
749 paths.append(p)
750 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
750 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
751 if any(p.startswith(p_venv) for p in paths):
751 if any(p.startswith(p_venv) for p in paths):
752 # Running properly in the virtualenv, don't need to do anything
752 # Running properly in the virtualenv, don't need to do anything
753 return
753 return
754
754
755 warn("Attempting to work in a virtualenv. If you encounter problems, please "
755 warn("Attempting to work in a virtualenv. If you encounter problems, please "
756 "install IPython inside the virtualenv.")
756 "install IPython inside the virtualenv.")
757 if sys.platform == "win32":
757 if sys.platform == "win32":
758 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
758 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
759 else:
759 else:
760 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
760 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
761 'python%d.%d' % sys.version_info[:2], 'site-packages')
761 'python%d.%d' % sys.version_info[:2], 'site-packages')
762
762
763 import site
763 import site
764 sys.path.insert(0, virtual_env)
764 sys.path.insert(0, virtual_env)
765 site.addsitedir(virtual_env)
765 site.addsitedir(virtual_env)
766
766
767 #-------------------------------------------------------------------------
767 #-------------------------------------------------------------------------
768 # Things related to injections into the sys module
768 # Things related to injections into the sys module
769 #-------------------------------------------------------------------------
769 #-------------------------------------------------------------------------
770
770
771 def save_sys_module_state(self):
771 def save_sys_module_state(self):
772 """Save the state of hooks in the sys module.
772 """Save the state of hooks in the sys module.
773
773
774 This has to be called after self.user_module is created.
774 This has to be called after self.user_module is created.
775 """
775 """
776 self._orig_sys_module_state = {}
776 self._orig_sys_module_state = {}
777 self._orig_sys_module_state['stdin'] = sys.stdin
777 self._orig_sys_module_state['stdin'] = sys.stdin
778 self._orig_sys_module_state['stdout'] = sys.stdout
778 self._orig_sys_module_state['stdout'] = sys.stdout
779 self._orig_sys_module_state['stderr'] = sys.stderr
779 self._orig_sys_module_state['stderr'] = sys.stderr
780 self._orig_sys_module_state['excepthook'] = sys.excepthook
780 self._orig_sys_module_state['excepthook'] = sys.excepthook
781 self._orig_sys_modules_main_name = self.user_module.__name__
781 self._orig_sys_modules_main_name = self.user_module.__name__
782 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
782 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
783
783
784 def restore_sys_module_state(self):
784 def restore_sys_module_state(self):
785 """Restore the state of the sys module."""
785 """Restore the state of the sys module."""
786 try:
786 try:
787 for k, v in iteritems(self._orig_sys_module_state):
787 for k, v in iteritems(self._orig_sys_module_state):
788 setattr(sys, k, v)
788 setattr(sys, k, v)
789 except AttributeError:
789 except AttributeError:
790 pass
790 pass
791 # Reset what what done in self.init_sys_modules
791 # Reset what what done in self.init_sys_modules
792 if self._orig_sys_modules_main_mod is not None:
792 if self._orig_sys_modules_main_mod is not None:
793 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
793 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
794
794
795 #-------------------------------------------------------------------------
795 #-------------------------------------------------------------------------
796 # Things related to the banner
796 # Things related to the banner
797 #-------------------------------------------------------------------------
797 #-------------------------------------------------------------------------
798
798
799 @property
799 @property
800 def banner(self):
800 def banner(self):
801 banner = self.banner1
801 banner = self.banner1
802 if self.profile and self.profile != 'default':
802 if self.profile and self.profile != 'default':
803 banner += '\nIPython profile: %s\n' % self.profile
803 banner += '\nIPython profile: %s\n' % self.profile
804 if self.banner2:
804 if self.banner2:
805 banner += '\n' + self.banner2
805 banner += '\n' + self.banner2
806 return banner
806 return banner
807
807
808 def show_banner(self, banner=None):
808 def show_banner(self, banner=None):
809 if banner is None:
809 if banner is None:
810 banner = self.banner
810 banner = self.banner
811 self.write(banner)
811 self.write(banner)
812
812
813 #-------------------------------------------------------------------------
813 #-------------------------------------------------------------------------
814 # Things related to hooks
814 # Things related to hooks
815 #-------------------------------------------------------------------------
815 #-------------------------------------------------------------------------
816
816
817 def init_hooks(self):
817 def init_hooks(self):
818 # hooks holds pointers used for user-side customizations
818 # hooks holds pointers used for user-side customizations
819 self.hooks = Struct()
819 self.hooks = Struct()
820
820
821 self.strdispatchers = {}
821 self.strdispatchers = {}
822
822
823 # Set all default hooks, defined in the IPython.hooks module.
823 # Set all default hooks, defined in the IPython.hooks module.
824 hooks = IPython.core.hooks
824 hooks = IPython.core.hooks
825 for hook_name in hooks.__all__:
825 for hook_name in hooks.__all__:
826 # default hooks have priority 100, i.e. low; user hooks should have
826 # default hooks have priority 100, i.e. low; user hooks should have
827 # 0-100 priority
827 # 0-100 priority
828 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
828 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
829
829
830 if self.display_page:
830 if self.display_page:
831 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
831 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
832
832
833 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
833 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
834 _warn_deprecated=True):
834 _warn_deprecated=True):
835 """set_hook(name,hook) -> sets an internal IPython hook.
835 """set_hook(name,hook) -> sets an internal IPython hook.
836
836
837 IPython exposes some of its internal API as user-modifiable hooks. By
837 IPython exposes some of its internal API as user-modifiable hooks. By
838 adding your function to one of these hooks, you can modify IPython's
838 adding your function to one of these hooks, you can modify IPython's
839 behavior to call at runtime your own routines."""
839 behavior to call at runtime your own routines."""
840
840
841 # At some point in the future, this should validate the hook before it
841 # At some point in the future, this should validate the hook before it
842 # accepts it. Probably at least check that the hook takes the number
842 # accepts it. Probably at least check that the hook takes the number
843 # of args it's supposed to.
843 # of args it's supposed to.
844
844
845 f = types.MethodType(hook,self)
845 f = types.MethodType(hook,self)
846
846
847 # check if the hook is for strdispatcher first
847 # check if the hook is for strdispatcher first
848 if str_key is not None:
848 if str_key is not None:
849 sdp = self.strdispatchers.get(name, StrDispatch())
849 sdp = self.strdispatchers.get(name, StrDispatch())
850 sdp.add_s(str_key, f, priority )
850 sdp.add_s(str_key, f, priority )
851 self.strdispatchers[name] = sdp
851 self.strdispatchers[name] = sdp
852 return
852 return
853 if re_key is not None:
853 if re_key is not None:
854 sdp = self.strdispatchers.get(name, StrDispatch())
854 sdp = self.strdispatchers.get(name, StrDispatch())
855 sdp.add_re(re.compile(re_key), f, priority )
855 sdp.add_re(re.compile(re_key), f, priority )
856 self.strdispatchers[name] = sdp
856 self.strdispatchers[name] = sdp
857 return
857 return
858
858
859 dp = getattr(self.hooks, name, None)
859 dp = getattr(self.hooks, name, None)
860 if name not in IPython.core.hooks.__all__:
860 if name not in IPython.core.hooks.__all__:
861 print("Warning! Hook '%s' is not one of %s" % \
861 print("Warning! Hook '%s' is not one of %s" % \
862 (name, IPython.core.hooks.__all__ ))
862 (name, IPython.core.hooks.__all__ ))
863
863
864 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
864 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
865 alternative = IPython.core.hooks.deprecated[name]
865 alternative = IPython.core.hooks.deprecated[name]
866 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative))
866 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative))
867
867
868 if not dp:
868 if not dp:
869 dp = IPython.core.hooks.CommandChainDispatcher()
869 dp = IPython.core.hooks.CommandChainDispatcher()
870
870
871 try:
871 try:
872 dp.add(f,priority)
872 dp.add(f,priority)
873 except AttributeError:
873 except AttributeError:
874 # it was not commandchain, plain old func - replace
874 # it was not commandchain, plain old func - replace
875 dp = f
875 dp = f
876
876
877 setattr(self.hooks,name, dp)
877 setattr(self.hooks,name, dp)
878
878
879 #-------------------------------------------------------------------------
879 #-------------------------------------------------------------------------
880 # Things related to events
880 # Things related to events
881 #-------------------------------------------------------------------------
881 #-------------------------------------------------------------------------
882
882
883 def init_events(self):
883 def init_events(self):
884 self.events = EventManager(self, available_events)
884 self.events = EventManager(self, available_events)
885
885
886 self.events.register("pre_execute", self._clear_warning_registry)
886 self.events.register("pre_execute", self._clear_warning_registry)
887
887
888 def register_post_execute(self, func):
888 def register_post_execute(self, func):
889 """DEPRECATED: Use ip.events.register('post_run_cell', func)
889 """DEPRECATED: Use ip.events.register('post_run_cell', func)
890
890
891 Register a function for calling after code execution.
891 Register a function for calling after code execution.
892 """
892 """
893 warn("ip.register_post_execute is deprecated, use "
893 warn("ip.register_post_execute is deprecated, use "
894 "ip.events.register('post_run_cell', func) instead.")
894 "ip.events.register('post_run_cell', func) instead.")
895 self.events.register('post_run_cell', func)
895 self.events.register('post_run_cell', func)
896
896
897 def _clear_warning_registry(self):
897 def _clear_warning_registry(self):
898 # clear the warning registry, so that different code blocks with
898 # clear the warning registry, so that different code blocks with
899 # overlapping line number ranges don't cause spurious suppression of
899 # overlapping line number ranges don't cause spurious suppression of
900 # warnings (see gh-6611 for details)
900 # warnings (see gh-6611 for details)
901 if "__warningregistry__" in self.user_global_ns:
901 if "__warningregistry__" in self.user_global_ns:
902 del self.user_global_ns["__warningregistry__"]
902 del self.user_global_ns["__warningregistry__"]
903
903
904 #-------------------------------------------------------------------------
904 #-------------------------------------------------------------------------
905 # Things related to the "main" module
905 # Things related to the "main" module
906 #-------------------------------------------------------------------------
906 #-------------------------------------------------------------------------
907
907
908 def new_main_mod(self, filename, modname):
908 def new_main_mod(self, filename, modname):
909 """Return a new 'main' module object for user code execution.
909 """Return a new 'main' module object for user code execution.
910
910
911 ``filename`` should be the path of the script which will be run in the
911 ``filename`` should be the path of the script which will be run in the
912 module. Requests with the same filename will get the same module, with
912 module. Requests with the same filename will get the same module, with
913 its namespace cleared.
913 its namespace cleared.
914
914
915 ``modname`` should be the module name - normally either '__main__' or
915 ``modname`` should be the module name - normally either '__main__' or
916 the basename of the file without the extension.
916 the basename of the file without the extension.
917
917
918 When scripts are executed via %run, we must keep a reference to their
918 When scripts are executed via %run, we must keep a reference to their
919 __main__ module around so that Python doesn't
919 __main__ module around so that Python doesn't
920 clear it, rendering references to module globals useless.
920 clear it, rendering references to module globals useless.
921
921
922 This method keeps said reference in a private dict, keyed by the
922 This method keeps said reference in a private dict, keyed by the
923 absolute path of the script. This way, for multiple executions of the
923 absolute path of the script. This way, for multiple executions of the
924 same script we only keep one copy of the namespace (the last one),
924 same script we only keep one copy of the namespace (the last one),
925 thus preventing memory leaks from old references while allowing the
925 thus preventing memory leaks from old references while allowing the
926 objects from the last execution to be accessible.
926 objects from the last execution to be accessible.
927 """
927 """
928 filename = os.path.abspath(filename)
928 filename = os.path.abspath(filename)
929 try:
929 try:
930 main_mod = self._main_mod_cache[filename]
930 main_mod = self._main_mod_cache[filename]
931 except KeyError:
931 except KeyError:
932 main_mod = self._main_mod_cache[filename] = types.ModuleType(
932 main_mod = self._main_mod_cache[filename] = types.ModuleType(
933 py3compat.cast_bytes_py2(modname),
933 py3compat.cast_bytes_py2(modname),
934 doc="Module created for script run in IPython")
934 doc="Module created for script run in IPython")
935 else:
935 else:
936 main_mod.__dict__.clear()
936 main_mod.__dict__.clear()
937 main_mod.__name__ = modname
937 main_mod.__name__ = modname
938
938
939 main_mod.__file__ = filename
939 main_mod.__file__ = filename
940 # It seems pydoc (and perhaps others) needs any module instance to
940 # It seems pydoc (and perhaps others) needs any module instance to
941 # implement a __nonzero__ method
941 # implement a __nonzero__ method
942 main_mod.__nonzero__ = lambda : True
942 main_mod.__nonzero__ = lambda : True
943
943
944 return main_mod
944 return main_mod
945
945
946 def clear_main_mod_cache(self):
946 def clear_main_mod_cache(self):
947 """Clear the cache of main modules.
947 """Clear the cache of main modules.
948
948
949 Mainly for use by utilities like %reset.
949 Mainly for use by utilities like %reset.
950
950
951 Examples
951 Examples
952 --------
952 --------
953
953
954 In [15]: import IPython
954 In [15]: import IPython
955
955
956 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
956 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
957
957
958 In [17]: len(_ip._main_mod_cache) > 0
958 In [17]: len(_ip._main_mod_cache) > 0
959 Out[17]: True
959 Out[17]: True
960
960
961 In [18]: _ip.clear_main_mod_cache()
961 In [18]: _ip.clear_main_mod_cache()
962
962
963 In [19]: len(_ip._main_mod_cache) == 0
963 In [19]: len(_ip._main_mod_cache) == 0
964 Out[19]: True
964 Out[19]: True
965 """
965 """
966 self._main_mod_cache.clear()
966 self._main_mod_cache.clear()
967
967
968 #-------------------------------------------------------------------------
968 #-------------------------------------------------------------------------
969 # Things related to debugging
969 # Things related to debugging
970 #-------------------------------------------------------------------------
970 #-------------------------------------------------------------------------
971
971
972 def init_pdb(self):
972 def init_pdb(self):
973 # Set calling of pdb on exceptions
973 # Set calling of pdb on exceptions
974 # self.call_pdb is a property
974 # self.call_pdb is a property
975 self.call_pdb = self.pdb
975 self.call_pdb = self.pdb
976
976
977 def _get_call_pdb(self):
977 def _get_call_pdb(self):
978 return self._call_pdb
978 return self._call_pdb
979
979
980 def _set_call_pdb(self,val):
980 def _set_call_pdb(self,val):
981
981
982 if val not in (0,1,False,True):
982 if val not in (0,1,False,True):
983 raise ValueError('new call_pdb value must be boolean')
983 raise ValueError('new call_pdb value must be boolean')
984
984
985 # store value in instance
985 # store value in instance
986 self._call_pdb = val
986 self._call_pdb = val
987
987
988 # notify the actual exception handlers
988 # notify the actual exception handlers
989 self.InteractiveTB.call_pdb = val
989 self.InteractiveTB.call_pdb = val
990
990
991 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
991 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
992 'Control auto-activation of pdb at exceptions')
992 'Control auto-activation of pdb at exceptions')
993
993
994 def debugger(self,force=False):
994 def debugger(self,force=False):
995 """Call the pydb/pdb debugger.
995 """Call the pydb/pdb debugger.
996
996
997 Keywords:
997 Keywords:
998
998
999 - force(False): by default, this routine checks the instance call_pdb
999 - force(False): by default, this routine checks the instance call_pdb
1000 flag and does not actually invoke the debugger if the flag is false.
1000 flag and does not actually invoke the debugger if the flag is false.
1001 The 'force' option forces the debugger to activate even if the flag
1001 The 'force' option forces the debugger to activate even if the flag
1002 is false.
1002 is false.
1003 """
1003 """
1004
1004
1005 if not (force or self.call_pdb):
1005 if not (force or self.call_pdb):
1006 return
1006 return
1007
1007
1008 if not hasattr(sys,'last_traceback'):
1008 if not hasattr(sys,'last_traceback'):
1009 error('No traceback has been produced, nothing to debug.')
1009 error('No traceback has been produced, nothing to debug.')
1010 return
1010 return
1011
1011
1012 # use pydb if available
1012 # use pydb if available
1013 if debugger.has_pydb:
1013 if debugger.has_pydb:
1014 from pydb import pm
1014 from pydb import pm
1015 else:
1015 else:
1016 # fallback to our internal debugger
1016 # fallback to our internal debugger
1017 pm = lambda : self.InteractiveTB.debugger(force=True)
1017 pm = lambda : self.InteractiveTB.debugger(force=True)
1018
1018
1019 with self.readline_no_record:
1019 with self.readline_no_record:
1020 pm()
1020 pm()
1021
1021
1022 #-------------------------------------------------------------------------
1022 #-------------------------------------------------------------------------
1023 # Things related to IPython's various namespaces
1023 # Things related to IPython's various namespaces
1024 #-------------------------------------------------------------------------
1024 #-------------------------------------------------------------------------
1025 default_user_namespaces = True
1025 default_user_namespaces = True
1026
1026
1027 def init_create_namespaces(self, user_module=None, user_ns=None):
1027 def init_create_namespaces(self, user_module=None, user_ns=None):
1028 # Create the namespace where the user will operate. user_ns is
1028 # Create the namespace where the user will operate. user_ns is
1029 # normally the only one used, and it is passed to the exec calls as
1029 # normally the only one used, and it is passed to the exec calls as
1030 # the locals argument. But we do carry a user_global_ns namespace
1030 # the locals argument. But we do carry a user_global_ns namespace
1031 # given as the exec 'globals' argument, This is useful in embedding
1031 # given as the exec 'globals' argument, This is useful in embedding
1032 # situations where the ipython shell opens in a context where the
1032 # situations where the ipython shell opens in a context where the
1033 # distinction between locals and globals is meaningful. For
1033 # distinction between locals and globals is meaningful. For
1034 # non-embedded contexts, it is just the same object as the user_ns dict.
1034 # non-embedded contexts, it is just the same object as the user_ns dict.
1035
1035
1036 # FIXME. For some strange reason, __builtins__ is showing up at user
1036 # FIXME. For some strange reason, __builtins__ is showing up at user
1037 # level as a dict instead of a module. This is a manual fix, but I
1037 # level as a dict instead of a module. This is a manual fix, but I
1038 # should really track down where the problem is coming from. Alex
1038 # should really track down where the problem is coming from. Alex
1039 # Schmolck reported this problem first.
1039 # Schmolck reported this problem first.
1040
1040
1041 # A useful post by Alex Martelli on this topic:
1041 # A useful post by Alex Martelli on this topic:
1042 # Re: inconsistent value from __builtins__
1042 # Re: inconsistent value from __builtins__
1043 # Von: Alex Martelli <aleaxit@yahoo.com>
1043 # Von: Alex Martelli <aleaxit@yahoo.com>
1044 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1044 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1045 # Gruppen: comp.lang.python
1045 # Gruppen: comp.lang.python
1046
1046
1047 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1047 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1048 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1048 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1049 # > <type 'dict'>
1049 # > <type 'dict'>
1050 # > >>> print type(__builtins__)
1050 # > >>> print type(__builtins__)
1051 # > <type 'module'>
1051 # > <type 'module'>
1052 # > Is this difference in return value intentional?
1052 # > Is this difference in return value intentional?
1053
1053
1054 # Well, it's documented that '__builtins__' can be either a dictionary
1054 # Well, it's documented that '__builtins__' can be either a dictionary
1055 # or a module, and it's been that way for a long time. Whether it's
1055 # or a module, and it's been that way for a long time. Whether it's
1056 # intentional (or sensible), I don't know. In any case, the idea is
1056 # intentional (or sensible), I don't know. In any case, the idea is
1057 # that if you need to access the built-in namespace directly, you
1057 # that if you need to access the built-in namespace directly, you
1058 # should start with "import __builtin__" (note, no 's') which will
1058 # should start with "import __builtin__" (note, no 's') which will
1059 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1059 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1060
1060
1061 # These routines return a properly built module and dict as needed by
1061 # These routines return a properly built module and dict as needed by
1062 # the rest of the code, and can also be used by extension writers to
1062 # the rest of the code, and can also be used by extension writers to
1063 # generate properly initialized namespaces.
1063 # generate properly initialized namespaces.
1064 if (user_ns is not None) or (user_module is not None):
1064 if (user_ns is not None) or (user_module is not None):
1065 self.default_user_namespaces = False
1065 self.default_user_namespaces = False
1066 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1066 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1067
1067
1068 # A record of hidden variables we have added to the user namespace, so
1068 # A record of hidden variables we have added to the user namespace, so
1069 # we can list later only variables defined in actual interactive use.
1069 # we can list later only variables defined in actual interactive use.
1070 self.user_ns_hidden = {}
1070 self.user_ns_hidden = {}
1071
1071
1072 # Now that FakeModule produces a real module, we've run into a nasty
1072 # Now that FakeModule produces a real module, we've run into a nasty
1073 # problem: after script execution (via %run), the module where the user
1073 # problem: after script execution (via %run), the module where the user
1074 # code ran is deleted. Now that this object is a true module (needed
1074 # code ran is deleted. Now that this object is a true module (needed
1075 # so docetst and other tools work correctly), the Python module
1075 # so docetst and other tools work correctly), the Python module
1076 # teardown mechanism runs over it, and sets to None every variable
1076 # teardown mechanism runs over it, and sets to None every variable
1077 # present in that module. Top-level references to objects from the
1077 # present in that module. Top-level references to objects from the
1078 # script survive, because the user_ns is updated with them. However,
1078 # script survive, because the user_ns is updated with them. However,
1079 # calling functions defined in the script that use other things from
1079 # calling functions defined in the script that use other things from
1080 # the script will fail, because the function's closure had references
1080 # the script will fail, because the function's closure had references
1081 # to the original objects, which are now all None. So we must protect
1081 # to the original objects, which are now all None. So we must protect
1082 # these modules from deletion by keeping a cache.
1082 # these modules from deletion by keeping a cache.
1083 #
1083 #
1084 # To avoid keeping stale modules around (we only need the one from the
1084 # To avoid keeping stale modules around (we only need the one from the
1085 # last run), we use a dict keyed with the full path to the script, so
1085 # last run), we use a dict keyed with the full path to the script, so
1086 # only the last version of the module is held in the cache. Note,
1086 # only the last version of the module is held in the cache. Note,
1087 # however, that we must cache the module *namespace contents* (their
1087 # however, that we must cache the module *namespace contents* (their
1088 # __dict__). Because if we try to cache the actual modules, old ones
1088 # __dict__). Because if we try to cache the actual modules, old ones
1089 # (uncached) could be destroyed while still holding references (such as
1089 # (uncached) could be destroyed while still holding references (such as
1090 # those held by GUI objects that tend to be long-lived)>
1090 # those held by GUI objects that tend to be long-lived)>
1091 #
1091 #
1092 # The %reset command will flush this cache. See the cache_main_mod()
1092 # The %reset command will flush this cache. See the cache_main_mod()
1093 # and clear_main_mod_cache() methods for details on use.
1093 # and clear_main_mod_cache() methods for details on use.
1094
1094
1095 # This is the cache used for 'main' namespaces
1095 # This is the cache used for 'main' namespaces
1096 self._main_mod_cache = {}
1096 self._main_mod_cache = {}
1097
1097
1098 # A table holding all the namespaces IPython deals with, so that
1098 # A table holding all the namespaces IPython deals with, so that
1099 # introspection facilities can search easily.
1099 # introspection facilities can search easily.
1100 self.ns_table = {'user_global':self.user_module.__dict__,
1100 self.ns_table = {'user_global':self.user_module.__dict__,
1101 'user_local':self.user_ns,
1101 'user_local':self.user_ns,
1102 'builtin':builtin_mod.__dict__
1102 'builtin':builtin_mod.__dict__
1103 }
1103 }
1104
1104
1105 @property
1105 @property
1106 def user_global_ns(self):
1106 def user_global_ns(self):
1107 return self.user_module.__dict__
1107 return self.user_module.__dict__
1108
1108
1109 def prepare_user_module(self, user_module=None, user_ns=None):
1109 def prepare_user_module(self, user_module=None, user_ns=None):
1110 """Prepare the module and namespace in which user code will be run.
1110 """Prepare the module and namespace in which user code will be run.
1111
1111
1112 When IPython is started normally, both parameters are None: a new module
1112 When IPython is started normally, both parameters are None: a new module
1113 is created automatically, and its __dict__ used as the namespace.
1113 is created automatically, and its __dict__ used as the namespace.
1114
1114
1115 If only user_module is provided, its __dict__ is used as the namespace.
1115 If only user_module is provided, its __dict__ is used as the namespace.
1116 If only user_ns is provided, a dummy module is created, and user_ns
1116 If only user_ns is provided, a dummy module is created, and user_ns
1117 becomes the global namespace. If both are provided (as they may be
1117 becomes the global namespace. If both are provided (as they may be
1118 when embedding), user_ns is the local namespace, and user_module
1118 when embedding), user_ns is the local namespace, and user_module
1119 provides the global namespace.
1119 provides the global namespace.
1120
1120
1121 Parameters
1121 Parameters
1122 ----------
1122 ----------
1123 user_module : module, optional
1123 user_module : module, optional
1124 The current user module in which IPython is being run. If None,
1124 The current user module in which IPython is being run. If None,
1125 a clean module will be created.
1125 a clean module will be created.
1126 user_ns : dict, optional
1126 user_ns : dict, optional
1127 A namespace in which to run interactive commands.
1127 A namespace in which to run interactive commands.
1128
1128
1129 Returns
1129 Returns
1130 -------
1130 -------
1131 A tuple of user_module and user_ns, each properly initialised.
1131 A tuple of user_module and user_ns, each properly initialised.
1132 """
1132 """
1133 if user_module is None and user_ns is not None:
1133 if user_module is None and user_ns is not None:
1134 user_ns.setdefault("__name__", "__main__")
1134 user_ns.setdefault("__name__", "__main__")
1135 user_module = DummyMod()
1135 user_module = DummyMod()
1136 user_module.__dict__ = user_ns
1136 user_module.__dict__ = user_ns
1137
1137
1138 if user_module is None:
1138 if user_module is None:
1139 user_module = types.ModuleType("__main__",
1139 user_module = types.ModuleType("__main__",
1140 doc="Automatically created module for IPython interactive environment")
1140 doc="Automatically created module for IPython interactive environment")
1141
1141
1142 # We must ensure that __builtin__ (without the final 's') is always
1142 # We must ensure that __builtin__ (without the final 's') is always
1143 # available and pointing to the __builtin__ *module*. For more details:
1143 # available and pointing to the __builtin__ *module*. For more details:
1144 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1144 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1145 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1145 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1146 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1146 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1147
1147
1148 if user_ns is None:
1148 if user_ns is None:
1149 user_ns = user_module.__dict__
1149 user_ns = user_module.__dict__
1150
1150
1151 return user_module, user_ns
1151 return user_module, user_ns
1152
1152
1153 def init_sys_modules(self):
1153 def init_sys_modules(self):
1154 # We need to insert into sys.modules something that looks like a
1154 # We need to insert into sys.modules something that looks like a
1155 # module but which accesses the IPython namespace, for shelve and
1155 # module but which accesses the IPython namespace, for shelve and
1156 # pickle to work interactively. Normally they rely on getting
1156 # pickle to work interactively. Normally they rely on getting
1157 # everything out of __main__, but for embedding purposes each IPython
1157 # everything out of __main__, but for embedding purposes each IPython
1158 # instance has its own private namespace, so we can't go shoving
1158 # instance has its own private namespace, so we can't go shoving
1159 # everything into __main__.
1159 # everything into __main__.
1160
1160
1161 # note, however, that we should only do this for non-embedded
1161 # note, however, that we should only do this for non-embedded
1162 # ipythons, which really mimic the __main__.__dict__ with their own
1162 # ipythons, which really mimic the __main__.__dict__ with their own
1163 # namespace. Embedded instances, on the other hand, should not do
1163 # namespace. Embedded instances, on the other hand, should not do
1164 # this because they need to manage the user local/global namespaces
1164 # this because they need to manage the user local/global namespaces
1165 # only, but they live within a 'normal' __main__ (meaning, they
1165 # only, but they live within a 'normal' __main__ (meaning, they
1166 # shouldn't overtake the execution environment of the script they're
1166 # shouldn't overtake the execution environment of the script they're
1167 # embedded in).
1167 # embedded in).
1168
1168
1169 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1169 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1170 main_name = self.user_module.__name__
1170 main_name = self.user_module.__name__
1171 sys.modules[main_name] = self.user_module
1171 sys.modules[main_name] = self.user_module
1172
1172
1173 def init_user_ns(self):
1173 def init_user_ns(self):
1174 """Initialize all user-visible namespaces to their minimum defaults.
1174 """Initialize all user-visible namespaces to their minimum defaults.
1175
1175
1176 Certain history lists are also initialized here, as they effectively
1176 Certain history lists are also initialized here, as they effectively
1177 act as user namespaces.
1177 act as user namespaces.
1178
1178
1179 Notes
1179 Notes
1180 -----
1180 -----
1181 All data structures here are only filled in, they are NOT reset by this
1181 All data structures here are only filled in, they are NOT reset by this
1182 method. If they were not empty before, data will simply be added to
1182 method. If they were not empty before, data will simply be added to
1183 therm.
1183 therm.
1184 """
1184 """
1185 # This function works in two parts: first we put a few things in
1185 # This function works in two parts: first we put a few things in
1186 # user_ns, and we sync that contents into user_ns_hidden so that these
1186 # user_ns, and we sync that contents into user_ns_hidden so that these
1187 # initial variables aren't shown by %who. After the sync, we add the
1187 # initial variables aren't shown by %who. After the sync, we add the
1188 # rest of what we *do* want the user to see with %who even on a new
1188 # rest of what we *do* want the user to see with %who even on a new
1189 # session (probably nothing, so theye really only see their own stuff)
1189 # session (probably nothing, so theye really only see their own stuff)
1190
1190
1191 # The user dict must *always* have a __builtin__ reference to the
1191 # The user dict must *always* have a __builtin__ reference to the
1192 # Python standard __builtin__ namespace, which must be imported.
1192 # Python standard __builtin__ namespace, which must be imported.
1193 # This is so that certain operations in prompt evaluation can be
1193 # This is so that certain operations in prompt evaluation can be
1194 # reliably executed with builtins. Note that we can NOT use
1194 # reliably executed with builtins. Note that we can NOT use
1195 # __builtins__ (note the 's'), because that can either be a dict or a
1195 # __builtins__ (note the 's'), because that can either be a dict or a
1196 # module, and can even mutate at runtime, depending on the context
1196 # module, and can even mutate at runtime, depending on the context
1197 # (Python makes no guarantees on it). In contrast, __builtin__ is
1197 # (Python makes no guarantees on it). In contrast, __builtin__ is
1198 # always a module object, though it must be explicitly imported.
1198 # always a module object, though it must be explicitly imported.
1199
1199
1200 # For more details:
1200 # For more details:
1201 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1201 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1202 ns = dict()
1202 ns = dict()
1203
1203
1204 # make global variables for user access to the histories
1204 # make global variables for user access to the histories
1205 ns['_ih'] = self.history_manager.input_hist_parsed
1205 ns['_ih'] = self.history_manager.input_hist_parsed
1206 ns['_oh'] = self.history_manager.output_hist
1206 ns['_oh'] = self.history_manager.output_hist
1207 ns['_dh'] = self.history_manager.dir_hist
1207 ns['_dh'] = self.history_manager.dir_hist
1208
1208
1209 ns['_sh'] = shadowns
1209 ns['_sh'] = shadowns
1210
1210
1211 # user aliases to input and output histories. These shouldn't show up
1211 # user aliases to input and output histories. These shouldn't show up
1212 # in %who, as they can have very large reprs.
1212 # in %who, as they can have very large reprs.
1213 ns['In'] = self.history_manager.input_hist_parsed
1213 ns['In'] = self.history_manager.input_hist_parsed
1214 ns['Out'] = self.history_manager.output_hist
1214 ns['Out'] = self.history_manager.output_hist
1215
1215
1216 # Store myself as the public api!!!
1216 # Store myself as the public api!!!
1217 ns['get_ipython'] = self.get_ipython
1217 ns['get_ipython'] = self.get_ipython
1218
1218
1219 ns['exit'] = self.exiter
1219 ns['exit'] = self.exiter
1220 ns['quit'] = self.exiter
1220 ns['quit'] = self.exiter
1221
1221
1222 # Sync what we've added so far to user_ns_hidden so these aren't seen
1222 # Sync what we've added so far to user_ns_hidden so these aren't seen
1223 # by %who
1223 # by %who
1224 self.user_ns_hidden.update(ns)
1224 self.user_ns_hidden.update(ns)
1225
1225
1226 # Anything put into ns now would show up in %who. Think twice before
1226 # Anything put into ns now would show up in %who. Think twice before
1227 # putting anything here, as we really want %who to show the user their
1227 # putting anything here, as we really want %who to show the user their
1228 # stuff, not our variables.
1228 # stuff, not our variables.
1229
1229
1230 # Finally, update the real user's namespace
1230 # Finally, update the real user's namespace
1231 self.user_ns.update(ns)
1231 self.user_ns.update(ns)
1232
1232
1233 @property
1233 @property
1234 def all_ns_refs(self):
1234 def all_ns_refs(self):
1235 """Get a list of references to all the namespace dictionaries in which
1235 """Get a list of references to all the namespace dictionaries in which
1236 IPython might store a user-created object.
1236 IPython might store a user-created object.
1237
1237
1238 Note that this does not include the displayhook, which also caches
1238 Note that this does not include the displayhook, which also caches
1239 objects from the output."""
1239 objects from the output."""
1240 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1240 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1241 [m.__dict__ for m in self._main_mod_cache.values()]
1241 [m.__dict__ for m in self._main_mod_cache.values()]
1242
1242
1243 def reset(self, new_session=True):
1243 def reset(self, new_session=True):
1244 """Clear all internal namespaces, and attempt to release references to
1244 """Clear all internal namespaces, and attempt to release references to
1245 user objects.
1245 user objects.
1246
1246
1247 If new_session is True, a new history session will be opened.
1247 If new_session is True, a new history session will be opened.
1248 """
1248 """
1249 # Clear histories
1249 # Clear histories
1250 self.history_manager.reset(new_session)
1250 self.history_manager.reset(new_session)
1251 # Reset counter used to index all histories
1251 # Reset counter used to index all histories
1252 if new_session:
1252 if new_session:
1253 self.execution_count = 1
1253 self.execution_count = 1
1254
1254
1255 # Flush cached output items
1255 # Flush cached output items
1256 if self.displayhook.do_full_cache:
1256 if self.displayhook.do_full_cache:
1257 self.displayhook.flush()
1257 self.displayhook.flush()
1258
1258
1259 # The main execution namespaces must be cleared very carefully,
1259 # The main execution namespaces must be cleared very carefully,
1260 # skipping the deletion of the builtin-related keys, because doing so
1260 # skipping the deletion of the builtin-related keys, because doing so
1261 # would cause errors in many object's __del__ methods.
1261 # would cause errors in many object's __del__ methods.
1262 if self.user_ns is not self.user_global_ns:
1262 if self.user_ns is not self.user_global_ns:
1263 self.user_ns.clear()
1263 self.user_ns.clear()
1264 ns = self.user_global_ns
1264 ns = self.user_global_ns
1265 drop_keys = set(ns.keys())
1265 drop_keys = set(ns.keys())
1266 drop_keys.discard('__builtin__')
1266 drop_keys.discard('__builtin__')
1267 drop_keys.discard('__builtins__')
1267 drop_keys.discard('__builtins__')
1268 drop_keys.discard('__name__')
1268 drop_keys.discard('__name__')
1269 for k in drop_keys:
1269 for k in drop_keys:
1270 del ns[k]
1270 del ns[k]
1271
1271
1272 self.user_ns_hidden.clear()
1272 self.user_ns_hidden.clear()
1273
1273
1274 # Restore the user namespaces to minimal usability
1274 # Restore the user namespaces to minimal usability
1275 self.init_user_ns()
1275 self.init_user_ns()
1276
1276
1277 # Restore the default and user aliases
1277 # Restore the default and user aliases
1278 self.alias_manager.clear_aliases()
1278 self.alias_manager.clear_aliases()
1279 self.alias_manager.init_aliases()
1279 self.alias_manager.init_aliases()
1280
1280
1281 # Flush the private list of module references kept for script
1281 # Flush the private list of module references kept for script
1282 # execution protection
1282 # execution protection
1283 self.clear_main_mod_cache()
1283 self.clear_main_mod_cache()
1284
1284
1285 def del_var(self, varname, by_name=False):
1285 def del_var(self, varname, by_name=False):
1286 """Delete a variable from the various namespaces, so that, as
1286 """Delete a variable from the various namespaces, so that, as
1287 far as possible, we're not keeping any hidden references to it.
1287 far as possible, we're not keeping any hidden references to it.
1288
1288
1289 Parameters
1289 Parameters
1290 ----------
1290 ----------
1291 varname : str
1291 varname : str
1292 The name of the variable to delete.
1292 The name of the variable to delete.
1293 by_name : bool
1293 by_name : bool
1294 If True, delete variables with the given name in each
1294 If True, delete variables with the given name in each
1295 namespace. If False (default), find the variable in the user
1295 namespace. If False (default), find the variable in the user
1296 namespace, and delete references to it.
1296 namespace, and delete references to it.
1297 """
1297 """
1298 if varname in ('__builtin__', '__builtins__'):
1298 if varname in ('__builtin__', '__builtins__'):
1299 raise ValueError("Refusing to delete %s" % varname)
1299 raise ValueError("Refusing to delete %s" % varname)
1300
1300
1301 ns_refs = self.all_ns_refs
1301 ns_refs = self.all_ns_refs
1302
1302
1303 if by_name: # Delete by name
1303 if by_name: # Delete by name
1304 for ns in ns_refs:
1304 for ns in ns_refs:
1305 try:
1305 try:
1306 del ns[varname]
1306 del ns[varname]
1307 except KeyError:
1307 except KeyError:
1308 pass
1308 pass
1309 else: # Delete by object
1309 else: # Delete by object
1310 try:
1310 try:
1311 obj = self.user_ns[varname]
1311 obj = self.user_ns[varname]
1312 except KeyError:
1312 except KeyError:
1313 raise NameError("name '%s' is not defined" % varname)
1313 raise NameError("name '%s' is not defined" % varname)
1314 # Also check in output history
1314 # Also check in output history
1315 ns_refs.append(self.history_manager.output_hist)
1315 ns_refs.append(self.history_manager.output_hist)
1316 for ns in ns_refs:
1316 for ns in ns_refs:
1317 to_delete = [n for n, o in iteritems(ns) if o is obj]
1317 to_delete = [n for n, o in iteritems(ns) if o is obj]
1318 for name in to_delete:
1318 for name in to_delete:
1319 del ns[name]
1319 del ns[name]
1320
1320
1321 # displayhook keeps extra references, but not in a dictionary
1321 # displayhook keeps extra references, but not in a dictionary
1322 for name in ('_', '__', '___'):
1322 for name in ('_', '__', '___'):
1323 if getattr(self.displayhook, name) is obj:
1323 if getattr(self.displayhook, name) is obj:
1324 setattr(self.displayhook, name, None)
1324 setattr(self.displayhook, name, None)
1325
1325
1326 def reset_selective(self, regex=None):
1326 def reset_selective(self, regex=None):
1327 """Clear selective variables from internal namespaces based on a
1327 """Clear selective variables from internal namespaces based on a
1328 specified regular expression.
1328 specified regular expression.
1329
1329
1330 Parameters
1330 Parameters
1331 ----------
1331 ----------
1332 regex : string or compiled pattern, optional
1332 regex : string or compiled pattern, optional
1333 A regular expression pattern that will be used in searching
1333 A regular expression pattern that will be used in searching
1334 variable names in the users namespaces.
1334 variable names in the users namespaces.
1335 """
1335 """
1336 if regex is not None:
1336 if regex is not None:
1337 try:
1337 try:
1338 m = re.compile(regex)
1338 m = re.compile(regex)
1339 except TypeError:
1339 except TypeError:
1340 raise TypeError('regex must be a string or compiled pattern')
1340 raise TypeError('regex must be a string or compiled pattern')
1341 # Search for keys in each namespace that match the given regex
1341 # Search for keys in each namespace that match the given regex
1342 # If a match is found, delete the key/value pair.
1342 # If a match is found, delete the key/value pair.
1343 for ns in self.all_ns_refs:
1343 for ns in self.all_ns_refs:
1344 for var in ns:
1344 for var in ns:
1345 if m.search(var):
1345 if m.search(var):
1346 del ns[var]
1346 del ns[var]
1347
1347
1348 def push(self, variables, interactive=True):
1348 def push(self, variables, interactive=True):
1349 """Inject a group of variables into the IPython user namespace.
1349 """Inject a group of variables into the IPython user namespace.
1350
1350
1351 Parameters
1351 Parameters
1352 ----------
1352 ----------
1353 variables : dict, str or list/tuple of str
1353 variables : dict, str or list/tuple of str
1354 The variables to inject into the user's namespace. If a dict, a
1354 The variables to inject into the user's namespace. If a dict, a
1355 simple update is done. If a str, the string is assumed to have
1355 simple update is done. If a str, the string is assumed to have
1356 variable names separated by spaces. A list/tuple of str can also
1356 variable names separated by spaces. A list/tuple of str can also
1357 be used to give the variable names. If just the variable names are
1357 be used to give the variable names. If just the variable names are
1358 give (list/tuple/str) then the variable values looked up in the
1358 give (list/tuple/str) then the variable values looked up in the
1359 callers frame.
1359 callers frame.
1360 interactive : bool
1360 interactive : bool
1361 If True (default), the variables will be listed with the ``who``
1361 If True (default), the variables will be listed with the ``who``
1362 magic.
1362 magic.
1363 """
1363 """
1364 vdict = None
1364 vdict = None
1365
1365
1366 # We need a dict of name/value pairs to do namespace updates.
1366 # We need a dict of name/value pairs to do namespace updates.
1367 if isinstance(variables, dict):
1367 if isinstance(variables, dict):
1368 vdict = variables
1368 vdict = variables
1369 elif isinstance(variables, string_types+(list, tuple)):
1369 elif isinstance(variables, string_types+(list, tuple)):
1370 if isinstance(variables, string_types):
1370 if isinstance(variables, string_types):
1371 vlist = variables.split()
1371 vlist = variables.split()
1372 else:
1372 else:
1373 vlist = variables
1373 vlist = variables
1374 vdict = {}
1374 vdict = {}
1375 cf = sys._getframe(1)
1375 cf = sys._getframe(1)
1376 for name in vlist:
1376 for name in vlist:
1377 try:
1377 try:
1378 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1378 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1379 except:
1379 except:
1380 print('Could not get variable %s from %s' %
1380 print('Could not get variable %s from %s' %
1381 (name,cf.f_code.co_name))
1381 (name,cf.f_code.co_name))
1382 else:
1382 else:
1383 raise ValueError('variables must be a dict/str/list/tuple')
1383 raise ValueError('variables must be a dict/str/list/tuple')
1384
1384
1385 # Propagate variables to user namespace
1385 # Propagate variables to user namespace
1386 self.user_ns.update(vdict)
1386 self.user_ns.update(vdict)
1387
1387
1388 # And configure interactive visibility
1388 # And configure interactive visibility
1389 user_ns_hidden = self.user_ns_hidden
1389 user_ns_hidden = self.user_ns_hidden
1390 if interactive:
1390 if interactive:
1391 for name in vdict:
1391 for name in vdict:
1392 user_ns_hidden.pop(name, None)
1392 user_ns_hidden.pop(name, None)
1393 else:
1393 else:
1394 user_ns_hidden.update(vdict)
1394 user_ns_hidden.update(vdict)
1395
1395
1396 def drop_by_id(self, variables):
1396 def drop_by_id(self, variables):
1397 """Remove a dict of variables from the user namespace, if they are the
1397 """Remove a dict of variables from the user namespace, if they are the
1398 same as the values in the dictionary.
1398 same as the values in the dictionary.
1399
1399
1400 This is intended for use by extensions: variables that they've added can
1400 This is intended for use by extensions: variables that they've added can
1401 be taken back out if they are unloaded, without removing any that the
1401 be taken back out if they are unloaded, without removing any that the
1402 user has overwritten.
1402 user has overwritten.
1403
1403
1404 Parameters
1404 Parameters
1405 ----------
1405 ----------
1406 variables : dict
1406 variables : dict
1407 A dictionary mapping object names (as strings) to the objects.
1407 A dictionary mapping object names (as strings) to the objects.
1408 """
1408 """
1409 for name, obj in iteritems(variables):
1409 for name, obj in iteritems(variables):
1410 if name in self.user_ns and self.user_ns[name] is obj:
1410 if name in self.user_ns and self.user_ns[name] is obj:
1411 del self.user_ns[name]
1411 del self.user_ns[name]
1412 self.user_ns_hidden.pop(name, None)
1412 self.user_ns_hidden.pop(name, None)
1413
1413
1414 #-------------------------------------------------------------------------
1414 #-------------------------------------------------------------------------
1415 # Things related to object introspection
1415 # Things related to object introspection
1416 #-------------------------------------------------------------------------
1416 #-------------------------------------------------------------------------
1417
1417
1418 def _ofind(self, oname, namespaces=None):
1418 def _ofind(self, oname, namespaces=None):
1419 """Find an object in the available namespaces.
1419 """Find an object in the available namespaces.
1420
1420
1421 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1421 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1422
1422
1423 Has special code to detect magic functions.
1423 Has special code to detect magic functions.
1424 """
1424 """
1425 oname = oname.strip()
1425 oname = oname.strip()
1426 #print '1- oname: <%r>' % oname # dbg
1426 #print '1- oname: <%r>' % oname # dbg
1427 if not oname.startswith(ESC_MAGIC) and \
1427 if not oname.startswith(ESC_MAGIC) and \
1428 not oname.startswith(ESC_MAGIC2) and \
1428 not oname.startswith(ESC_MAGIC2) and \
1429 not py3compat.isidentifier(oname, dotted=True):
1429 not py3compat.isidentifier(oname, dotted=True):
1430 return dict(found=False)
1430 return dict(found=False)
1431
1431
1432 alias_ns = None
1432 alias_ns = None
1433 if namespaces is None:
1433 if namespaces is None:
1434 # Namespaces to search in:
1434 # Namespaces to search in:
1435 # Put them in a list. The order is important so that we
1435 # Put them in a list. The order is important so that we
1436 # find things in the same order that Python finds them.
1436 # find things in the same order that Python finds them.
1437 namespaces = [ ('Interactive', self.user_ns),
1437 namespaces = [ ('Interactive', self.user_ns),
1438 ('Interactive (global)', self.user_global_ns),
1438 ('Interactive (global)', self.user_global_ns),
1439 ('Python builtin', builtin_mod.__dict__),
1439 ('Python builtin', builtin_mod.__dict__),
1440 ]
1440 ]
1441
1441
1442 # initialize results to 'null'
1442 # initialize results to 'null'
1443 found = False; obj = None; ospace = None; ds = None;
1443 found = False; obj = None; ospace = None; ds = None;
1444 ismagic = False; isalias = False; parent = None
1444 ismagic = False; isalias = False; parent = None
1445
1445
1446 # We need to special-case 'print', which as of python2.6 registers as a
1446 # We need to special-case 'print', which as of python2.6 registers as a
1447 # function but should only be treated as one if print_function was
1447 # function but should only be treated as one if print_function was
1448 # loaded with a future import. In this case, just bail.
1448 # loaded with a future import. In this case, just bail.
1449 if (oname == 'print' and not py3compat.PY3 and not \
1449 if (oname == 'print' and not py3compat.PY3 and not \
1450 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1450 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1451 return {'found':found, 'obj':obj, 'namespace':ospace,
1451 return {'found':found, 'obj':obj, 'namespace':ospace,
1452 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1452 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1453
1453
1454 # Look for the given name by splitting it in parts. If the head is
1454 # Look for the given name by splitting it in parts. If the head is
1455 # found, then we look for all the remaining parts as members, and only
1455 # found, then we look for all the remaining parts as members, and only
1456 # declare success if we can find them all.
1456 # declare success if we can find them all.
1457 oname_parts = oname.split('.')
1457 oname_parts = oname.split('.')
1458 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1458 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1459 for nsname,ns in namespaces:
1459 for nsname,ns in namespaces:
1460 try:
1460 try:
1461 obj = ns[oname_head]
1461 obj = ns[oname_head]
1462 except KeyError:
1462 except KeyError:
1463 continue
1463 continue
1464 else:
1464 else:
1465 #print 'oname_rest:', oname_rest # dbg
1465 #print 'oname_rest:', oname_rest # dbg
1466 for idx, part in enumerate(oname_rest):
1466 for idx, part in enumerate(oname_rest):
1467 try:
1467 try:
1468 parent = obj
1468 parent = obj
1469 # The last part is looked up in a special way to avoid
1469 # The last part is looked up in a special way to avoid
1470 # descriptor invocation as it may raise or have side
1470 # descriptor invocation as it may raise or have side
1471 # effects.
1471 # effects.
1472 if idx == len(oname_rest) - 1:
1472 if idx == len(oname_rest) - 1:
1473 obj = self._getattr_property(obj, part)
1473 obj = self._getattr_property(obj, part)
1474 else:
1474 else:
1475 obj = getattr(obj, part)
1475 obj = getattr(obj, part)
1476 except:
1476 except:
1477 # Blanket except b/c some badly implemented objects
1477 # Blanket except b/c some badly implemented objects
1478 # allow __getattr__ to raise exceptions other than
1478 # allow __getattr__ to raise exceptions other than
1479 # AttributeError, which then crashes IPython.
1479 # AttributeError, which then crashes IPython.
1480 break
1480 break
1481 else:
1481 else:
1482 # If we finish the for loop (no break), we got all members
1482 # If we finish the for loop (no break), we got all members
1483 found = True
1483 found = True
1484 ospace = nsname
1484 ospace = nsname
1485 break # namespace loop
1485 break # namespace loop
1486
1486
1487 # Try to see if it's magic
1487 # Try to see if it's magic
1488 if not found:
1488 if not found:
1489 obj = None
1489 obj = None
1490 if oname.startswith(ESC_MAGIC2):
1490 if oname.startswith(ESC_MAGIC2):
1491 oname = oname.lstrip(ESC_MAGIC2)
1491 oname = oname.lstrip(ESC_MAGIC2)
1492 obj = self.find_cell_magic(oname)
1492 obj = self.find_cell_magic(oname)
1493 elif oname.startswith(ESC_MAGIC):
1493 elif oname.startswith(ESC_MAGIC):
1494 oname = oname.lstrip(ESC_MAGIC)
1494 oname = oname.lstrip(ESC_MAGIC)
1495 obj = self.find_line_magic(oname)
1495 obj = self.find_line_magic(oname)
1496 else:
1496 else:
1497 # search without prefix, so run? will find %run?
1497 # search without prefix, so run? will find %run?
1498 obj = self.find_line_magic(oname)
1498 obj = self.find_line_magic(oname)
1499 if obj is None:
1499 if obj is None:
1500 obj = self.find_cell_magic(oname)
1500 obj = self.find_cell_magic(oname)
1501 if obj is not None:
1501 if obj is not None:
1502 found = True
1502 found = True
1503 ospace = 'IPython internal'
1503 ospace = 'IPython internal'
1504 ismagic = True
1504 ismagic = True
1505 isalias = isinstance(obj, Alias)
1505
1506
1506 # Last try: special-case some literals like '', [], {}, etc:
1507 # Last try: special-case some literals like '', [], {}, etc:
1507 if not found and oname_head in ["''",'""','[]','{}','()']:
1508 if not found and oname_head in ["''",'""','[]','{}','()']:
1508 obj = eval(oname_head)
1509 obj = eval(oname_head)
1509 found = True
1510 found = True
1510 ospace = 'Interactive'
1511 ospace = 'Interactive'
1511
1512
1512 return {'found':found, 'obj':obj, 'namespace':ospace,
1513 return {'found':found, 'obj':obj, 'namespace':ospace,
1513 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1514 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1514
1515
1515 @staticmethod
1516 @staticmethod
1516 def _getattr_property(obj, attrname):
1517 def _getattr_property(obj, attrname):
1517 """Property-aware getattr to use in object finding.
1518 """Property-aware getattr to use in object finding.
1518
1519
1519 If attrname represents a property, return it unevaluated (in case it has
1520 If attrname represents a property, return it unevaluated (in case it has
1520 side effects or raises an error.
1521 side effects or raises an error.
1521
1522
1522 """
1523 """
1523 if not isinstance(obj, type):
1524 if not isinstance(obj, type):
1524 try:
1525 try:
1525 # `getattr(type(obj), attrname)` is not guaranteed to return
1526 # `getattr(type(obj), attrname)` is not guaranteed to return
1526 # `obj`, but does so for property:
1527 # `obj`, but does so for property:
1527 #
1528 #
1528 # property.__get__(self, None, cls) -> self
1529 # property.__get__(self, None, cls) -> self
1529 #
1530 #
1530 # The universal alternative is to traverse the mro manually
1531 # The universal alternative is to traverse the mro manually
1531 # searching for attrname in class dicts.
1532 # searching for attrname in class dicts.
1532 attr = getattr(type(obj), attrname)
1533 attr = getattr(type(obj), attrname)
1533 except AttributeError:
1534 except AttributeError:
1534 pass
1535 pass
1535 else:
1536 else:
1536 # This relies on the fact that data descriptors (with both
1537 # This relies on the fact that data descriptors (with both
1537 # __get__ & __set__ magic methods) take precedence over
1538 # __get__ & __set__ magic methods) take precedence over
1538 # instance-level attributes:
1539 # instance-level attributes:
1539 #
1540 #
1540 # class A(object):
1541 # class A(object):
1541 # @property
1542 # @property
1542 # def foobar(self): return 123
1543 # def foobar(self): return 123
1543 # a = A()
1544 # a = A()
1544 # a.__dict__['foobar'] = 345
1545 # a.__dict__['foobar'] = 345
1545 # a.foobar # == 123
1546 # a.foobar # == 123
1546 #
1547 #
1547 # So, a property may be returned right away.
1548 # So, a property may be returned right away.
1548 if isinstance(attr, property):
1549 if isinstance(attr, property):
1549 return attr
1550 return attr
1550
1551
1551 # Nothing helped, fall back.
1552 # Nothing helped, fall back.
1552 return getattr(obj, attrname)
1553 return getattr(obj, attrname)
1553
1554
1554 def _object_find(self, oname, namespaces=None):
1555 def _object_find(self, oname, namespaces=None):
1555 """Find an object and return a struct with info about it."""
1556 """Find an object and return a struct with info about it."""
1556 return Struct(self._ofind(oname, namespaces))
1557 return Struct(self._ofind(oname, namespaces))
1557
1558
1558 def _inspect(self, meth, oname, namespaces=None, **kw):
1559 def _inspect(self, meth, oname, namespaces=None, **kw):
1559 """Generic interface to the inspector system.
1560 """Generic interface to the inspector system.
1560
1561
1561 This function is meant to be called by pdef, pdoc & friends."""
1562 This function is meant to be called by pdef, pdoc & friends."""
1562 info = self._object_find(oname, namespaces)
1563 info = self._object_find(oname, namespaces)
1563 if info.found:
1564 if info.found:
1564 pmethod = getattr(self.inspector, meth)
1565 pmethod = getattr(self.inspector, meth)
1565 formatter = format_screen if info.ismagic else None
1566 formatter = format_screen if info.ismagic else None
1566 if meth == 'pdoc':
1567 if meth == 'pdoc':
1567 pmethod(info.obj, oname, formatter)
1568 pmethod(info.obj, oname, formatter)
1568 elif meth == 'pinfo':
1569 elif meth == 'pinfo':
1569 pmethod(info.obj, oname, formatter, info, **kw)
1570 pmethod(info.obj, oname, formatter, info, **kw)
1570 else:
1571 else:
1571 pmethod(info.obj, oname)
1572 pmethod(info.obj, oname)
1572 else:
1573 else:
1573 print('Object `%s` not found.' % oname)
1574 print('Object `%s` not found.' % oname)
1574 return 'not found' # so callers can take other action
1575 return 'not found' # so callers can take other action
1575
1576
1576 def object_inspect(self, oname, detail_level=0):
1577 def object_inspect(self, oname, detail_level=0):
1577 """Get object info about oname"""
1578 """Get object info about oname"""
1578 with self.builtin_trap:
1579 with self.builtin_trap:
1579 info = self._object_find(oname)
1580 info = self._object_find(oname)
1580 if info.found:
1581 if info.found:
1581 return self.inspector.info(info.obj, oname, info=info,
1582 return self.inspector.info(info.obj, oname, info=info,
1582 detail_level=detail_level
1583 detail_level=detail_level
1583 )
1584 )
1584 else:
1585 else:
1585 return oinspect.object_info(name=oname, found=False)
1586 return oinspect.object_info(name=oname, found=False)
1586
1587
1587 def object_inspect_text(self, oname, detail_level=0):
1588 def object_inspect_text(self, oname, detail_level=0):
1588 """Get object info as formatted text"""
1589 """Get object info as formatted text"""
1589 with self.builtin_trap:
1590 with self.builtin_trap:
1590 info = self._object_find(oname)
1591 info = self._object_find(oname)
1591 if info.found:
1592 if info.found:
1592 return self.inspector._format_info(info.obj, oname, info=info,
1593 return self.inspector._format_info(info.obj, oname, info=info,
1593 detail_level=detail_level
1594 detail_level=detail_level
1594 )
1595 )
1595 else:
1596 else:
1596 raise KeyError(oname)
1597 raise KeyError(oname)
1597
1598
1598 #-------------------------------------------------------------------------
1599 #-------------------------------------------------------------------------
1599 # Things related to history management
1600 # Things related to history management
1600 #-------------------------------------------------------------------------
1601 #-------------------------------------------------------------------------
1601
1602
1602 def init_history(self):
1603 def init_history(self):
1603 """Sets up the command history, and starts regular autosaves."""
1604 """Sets up the command history, and starts regular autosaves."""
1604 self.history_manager = HistoryManager(shell=self, parent=self)
1605 self.history_manager = HistoryManager(shell=self, parent=self)
1605 self.configurables.append(self.history_manager)
1606 self.configurables.append(self.history_manager)
1606
1607
1607 #-------------------------------------------------------------------------
1608 #-------------------------------------------------------------------------
1608 # Things related to exception handling and tracebacks (not debugging)
1609 # Things related to exception handling and tracebacks (not debugging)
1609 #-------------------------------------------------------------------------
1610 #-------------------------------------------------------------------------
1610
1611
1611 def init_traceback_handlers(self, custom_exceptions):
1612 def init_traceback_handlers(self, custom_exceptions):
1612 # Syntax error handler.
1613 # Syntax error handler.
1613 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1614 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1614
1615
1615 # The interactive one is initialized with an offset, meaning we always
1616 # The interactive one is initialized with an offset, meaning we always
1616 # want to remove the topmost item in the traceback, which is our own
1617 # want to remove the topmost item in the traceback, which is our own
1617 # internal code. Valid modes: ['Plain','Context','Verbose']
1618 # internal code. Valid modes: ['Plain','Context','Verbose']
1618 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1619 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1619 color_scheme='NoColor',
1620 color_scheme='NoColor',
1620 tb_offset = 1,
1621 tb_offset = 1,
1621 check_cache=check_linecache_ipython)
1622 check_cache=check_linecache_ipython)
1622
1623
1623 # The instance will store a pointer to the system-wide exception hook,
1624 # The instance will store a pointer to the system-wide exception hook,
1624 # so that runtime code (such as magics) can access it. This is because
1625 # so that runtime code (such as magics) can access it. This is because
1625 # during the read-eval loop, it may get temporarily overwritten.
1626 # during the read-eval loop, it may get temporarily overwritten.
1626 self.sys_excepthook = sys.excepthook
1627 self.sys_excepthook = sys.excepthook
1627
1628
1628 # and add any custom exception handlers the user may have specified
1629 # and add any custom exception handlers the user may have specified
1629 self.set_custom_exc(*custom_exceptions)
1630 self.set_custom_exc(*custom_exceptions)
1630
1631
1631 # Set the exception mode
1632 # Set the exception mode
1632 self.InteractiveTB.set_mode(mode=self.xmode)
1633 self.InteractiveTB.set_mode(mode=self.xmode)
1633
1634
1634 def set_custom_exc(self, exc_tuple, handler):
1635 def set_custom_exc(self, exc_tuple, handler):
1635 """set_custom_exc(exc_tuple,handler)
1636 """set_custom_exc(exc_tuple,handler)
1636
1637
1637 Set a custom exception handler, which will be called if any of the
1638 Set a custom exception handler, which will be called if any of the
1638 exceptions in exc_tuple occur in the mainloop (specifically, in the
1639 exceptions in exc_tuple occur in the mainloop (specifically, in the
1639 run_code() method).
1640 run_code() method).
1640
1641
1641 Parameters
1642 Parameters
1642 ----------
1643 ----------
1643
1644
1644 exc_tuple : tuple of exception classes
1645 exc_tuple : tuple of exception classes
1645 A *tuple* of exception classes, for which to call the defined
1646 A *tuple* of exception classes, for which to call the defined
1646 handler. It is very important that you use a tuple, and NOT A
1647 handler. It is very important that you use a tuple, and NOT A
1647 LIST here, because of the way Python's except statement works. If
1648 LIST here, because of the way Python's except statement works. If
1648 you only want to trap a single exception, use a singleton tuple::
1649 you only want to trap a single exception, use a singleton tuple::
1649
1650
1650 exc_tuple == (MyCustomException,)
1651 exc_tuple == (MyCustomException,)
1651
1652
1652 handler : callable
1653 handler : callable
1653 handler must have the following signature::
1654 handler must have the following signature::
1654
1655
1655 def my_handler(self, etype, value, tb, tb_offset=None):
1656 def my_handler(self, etype, value, tb, tb_offset=None):
1656 ...
1657 ...
1657 return structured_traceback
1658 return structured_traceback
1658
1659
1659 Your handler must return a structured traceback (a list of strings),
1660 Your handler must return a structured traceback (a list of strings),
1660 or None.
1661 or None.
1661
1662
1662 This will be made into an instance method (via types.MethodType)
1663 This will be made into an instance method (via types.MethodType)
1663 of IPython itself, and it will be called if any of the exceptions
1664 of IPython itself, and it will be called if any of the exceptions
1664 listed in the exc_tuple are caught. If the handler is None, an
1665 listed in the exc_tuple are caught. If the handler is None, an
1665 internal basic one is used, which just prints basic info.
1666 internal basic one is used, which just prints basic info.
1666
1667
1667 To protect IPython from crashes, if your handler ever raises an
1668 To protect IPython from crashes, if your handler ever raises an
1668 exception or returns an invalid result, it will be immediately
1669 exception or returns an invalid result, it will be immediately
1669 disabled.
1670 disabled.
1670
1671
1671 WARNING: by putting in your own exception handler into IPython's main
1672 WARNING: by putting in your own exception handler into IPython's main
1672 execution loop, you run a very good chance of nasty crashes. This
1673 execution loop, you run a very good chance of nasty crashes. This
1673 facility should only be used if you really know what you are doing."""
1674 facility should only be used if you really know what you are doing."""
1674
1675
1675 assert type(exc_tuple)==type(()) , \
1676 assert type(exc_tuple)==type(()) , \
1676 "The custom exceptions must be given AS A TUPLE."
1677 "The custom exceptions must be given AS A TUPLE."
1677
1678
1678 def dummy_handler(self,etype,value,tb,tb_offset=None):
1679 def dummy_handler(self,etype,value,tb,tb_offset=None):
1679 print('*** Simple custom exception handler ***')
1680 print('*** Simple custom exception handler ***')
1680 print('Exception type :',etype)
1681 print('Exception type :',etype)
1681 print('Exception value:',value)
1682 print('Exception value:',value)
1682 print('Traceback :',tb)
1683 print('Traceback :',tb)
1683 #print 'Source code :','\n'.join(self.buffer)
1684 #print 'Source code :','\n'.join(self.buffer)
1684
1685
1685 def validate_stb(stb):
1686 def validate_stb(stb):
1686 """validate structured traceback return type
1687 """validate structured traceback return type
1687
1688
1688 return type of CustomTB *should* be a list of strings, but allow
1689 return type of CustomTB *should* be a list of strings, but allow
1689 single strings or None, which are harmless.
1690 single strings or None, which are harmless.
1690
1691
1691 This function will *always* return a list of strings,
1692 This function will *always* return a list of strings,
1692 and will raise a TypeError if stb is inappropriate.
1693 and will raise a TypeError if stb is inappropriate.
1693 """
1694 """
1694 msg = "CustomTB must return list of strings, not %r" % stb
1695 msg = "CustomTB must return list of strings, not %r" % stb
1695 if stb is None:
1696 if stb is None:
1696 return []
1697 return []
1697 elif isinstance(stb, string_types):
1698 elif isinstance(stb, string_types):
1698 return [stb]
1699 return [stb]
1699 elif not isinstance(stb, list):
1700 elif not isinstance(stb, list):
1700 raise TypeError(msg)
1701 raise TypeError(msg)
1701 # it's a list
1702 # it's a list
1702 for line in stb:
1703 for line in stb:
1703 # check every element
1704 # check every element
1704 if not isinstance(line, string_types):
1705 if not isinstance(line, string_types):
1705 raise TypeError(msg)
1706 raise TypeError(msg)
1706 return stb
1707 return stb
1707
1708
1708 if handler is None:
1709 if handler is None:
1709 wrapped = dummy_handler
1710 wrapped = dummy_handler
1710 else:
1711 else:
1711 def wrapped(self,etype,value,tb,tb_offset=None):
1712 def wrapped(self,etype,value,tb,tb_offset=None):
1712 """wrap CustomTB handler, to protect IPython from user code
1713 """wrap CustomTB handler, to protect IPython from user code
1713
1714
1714 This makes it harder (but not impossible) for custom exception
1715 This makes it harder (but not impossible) for custom exception
1715 handlers to crash IPython.
1716 handlers to crash IPython.
1716 """
1717 """
1717 try:
1718 try:
1718 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1719 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1719 return validate_stb(stb)
1720 return validate_stb(stb)
1720 except:
1721 except:
1721 # clear custom handler immediately
1722 # clear custom handler immediately
1722 self.set_custom_exc((), None)
1723 self.set_custom_exc((), None)
1723 print("Custom TB Handler failed, unregistering", file=io.stderr)
1724 print("Custom TB Handler failed, unregistering", file=io.stderr)
1724 # show the exception in handler first
1725 # show the exception in handler first
1725 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1726 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1726 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1727 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1727 print("The original exception:", file=io.stdout)
1728 print("The original exception:", file=io.stdout)
1728 stb = self.InteractiveTB.structured_traceback(
1729 stb = self.InteractiveTB.structured_traceback(
1729 (etype,value,tb), tb_offset=tb_offset
1730 (etype,value,tb), tb_offset=tb_offset
1730 )
1731 )
1731 return stb
1732 return stb
1732
1733
1733 self.CustomTB = types.MethodType(wrapped,self)
1734 self.CustomTB = types.MethodType(wrapped,self)
1734 self.custom_exceptions = exc_tuple
1735 self.custom_exceptions = exc_tuple
1735
1736
1736 def excepthook(self, etype, value, tb):
1737 def excepthook(self, etype, value, tb):
1737 """One more defense for GUI apps that call sys.excepthook.
1738 """One more defense for GUI apps that call sys.excepthook.
1738
1739
1739 GUI frameworks like wxPython trap exceptions and call
1740 GUI frameworks like wxPython trap exceptions and call
1740 sys.excepthook themselves. I guess this is a feature that
1741 sys.excepthook themselves. I guess this is a feature that
1741 enables them to keep running after exceptions that would
1742 enables them to keep running after exceptions that would
1742 otherwise kill their mainloop. This is a bother for IPython
1743 otherwise kill their mainloop. This is a bother for IPython
1743 which excepts to catch all of the program exceptions with a try:
1744 which excepts to catch all of the program exceptions with a try:
1744 except: statement.
1745 except: statement.
1745
1746
1746 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1747 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1747 any app directly invokes sys.excepthook, it will look to the user like
1748 any app directly invokes sys.excepthook, it will look to the user like
1748 IPython crashed. In order to work around this, we can disable the
1749 IPython crashed. In order to work around this, we can disable the
1749 CrashHandler and replace it with this excepthook instead, which prints a
1750 CrashHandler and replace it with this excepthook instead, which prints a
1750 regular traceback using our InteractiveTB. In this fashion, apps which
1751 regular traceback using our InteractiveTB. In this fashion, apps which
1751 call sys.excepthook will generate a regular-looking exception from
1752 call sys.excepthook will generate a regular-looking exception from
1752 IPython, and the CrashHandler will only be triggered by real IPython
1753 IPython, and the CrashHandler will only be triggered by real IPython
1753 crashes.
1754 crashes.
1754
1755
1755 This hook should be used sparingly, only in places which are not likely
1756 This hook should be used sparingly, only in places which are not likely
1756 to be true IPython errors.
1757 to be true IPython errors.
1757 """
1758 """
1758 self.showtraceback((etype, value, tb), tb_offset=0)
1759 self.showtraceback((etype, value, tb), tb_offset=0)
1759
1760
1760 def _get_exc_info(self, exc_tuple=None):
1761 def _get_exc_info(self, exc_tuple=None):
1761 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1762 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1762
1763
1763 Ensures sys.last_type,value,traceback hold the exc_info we found,
1764 Ensures sys.last_type,value,traceback hold the exc_info we found,
1764 from whichever source.
1765 from whichever source.
1765
1766
1766 raises ValueError if none of these contain any information
1767 raises ValueError if none of these contain any information
1767 """
1768 """
1768 if exc_tuple is None:
1769 if exc_tuple is None:
1769 etype, value, tb = sys.exc_info()
1770 etype, value, tb = sys.exc_info()
1770 else:
1771 else:
1771 etype, value, tb = exc_tuple
1772 etype, value, tb = exc_tuple
1772
1773
1773 if etype is None:
1774 if etype is None:
1774 if hasattr(sys, 'last_type'):
1775 if hasattr(sys, 'last_type'):
1775 etype, value, tb = sys.last_type, sys.last_value, \
1776 etype, value, tb = sys.last_type, sys.last_value, \
1776 sys.last_traceback
1777 sys.last_traceback
1777
1778
1778 if etype is None:
1779 if etype is None:
1779 raise ValueError("No exception to find")
1780 raise ValueError("No exception to find")
1780
1781
1781 # Now store the exception info in sys.last_type etc.
1782 # Now store the exception info in sys.last_type etc.
1782 # WARNING: these variables are somewhat deprecated and not
1783 # WARNING: these variables are somewhat deprecated and not
1783 # necessarily safe to use in a threaded environment, but tools
1784 # necessarily safe to use in a threaded environment, but tools
1784 # like pdb depend on their existence, so let's set them. If we
1785 # like pdb depend on their existence, so let's set them. If we
1785 # find problems in the field, we'll need to revisit their use.
1786 # find problems in the field, we'll need to revisit their use.
1786 sys.last_type = etype
1787 sys.last_type = etype
1787 sys.last_value = value
1788 sys.last_value = value
1788 sys.last_traceback = tb
1789 sys.last_traceback = tb
1789
1790
1790 return etype, value, tb
1791 return etype, value, tb
1791
1792
1792 def show_usage_error(self, exc):
1793 def show_usage_error(self, exc):
1793 """Show a short message for UsageErrors
1794 """Show a short message for UsageErrors
1794
1795
1795 These are special exceptions that shouldn't show a traceback.
1796 These are special exceptions that shouldn't show a traceback.
1796 """
1797 """
1797 self.write_err("UsageError: %s" % exc)
1798 self.write_err("UsageError: %s" % exc)
1798
1799
1799 def get_exception_only(self, exc_tuple=None):
1800 def get_exception_only(self, exc_tuple=None):
1800 """
1801 """
1801 Return as a string (ending with a newline) the exception that
1802 Return as a string (ending with a newline) the exception that
1802 just occurred, without any traceback.
1803 just occurred, without any traceback.
1803 """
1804 """
1804 etype, value, tb = self._get_exc_info(exc_tuple)
1805 etype, value, tb = self._get_exc_info(exc_tuple)
1805 msg = traceback.format_exception_only(etype, value)
1806 msg = traceback.format_exception_only(etype, value)
1806 return ''.join(msg)
1807 return ''.join(msg)
1807
1808
1808 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1809 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1809 exception_only=False):
1810 exception_only=False):
1810 """Display the exception that just occurred.
1811 """Display the exception that just occurred.
1811
1812
1812 If nothing is known about the exception, this is the method which
1813 If nothing is known about the exception, this is the method which
1813 should be used throughout the code for presenting user tracebacks,
1814 should be used throughout the code for presenting user tracebacks,
1814 rather than directly invoking the InteractiveTB object.
1815 rather than directly invoking the InteractiveTB object.
1815
1816
1816 A specific showsyntaxerror() also exists, but this method can take
1817 A specific showsyntaxerror() also exists, but this method can take
1817 care of calling it if needed, so unless you are explicitly catching a
1818 care of calling it if needed, so unless you are explicitly catching a
1818 SyntaxError exception, don't try to analyze the stack manually and
1819 SyntaxError exception, don't try to analyze the stack manually and
1819 simply call this method."""
1820 simply call this method."""
1820
1821
1821 try:
1822 try:
1822 try:
1823 try:
1823 etype, value, tb = self._get_exc_info(exc_tuple)
1824 etype, value, tb = self._get_exc_info(exc_tuple)
1824 except ValueError:
1825 except ValueError:
1825 self.write_err('No traceback available to show.\n')
1826 self.write_err('No traceback available to show.\n')
1826 return
1827 return
1827
1828
1828 if issubclass(etype, SyntaxError):
1829 if issubclass(etype, SyntaxError):
1829 # Though this won't be called by syntax errors in the input
1830 # Though this won't be called by syntax errors in the input
1830 # line, there may be SyntaxError cases with imported code.
1831 # line, there may be SyntaxError cases with imported code.
1831 self.showsyntaxerror(filename)
1832 self.showsyntaxerror(filename)
1832 elif etype is UsageError:
1833 elif etype is UsageError:
1833 self.show_usage_error(value)
1834 self.show_usage_error(value)
1834 else:
1835 else:
1835 if exception_only:
1836 if exception_only:
1836 stb = ['An exception has occurred, use %tb to see '
1837 stb = ['An exception has occurred, use %tb to see '
1837 'the full traceback.\n']
1838 'the full traceback.\n']
1838 stb.extend(self.InteractiveTB.get_exception_only(etype,
1839 stb.extend(self.InteractiveTB.get_exception_only(etype,
1839 value))
1840 value))
1840 else:
1841 else:
1841 try:
1842 try:
1842 # Exception classes can customise their traceback - we
1843 # Exception classes can customise their traceback - we
1843 # use this in IPython.parallel for exceptions occurring
1844 # use this in IPython.parallel for exceptions occurring
1844 # in the engines. This should return a list of strings.
1845 # in the engines. This should return a list of strings.
1845 stb = value._render_traceback_()
1846 stb = value._render_traceback_()
1846 except Exception:
1847 except Exception:
1847 stb = self.InteractiveTB.structured_traceback(etype,
1848 stb = self.InteractiveTB.structured_traceback(etype,
1848 value, tb, tb_offset=tb_offset)
1849 value, tb, tb_offset=tb_offset)
1849
1850
1850 self._showtraceback(etype, value, stb)
1851 self._showtraceback(etype, value, stb)
1851 if self.call_pdb:
1852 if self.call_pdb:
1852 # drop into debugger
1853 # drop into debugger
1853 self.debugger(force=True)
1854 self.debugger(force=True)
1854 return
1855 return
1855
1856
1856 # Actually show the traceback
1857 # Actually show the traceback
1857 self._showtraceback(etype, value, stb)
1858 self._showtraceback(etype, value, stb)
1858
1859
1859 except KeyboardInterrupt:
1860 except KeyboardInterrupt:
1860 self.write_err('\n' + self.get_exception_only())
1861 self.write_err('\n' + self.get_exception_only())
1861
1862
1862 def _showtraceback(self, etype, evalue, stb):
1863 def _showtraceback(self, etype, evalue, stb):
1863 """Actually show a traceback.
1864 """Actually show a traceback.
1864
1865
1865 Subclasses may override this method to put the traceback on a different
1866 Subclasses may override this method to put the traceback on a different
1866 place, like a side channel.
1867 place, like a side channel.
1867 """
1868 """
1868 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1869 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1869
1870
1870 def showsyntaxerror(self, filename=None):
1871 def showsyntaxerror(self, filename=None):
1871 """Display the syntax error that just occurred.
1872 """Display the syntax error that just occurred.
1872
1873
1873 This doesn't display a stack trace because there isn't one.
1874 This doesn't display a stack trace because there isn't one.
1874
1875
1875 If a filename is given, it is stuffed in the exception instead
1876 If a filename is given, it is stuffed in the exception instead
1876 of what was there before (because Python's parser always uses
1877 of what was there before (because Python's parser always uses
1877 "<string>" when reading from a string).
1878 "<string>" when reading from a string).
1878 """
1879 """
1879 etype, value, last_traceback = self._get_exc_info()
1880 etype, value, last_traceback = self._get_exc_info()
1880
1881
1881 if filename and issubclass(etype, SyntaxError):
1882 if filename and issubclass(etype, SyntaxError):
1882 try:
1883 try:
1883 value.filename = filename
1884 value.filename = filename
1884 except:
1885 except:
1885 # Not the format we expect; leave it alone
1886 # Not the format we expect; leave it alone
1886 pass
1887 pass
1887
1888
1888 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1889 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1889 self._showtraceback(etype, value, stb)
1890 self._showtraceback(etype, value, stb)
1890
1891
1891 # This is overridden in TerminalInteractiveShell to show a message about
1892 # This is overridden in TerminalInteractiveShell to show a message about
1892 # the %paste magic.
1893 # the %paste magic.
1893 def showindentationerror(self):
1894 def showindentationerror(self):
1894 """Called by run_cell when there's an IndentationError in code entered
1895 """Called by run_cell when there's an IndentationError in code entered
1895 at the prompt.
1896 at the prompt.
1896
1897
1897 This is overridden in TerminalInteractiveShell to show a message about
1898 This is overridden in TerminalInteractiveShell to show a message about
1898 the %paste magic."""
1899 the %paste magic."""
1899 self.showsyntaxerror()
1900 self.showsyntaxerror()
1900
1901
1901 #-------------------------------------------------------------------------
1902 #-------------------------------------------------------------------------
1902 # Things related to readline
1903 # Things related to readline
1903 #-------------------------------------------------------------------------
1904 #-------------------------------------------------------------------------
1904
1905
1905 def init_readline(self):
1906 def init_readline(self):
1906 """Command history completion/saving/reloading."""
1907 """Command history completion/saving/reloading."""
1907
1908
1908 if self.readline_use:
1909 if self.readline_use:
1909 import IPython.utils.rlineimpl as readline
1910 import IPython.utils.rlineimpl as readline
1910
1911
1911 self.rl_next_input = None
1912 self.rl_next_input = None
1912 self.rl_do_indent = False
1913 self.rl_do_indent = False
1913
1914
1914 if not self.readline_use or not readline.have_readline:
1915 if not self.readline_use or not readline.have_readline:
1915 self.has_readline = False
1916 self.has_readline = False
1916 self.readline = None
1917 self.readline = None
1917 # Set a number of methods that depend on readline to be no-op
1918 # Set a number of methods that depend on readline to be no-op
1918 self.readline_no_record = no_op_context
1919 self.readline_no_record = no_op_context
1919 self.set_readline_completer = no_op
1920 self.set_readline_completer = no_op
1920 self.set_custom_completer = no_op
1921 self.set_custom_completer = no_op
1921 if self.readline_use:
1922 if self.readline_use:
1922 warn('Readline services not available or not loaded.')
1923 warn('Readline services not available or not loaded.')
1923 else:
1924 else:
1924 self.has_readline = True
1925 self.has_readline = True
1925 self.readline = readline
1926 self.readline = readline
1926 sys.modules['readline'] = readline
1927 sys.modules['readline'] = readline
1927
1928
1928 # Platform-specific configuration
1929 # Platform-specific configuration
1929 if os.name == 'nt':
1930 if os.name == 'nt':
1930 # FIXME - check with Frederick to see if we can harmonize
1931 # FIXME - check with Frederick to see if we can harmonize
1931 # naming conventions with pyreadline to avoid this
1932 # naming conventions with pyreadline to avoid this
1932 # platform-dependent check
1933 # platform-dependent check
1933 self.readline_startup_hook = readline.set_pre_input_hook
1934 self.readline_startup_hook = readline.set_pre_input_hook
1934 else:
1935 else:
1935 self.readline_startup_hook = readline.set_startup_hook
1936 self.readline_startup_hook = readline.set_startup_hook
1936
1937
1937 # Readline config order:
1938 # Readline config order:
1938 # - IPython config (default value)
1939 # - IPython config (default value)
1939 # - custom inputrc
1940 # - custom inputrc
1940 # - IPython config (user customized)
1941 # - IPython config (user customized)
1941
1942
1942 # load IPython config before inputrc if default
1943 # load IPython config before inputrc if default
1943 # skip if libedit because parse_and_bind syntax is different
1944 # skip if libedit because parse_and_bind syntax is different
1944 if not self._custom_readline_config and not readline.uses_libedit:
1945 if not self._custom_readline_config and not readline.uses_libedit:
1945 for rlcommand in self.readline_parse_and_bind:
1946 for rlcommand in self.readline_parse_and_bind:
1946 readline.parse_and_bind(rlcommand)
1947 readline.parse_and_bind(rlcommand)
1947
1948
1948 # Load user's initrc file (readline config)
1949 # Load user's initrc file (readline config)
1949 # Or if libedit is used, load editrc.
1950 # Or if libedit is used, load editrc.
1950 inputrc_name = os.environ.get('INPUTRC')
1951 inputrc_name = os.environ.get('INPUTRC')
1951 if inputrc_name is None:
1952 if inputrc_name is None:
1952 inputrc_name = '.inputrc'
1953 inputrc_name = '.inputrc'
1953 if readline.uses_libedit:
1954 if readline.uses_libedit:
1954 inputrc_name = '.editrc'
1955 inputrc_name = '.editrc'
1955 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1956 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1956 if os.path.isfile(inputrc_name):
1957 if os.path.isfile(inputrc_name):
1957 try:
1958 try:
1958 readline.read_init_file(inputrc_name)
1959 readline.read_init_file(inputrc_name)
1959 except:
1960 except:
1960 warn('Problems reading readline initialization file <%s>'
1961 warn('Problems reading readline initialization file <%s>'
1961 % inputrc_name)
1962 % inputrc_name)
1962
1963
1963 # load IPython config after inputrc if user has customized
1964 # load IPython config after inputrc if user has customized
1964 if self._custom_readline_config:
1965 if self._custom_readline_config:
1965 for rlcommand in self.readline_parse_and_bind:
1966 for rlcommand in self.readline_parse_and_bind:
1966 readline.parse_and_bind(rlcommand)
1967 readline.parse_and_bind(rlcommand)
1967
1968
1968 # Remove some chars from the delimiters list. If we encounter
1969 # Remove some chars from the delimiters list. If we encounter
1969 # unicode chars, discard them.
1970 # unicode chars, discard them.
1970 delims = readline.get_completer_delims()
1971 delims = readline.get_completer_delims()
1971 if not py3compat.PY3:
1972 if not py3compat.PY3:
1972 delims = delims.encode("ascii", "ignore")
1973 delims = delims.encode("ascii", "ignore")
1973 for d in self.readline_remove_delims:
1974 for d in self.readline_remove_delims:
1974 delims = delims.replace(d, "")
1975 delims = delims.replace(d, "")
1975 delims = delims.replace(ESC_MAGIC, '')
1976 delims = delims.replace(ESC_MAGIC, '')
1976 readline.set_completer_delims(delims)
1977 readline.set_completer_delims(delims)
1977 # Store these so we can restore them if something like rpy2 modifies
1978 # Store these so we can restore them if something like rpy2 modifies
1978 # them.
1979 # them.
1979 self.readline_delims = delims
1980 self.readline_delims = delims
1980 # otherwise we end up with a monster history after a while:
1981 # otherwise we end up with a monster history after a while:
1981 readline.set_history_length(self.history_length)
1982 readline.set_history_length(self.history_length)
1982
1983
1983 self.refill_readline_hist()
1984 self.refill_readline_hist()
1984 self.readline_no_record = ReadlineNoRecord(self)
1985 self.readline_no_record = ReadlineNoRecord(self)
1985
1986
1986 # Configure auto-indent for all platforms
1987 # Configure auto-indent for all platforms
1987 self.set_autoindent(self.autoindent)
1988 self.set_autoindent(self.autoindent)
1988
1989
1989 def refill_readline_hist(self):
1990 def refill_readline_hist(self):
1990 # Load the last 1000 lines from history
1991 # Load the last 1000 lines from history
1991 self.readline.clear_history()
1992 self.readline.clear_history()
1992 stdin_encoding = sys.stdin.encoding or "utf-8"
1993 stdin_encoding = sys.stdin.encoding or "utf-8"
1993 last_cell = u""
1994 last_cell = u""
1994 for _, _, cell in self.history_manager.get_tail(1000,
1995 for _, _, cell in self.history_manager.get_tail(1000,
1995 include_latest=True):
1996 include_latest=True):
1996 # Ignore blank lines and consecutive duplicates
1997 # Ignore blank lines and consecutive duplicates
1997 cell = cell.rstrip()
1998 cell = cell.rstrip()
1998 if cell and (cell != last_cell):
1999 if cell and (cell != last_cell):
1999 try:
2000 try:
2000 if self.multiline_history:
2001 if self.multiline_history:
2001 self.readline.add_history(py3compat.unicode_to_str(cell,
2002 self.readline.add_history(py3compat.unicode_to_str(cell,
2002 stdin_encoding))
2003 stdin_encoding))
2003 else:
2004 else:
2004 for line in cell.splitlines():
2005 for line in cell.splitlines():
2005 self.readline.add_history(py3compat.unicode_to_str(line,
2006 self.readline.add_history(py3compat.unicode_to_str(line,
2006 stdin_encoding))
2007 stdin_encoding))
2007 last_cell = cell
2008 last_cell = cell
2008
2009
2009 except TypeError:
2010 except TypeError:
2010 # The history DB can get corrupted so it returns strings
2011 # The history DB can get corrupted so it returns strings
2011 # containing null bytes, which readline objects to.
2012 # containing null bytes, which readline objects to.
2012 continue
2013 continue
2013
2014
2014 @skip_doctest
2015 @skip_doctest
2015 def set_next_input(self, s, replace=False):
2016 def set_next_input(self, s, replace=False):
2016 """ Sets the 'default' input string for the next command line.
2017 """ Sets the 'default' input string for the next command line.
2017
2018
2018 Requires readline.
2019 Requires readline.
2019
2020
2020 Example::
2021 Example::
2021
2022
2022 In [1]: _ip.set_next_input("Hello Word")
2023 In [1]: _ip.set_next_input("Hello Word")
2023 In [2]: Hello Word_ # cursor is here
2024 In [2]: Hello Word_ # cursor is here
2024 """
2025 """
2025 self.rl_next_input = py3compat.cast_bytes_py2(s)
2026 self.rl_next_input = py3compat.cast_bytes_py2(s)
2026
2027
2027 # Maybe move this to the terminal subclass?
2028 # Maybe move this to the terminal subclass?
2028 def pre_readline(self):
2029 def pre_readline(self):
2029 """readline hook to be used at the start of each line.
2030 """readline hook to be used at the start of each line.
2030
2031
2031 Currently it handles auto-indent only."""
2032 Currently it handles auto-indent only."""
2032
2033
2033 if self.rl_do_indent:
2034 if self.rl_do_indent:
2034 self.readline.insert_text(self._indent_current_str())
2035 self.readline.insert_text(self._indent_current_str())
2035 if self.rl_next_input is not None:
2036 if self.rl_next_input is not None:
2036 self.readline.insert_text(self.rl_next_input)
2037 self.readline.insert_text(self.rl_next_input)
2037 self.rl_next_input = None
2038 self.rl_next_input = None
2038
2039
2039 def _indent_current_str(self):
2040 def _indent_current_str(self):
2040 """return the current level of indentation as a string"""
2041 """return the current level of indentation as a string"""
2041 return self.input_splitter.indent_spaces * ' '
2042 return self.input_splitter.indent_spaces * ' '
2042
2043
2043 #-------------------------------------------------------------------------
2044 #-------------------------------------------------------------------------
2044 # Things related to text completion
2045 # Things related to text completion
2045 #-------------------------------------------------------------------------
2046 #-------------------------------------------------------------------------
2046
2047
2047 def init_completer(self):
2048 def init_completer(self):
2048 """Initialize the completion machinery.
2049 """Initialize the completion machinery.
2049
2050
2050 This creates completion machinery that can be used by client code,
2051 This creates completion machinery that can be used by client code,
2051 either interactively in-process (typically triggered by the readline
2052 either interactively in-process (typically triggered by the readline
2052 library), programatically (such as in test suites) or out-of-prcess
2053 library), programatically (such as in test suites) or out-of-prcess
2053 (typically over the network by remote frontends).
2054 (typically over the network by remote frontends).
2054 """
2055 """
2055 from IPython.core.completer import IPCompleter
2056 from IPython.core.completer import IPCompleter
2056 from IPython.core.completerlib import (module_completer,
2057 from IPython.core.completerlib import (module_completer,
2057 magic_run_completer, cd_completer, reset_completer)
2058 magic_run_completer, cd_completer, reset_completer)
2058
2059
2059 self.Completer = IPCompleter(shell=self,
2060 self.Completer = IPCompleter(shell=self,
2060 namespace=self.user_ns,
2061 namespace=self.user_ns,
2061 global_namespace=self.user_global_ns,
2062 global_namespace=self.user_global_ns,
2062 use_readline=self.has_readline,
2063 use_readline=self.has_readline,
2063 parent=self,
2064 parent=self,
2064 )
2065 )
2065 self.configurables.append(self.Completer)
2066 self.configurables.append(self.Completer)
2066
2067
2067 # Add custom completers to the basic ones built into IPCompleter
2068 # Add custom completers to the basic ones built into IPCompleter
2068 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2069 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2069 self.strdispatchers['complete_command'] = sdisp
2070 self.strdispatchers['complete_command'] = sdisp
2070 self.Completer.custom_completers = sdisp
2071 self.Completer.custom_completers = sdisp
2071
2072
2072 self.set_hook('complete_command', module_completer, str_key = 'import')
2073 self.set_hook('complete_command', module_completer, str_key = 'import')
2073 self.set_hook('complete_command', module_completer, str_key = 'from')
2074 self.set_hook('complete_command', module_completer, str_key = 'from')
2074 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2075 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2075 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2076 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2076 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2077 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2077
2078
2078 # Only configure readline if we truly are using readline. IPython can
2079 # Only configure readline if we truly are using readline. IPython can
2079 # do tab-completion over the network, in GUIs, etc, where readline
2080 # do tab-completion over the network, in GUIs, etc, where readline
2080 # itself may be absent
2081 # itself may be absent
2081 if self.has_readline:
2082 if self.has_readline:
2082 self.set_readline_completer()
2083 self.set_readline_completer()
2083
2084
2084 def complete(self, text, line=None, cursor_pos=None):
2085 def complete(self, text, line=None, cursor_pos=None):
2085 """Return the completed text and a list of completions.
2086 """Return the completed text and a list of completions.
2086
2087
2087 Parameters
2088 Parameters
2088 ----------
2089 ----------
2089
2090
2090 text : string
2091 text : string
2091 A string of text to be completed on. It can be given as empty and
2092 A string of text to be completed on. It can be given as empty and
2092 instead a line/position pair are given. In this case, the
2093 instead a line/position pair are given. In this case, the
2093 completer itself will split the line like readline does.
2094 completer itself will split the line like readline does.
2094
2095
2095 line : string, optional
2096 line : string, optional
2096 The complete line that text is part of.
2097 The complete line that text is part of.
2097
2098
2098 cursor_pos : int, optional
2099 cursor_pos : int, optional
2099 The position of the cursor on the input line.
2100 The position of the cursor on the input line.
2100
2101
2101 Returns
2102 Returns
2102 -------
2103 -------
2103 text : string
2104 text : string
2104 The actual text that was completed.
2105 The actual text that was completed.
2105
2106
2106 matches : list
2107 matches : list
2107 A sorted list with all possible completions.
2108 A sorted list with all possible completions.
2108
2109
2109 The optional arguments allow the completion to take more context into
2110 The optional arguments allow the completion to take more context into
2110 account, and are part of the low-level completion API.
2111 account, and are part of the low-level completion API.
2111
2112
2112 This is a wrapper around the completion mechanism, similar to what
2113 This is a wrapper around the completion mechanism, similar to what
2113 readline does at the command line when the TAB key is hit. By
2114 readline does at the command line when the TAB key is hit. By
2114 exposing it as a method, it can be used by other non-readline
2115 exposing it as a method, it can be used by other non-readline
2115 environments (such as GUIs) for text completion.
2116 environments (such as GUIs) for text completion.
2116
2117
2117 Simple usage example:
2118 Simple usage example:
2118
2119
2119 In [1]: x = 'hello'
2120 In [1]: x = 'hello'
2120
2121
2121 In [2]: _ip.complete('x.l')
2122 In [2]: _ip.complete('x.l')
2122 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2123 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2123 """
2124 """
2124
2125
2125 # Inject names into __builtin__ so we can complete on the added names.
2126 # Inject names into __builtin__ so we can complete on the added names.
2126 with self.builtin_trap:
2127 with self.builtin_trap:
2127 return self.Completer.complete(text, line, cursor_pos)
2128 return self.Completer.complete(text, line, cursor_pos)
2128
2129
2129 def set_custom_completer(self, completer, pos=0):
2130 def set_custom_completer(self, completer, pos=0):
2130 """Adds a new custom completer function.
2131 """Adds a new custom completer function.
2131
2132
2132 The position argument (defaults to 0) is the index in the completers
2133 The position argument (defaults to 0) is the index in the completers
2133 list where you want the completer to be inserted."""
2134 list where you want the completer to be inserted."""
2134
2135
2135 newcomp = types.MethodType(completer,self.Completer)
2136 newcomp = types.MethodType(completer,self.Completer)
2136 self.Completer.matchers.insert(pos,newcomp)
2137 self.Completer.matchers.insert(pos,newcomp)
2137
2138
2138 def set_readline_completer(self):
2139 def set_readline_completer(self):
2139 """Reset readline's completer to be our own."""
2140 """Reset readline's completer to be our own."""
2140 self.readline.set_completer(self.Completer.rlcomplete)
2141 self.readline.set_completer(self.Completer.rlcomplete)
2141
2142
2142 def set_completer_frame(self, frame=None):
2143 def set_completer_frame(self, frame=None):
2143 """Set the frame of the completer."""
2144 """Set the frame of the completer."""
2144 if frame:
2145 if frame:
2145 self.Completer.namespace = frame.f_locals
2146 self.Completer.namespace = frame.f_locals
2146 self.Completer.global_namespace = frame.f_globals
2147 self.Completer.global_namespace = frame.f_globals
2147 else:
2148 else:
2148 self.Completer.namespace = self.user_ns
2149 self.Completer.namespace = self.user_ns
2149 self.Completer.global_namespace = self.user_global_ns
2150 self.Completer.global_namespace = self.user_global_ns
2150
2151
2151 #-------------------------------------------------------------------------
2152 #-------------------------------------------------------------------------
2152 # Things related to magics
2153 # Things related to magics
2153 #-------------------------------------------------------------------------
2154 #-------------------------------------------------------------------------
2154
2155
2155 def init_magics(self):
2156 def init_magics(self):
2156 from IPython.core import magics as m
2157 from IPython.core import magics as m
2157 self.magics_manager = magic.MagicsManager(shell=self,
2158 self.magics_manager = magic.MagicsManager(shell=self,
2158 parent=self,
2159 parent=self,
2159 user_magics=m.UserMagics(self))
2160 user_magics=m.UserMagics(self))
2160 self.configurables.append(self.magics_manager)
2161 self.configurables.append(self.magics_manager)
2161
2162
2162 # Expose as public API from the magics manager
2163 # Expose as public API from the magics manager
2163 self.register_magics = self.magics_manager.register
2164 self.register_magics = self.magics_manager.register
2164 self.define_magic = self.magics_manager.define_magic
2165 self.define_magic = self.magics_manager.define_magic
2165
2166
2166 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2167 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2167 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2168 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2168 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2169 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2169 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2170 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2170 )
2171 )
2171
2172
2172 # Register Magic Aliases
2173 # Register Magic Aliases
2173 mman = self.magics_manager
2174 mman = self.magics_manager
2174 # FIXME: magic aliases should be defined by the Magics classes
2175 # FIXME: magic aliases should be defined by the Magics classes
2175 # or in MagicsManager, not here
2176 # or in MagicsManager, not here
2176 mman.register_alias('ed', 'edit')
2177 mman.register_alias('ed', 'edit')
2177 mman.register_alias('hist', 'history')
2178 mman.register_alias('hist', 'history')
2178 mman.register_alias('rep', 'recall')
2179 mman.register_alias('rep', 'recall')
2179 mman.register_alias('SVG', 'svg', 'cell')
2180 mman.register_alias('SVG', 'svg', 'cell')
2180 mman.register_alias('HTML', 'html', 'cell')
2181 mman.register_alias('HTML', 'html', 'cell')
2181 mman.register_alias('file', 'writefile', 'cell')
2182 mman.register_alias('file', 'writefile', 'cell')
2182
2183
2183 # FIXME: Move the color initialization to the DisplayHook, which
2184 # FIXME: Move the color initialization to the DisplayHook, which
2184 # should be split into a prompt manager and displayhook. We probably
2185 # should be split into a prompt manager and displayhook. We probably
2185 # even need a centralize colors management object.
2186 # even need a centralize colors management object.
2186 self.magic('colors %s' % self.colors)
2187 self.magic('colors %s' % self.colors)
2187
2188
2188 # Defined here so that it's included in the documentation
2189 # Defined here so that it's included in the documentation
2189 @functools.wraps(magic.MagicsManager.register_function)
2190 @functools.wraps(magic.MagicsManager.register_function)
2190 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2191 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2191 self.magics_manager.register_function(func,
2192 self.magics_manager.register_function(func,
2192 magic_kind=magic_kind, magic_name=magic_name)
2193 magic_kind=magic_kind, magic_name=magic_name)
2193
2194
2194 def run_line_magic(self, magic_name, line):
2195 def run_line_magic(self, magic_name, line):
2195 """Execute the given line magic.
2196 """Execute the given line magic.
2196
2197
2197 Parameters
2198 Parameters
2198 ----------
2199 ----------
2199 magic_name : str
2200 magic_name : str
2200 Name of the desired magic function, without '%' prefix.
2201 Name of the desired magic function, without '%' prefix.
2201
2202
2202 line : str
2203 line : str
2203 The rest of the input line as a single string.
2204 The rest of the input line as a single string.
2204 """
2205 """
2205 fn = self.find_line_magic(magic_name)
2206 fn = self.find_line_magic(magic_name)
2206 if fn is None:
2207 if fn is None:
2207 cm = self.find_cell_magic(magic_name)
2208 cm = self.find_cell_magic(magic_name)
2208 etpl = "Line magic function `%%%s` not found%s."
2209 etpl = "Line magic function `%%%s` not found%s."
2209 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2210 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2210 'did you mean that instead?)' % magic_name )
2211 'did you mean that instead?)' % magic_name )
2211 error(etpl % (magic_name, extra))
2212 error(etpl % (magic_name, extra))
2212 else:
2213 else:
2213 # Note: this is the distance in the stack to the user's frame.
2214 # Note: this is the distance in the stack to the user's frame.
2214 # This will need to be updated if the internal calling logic gets
2215 # This will need to be updated if the internal calling logic gets
2215 # refactored, or else we'll be expanding the wrong variables.
2216 # refactored, or else we'll be expanding the wrong variables.
2216 stack_depth = 2
2217 stack_depth = 2
2217 magic_arg_s = self.var_expand(line, stack_depth)
2218 magic_arg_s = self.var_expand(line, stack_depth)
2218 # Put magic args in a list so we can call with f(*a) syntax
2219 # Put magic args in a list so we can call with f(*a) syntax
2219 args = [magic_arg_s]
2220 args = [magic_arg_s]
2220 kwargs = {}
2221 kwargs = {}
2221 # Grab local namespace if we need it:
2222 # Grab local namespace if we need it:
2222 if getattr(fn, "needs_local_scope", False):
2223 if getattr(fn, "needs_local_scope", False):
2223 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2224 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2224 with self.builtin_trap:
2225 with self.builtin_trap:
2225 result = fn(*args,**kwargs)
2226 result = fn(*args,**kwargs)
2226 return result
2227 return result
2227
2228
2228 def run_cell_magic(self, magic_name, line, cell):
2229 def run_cell_magic(self, magic_name, line, cell):
2229 """Execute the given cell magic.
2230 """Execute the given cell magic.
2230
2231
2231 Parameters
2232 Parameters
2232 ----------
2233 ----------
2233 magic_name : str
2234 magic_name : str
2234 Name of the desired magic function, without '%' prefix.
2235 Name of the desired magic function, without '%' prefix.
2235
2236
2236 line : str
2237 line : str
2237 The rest of the first input line as a single string.
2238 The rest of the first input line as a single string.
2238
2239
2239 cell : str
2240 cell : str
2240 The body of the cell as a (possibly multiline) string.
2241 The body of the cell as a (possibly multiline) string.
2241 """
2242 """
2242 fn = self.find_cell_magic(magic_name)
2243 fn = self.find_cell_magic(magic_name)
2243 if fn is None:
2244 if fn is None:
2244 lm = self.find_line_magic(magic_name)
2245 lm = self.find_line_magic(magic_name)
2245 etpl = "Cell magic `%%{0}` not found{1}."
2246 etpl = "Cell magic `%%{0}` not found{1}."
2246 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2247 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2247 'did you mean that instead?)'.format(magic_name))
2248 'did you mean that instead?)'.format(magic_name))
2248 error(etpl.format(magic_name, extra))
2249 error(etpl.format(magic_name, extra))
2249 elif cell == '':
2250 elif cell == '':
2250 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2251 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2251 if self.find_line_magic(magic_name) is not None:
2252 if self.find_line_magic(magic_name) is not None:
2252 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2253 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2253 raise UsageError(message)
2254 raise UsageError(message)
2254 else:
2255 else:
2255 # Note: this is the distance in the stack to the user's frame.
2256 # Note: this is the distance in the stack to the user's frame.
2256 # This will need to be updated if the internal calling logic gets
2257 # This will need to be updated if the internal calling logic gets
2257 # refactored, or else we'll be expanding the wrong variables.
2258 # refactored, or else we'll be expanding the wrong variables.
2258 stack_depth = 2
2259 stack_depth = 2
2259 magic_arg_s = self.var_expand(line, stack_depth)
2260 magic_arg_s = self.var_expand(line, stack_depth)
2260 with self.builtin_trap:
2261 with self.builtin_trap:
2261 result = fn(magic_arg_s, cell)
2262 result = fn(magic_arg_s, cell)
2262 return result
2263 return result
2263
2264
2264 def find_line_magic(self, magic_name):
2265 def find_line_magic(self, magic_name):
2265 """Find and return a line magic by name.
2266 """Find and return a line magic by name.
2266
2267
2267 Returns None if the magic isn't found."""
2268 Returns None if the magic isn't found."""
2268 return self.magics_manager.magics['line'].get(magic_name)
2269 return self.magics_manager.magics['line'].get(magic_name)
2269
2270
2270 def find_cell_magic(self, magic_name):
2271 def find_cell_magic(self, magic_name):
2271 """Find and return a cell magic by name.
2272 """Find and return a cell magic by name.
2272
2273
2273 Returns None if the magic isn't found."""
2274 Returns None if the magic isn't found."""
2274 return self.magics_manager.magics['cell'].get(magic_name)
2275 return self.magics_manager.magics['cell'].get(magic_name)
2275
2276
2276 def find_magic(self, magic_name, magic_kind='line'):
2277 def find_magic(self, magic_name, magic_kind='line'):
2277 """Find and return a magic of the given type by name.
2278 """Find and return a magic of the given type by name.
2278
2279
2279 Returns None if the magic isn't found."""
2280 Returns None if the magic isn't found."""
2280 return self.magics_manager.magics[magic_kind].get(magic_name)
2281 return self.magics_manager.magics[magic_kind].get(magic_name)
2281
2282
2282 def magic(self, arg_s):
2283 def magic(self, arg_s):
2283 """DEPRECATED. Use run_line_magic() instead.
2284 """DEPRECATED. Use run_line_magic() instead.
2284
2285
2285 Call a magic function by name.
2286 Call a magic function by name.
2286
2287
2287 Input: a string containing the name of the magic function to call and
2288 Input: a string containing the name of the magic function to call and
2288 any additional arguments to be passed to the magic.
2289 any additional arguments to be passed to the magic.
2289
2290
2290 magic('name -opt foo bar') is equivalent to typing at the ipython
2291 magic('name -opt foo bar') is equivalent to typing at the ipython
2291 prompt:
2292 prompt:
2292
2293
2293 In[1]: %name -opt foo bar
2294 In[1]: %name -opt foo bar
2294
2295
2295 To call a magic without arguments, simply use magic('name').
2296 To call a magic without arguments, simply use magic('name').
2296
2297
2297 This provides a proper Python function to call IPython's magics in any
2298 This provides a proper Python function to call IPython's magics in any
2298 valid Python code you can type at the interpreter, including loops and
2299 valid Python code you can type at the interpreter, including loops and
2299 compound statements.
2300 compound statements.
2300 """
2301 """
2301 # TODO: should we issue a loud deprecation warning here?
2302 # TODO: should we issue a loud deprecation warning here?
2302 magic_name, _, magic_arg_s = arg_s.partition(' ')
2303 magic_name, _, magic_arg_s = arg_s.partition(' ')
2303 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2304 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2304 return self.run_line_magic(magic_name, magic_arg_s)
2305 return self.run_line_magic(magic_name, magic_arg_s)
2305
2306
2306 #-------------------------------------------------------------------------
2307 #-------------------------------------------------------------------------
2307 # Things related to macros
2308 # Things related to macros
2308 #-------------------------------------------------------------------------
2309 #-------------------------------------------------------------------------
2309
2310
2310 def define_macro(self, name, themacro):
2311 def define_macro(self, name, themacro):
2311 """Define a new macro
2312 """Define a new macro
2312
2313
2313 Parameters
2314 Parameters
2314 ----------
2315 ----------
2315 name : str
2316 name : str
2316 The name of the macro.
2317 The name of the macro.
2317 themacro : str or Macro
2318 themacro : str or Macro
2318 The action to do upon invoking the macro. If a string, a new
2319 The action to do upon invoking the macro. If a string, a new
2319 Macro object is created by passing the string to it.
2320 Macro object is created by passing the string to it.
2320 """
2321 """
2321
2322
2322 from IPython.core import macro
2323 from IPython.core import macro
2323
2324
2324 if isinstance(themacro, string_types):
2325 if isinstance(themacro, string_types):
2325 themacro = macro.Macro(themacro)
2326 themacro = macro.Macro(themacro)
2326 if not isinstance(themacro, macro.Macro):
2327 if not isinstance(themacro, macro.Macro):
2327 raise ValueError('A macro must be a string or a Macro instance.')
2328 raise ValueError('A macro must be a string or a Macro instance.')
2328 self.user_ns[name] = themacro
2329 self.user_ns[name] = themacro
2329
2330
2330 #-------------------------------------------------------------------------
2331 #-------------------------------------------------------------------------
2331 # Things related to the running of system commands
2332 # Things related to the running of system commands
2332 #-------------------------------------------------------------------------
2333 #-------------------------------------------------------------------------
2333
2334
2334 def system_piped(self, cmd):
2335 def system_piped(self, cmd):
2335 """Call the given cmd in a subprocess, piping stdout/err
2336 """Call the given cmd in a subprocess, piping stdout/err
2336
2337
2337 Parameters
2338 Parameters
2338 ----------
2339 ----------
2339 cmd : str
2340 cmd : str
2340 Command to execute (can not end in '&', as background processes are
2341 Command to execute (can not end in '&', as background processes are
2341 not supported. Should not be a command that expects input
2342 not supported. Should not be a command that expects input
2342 other than simple text.
2343 other than simple text.
2343 """
2344 """
2344 if cmd.rstrip().endswith('&'):
2345 if cmd.rstrip().endswith('&'):
2345 # this is *far* from a rigorous test
2346 # this is *far* from a rigorous test
2346 # We do not support backgrounding processes because we either use
2347 # We do not support backgrounding processes because we either use
2347 # pexpect or pipes to read from. Users can always just call
2348 # pexpect or pipes to read from. Users can always just call
2348 # os.system() or use ip.system=ip.system_raw
2349 # os.system() or use ip.system=ip.system_raw
2349 # if they really want a background process.
2350 # if they really want a background process.
2350 raise OSError("Background processes not supported.")
2351 raise OSError("Background processes not supported.")
2351
2352
2352 # we explicitly do NOT return the subprocess status code, because
2353 # we explicitly do NOT return the subprocess status code, because
2353 # a non-None value would trigger :func:`sys.displayhook` calls.
2354 # a non-None value would trigger :func:`sys.displayhook` calls.
2354 # Instead, we store the exit_code in user_ns.
2355 # Instead, we store the exit_code in user_ns.
2355 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2356 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2356
2357
2357 def system_raw(self, cmd):
2358 def system_raw(self, cmd):
2358 """Call the given cmd in a subprocess using os.system on Windows or
2359 """Call the given cmd in a subprocess using os.system on Windows or
2359 subprocess.call using the system shell on other platforms.
2360 subprocess.call using the system shell on other platforms.
2360
2361
2361 Parameters
2362 Parameters
2362 ----------
2363 ----------
2363 cmd : str
2364 cmd : str
2364 Command to execute.
2365 Command to execute.
2365 """
2366 """
2366 cmd = self.var_expand(cmd, depth=1)
2367 cmd = self.var_expand(cmd, depth=1)
2367 # protect os.system from UNC paths on Windows, which it can't handle:
2368 # protect os.system from UNC paths on Windows, which it can't handle:
2368 if sys.platform == 'win32':
2369 if sys.platform == 'win32':
2369 from IPython.utils._process_win32 import AvoidUNCPath
2370 from IPython.utils._process_win32 import AvoidUNCPath
2370 with AvoidUNCPath() as path:
2371 with AvoidUNCPath() as path:
2371 if path is not None:
2372 if path is not None:
2372 cmd = '"pushd %s &&"%s' % (path, cmd)
2373 cmd = '"pushd %s &&"%s' % (path, cmd)
2373 cmd = py3compat.unicode_to_str(cmd)
2374 cmd = py3compat.unicode_to_str(cmd)
2374 try:
2375 try:
2375 ec = os.system(cmd)
2376 ec = os.system(cmd)
2376 except KeyboardInterrupt:
2377 except KeyboardInterrupt:
2377 self.write_err('\n' + self.get_exception_only())
2378 self.write_err('\n' + self.get_exception_only())
2378 ec = -2
2379 ec = -2
2379 else:
2380 else:
2380 cmd = py3compat.unicode_to_str(cmd)
2381 cmd = py3compat.unicode_to_str(cmd)
2381 # For posix the result of the subprocess.call() below is an exit
2382 # For posix the result of the subprocess.call() below is an exit
2382 # code, which by convention is zero for success, positive for
2383 # code, which by convention is zero for success, positive for
2383 # program failure. Exit codes above 128 are reserved for signals,
2384 # program failure. Exit codes above 128 are reserved for signals,
2384 # and the formula for converting a signal to an exit code is usually
2385 # and the formula for converting a signal to an exit code is usually
2385 # signal_number+128. To more easily differentiate between exit
2386 # signal_number+128. To more easily differentiate between exit
2386 # codes and signals, ipython uses negative numbers. For instance
2387 # codes and signals, ipython uses negative numbers. For instance
2387 # since control-c is signal 2 but exit code 130, ipython's
2388 # since control-c is signal 2 but exit code 130, ipython's
2388 # _exit_code variable will read -2. Note that some shells like
2389 # _exit_code variable will read -2. Note that some shells like
2389 # csh and fish don't follow sh/bash conventions for exit codes.
2390 # csh and fish don't follow sh/bash conventions for exit codes.
2390 executable = os.environ.get('SHELL', None)
2391 executable = os.environ.get('SHELL', None)
2391 try:
2392 try:
2392 # Use env shell instead of default /bin/sh
2393 # Use env shell instead of default /bin/sh
2393 ec = subprocess.call(cmd, shell=True, executable=executable)
2394 ec = subprocess.call(cmd, shell=True, executable=executable)
2394 except KeyboardInterrupt:
2395 except KeyboardInterrupt:
2395 # intercept control-C; a long traceback is not useful here
2396 # intercept control-C; a long traceback is not useful here
2396 self.write_err('\n' + self.get_exception_only())
2397 self.write_err('\n' + self.get_exception_only())
2397 ec = 130
2398 ec = 130
2398 if ec > 128:
2399 if ec > 128:
2399 ec = -(ec - 128)
2400 ec = -(ec - 128)
2400
2401
2401 # We explicitly do NOT return the subprocess status code, because
2402 # We explicitly do NOT return the subprocess status code, because
2402 # a non-None value would trigger :func:`sys.displayhook` calls.
2403 # a non-None value would trigger :func:`sys.displayhook` calls.
2403 # Instead, we store the exit_code in user_ns. Note the semantics
2404 # Instead, we store the exit_code in user_ns. Note the semantics
2404 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2405 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2405 # but raising SystemExit(_exit_code) will give status 254!
2406 # but raising SystemExit(_exit_code) will give status 254!
2406 self.user_ns['_exit_code'] = ec
2407 self.user_ns['_exit_code'] = ec
2407
2408
2408 # use piped system by default, because it is better behaved
2409 # use piped system by default, because it is better behaved
2409 system = system_piped
2410 system = system_piped
2410
2411
2411 def getoutput(self, cmd, split=True, depth=0):
2412 def getoutput(self, cmd, split=True, depth=0):
2412 """Get output (possibly including stderr) from a subprocess.
2413 """Get output (possibly including stderr) from a subprocess.
2413
2414
2414 Parameters
2415 Parameters
2415 ----------
2416 ----------
2416 cmd : str
2417 cmd : str
2417 Command to execute (can not end in '&', as background processes are
2418 Command to execute (can not end in '&', as background processes are
2418 not supported.
2419 not supported.
2419 split : bool, optional
2420 split : bool, optional
2420 If True, split the output into an IPython SList. Otherwise, an
2421 If True, split the output into an IPython SList. Otherwise, an
2421 IPython LSString is returned. These are objects similar to normal
2422 IPython LSString is returned. These are objects similar to normal
2422 lists and strings, with a few convenience attributes for easier
2423 lists and strings, with a few convenience attributes for easier
2423 manipulation of line-based output. You can use '?' on them for
2424 manipulation of line-based output. You can use '?' on them for
2424 details.
2425 details.
2425 depth : int, optional
2426 depth : int, optional
2426 How many frames above the caller are the local variables which should
2427 How many frames above the caller are the local variables which should
2427 be expanded in the command string? The default (0) assumes that the
2428 be expanded in the command string? The default (0) assumes that the
2428 expansion variables are in the stack frame calling this function.
2429 expansion variables are in the stack frame calling this function.
2429 """
2430 """
2430 if cmd.rstrip().endswith('&'):
2431 if cmd.rstrip().endswith('&'):
2431 # this is *far* from a rigorous test
2432 # this is *far* from a rigorous test
2432 raise OSError("Background processes not supported.")
2433 raise OSError("Background processes not supported.")
2433 out = getoutput(self.var_expand(cmd, depth=depth+1))
2434 out = getoutput(self.var_expand(cmd, depth=depth+1))
2434 if split:
2435 if split:
2435 out = SList(out.splitlines())
2436 out = SList(out.splitlines())
2436 else:
2437 else:
2437 out = LSString(out)
2438 out = LSString(out)
2438 return out
2439 return out
2439
2440
2440 #-------------------------------------------------------------------------
2441 #-------------------------------------------------------------------------
2441 # Things related to aliases
2442 # Things related to aliases
2442 #-------------------------------------------------------------------------
2443 #-------------------------------------------------------------------------
2443
2444
2444 def init_alias(self):
2445 def init_alias(self):
2445 self.alias_manager = AliasManager(shell=self, parent=self)
2446 self.alias_manager = AliasManager(shell=self, parent=self)
2446 self.configurables.append(self.alias_manager)
2447 self.configurables.append(self.alias_manager)
2447
2448
2448 #-------------------------------------------------------------------------
2449 #-------------------------------------------------------------------------
2449 # Things related to extensions
2450 # Things related to extensions
2450 #-------------------------------------------------------------------------
2451 #-------------------------------------------------------------------------
2451
2452
2452 def init_extension_manager(self):
2453 def init_extension_manager(self):
2453 self.extension_manager = ExtensionManager(shell=self, parent=self)
2454 self.extension_manager = ExtensionManager(shell=self, parent=self)
2454 self.configurables.append(self.extension_manager)
2455 self.configurables.append(self.extension_manager)
2455
2456
2456 #-------------------------------------------------------------------------
2457 #-------------------------------------------------------------------------
2457 # Things related to payloads
2458 # Things related to payloads
2458 #-------------------------------------------------------------------------
2459 #-------------------------------------------------------------------------
2459
2460
2460 def init_payload(self):
2461 def init_payload(self):
2461 self.payload_manager = PayloadManager(parent=self)
2462 self.payload_manager = PayloadManager(parent=self)
2462 self.configurables.append(self.payload_manager)
2463 self.configurables.append(self.payload_manager)
2463
2464
2464 #-------------------------------------------------------------------------
2465 #-------------------------------------------------------------------------
2465 # Things related to the prefilter
2466 # Things related to the prefilter
2466 #-------------------------------------------------------------------------
2467 #-------------------------------------------------------------------------
2467
2468
2468 def init_prefilter(self):
2469 def init_prefilter(self):
2469 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2470 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2470 self.configurables.append(self.prefilter_manager)
2471 self.configurables.append(self.prefilter_manager)
2471 # Ultimately this will be refactored in the new interpreter code, but
2472 # Ultimately this will be refactored in the new interpreter code, but
2472 # for now, we should expose the main prefilter method (there's legacy
2473 # for now, we should expose the main prefilter method (there's legacy
2473 # code out there that may rely on this).
2474 # code out there that may rely on this).
2474 self.prefilter = self.prefilter_manager.prefilter_lines
2475 self.prefilter = self.prefilter_manager.prefilter_lines
2475
2476
2476 def auto_rewrite_input(self, cmd):
2477 def auto_rewrite_input(self, cmd):
2477 """Print to the screen the rewritten form of the user's command.
2478 """Print to the screen the rewritten form of the user's command.
2478
2479
2479 This shows visual feedback by rewriting input lines that cause
2480 This shows visual feedback by rewriting input lines that cause
2480 automatic calling to kick in, like::
2481 automatic calling to kick in, like::
2481
2482
2482 /f x
2483 /f x
2483
2484
2484 into::
2485 into::
2485
2486
2486 ------> f(x)
2487 ------> f(x)
2487
2488
2488 after the user's input prompt. This helps the user understand that the
2489 after the user's input prompt. This helps the user understand that the
2489 input line was transformed automatically by IPython.
2490 input line was transformed automatically by IPython.
2490 """
2491 """
2491 if not self.show_rewritten_input:
2492 if not self.show_rewritten_input:
2492 return
2493 return
2493
2494
2494 rw = self.prompt_manager.render('rewrite') + cmd
2495 rw = self.prompt_manager.render('rewrite') + cmd
2495
2496
2496 try:
2497 try:
2497 # plain ascii works better w/ pyreadline, on some machines, so
2498 # plain ascii works better w/ pyreadline, on some machines, so
2498 # we use it and only print uncolored rewrite if we have unicode
2499 # we use it and only print uncolored rewrite if we have unicode
2499 rw = str(rw)
2500 rw = str(rw)
2500 print(rw, file=io.stdout)
2501 print(rw, file=io.stdout)
2501 except UnicodeEncodeError:
2502 except UnicodeEncodeError:
2502 print("------> " + cmd)
2503 print("------> " + cmd)
2503
2504
2504 #-------------------------------------------------------------------------
2505 #-------------------------------------------------------------------------
2505 # Things related to extracting values/expressions from kernel and user_ns
2506 # Things related to extracting values/expressions from kernel and user_ns
2506 #-------------------------------------------------------------------------
2507 #-------------------------------------------------------------------------
2507
2508
2508 def _user_obj_error(self):
2509 def _user_obj_error(self):
2509 """return simple exception dict
2510 """return simple exception dict
2510
2511
2511 for use in user_expressions
2512 for use in user_expressions
2512 """
2513 """
2513
2514
2514 etype, evalue, tb = self._get_exc_info()
2515 etype, evalue, tb = self._get_exc_info()
2515 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2516 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2516
2517
2517 exc_info = {
2518 exc_info = {
2518 u'status' : 'error',
2519 u'status' : 'error',
2519 u'traceback' : stb,
2520 u'traceback' : stb,
2520 u'ename' : unicode_type(etype.__name__),
2521 u'ename' : unicode_type(etype.__name__),
2521 u'evalue' : py3compat.safe_unicode(evalue),
2522 u'evalue' : py3compat.safe_unicode(evalue),
2522 }
2523 }
2523
2524
2524 return exc_info
2525 return exc_info
2525
2526
2526 def _format_user_obj(self, obj):
2527 def _format_user_obj(self, obj):
2527 """format a user object to display dict
2528 """format a user object to display dict
2528
2529
2529 for use in user_expressions
2530 for use in user_expressions
2530 """
2531 """
2531
2532
2532 data, md = self.display_formatter.format(obj)
2533 data, md = self.display_formatter.format(obj)
2533 value = {
2534 value = {
2534 'status' : 'ok',
2535 'status' : 'ok',
2535 'data' : data,
2536 'data' : data,
2536 'metadata' : md,
2537 'metadata' : md,
2537 }
2538 }
2538 return value
2539 return value
2539
2540
2540 def user_expressions(self, expressions):
2541 def user_expressions(self, expressions):
2541 """Evaluate a dict of expressions in the user's namespace.
2542 """Evaluate a dict of expressions in the user's namespace.
2542
2543
2543 Parameters
2544 Parameters
2544 ----------
2545 ----------
2545 expressions : dict
2546 expressions : dict
2546 A dict with string keys and string values. The expression values
2547 A dict with string keys and string values. The expression values
2547 should be valid Python expressions, each of which will be evaluated
2548 should be valid Python expressions, each of which will be evaluated
2548 in the user namespace.
2549 in the user namespace.
2549
2550
2550 Returns
2551 Returns
2551 -------
2552 -------
2552 A dict, keyed like the input expressions dict, with the rich mime-typed
2553 A dict, keyed like the input expressions dict, with the rich mime-typed
2553 display_data of each value.
2554 display_data of each value.
2554 """
2555 """
2555 out = {}
2556 out = {}
2556 user_ns = self.user_ns
2557 user_ns = self.user_ns
2557 global_ns = self.user_global_ns
2558 global_ns = self.user_global_ns
2558
2559
2559 for key, expr in iteritems(expressions):
2560 for key, expr in iteritems(expressions):
2560 try:
2561 try:
2561 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2562 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2562 except:
2563 except:
2563 value = self._user_obj_error()
2564 value = self._user_obj_error()
2564 out[key] = value
2565 out[key] = value
2565 return out
2566 return out
2566
2567
2567 #-------------------------------------------------------------------------
2568 #-------------------------------------------------------------------------
2568 # Things related to the running of code
2569 # Things related to the running of code
2569 #-------------------------------------------------------------------------
2570 #-------------------------------------------------------------------------
2570
2571
2571 def ex(self, cmd):
2572 def ex(self, cmd):
2572 """Execute a normal python statement in user namespace."""
2573 """Execute a normal python statement in user namespace."""
2573 with self.builtin_trap:
2574 with self.builtin_trap:
2574 exec(cmd, self.user_global_ns, self.user_ns)
2575 exec(cmd, self.user_global_ns, self.user_ns)
2575
2576
2576 def ev(self, expr):
2577 def ev(self, expr):
2577 """Evaluate python expression expr in user namespace.
2578 """Evaluate python expression expr in user namespace.
2578
2579
2579 Returns the result of evaluation
2580 Returns the result of evaluation
2580 """
2581 """
2581 with self.builtin_trap:
2582 with self.builtin_trap:
2582 return eval(expr, self.user_global_ns, self.user_ns)
2583 return eval(expr, self.user_global_ns, self.user_ns)
2583
2584
2584 def safe_execfile(self, fname, *where, **kw):
2585 def safe_execfile(self, fname, *where, **kw):
2585 """A safe version of the builtin execfile().
2586 """A safe version of the builtin execfile().
2586
2587
2587 This version will never throw an exception, but instead print
2588 This version will never throw an exception, but instead print
2588 helpful error messages to the screen. This only works on pure
2589 helpful error messages to the screen. This only works on pure
2589 Python files with the .py extension.
2590 Python files with the .py extension.
2590
2591
2591 Parameters
2592 Parameters
2592 ----------
2593 ----------
2593 fname : string
2594 fname : string
2594 The name of the file to be executed.
2595 The name of the file to be executed.
2595 where : tuple
2596 where : tuple
2596 One or two namespaces, passed to execfile() as (globals,locals).
2597 One or two namespaces, passed to execfile() as (globals,locals).
2597 If only one is given, it is passed as both.
2598 If only one is given, it is passed as both.
2598 exit_ignore : bool (False)
2599 exit_ignore : bool (False)
2599 If True, then silence SystemExit for non-zero status (it is always
2600 If True, then silence SystemExit for non-zero status (it is always
2600 silenced for zero status, as it is so common).
2601 silenced for zero status, as it is so common).
2601 raise_exceptions : bool (False)
2602 raise_exceptions : bool (False)
2602 If True raise exceptions everywhere. Meant for testing.
2603 If True raise exceptions everywhere. Meant for testing.
2603 shell_futures : bool (False)
2604 shell_futures : bool (False)
2604 If True, the code will share future statements with the interactive
2605 If True, the code will share future statements with the interactive
2605 shell. It will both be affected by previous __future__ imports, and
2606 shell. It will both be affected by previous __future__ imports, and
2606 any __future__ imports in the code will affect the shell. If False,
2607 any __future__ imports in the code will affect the shell. If False,
2607 __future__ imports are not shared in either direction.
2608 __future__ imports are not shared in either direction.
2608
2609
2609 """
2610 """
2610 kw.setdefault('exit_ignore', False)
2611 kw.setdefault('exit_ignore', False)
2611 kw.setdefault('raise_exceptions', False)
2612 kw.setdefault('raise_exceptions', False)
2612 kw.setdefault('shell_futures', False)
2613 kw.setdefault('shell_futures', False)
2613
2614
2614 fname = os.path.abspath(os.path.expanduser(fname))
2615 fname = os.path.abspath(os.path.expanduser(fname))
2615
2616
2616 # Make sure we can open the file
2617 # Make sure we can open the file
2617 try:
2618 try:
2618 with open(fname) as thefile:
2619 with open(fname) as thefile:
2619 pass
2620 pass
2620 except:
2621 except:
2621 warn('Could not open file <%s> for safe execution.' % fname)
2622 warn('Could not open file <%s> for safe execution.' % fname)
2622 return
2623 return
2623
2624
2624 # Find things also in current directory. This is needed to mimic the
2625 # Find things also in current directory. This is needed to mimic the
2625 # behavior of running a script from the system command line, where
2626 # behavior of running a script from the system command line, where
2626 # Python inserts the script's directory into sys.path
2627 # Python inserts the script's directory into sys.path
2627 dname = os.path.dirname(fname)
2628 dname = os.path.dirname(fname)
2628
2629
2629 with prepended_to_syspath(dname):
2630 with prepended_to_syspath(dname):
2630 try:
2631 try:
2631 glob, loc = (where + (None, ))[:2]
2632 glob, loc = (where + (None, ))[:2]
2632 py3compat.execfile(
2633 py3compat.execfile(
2633 fname, glob, loc,
2634 fname, glob, loc,
2634 self.compile if kw['shell_futures'] else None)
2635 self.compile if kw['shell_futures'] else None)
2635 except SystemExit as status:
2636 except SystemExit as status:
2636 # If the call was made with 0 or None exit status (sys.exit(0)
2637 # If the call was made with 0 or None exit status (sys.exit(0)
2637 # or sys.exit() ), don't bother showing a traceback, as both of
2638 # or sys.exit() ), don't bother showing a traceback, as both of
2638 # these are considered normal by the OS:
2639 # these are considered normal by the OS:
2639 # > python -c'import sys;sys.exit(0)'; echo $?
2640 # > python -c'import sys;sys.exit(0)'; echo $?
2640 # 0
2641 # 0
2641 # > python -c'import sys;sys.exit()'; echo $?
2642 # > python -c'import sys;sys.exit()'; echo $?
2642 # 0
2643 # 0
2643 # For other exit status, we show the exception unless
2644 # For other exit status, we show the exception unless
2644 # explicitly silenced, but only in short form.
2645 # explicitly silenced, but only in short form.
2645 if kw['raise_exceptions']:
2646 if kw['raise_exceptions']:
2646 raise
2647 raise
2647 if status.code and not kw['exit_ignore']:
2648 if status.code and not kw['exit_ignore']:
2648 self.showtraceback(exception_only=True)
2649 self.showtraceback(exception_only=True)
2649 except:
2650 except:
2650 if kw['raise_exceptions']:
2651 if kw['raise_exceptions']:
2651 raise
2652 raise
2652 # tb offset is 2 because we wrap execfile
2653 # tb offset is 2 because we wrap execfile
2653 self.showtraceback(tb_offset=2)
2654 self.showtraceback(tb_offset=2)
2654
2655
2655 def safe_execfile_ipy(self, fname, shell_futures=False):
2656 def safe_execfile_ipy(self, fname, shell_futures=False):
2656 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2657 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2657
2658
2658 Parameters
2659 Parameters
2659 ----------
2660 ----------
2660 fname : str
2661 fname : str
2661 The name of the file to execute. The filename must have a
2662 The name of the file to execute. The filename must have a
2662 .ipy or .ipynb extension.
2663 .ipy or .ipynb extension.
2663 shell_futures : bool (False)
2664 shell_futures : bool (False)
2664 If True, the code will share future statements with the interactive
2665 If True, the code will share future statements with the interactive
2665 shell. It will both be affected by previous __future__ imports, and
2666 shell. It will both be affected by previous __future__ imports, and
2666 any __future__ imports in the code will affect the shell. If False,
2667 any __future__ imports in the code will affect the shell. If False,
2667 __future__ imports are not shared in either direction.
2668 __future__ imports are not shared in either direction.
2668 """
2669 """
2669 fname = os.path.abspath(os.path.expanduser(fname))
2670 fname = os.path.abspath(os.path.expanduser(fname))
2670
2671
2671 # Make sure we can open the file
2672 # Make sure we can open the file
2672 try:
2673 try:
2673 with open(fname) as thefile:
2674 with open(fname) as thefile:
2674 pass
2675 pass
2675 except:
2676 except:
2676 warn('Could not open file <%s> for safe execution.' % fname)
2677 warn('Could not open file <%s> for safe execution.' % fname)
2677 return
2678 return
2678
2679
2679 # Find things also in current directory. This is needed to mimic the
2680 # Find things also in current directory. This is needed to mimic the
2680 # behavior of running a script from the system command line, where
2681 # behavior of running a script from the system command line, where
2681 # Python inserts the script's directory into sys.path
2682 # Python inserts the script's directory into sys.path
2682 dname = os.path.dirname(fname)
2683 dname = os.path.dirname(fname)
2683
2684
2684 def get_cells():
2685 def get_cells():
2685 """generator for sequence of code blocks to run"""
2686 """generator for sequence of code blocks to run"""
2686 if fname.endswith('.ipynb'):
2687 if fname.endswith('.ipynb'):
2687 from IPython.nbformat import read
2688 from IPython.nbformat import read
2688 with io_open(fname) as f:
2689 with io_open(fname) as f:
2689 nb = read(f, as_version=4)
2690 nb = read(f, as_version=4)
2690 if not nb.cells:
2691 if not nb.cells:
2691 return
2692 return
2692 for cell in nb.cells:
2693 for cell in nb.cells:
2693 if cell.cell_type == 'code':
2694 if cell.cell_type == 'code':
2694 yield cell.source
2695 yield cell.source
2695 else:
2696 else:
2696 with open(fname) as f:
2697 with open(fname) as f:
2697 yield f.read()
2698 yield f.read()
2698
2699
2699 with prepended_to_syspath(dname):
2700 with prepended_to_syspath(dname):
2700 try:
2701 try:
2701 for cell in get_cells():
2702 for cell in get_cells():
2702 # self.run_cell currently captures all exceptions
2703 # self.run_cell currently captures all exceptions
2703 # raised in user code. It would be nice if there were
2704 # raised in user code. It would be nice if there were
2704 # versions of run_cell that did raise, so
2705 # versions of run_cell that did raise, so
2705 # we could catch the errors.
2706 # we could catch the errors.
2706 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2707 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2707 if not result.success:
2708 if not result.success:
2708 break
2709 break
2709 except:
2710 except:
2710 self.showtraceback()
2711 self.showtraceback()
2711 warn('Unknown failure executing file: <%s>' % fname)
2712 warn('Unknown failure executing file: <%s>' % fname)
2712
2713
2713 def safe_run_module(self, mod_name, where):
2714 def safe_run_module(self, mod_name, where):
2714 """A safe version of runpy.run_module().
2715 """A safe version of runpy.run_module().
2715
2716
2716 This version will never throw an exception, but instead print
2717 This version will never throw an exception, but instead print
2717 helpful error messages to the screen.
2718 helpful error messages to the screen.
2718
2719
2719 `SystemExit` exceptions with status code 0 or None are ignored.
2720 `SystemExit` exceptions with status code 0 or None are ignored.
2720
2721
2721 Parameters
2722 Parameters
2722 ----------
2723 ----------
2723 mod_name : string
2724 mod_name : string
2724 The name of the module to be executed.
2725 The name of the module to be executed.
2725 where : dict
2726 where : dict
2726 The globals namespace.
2727 The globals namespace.
2727 """
2728 """
2728 try:
2729 try:
2729 try:
2730 try:
2730 where.update(
2731 where.update(
2731 runpy.run_module(str(mod_name), run_name="__main__",
2732 runpy.run_module(str(mod_name), run_name="__main__",
2732 alter_sys=True)
2733 alter_sys=True)
2733 )
2734 )
2734 except SystemExit as status:
2735 except SystemExit as status:
2735 if status.code:
2736 if status.code:
2736 raise
2737 raise
2737 except:
2738 except:
2738 self.showtraceback()
2739 self.showtraceback()
2739 warn('Unknown failure executing module: <%s>' % mod_name)
2740 warn('Unknown failure executing module: <%s>' % mod_name)
2740
2741
2741 def _run_cached_cell_magic(self, magic_name, line):
2742 def _run_cached_cell_magic(self, magic_name, line):
2742 """Special method to call a cell magic with the data stored in self.
2743 """Special method to call a cell magic with the data stored in self.
2743 """
2744 """
2744 cell = self._current_cell_magic_body
2745 cell = self._current_cell_magic_body
2745 self._current_cell_magic_body = None
2746 self._current_cell_magic_body = None
2746 return self.run_cell_magic(magic_name, line, cell)
2747 return self.run_cell_magic(magic_name, line, cell)
2747
2748
2748 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2749 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2749 """Run a complete IPython cell.
2750 """Run a complete IPython cell.
2750
2751
2751 Parameters
2752 Parameters
2752 ----------
2753 ----------
2753 raw_cell : str
2754 raw_cell : str
2754 The code (including IPython code such as %magic functions) to run.
2755 The code (including IPython code such as %magic functions) to run.
2755 store_history : bool
2756 store_history : bool
2756 If True, the raw and translated cell will be stored in IPython's
2757 If True, the raw and translated cell will be stored in IPython's
2757 history. For user code calling back into IPython's machinery, this
2758 history. For user code calling back into IPython's machinery, this
2758 should be set to False.
2759 should be set to False.
2759 silent : bool
2760 silent : bool
2760 If True, avoid side-effects, such as implicit displayhooks and
2761 If True, avoid side-effects, such as implicit displayhooks and
2761 and logging. silent=True forces store_history=False.
2762 and logging. silent=True forces store_history=False.
2762 shell_futures : bool
2763 shell_futures : bool
2763 If True, the code will share future statements with the interactive
2764 If True, the code will share future statements with the interactive
2764 shell. It will both be affected by previous __future__ imports, and
2765 shell. It will both be affected by previous __future__ imports, and
2765 any __future__ imports in the code will affect the shell. If False,
2766 any __future__ imports in the code will affect the shell. If False,
2766 __future__ imports are not shared in either direction.
2767 __future__ imports are not shared in either direction.
2767
2768
2768 Returns
2769 Returns
2769 -------
2770 -------
2770 result : :class:`ExecutionResult`
2771 result : :class:`ExecutionResult`
2771 """
2772 """
2772 result = ExecutionResult()
2773 result = ExecutionResult()
2773
2774
2774 if (not raw_cell) or raw_cell.isspace():
2775 if (not raw_cell) or raw_cell.isspace():
2775 return result
2776 return result
2776
2777
2777 if silent:
2778 if silent:
2778 store_history = False
2779 store_history = False
2779
2780
2780 if store_history:
2781 if store_history:
2781 result.execution_count = self.execution_count
2782 result.execution_count = self.execution_count
2782
2783
2783 def error_before_exec(value):
2784 def error_before_exec(value):
2784 result.error_before_exec = value
2785 result.error_before_exec = value
2785 return result
2786 return result
2786
2787
2787 self.events.trigger('pre_execute')
2788 self.events.trigger('pre_execute')
2788 if not silent:
2789 if not silent:
2789 self.events.trigger('pre_run_cell')
2790 self.events.trigger('pre_run_cell')
2790
2791
2791 # If any of our input transformation (input_transformer_manager or
2792 # If any of our input transformation (input_transformer_manager or
2792 # prefilter_manager) raises an exception, we store it in this variable
2793 # prefilter_manager) raises an exception, we store it in this variable
2793 # so that we can display the error after logging the input and storing
2794 # so that we can display the error after logging the input and storing
2794 # it in the history.
2795 # it in the history.
2795 preprocessing_exc_tuple = None
2796 preprocessing_exc_tuple = None
2796 try:
2797 try:
2797 # Static input transformations
2798 # Static input transformations
2798 cell = self.input_transformer_manager.transform_cell(raw_cell)
2799 cell = self.input_transformer_manager.transform_cell(raw_cell)
2799 except SyntaxError:
2800 except SyntaxError:
2800 preprocessing_exc_tuple = sys.exc_info()
2801 preprocessing_exc_tuple = sys.exc_info()
2801 cell = raw_cell # cell has to exist so it can be stored/logged
2802 cell = raw_cell # cell has to exist so it can be stored/logged
2802 else:
2803 else:
2803 if len(cell.splitlines()) == 1:
2804 if len(cell.splitlines()) == 1:
2804 # Dynamic transformations - only applied for single line commands
2805 # Dynamic transformations - only applied for single line commands
2805 with self.builtin_trap:
2806 with self.builtin_trap:
2806 try:
2807 try:
2807 # use prefilter_lines to handle trailing newlines
2808 # use prefilter_lines to handle trailing newlines
2808 # restore trailing newline for ast.parse
2809 # restore trailing newline for ast.parse
2809 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2810 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2810 except Exception:
2811 except Exception:
2811 # don't allow prefilter errors to crash IPython
2812 # don't allow prefilter errors to crash IPython
2812 preprocessing_exc_tuple = sys.exc_info()
2813 preprocessing_exc_tuple = sys.exc_info()
2813
2814
2814 # Store raw and processed history
2815 # Store raw and processed history
2815 if store_history:
2816 if store_history:
2816 self.history_manager.store_inputs(self.execution_count,
2817 self.history_manager.store_inputs(self.execution_count,
2817 cell, raw_cell)
2818 cell, raw_cell)
2818 if not silent:
2819 if not silent:
2819 self.logger.log(cell, raw_cell)
2820 self.logger.log(cell, raw_cell)
2820
2821
2821 # Display the exception if input processing failed.
2822 # Display the exception if input processing failed.
2822 if preprocessing_exc_tuple is not None:
2823 if preprocessing_exc_tuple is not None:
2823 self.showtraceback(preprocessing_exc_tuple)
2824 self.showtraceback(preprocessing_exc_tuple)
2824 if store_history:
2825 if store_history:
2825 self.execution_count += 1
2826 self.execution_count += 1
2826 return error_before_exec(preprocessing_exc_tuple[2])
2827 return error_before_exec(preprocessing_exc_tuple[2])
2827
2828
2828 # Our own compiler remembers the __future__ environment. If we want to
2829 # Our own compiler remembers the __future__ environment. If we want to
2829 # run code with a separate __future__ environment, use the default
2830 # run code with a separate __future__ environment, use the default
2830 # compiler
2831 # compiler
2831 compiler = self.compile if shell_futures else CachingCompiler()
2832 compiler = self.compile if shell_futures else CachingCompiler()
2832
2833
2833 with self.builtin_trap:
2834 with self.builtin_trap:
2834 cell_name = self.compile.cache(cell, self.execution_count)
2835 cell_name = self.compile.cache(cell, self.execution_count)
2835
2836
2836 with self.display_trap:
2837 with self.display_trap:
2837 # Compile to bytecode
2838 # Compile to bytecode
2838 try:
2839 try:
2839 code_ast = compiler.ast_parse(cell, filename=cell_name)
2840 code_ast = compiler.ast_parse(cell, filename=cell_name)
2840 except IndentationError as e:
2841 except IndentationError as e:
2841 self.showindentationerror()
2842 self.showindentationerror()
2842 if store_history:
2843 if store_history:
2843 self.execution_count += 1
2844 self.execution_count += 1
2844 return error_before_exec(e)
2845 return error_before_exec(e)
2845 except (OverflowError, SyntaxError, ValueError, TypeError,
2846 except (OverflowError, SyntaxError, ValueError, TypeError,
2846 MemoryError) as e:
2847 MemoryError) as e:
2847 self.showsyntaxerror()
2848 self.showsyntaxerror()
2848 if store_history:
2849 if store_history:
2849 self.execution_count += 1
2850 self.execution_count += 1
2850 return error_before_exec(e)
2851 return error_before_exec(e)
2851
2852
2852 # Apply AST transformations
2853 # Apply AST transformations
2853 try:
2854 try:
2854 code_ast = self.transform_ast(code_ast)
2855 code_ast = self.transform_ast(code_ast)
2855 except InputRejected as e:
2856 except InputRejected as e:
2856 self.showtraceback()
2857 self.showtraceback()
2857 if store_history:
2858 if store_history:
2858 self.execution_count += 1
2859 self.execution_count += 1
2859 return error_before_exec(e)
2860 return error_before_exec(e)
2860
2861
2861 # Give the displayhook a reference to our ExecutionResult so it
2862 # Give the displayhook a reference to our ExecutionResult so it
2862 # can fill in the output value.
2863 # can fill in the output value.
2863 self.displayhook.exec_result = result
2864 self.displayhook.exec_result = result
2864
2865
2865 # Execute the user code
2866 # Execute the user code
2866 interactivity = "none" if silent else self.ast_node_interactivity
2867 interactivity = "none" if silent else self.ast_node_interactivity
2867 self.run_ast_nodes(code_ast.body, cell_name,
2868 self.run_ast_nodes(code_ast.body, cell_name,
2868 interactivity=interactivity, compiler=compiler, result=result)
2869 interactivity=interactivity, compiler=compiler, result=result)
2869
2870
2870 # Reset this so later displayed values do not modify the
2871 # Reset this so later displayed values do not modify the
2871 # ExecutionResult
2872 # ExecutionResult
2872 self.displayhook.exec_result = None
2873 self.displayhook.exec_result = None
2873
2874
2874 self.events.trigger('post_execute')
2875 self.events.trigger('post_execute')
2875 if not silent:
2876 if not silent:
2876 self.events.trigger('post_run_cell')
2877 self.events.trigger('post_run_cell')
2877
2878
2878 if store_history:
2879 if store_history:
2879 # Write output to the database. Does nothing unless
2880 # Write output to the database. Does nothing unless
2880 # history output logging is enabled.
2881 # history output logging is enabled.
2881 self.history_manager.store_output(self.execution_count)
2882 self.history_manager.store_output(self.execution_count)
2882 # Each cell is a *single* input, regardless of how many lines it has
2883 # Each cell is a *single* input, regardless of how many lines it has
2883 self.execution_count += 1
2884 self.execution_count += 1
2884
2885
2885 return result
2886 return result
2886
2887
2887 def transform_ast(self, node):
2888 def transform_ast(self, node):
2888 """Apply the AST transformations from self.ast_transformers
2889 """Apply the AST transformations from self.ast_transformers
2889
2890
2890 Parameters
2891 Parameters
2891 ----------
2892 ----------
2892 node : ast.Node
2893 node : ast.Node
2893 The root node to be transformed. Typically called with the ast.Module
2894 The root node to be transformed. Typically called with the ast.Module
2894 produced by parsing user input.
2895 produced by parsing user input.
2895
2896
2896 Returns
2897 Returns
2897 -------
2898 -------
2898 An ast.Node corresponding to the node it was called with. Note that it
2899 An ast.Node corresponding to the node it was called with. Note that it
2899 may also modify the passed object, so don't rely on references to the
2900 may also modify the passed object, so don't rely on references to the
2900 original AST.
2901 original AST.
2901 """
2902 """
2902 for transformer in self.ast_transformers:
2903 for transformer in self.ast_transformers:
2903 try:
2904 try:
2904 node = transformer.visit(node)
2905 node = transformer.visit(node)
2905 except InputRejected:
2906 except InputRejected:
2906 # User-supplied AST transformers can reject an input by raising
2907 # User-supplied AST transformers can reject an input by raising
2907 # an InputRejected. Short-circuit in this case so that we
2908 # an InputRejected. Short-circuit in this case so that we
2908 # don't unregister the transform.
2909 # don't unregister the transform.
2909 raise
2910 raise
2910 except Exception:
2911 except Exception:
2911 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2912 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2912 self.ast_transformers.remove(transformer)
2913 self.ast_transformers.remove(transformer)
2913
2914
2914 if self.ast_transformers:
2915 if self.ast_transformers:
2915 ast.fix_missing_locations(node)
2916 ast.fix_missing_locations(node)
2916 return node
2917 return node
2917
2918
2918
2919
2919 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2920 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2920 compiler=compile, result=None):
2921 compiler=compile, result=None):
2921 """Run a sequence of AST nodes. The execution mode depends on the
2922 """Run a sequence of AST nodes. The execution mode depends on the
2922 interactivity parameter.
2923 interactivity parameter.
2923
2924
2924 Parameters
2925 Parameters
2925 ----------
2926 ----------
2926 nodelist : list
2927 nodelist : list
2927 A sequence of AST nodes to run.
2928 A sequence of AST nodes to run.
2928 cell_name : str
2929 cell_name : str
2929 Will be passed to the compiler as the filename of the cell. Typically
2930 Will be passed to the compiler as the filename of the cell. Typically
2930 the value returned by ip.compile.cache(cell).
2931 the value returned by ip.compile.cache(cell).
2931 interactivity : str
2932 interactivity : str
2932 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2933 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2933 run interactively (displaying output from expressions). 'last_expr'
2934 run interactively (displaying output from expressions). 'last_expr'
2934 will run the last node interactively only if it is an expression (i.e.
2935 will run the last node interactively only if it is an expression (i.e.
2935 expressions in loops or other blocks are not displayed. Other values
2936 expressions in loops or other blocks are not displayed. Other values
2936 for this parameter will raise a ValueError.
2937 for this parameter will raise a ValueError.
2937 compiler : callable
2938 compiler : callable
2938 A function with the same interface as the built-in compile(), to turn
2939 A function with the same interface as the built-in compile(), to turn
2939 the AST nodes into code objects. Default is the built-in compile().
2940 the AST nodes into code objects. Default is the built-in compile().
2940 result : ExecutionResult, optional
2941 result : ExecutionResult, optional
2941 An object to store exceptions that occur during execution.
2942 An object to store exceptions that occur during execution.
2942
2943
2943 Returns
2944 Returns
2944 -------
2945 -------
2945 True if an exception occurred while running code, False if it finished
2946 True if an exception occurred while running code, False if it finished
2946 running.
2947 running.
2947 """
2948 """
2948 if not nodelist:
2949 if not nodelist:
2949 return
2950 return
2950
2951
2951 if interactivity == 'last_expr':
2952 if interactivity == 'last_expr':
2952 if isinstance(nodelist[-1], ast.Expr):
2953 if isinstance(nodelist[-1], ast.Expr):
2953 interactivity = "last"
2954 interactivity = "last"
2954 else:
2955 else:
2955 interactivity = "none"
2956 interactivity = "none"
2956
2957
2957 if interactivity == 'none':
2958 if interactivity == 'none':
2958 to_run_exec, to_run_interactive = nodelist, []
2959 to_run_exec, to_run_interactive = nodelist, []
2959 elif interactivity == 'last':
2960 elif interactivity == 'last':
2960 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2961 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2961 elif interactivity == 'all':
2962 elif interactivity == 'all':
2962 to_run_exec, to_run_interactive = [], nodelist
2963 to_run_exec, to_run_interactive = [], nodelist
2963 else:
2964 else:
2964 raise ValueError("Interactivity was %r" % interactivity)
2965 raise ValueError("Interactivity was %r" % interactivity)
2965
2966
2966 exec_count = self.execution_count
2967 exec_count = self.execution_count
2967
2968
2968 try:
2969 try:
2969 for i, node in enumerate(to_run_exec):
2970 for i, node in enumerate(to_run_exec):
2970 mod = ast.Module([node])
2971 mod = ast.Module([node])
2971 code = compiler(mod, cell_name, "exec")
2972 code = compiler(mod, cell_name, "exec")
2972 if self.run_code(code, result):
2973 if self.run_code(code, result):
2973 return True
2974 return True
2974
2975
2975 for i, node in enumerate(to_run_interactive):
2976 for i, node in enumerate(to_run_interactive):
2976 mod = ast.Interactive([node])
2977 mod = ast.Interactive([node])
2977 code = compiler(mod, cell_name, "single")
2978 code = compiler(mod, cell_name, "single")
2978 if self.run_code(code, result):
2979 if self.run_code(code, result):
2979 return True
2980 return True
2980
2981
2981 # Flush softspace
2982 # Flush softspace
2982 if softspace(sys.stdout, 0):
2983 if softspace(sys.stdout, 0):
2983 print()
2984 print()
2984
2985
2985 except:
2986 except:
2986 # It's possible to have exceptions raised here, typically by
2987 # It's possible to have exceptions raised here, typically by
2987 # compilation of odd code (such as a naked 'return' outside a
2988 # compilation of odd code (such as a naked 'return' outside a
2988 # function) that did parse but isn't valid. Typically the exception
2989 # function) that did parse but isn't valid. Typically the exception
2989 # is a SyntaxError, but it's safest just to catch anything and show
2990 # is a SyntaxError, but it's safest just to catch anything and show
2990 # the user a traceback.
2991 # the user a traceback.
2991
2992
2992 # We do only one try/except outside the loop to minimize the impact
2993 # We do only one try/except outside the loop to minimize the impact
2993 # on runtime, and also because if any node in the node list is
2994 # on runtime, and also because if any node in the node list is
2994 # broken, we should stop execution completely.
2995 # broken, we should stop execution completely.
2995 if result:
2996 if result:
2996 result.error_before_exec = sys.exc_info()[1]
2997 result.error_before_exec = sys.exc_info()[1]
2997 self.showtraceback()
2998 self.showtraceback()
2998 return True
2999 return True
2999
3000
3000 return False
3001 return False
3001
3002
3002 def run_code(self, code_obj, result=None):
3003 def run_code(self, code_obj, result=None):
3003 """Execute a code object.
3004 """Execute a code object.
3004
3005
3005 When an exception occurs, self.showtraceback() is called to display a
3006 When an exception occurs, self.showtraceback() is called to display a
3006 traceback.
3007 traceback.
3007
3008
3008 Parameters
3009 Parameters
3009 ----------
3010 ----------
3010 code_obj : code object
3011 code_obj : code object
3011 A compiled code object, to be executed
3012 A compiled code object, to be executed
3012 result : ExecutionResult, optional
3013 result : ExecutionResult, optional
3013 An object to store exceptions that occur during execution.
3014 An object to store exceptions that occur during execution.
3014
3015
3015 Returns
3016 Returns
3016 -------
3017 -------
3017 False : successful execution.
3018 False : successful execution.
3018 True : an error occurred.
3019 True : an error occurred.
3019 """
3020 """
3020 # Set our own excepthook in case the user code tries to call it
3021 # Set our own excepthook in case the user code tries to call it
3021 # directly, so that the IPython crash handler doesn't get triggered
3022 # directly, so that the IPython crash handler doesn't get triggered
3022 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3023 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3023
3024
3024 # we save the original sys.excepthook in the instance, in case config
3025 # we save the original sys.excepthook in the instance, in case config
3025 # code (such as magics) needs access to it.
3026 # code (such as magics) needs access to it.
3026 self.sys_excepthook = old_excepthook
3027 self.sys_excepthook = old_excepthook
3027 outflag = 1 # happens in more places, so it's easier as default
3028 outflag = 1 # happens in more places, so it's easier as default
3028 try:
3029 try:
3029 try:
3030 try:
3030 self.hooks.pre_run_code_hook()
3031 self.hooks.pre_run_code_hook()
3031 #rprint('Running code', repr(code_obj)) # dbg
3032 #rprint('Running code', repr(code_obj)) # dbg
3032 exec(code_obj, self.user_global_ns, self.user_ns)
3033 exec(code_obj, self.user_global_ns, self.user_ns)
3033 finally:
3034 finally:
3034 # Reset our crash handler in place
3035 # Reset our crash handler in place
3035 sys.excepthook = old_excepthook
3036 sys.excepthook = old_excepthook
3036 except SystemExit as e:
3037 except SystemExit as e:
3037 if result is not None:
3038 if result is not None:
3038 result.error_in_exec = e
3039 result.error_in_exec = e
3039 self.showtraceback(exception_only=True)
3040 self.showtraceback(exception_only=True)
3040 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
3041 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
3041 except self.custom_exceptions:
3042 except self.custom_exceptions:
3042 etype, value, tb = sys.exc_info()
3043 etype, value, tb = sys.exc_info()
3043 if result is not None:
3044 if result is not None:
3044 result.error_in_exec = value
3045 result.error_in_exec = value
3045 self.CustomTB(etype, value, tb)
3046 self.CustomTB(etype, value, tb)
3046 except:
3047 except:
3047 if result is not None:
3048 if result is not None:
3048 result.error_in_exec = sys.exc_info()[1]
3049 result.error_in_exec = sys.exc_info()[1]
3049 self.showtraceback()
3050 self.showtraceback()
3050 else:
3051 else:
3051 outflag = 0
3052 outflag = 0
3052 return outflag
3053 return outflag
3053
3054
3054 # For backwards compatibility
3055 # For backwards compatibility
3055 runcode = run_code
3056 runcode = run_code
3056
3057
3057 #-------------------------------------------------------------------------
3058 #-------------------------------------------------------------------------
3058 # Things related to GUI support and pylab
3059 # Things related to GUI support and pylab
3059 #-------------------------------------------------------------------------
3060 #-------------------------------------------------------------------------
3060
3061
3061 def enable_gui(self, gui=None):
3062 def enable_gui(self, gui=None):
3062 raise NotImplementedError('Implement enable_gui in a subclass')
3063 raise NotImplementedError('Implement enable_gui in a subclass')
3063
3064
3064 def enable_matplotlib(self, gui=None):
3065 def enable_matplotlib(self, gui=None):
3065 """Enable interactive matplotlib and inline figure support.
3066 """Enable interactive matplotlib and inline figure support.
3066
3067
3067 This takes the following steps:
3068 This takes the following steps:
3068
3069
3069 1. select the appropriate eventloop and matplotlib backend
3070 1. select the appropriate eventloop and matplotlib backend
3070 2. set up matplotlib for interactive use with that backend
3071 2. set up matplotlib for interactive use with that backend
3071 3. configure formatters for inline figure display
3072 3. configure formatters for inline figure display
3072 4. enable the selected gui eventloop
3073 4. enable the selected gui eventloop
3073
3074
3074 Parameters
3075 Parameters
3075 ----------
3076 ----------
3076 gui : optional, string
3077 gui : optional, string
3077 If given, dictates the choice of matplotlib GUI backend to use
3078 If given, dictates the choice of matplotlib GUI backend to use
3078 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3079 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3079 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3080 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3080 matplotlib (as dictated by the matplotlib build-time options plus the
3081 matplotlib (as dictated by the matplotlib build-time options plus the
3081 user's matplotlibrc configuration file). Note that not all backends
3082 user's matplotlibrc configuration file). Note that not all backends
3082 make sense in all contexts, for example a terminal ipython can't
3083 make sense in all contexts, for example a terminal ipython can't
3083 display figures inline.
3084 display figures inline.
3084 """
3085 """
3085 from IPython.core import pylabtools as pt
3086 from IPython.core import pylabtools as pt
3086 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3087 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3087
3088
3088 if gui != 'inline':
3089 if gui != 'inline':
3089 # If we have our first gui selection, store it
3090 # If we have our first gui selection, store it
3090 if self.pylab_gui_select is None:
3091 if self.pylab_gui_select is None:
3091 self.pylab_gui_select = gui
3092 self.pylab_gui_select = gui
3092 # Otherwise if they are different
3093 # Otherwise if they are different
3093 elif gui != self.pylab_gui_select:
3094 elif gui != self.pylab_gui_select:
3094 print ('Warning: Cannot change to a different GUI toolkit: %s.'
3095 print ('Warning: Cannot change to a different GUI toolkit: %s.'
3095 ' Using %s instead.' % (gui, self.pylab_gui_select))
3096 ' Using %s instead.' % (gui, self.pylab_gui_select))
3096 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3097 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3097
3098
3098 pt.activate_matplotlib(backend)
3099 pt.activate_matplotlib(backend)
3099 pt.configure_inline_support(self, backend)
3100 pt.configure_inline_support(self, backend)
3100
3101
3101 # Now we must activate the gui pylab wants to use, and fix %run to take
3102 # Now we must activate the gui pylab wants to use, and fix %run to take
3102 # plot updates into account
3103 # plot updates into account
3103 self.enable_gui(gui)
3104 self.enable_gui(gui)
3104 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3105 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3105 pt.mpl_runner(self.safe_execfile)
3106 pt.mpl_runner(self.safe_execfile)
3106
3107
3107 return gui, backend
3108 return gui, backend
3108
3109
3109 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3110 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3110 """Activate pylab support at runtime.
3111 """Activate pylab support at runtime.
3111
3112
3112 This turns on support for matplotlib, preloads into the interactive
3113 This turns on support for matplotlib, preloads into the interactive
3113 namespace all of numpy and pylab, and configures IPython to correctly
3114 namespace all of numpy and pylab, and configures IPython to correctly
3114 interact with the GUI event loop. The GUI backend to be used can be
3115 interact with the GUI event loop. The GUI backend to be used can be
3115 optionally selected with the optional ``gui`` argument.
3116 optionally selected with the optional ``gui`` argument.
3116
3117
3117 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3118 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3118
3119
3119 Parameters
3120 Parameters
3120 ----------
3121 ----------
3121 gui : optional, string
3122 gui : optional, string
3122 If given, dictates the choice of matplotlib GUI backend to use
3123 If given, dictates the choice of matplotlib GUI backend to use
3123 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3124 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3124 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3125 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3125 matplotlib (as dictated by the matplotlib build-time options plus the
3126 matplotlib (as dictated by the matplotlib build-time options plus the
3126 user's matplotlibrc configuration file). Note that not all backends
3127 user's matplotlibrc configuration file). Note that not all backends
3127 make sense in all contexts, for example a terminal ipython can't
3128 make sense in all contexts, for example a terminal ipython can't
3128 display figures inline.
3129 display figures inline.
3129 import_all : optional, bool, default: True
3130 import_all : optional, bool, default: True
3130 Whether to do `from numpy import *` and `from pylab import *`
3131 Whether to do `from numpy import *` and `from pylab import *`
3131 in addition to module imports.
3132 in addition to module imports.
3132 welcome_message : deprecated
3133 welcome_message : deprecated
3133 This argument is ignored, no welcome message will be displayed.
3134 This argument is ignored, no welcome message will be displayed.
3134 """
3135 """
3135 from IPython.core.pylabtools import import_pylab
3136 from IPython.core.pylabtools import import_pylab
3136
3137
3137 gui, backend = self.enable_matplotlib(gui)
3138 gui, backend = self.enable_matplotlib(gui)
3138
3139
3139 # We want to prevent the loading of pylab to pollute the user's
3140 # We want to prevent the loading of pylab to pollute the user's
3140 # namespace as shown by the %who* magics, so we execute the activation
3141 # namespace as shown by the %who* magics, so we execute the activation
3141 # code in an empty namespace, and we update *both* user_ns and
3142 # code in an empty namespace, and we update *both* user_ns and
3142 # user_ns_hidden with this information.
3143 # user_ns_hidden with this information.
3143 ns = {}
3144 ns = {}
3144 import_pylab(ns, import_all)
3145 import_pylab(ns, import_all)
3145 # warn about clobbered names
3146 # warn about clobbered names
3146 ignored = set(["__builtins__"])
3147 ignored = set(["__builtins__"])
3147 both = set(ns).intersection(self.user_ns).difference(ignored)
3148 both = set(ns).intersection(self.user_ns).difference(ignored)
3148 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3149 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3149 self.user_ns.update(ns)
3150 self.user_ns.update(ns)
3150 self.user_ns_hidden.update(ns)
3151 self.user_ns_hidden.update(ns)
3151 return gui, backend, clobbered
3152 return gui, backend, clobbered
3152
3153
3153 #-------------------------------------------------------------------------
3154 #-------------------------------------------------------------------------
3154 # Utilities
3155 # Utilities
3155 #-------------------------------------------------------------------------
3156 #-------------------------------------------------------------------------
3156
3157
3157 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3158 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3158 """Expand python variables in a string.
3159 """Expand python variables in a string.
3159
3160
3160 The depth argument indicates how many frames above the caller should
3161 The depth argument indicates how many frames above the caller should
3161 be walked to look for the local namespace where to expand variables.
3162 be walked to look for the local namespace where to expand variables.
3162
3163
3163 The global namespace for expansion is always the user's interactive
3164 The global namespace for expansion is always the user's interactive
3164 namespace.
3165 namespace.
3165 """
3166 """
3166 ns = self.user_ns.copy()
3167 ns = self.user_ns.copy()
3167 try:
3168 try:
3168 frame = sys._getframe(depth+1)
3169 frame = sys._getframe(depth+1)
3169 except ValueError:
3170 except ValueError:
3170 # This is thrown if there aren't that many frames on the stack,
3171 # This is thrown if there aren't that many frames on the stack,
3171 # e.g. if a script called run_line_magic() directly.
3172 # e.g. if a script called run_line_magic() directly.
3172 pass
3173 pass
3173 else:
3174 else:
3174 ns.update(frame.f_locals)
3175 ns.update(frame.f_locals)
3175
3176
3176 try:
3177 try:
3177 # We have to use .vformat() here, because 'self' is a valid and common
3178 # We have to use .vformat() here, because 'self' is a valid and common
3178 # name, and expanding **ns for .format() would make it collide with
3179 # name, and expanding **ns for .format() would make it collide with
3179 # the 'self' argument of the method.
3180 # the 'self' argument of the method.
3180 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3181 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3181 except Exception:
3182 except Exception:
3182 # if formatter couldn't format, just let it go untransformed
3183 # if formatter couldn't format, just let it go untransformed
3183 pass
3184 pass
3184 return cmd
3185 return cmd
3185
3186
3186 def mktempfile(self, data=None, prefix='ipython_edit_'):
3187 def mktempfile(self, data=None, prefix='ipython_edit_'):
3187 """Make a new tempfile and return its filename.
3188 """Make a new tempfile and return its filename.
3188
3189
3189 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3190 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3190 but it registers the created filename internally so ipython cleans it up
3191 but it registers the created filename internally so ipython cleans it up
3191 at exit time.
3192 at exit time.
3192
3193
3193 Optional inputs:
3194 Optional inputs:
3194
3195
3195 - data(None): if data is given, it gets written out to the temp file
3196 - data(None): if data is given, it gets written out to the temp file
3196 immediately, and the file is closed again."""
3197 immediately, and the file is closed again."""
3197
3198
3198 dirname = tempfile.mkdtemp(prefix=prefix)
3199 dirname = tempfile.mkdtemp(prefix=prefix)
3199 self.tempdirs.append(dirname)
3200 self.tempdirs.append(dirname)
3200
3201
3201 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3202 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3202 os.close(handle) # On Windows, there can only be one open handle on a file
3203 os.close(handle) # On Windows, there can only be one open handle on a file
3203 self.tempfiles.append(filename)
3204 self.tempfiles.append(filename)
3204
3205
3205 if data:
3206 if data:
3206 tmp_file = open(filename,'w')
3207 tmp_file = open(filename,'w')
3207 tmp_file.write(data)
3208 tmp_file.write(data)
3208 tmp_file.close()
3209 tmp_file.close()
3209 return filename
3210 return filename
3210
3211
3211 # TODO: This should be removed when Term is refactored.
3212 # TODO: This should be removed when Term is refactored.
3212 def write(self,data):
3213 def write(self,data):
3213 """Write a string to the default output"""
3214 """Write a string to the default output"""
3214 io.stdout.write(data)
3215 io.stdout.write(data)
3215
3216
3216 # TODO: This should be removed when Term is refactored.
3217 # TODO: This should be removed when Term is refactored.
3217 def write_err(self,data):
3218 def write_err(self,data):
3218 """Write a string to the default error output"""
3219 """Write a string to the default error output"""
3219 io.stderr.write(data)
3220 io.stderr.write(data)
3220
3221
3221 def ask_yes_no(self, prompt, default=None):
3222 def ask_yes_no(self, prompt, default=None):
3222 if self.quiet:
3223 if self.quiet:
3223 return True
3224 return True
3224 return ask_yes_no(prompt,default)
3225 return ask_yes_no(prompt,default)
3225
3226
3226 def show_usage(self):
3227 def show_usage(self):
3227 """Show a usage message"""
3228 """Show a usage message"""
3228 page.page(IPython.core.usage.interactive_usage)
3229 page.page(IPython.core.usage.interactive_usage)
3229
3230
3230 def extract_input_lines(self, range_str, raw=False):
3231 def extract_input_lines(self, range_str, raw=False):
3231 """Return as a string a set of input history slices.
3232 """Return as a string a set of input history slices.
3232
3233
3233 Parameters
3234 Parameters
3234 ----------
3235 ----------
3235 range_str : string
3236 range_str : string
3236 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3237 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3237 since this function is for use by magic functions which get their
3238 since this function is for use by magic functions which get their
3238 arguments as strings. The number before the / is the session
3239 arguments as strings. The number before the / is the session
3239 number: ~n goes n back from the current session.
3240 number: ~n goes n back from the current session.
3240
3241
3241 raw : bool, optional
3242 raw : bool, optional
3242 By default, the processed input is used. If this is true, the raw
3243 By default, the processed input is used. If this is true, the raw
3243 input history is used instead.
3244 input history is used instead.
3244
3245
3245 Notes
3246 Notes
3246 -----
3247 -----
3247
3248
3248 Slices can be described with two notations:
3249 Slices can be described with two notations:
3249
3250
3250 * ``N:M`` -> standard python form, means including items N...(M-1).
3251 * ``N:M`` -> standard python form, means including items N...(M-1).
3251 * ``N-M`` -> include items N..M (closed endpoint).
3252 * ``N-M`` -> include items N..M (closed endpoint).
3252 """
3253 """
3253 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3254 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3254 return "\n".join(x for _, _, x in lines)
3255 return "\n".join(x for _, _, x in lines)
3255
3256
3256 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3257 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3257 """Get a code string from history, file, url, or a string or macro.
3258 """Get a code string from history, file, url, or a string or macro.
3258
3259
3259 This is mainly used by magic functions.
3260 This is mainly used by magic functions.
3260
3261
3261 Parameters
3262 Parameters
3262 ----------
3263 ----------
3263
3264
3264 target : str
3265 target : str
3265
3266
3266 A string specifying code to retrieve. This will be tried respectively
3267 A string specifying code to retrieve. This will be tried respectively
3267 as: ranges of input history (see %history for syntax), url,
3268 as: ranges of input history (see %history for syntax), url,
3268 correspnding .py file, filename, or an expression evaluating to a
3269 correspnding .py file, filename, or an expression evaluating to a
3269 string or Macro in the user namespace.
3270 string or Macro in the user namespace.
3270
3271
3271 raw : bool
3272 raw : bool
3272 If true (default), retrieve raw history. Has no effect on the other
3273 If true (default), retrieve raw history. Has no effect on the other
3273 retrieval mechanisms.
3274 retrieval mechanisms.
3274
3275
3275 py_only : bool (default False)
3276 py_only : bool (default False)
3276 Only try to fetch python code, do not try alternative methods to decode file
3277 Only try to fetch python code, do not try alternative methods to decode file
3277 if unicode fails.
3278 if unicode fails.
3278
3279
3279 Returns
3280 Returns
3280 -------
3281 -------
3281 A string of code.
3282 A string of code.
3282
3283
3283 ValueError is raised if nothing is found, and TypeError if it evaluates
3284 ValueError is raised if nothing is found, and TypeError if it evaluates
3284 to an object of another type. In each case, .args[0] is a printable
3285 to an object of another type. In each case, .args[0] is a printable
3285 message.
3286 message.
3286 """
3287 """
3287 code = self.extract_input_lines(target, raw=raw) # Grab history
3288 code = self.extract_input_lines(target, raw=raw) # Grab history
3288 if code:
3289 if code:
3289 return code
3290 return code
3290 utarget = unquote_filename(target)
3291 utarget = unquote_filename(target)
3291 try:
3292 try:
3292 if utarget.startswith(('http://', 'https://')):
3293 if utarget.startswith(('http://', 'https://')):
3293 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3294 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3294 except UnicodeDecodeError:
3295 except UnicodeDecodeError:
3295 if not py_only :
3296 if not py_only :
3296 # Deferred import
3297 # Deferred import
3297 try:
3298 try:
3298 from urllib.request import urlopen # Py3
3299 from urllib.request import urlopen # Py3
3299 except ImportError:
3300 except ImportError:
3300 from urllib import urlopen
3301 from urllib import urlopen
3301 response = urlopen(target)
3302 response = urlopen(target)
3302 return response.read().decode('latin1')
3303 return response.read().decode('latin1')
3303 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3304 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3304
3305
3305 potential_target = [target]
3306 potential_target = [target]
3306 try :
3307 try :
3307 potential_target.insert(0,get_py_filename(target))
3308 potential_target.insert(0,get_py_filename(target))
3308 except IOError:
3309 except IOError:
3309 pass
3310 pass
3310
3311
3311 for tgt in potential_target :
3312 for tgt in potential_target :
3312 if os.path.isfile(tgt): # Read file
3313 if os.path.isfile(tgt): # Read file
3313 try :
3314 try :
3314 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3315 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3315 except UnicodeDecodeError :
3316 except UnicodeDecodeError :
3316 if not py_only :
3317 if not py_only :
3317 with io_open(tgt,'r', encoding='latin1') as f :
3318 with io_open(tgt,'r', encoding='latin1') as f :
3318 return f.read()
3319 return f.read()
3319 raise ValueError(("'%s' seem to be unreadable.") % target)
3320 raise ValueError(("'%s' seem to be unreadable.") % target)
3320 elif os.path.isdir(os.path.expanduser(tgt)):
3321 elif os.path.isdir(os.path.expanduser(tgt)):
3321 raise ValueError("'%s' is a directory, not a regular file." % target)
3322 raise ValueError("'%s' is a directory, not a regular file." % target)
3322
3323
3323 if search_ns:
3324 if search_ns:
3324 # Inspect namespace to load object source
3325 # Inspect namespace to load object source
3325 object_info = self.object_inspect(target, detail_level=1)
3326 object_info = self.object_inspect(target, detail_level=1)
3326 if object_info['found'] and object_info['source']:
3327 if object_info['found'] and object_info['source']:
3327 return object_info['source']
3328 return object_info['source']
3328
3329
3329 try: # User namespace
3330 try: # User namespace
3330 codeobj = eval(target, self.user_ns)
3331 codeobj = eval(target, self.user_ns)
3331 except Exception:
3332 except Exception:
3332 raise ValueError(("'%s' was not found in history, as a file, url, "
3333 raise ValueError(("'%s' was not found in history, as a file, url, "
3333 "nor in the user namespace.") % target)
3334 "nor in the user namespace.") % target)
3334
3335
3335 if isinstance(codeobj, string_types):
3336 if isinstance(codeobj, string_types):
3336 return codeobj
3337 return codeobj
3337 elif isinstance(codeobj, Macro):
3338 elif isinstance(codeobj, Macro):
3338 return codeobj.value
3339 return codeobj.value
3339
3340
3340 raise TypeError("%s is neither a string nor a macro." % target,
3341 raise TypeError("%s is neither a string nor a macro." % target,
3341 codeobj)
3342 codeobj)
3342
3343
3343 #-------------------------------------------------------------------------
3344 #-------------------------------------------------------------------------
3344 # Things related to IPython exiting
3345 # Things related to IPython exiting
3345 #-------------------------------------------------------------------------
3346 #-------------------------------------------------------------------------
3346 def atexit_operations(self):
3347 def atexit_operations(self):
3347 """This will be executed at the time of exit.
3348 """This will be executed at the time of exit.
3348
3349
3349 Cleanup operations and saving of persistent data that is done
3350 Cleanup operations and saving of persistent data that is done
3350 unconditionally by IPython should be performed here.
3351 unconditionally by IPython should be performed here.
3351
3352
3352 For things that may depend on startup flags or platform specifics (such
3353 For things that may depend on startup flags or platform specifics (such
3353 as having readline or not), register a separate atexit function in the
3354 as having readline or not), register a separate atexit function in the
3354 code that has the appropriate information, rather than trying to
3355 code that has the appropriate information, rather than trying to
3355 clutter
3356 clutter
3356 """
3357 """
3357 # Close the history session (this stores the end time and line count)
3358 # Close the history session (this stores the end time and line count)
3358 # this must be *before* the tempfile cleanup, in case of temporary
3359 # this must be *before* the tempfile cleanup, in case of temporary
3359 # history db
3360 # history db
3360 self.history_manager.end_session()
3361 self.history_manager.end_session()
3361
3362
3362 # Cleanup all tempfiles and folders left around
3363 # Cleanup all tempfiles and folders left around
3363 for tfile in self.tempfiles:
3364 for tfile in self.tempfiles:
3364 try:
3365 try:
3365 os.unlink(tfile)
3366 os.unlink(tfile)
3366 except OSError:
3367 except OSError:
3367 pass
3368 pass
3368
3369
3369 for tdir in self.tempdirs:
3370 for tdir in self.tempdirs:
3370 try:
3371 try:
3371 os.rmdir(tdir)
3372 os.rmdir(tdir)
3372 except OSError:
3373 except OSError:
3373 pass
3374 pass
3374
3375
3375 # Clear all user namespaces to release all references cleanly.
3376 # Clear all user namespaces to release all references cleanly.
3376 self.reset(new_session=False)
3377 self.reset(new_session=False)
3377
3378
3378 # Run user hooks
3379 # Run user hooks
3379 self.hooks.shutdown_hook()
3380 self.hooks.shutdown_hook()
3380
3381
3381 def cleanup(self):
3382 def cleanup(self):
3382 self.restore_sys_module_state()
3383 self.restore_sys_module_state()
3383
3384
3384
3385
3385 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3386 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3386 """An abstract base class for InteractiveShell."""
3387 """An abstract base class for InteractiveShell."""
3387
3388
3388 InteractiveShellABC.register(InteractiveShell)
3389 InteractiveShellABC.register(InteractiveShell)
@@ -1,919 +1,924 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
7 reference the name under which an object is being read.
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 from __future__ import print_function
13 from __future__ import print_function
14
14
15 __all__ = ['Inspector','InspectColors']
15 __all__ = ['Inspector','InspectColors']
16
16
17 # stdlib modules
17 # stdlib modules
18 import inspect
18 import inspect
19 import linecache
19 import linecache
20 import os
20 import os
21 from textwrap import dedent
21 from textwrap import dedent
22 import types
22 import types
23 import io as stdlib_io
23 import io as stdlib_io
24
24
25 try:
25 try:
26 from itertools import izip_longest
26 from itertools import izip_longest
27 except ImportError:
27 except ImportError:
28 from itertools import zip_longest as izip_longest
28 from itertools import zip_longest as izip_longest
29
29
30 # IPython's own
30 # IPython's own
31 from IPython.core import page
31 from IPython.core import page
32 from IPython.lib.pretty import pretty
32 from IPython.lib.pretty import pretty
33 from IPython.testing.skipdoctest import skip_doctest_py3
33 from IPython.testing.skipdoctest import skip_doctest_py3
34 from IPython.utils import PyColorize
34 from IPython.utils import PyColorize
35 from IPython.utils import io
35 from IPython.utils import io
36 from IPython.utils import openpy
36 from IPython.utils import openpy
37 from IPython.utils import py3compat
37 from IPython.utils import py3compat
38 from IPython.utils.dir2 import safe_hasattr
38 from IPython.utils.dir2 import safe_hasattr
39 from IPython.utils.path import compress_user
39 from IPython.utils.text import indent
40 from IPython.utils.text import indent
40 from IPython.utils.wildcard import list_namespace
41 from IPython.utils.wildcard import list_namespace
41 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
42 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
42 from IPython.utils.py3compat import cast_unicode, string_types, PY3
43 from IPython.utils.py3compat import cast_unicode, string_types, PY3
43 from IPython.utils.signatures import signature
44 from IPython.utils.signatures import signature
44
45
45 # builtin docstrings to ignore
46 # builtin docstrings to ignore
46 _func_call_docstring = types.FunctionType.__call__.__doc__
47 _func_call_docstring = types.FunctionType.__call__.__doc__
47 _object_init_docstring = object.__init__.__doc__
48 _object_init_docstring = object.__init__.__doc__
48 _builtin_type_docstrings = {
49 _builtin_type_docstrings = {
49 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
50 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
50 types.FunctionType, property)
51 types.FunctionType, property)
51 }
52 }
52
53
53 _builtin_func_type = type(all)
54 _builtin_func_type = type(all)
54 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
55 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
55 #****************************************************************************
56 #****************************************************************************
56 # Builtin color schemes
57 # Builtin color schemes
57
58
58 Colors = TermColors # just a shorthand
59 Colors = TermColors # just a shorthand
59
60
60 # Build a few color schemes
61 # Build a few color schemes
61 NoColor = ColorScheme(
62 NoColor = ColorScheme(
62 'NoColor',{
63 'NoColor',{
63 'header' : Colors.NoColor,
64 'header' : Colors.NoColor,
64 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
65 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
65 } )
66 } )
66
67
67 LinuxColors = ColorScheme(
68 LinuxColors = ColorScheme(
68 'Linux',{
69 'Linux',{
69 'header' : Colors.LightRed,
70 'header' : Colors.LightRed,
70 'normal' : Colors.Normal # color off (usu. Colors.Normal)
71 'normal' : Colors.Normal # color off (usu. Colors.Normal)
71 } )
72 } )
72
73
73 LightBGColors = ColorScheme(
74 LightBGColors = ColorScheme(
74 'LightBG',{
75 'LightBG',{
75 'header' : Colors.Red,
76 'header' : Colors.Red,
76 'normal' : Colors.Normal # color off (usu. Colors.Normal)
77 'normal' : Colors.Normal # color off (usu. Colors.Normal)
77 } )
78 } )
78
79
79 # Build table of color schemes (needed by the parser)
80 # Build table of color schemes (needed by the parser)
80 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
81 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
81 'Linux')
82 'Linux')
82
83
83 #****************************************************************************
84 #****************************************************************************
84 # Auxiliary functions and objects
85 # Auxiliary functions and objects
85
86
86 # See the messaging spec for the definition of all these fields. This list
87 # See the messaging spec for the definition of all these fields. This list
87 # effectively defines the order of display
88 # effectively defines the order of display
88 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
89 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
89 'length', 'file', 'definition', 'docstring', 'source',
90 'length', 'file', 'definition', 'docstring', 'source',
90 'init_definition', 'class_docstring', 'init_docstring',
91 'init_definition', 'class_docstring', 'init_docstring',
91 'call_def', 'call_docstring',
92 'call_def', 'call_docstring',
92 # These won't be printed but will be used to determine how to
93 # These won't be printed but will be used to determine how to
93 # format the object
94 # format the object
94 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
95 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
95 ]
96 ]
96
97
97
98
98 def object_info(**kw):
99 def object_info(**kw):
99 """Make an object info dict with all fields present."""
100 """Make an object info dict with all fields present."""
100 infodict = dict(izip_longest(info_fields, [None]))
101 infodict = dict(izip_longest(info_fields, [None]))
101 infodict.update(kw)
102 infodict.update(kw)
102 return infodict
103 return infodict
103
104
104
105
105 def get_encoding(obj):
106 def get_encoding(obj):
106 """Get encoding for python source file defining obj
107 """Get encoding for python source file defining obj
107
108
108 Returns None if obj is not defined in a sourcefile.
109 Returns None if obj is not defined in a sourcefile.
109 """
110 """
110 ofile = find_file(obj)
111 ofile = find_file(obj)
111 # run contents of file through pager starting at line where the object
112 # run contents of file through pager starting at line where the object
112 # is defined, as long as the file isn't binary and is actually on the
113 # is defined, as long as the file isn't binary and is actually on the
113 # filesystem.
114 # filesystem.
114 if ofile is None:
115 if ofile is None:
115 return None
116 return None
116 elif ofile.endswith(('.so', '.dll', '.pyd')):
117 elif ofile.endswith(('.so', '.dll', '.pyd')):
117 return None
118 return None
118 elif not os.path.isfile(ofile):
119 elif not os.path.isfile(ofile):
119 return None
120 return None
120 else:
121 else:
121 # Print only text files, not extension binaries. Note that
122 # Print only text files, not extension binaries. Note that
122 # getsourcelines returns lineno with 1-offset and page() uses
123 # getsourcelines returns lineno with 1-offset and page() uses
123 # 0-offset, so we must adjust.
124 # 0-offset, so we must adjust.
124 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
125 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
125 encoding, lines = openpy.detect_encoding(buffer.readline)
126 encoding, lines = openpy.detect_encoding(buffer.readline)
126 return encoding
127 return encoding
127
128
128 def getdoc(obj):
129 def getdoc(obj):
129 """Stable wrapper around inspect.getdoc.
130 """Stable wrapper around inspect.getdoc.
130
131
131 This can't crash because of attribute problems.
132 This can't crash because of attribute problems.
132
133
133 It also attempts to call a getdoc() method on the given object. This
134 It also attempts to call a getdoc() method on the given object. This
134 allows objects which provide their docstrings via non-standard mechanisms
135 allows objects which provide their docstrings via non-standard mechanisms
135 (like Pyro proxies) to still be inspected by ipython's ? system."""
136 (like Pyro proxies) to still be inspected by ipython's ? system."""
136 # Allow objects to offer customized documentation via a getdoc method:
137 # Allow objects to offer customized documentation via a getdoc method:
137 try:
138 try:
138 ds = obj.getdoc()
139 ds = obj.getdoc()
139 except Exception:
140 except Exception:
140 pass
141 pass
141 else:
142 else:
142 # if we get extra info, we add it to the normal docstring.
143 # if we get extra info, we add it to the normal docstring.
143 if isinstance(ds, string_types):
144 if isinstance(ds, string_types):
144 return inspect.cleandoc(ds)
145 return inspect.cleandoc(ds)
145
146
146 try:
147 try:
147 docstr = inspect.getdoc(obj)
148 docstr = inspect.getdoc(obj)
148 encoding = get_encoding(obj)
149 encoding = get_encoding(obj)
149 return py3compat.cast_unicode(docstr, encoding=encoding)
150 return py3compat.cast_unicode(docstr, encoding=encoding)
150 except Exception:
151 except Exception:
151 # Harden against an inspect failure, which can occur with
152 # Harden against an inspect failure, which can occur with
152 # SWIG-wrapped extensions.
153 # SWIG-wrapped extensions.
153 raise
154 raise
154 return None
155 return None
155
156
156
157
157 def getsource(obj, oname=''):
158 def getsource(obj, oname=''):
158 """Wrapper around inspect.getsource.
159 """Wrapper around inspect.getsource.
159
160
160 This can be modified by other projects to provide customized source
161 This can be modified by other projects to provide customized source
161 extraction.
162 extraction.
162
163
163 Parameters
164 Parameters
164 ----------
165 ----------
165 obj : object
166 obj : object
166 an object whose source code we will attempt to extract
167 an object whose source code we will attempt to extract
167 oname : str
168 oname : str
168 (optional) a name under which the object is known
169 (optional) a name under which the object is known
169
170
170 Returns
171 Returns
171 -------
172 -------
172 src : unicode or None
173 src : unicode or None
173
174
174 """
175 """
175
176
176 if isinstance(obj, property):
177 if isinstance(obj, property):
177 sources = []
178 sources = []
178 for attrname in ['fget', 'fset', 'fdel']:
179 for attrname in ['fget', 'fset', 'fdel']:
179 fn = getattr(obj, attrname)
180 fn = getattr(obj, attrname)
180 if fn is not None:
181 if fn is not None:
181 encoding = get_encoding(fn)
182 encoding = get_encoding(fn)
182 oname_prefix = ('%s.' % oname) if oname else ''
183 oname_prefix = ('%s.' % oname) if oname else ''
183 sources.append(cast_unicode(
184 sources.append(cast_unicode(
184 ''.join(('# ', oname_prefix, attrname)),
185 ''.join(('# ', oname_prefix, attrname)),
185 encoding=encoding))
186 encoding=encoding))
186 if inspect.isfunction(fn):
187 if inspect.isfunction(fn):
187 sources.append(dedent(getsource(fn)))
188 sources.append(dedent(getsource(fn)))
188 else:
189 else:
189 # Default str/repr only prints function name,
190 # Default str/repr only prints function name,
190 # pretty.pretty prints module name too.
191 # pretty.pretty prints module name too.
191 sources.append(cast_unicode(
192 sources.append(cast_unicode(
192 '%s%s = %s\n' % (
193 '%s%s = %s\n' % (
193 oname_prefix, attrname, pretty(fn)),
194 oname_prefix, attrname, pretty(fn)),
194 encoding=encoding))
195 encoding=encoding))
195 if sources:
196 if sources:
196 return '\n'.join(sources)
197 return '\n'.join(sources)
197 else:
198 else:
198 return None
199 return None
199
200
200 else:
201 else:
201 # Get source for non-property objects.
202 # Get source for non-property objects.
202
203
203 # '__wrapped__' attribute is used by some decorators (e.g. ones defined
204 # '__wrapped__' attribute is used by some decorators (e.g. ones defined
204 # functools) to provide access to the decorated function.
205 # functools) to provide access to the decorated function.
205 if hasattr(obj, "__wrapped__"):
206 if hasattr(obj, "__wrapped__"):
206 obj = obj.__wrapped__
207 obj = obj.__wrapped__
207
208
208 try:
209 try:
209 src = inspect.getsource(obj)
210 src = inspect.getsource(obj)
210 except TypeError:
211 except TypeError:
211 # The object itself provided no meaningful source, try looking for
212 # The object itself provided no meaningful source, try looking for
212 # its class definition instead.
213 # its class definition instead.
213 if hasattr(obj, '__class__'):
214 if hasattr(obj, '__class__'):
214 try:
215 try:
215 src = inspect.getsource(obj.__class__)
216 src = inspect.getsource(obj.__class__)
216 except TypeError:
217 except TypeError:
217 return None
218 return None
218
219
219 encoding = get_encoding(obj)
220 encoding = get_encoding(obj)
220 return cast_unicode(src, encoding=encoding)
221 return cast_unicode(src, encoding=encoding)
221
222
222
223
223 def is_simple_callable(obj):
224 def is_simple_callable(obj):
224 """True if obj is a function ()"""
225 """True if obj is a function ()"""
225 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
226 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
226 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
227 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
227
228
228
229
229 def getargspec(obj):
230 def getargspec(obj):
230 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
231 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
231 :func:inspect.getargspec` on Python 2.
232 :func:inspect.getargspec` on Python 2.
232
233
233 In addition to functions and methods, this can also handle objects with a
234 In addition to functions and methods, this can also handle objects with a
234 ``__call__`` attribute.
235 ``__call__`` attribute.
235 """
236 """
236 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
237 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
237 obj = obj.__call__
238 obj = obj.__call__
238
239
239 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
240 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
240
241
241
242
242 def format_argspec(argspec):
243 def format_argspec(argspec):
243 """Format argspect, convenience wrapper around inspect's.
244 """Format argspect, convenience wrapper around inspect's.
244
245
245 This takes a dict instead of ordered arguments and calls
246 This takes a dict instead of ordered arguments and calls
246 inspect.format_argspec with the arguments in the necessary order.
247 inspect.format_argspec with the arguments in the necessary order.
247 """
248 """
248 return inspect.formatargspec(argspec['args'], argspec['varargs'],
249 return inspect.formatargspec(argspec['args'], argspec['varargs'],
249 argspec['varkw'], argspec['defaults'])
250 argspec['varkw'], argspec['defaults'])
250
251
251
252
252 def call_tip(oinfo, format_call=True):
253 def call_tip(oinfo, format_call=True):
253 """Extract call tip data from an oinfo dict.
254 """Extract call tip data from an oinfo dict.
254
255
255 Parameters
256 Parameters
256 ----------
257 ----------
257 oinfo : dict
258 oinfo : dict
258
259
259 format_call : bool, optional
260 format_call : bool, optional
260 If True, the call line is formatted and returned as a string. If not, a
261 If True, the call line is formatted and returned as a string. If not, a
261 tuple of (name, argspec) is returned.
262 tuple of (name, argspec) is returned.
262
263
263 Returns
264 Returns
264 -------
265 -------
265 call_info : None, str or (str, dict) tuple.
266 call_info : None, str or (str, dict) tuple.
266 When format_call is True, the whole call information is formattted as a
267 When format_call is True, the whole call information is formattted as a
267 single string. Otherwise, the object's name and its argspec dict are
268 single string. Otherwise, the object's name and its argspec dict are
268 returned. If no call information is available, None is returned.
269 returned. If no call information is available, None is returned.
269
270
270 docstring : str or None
271 docstring : str or None
271 The most relevant docstring for calling purposes is returned, if
272 The most relevant docstring for calling purposes is returned, if
272 available. The priority is: call docstring for callable instances, then
273 available. The priority is: call docstring for callable instances, then
273 constructor docstring for classes, then main object's docstring otherwise
274 constructor docstring for classes, then main object's docstring otherwise
274 (regular functions).
275 (regular functions).
275 """
276 """
276 # Get call definition
277 # Get call definition
277 argspec = oinfo.get('argspec')
278 argspec = oinfo.get('argspec')
278 if argspec is None:
279 if argspec is None:
279 call_line = None
280 call_line = None
280 else:
281 else:
281 # Callable objects will have 'self' as their first argument, prune
282 # Callable objects will have 'self' as their first argument, prune
282 # it out if it's there for clarity (since users do *not* pass an
283 # it out if it's there for clarity (since users do *not* pass an
283 # extra first argument explicitly).
284 # extra first argument explicitly).
284 try:
285 try:
285 has_self = argspec['args'][0] == 'self'
286 has_self = argspec['args'][0] == 'self'
286 except (KeyError, IndexError):
287 except (KeyError, IndexError):
287 pass
288 pass
288 else:
289 else:
289 if has_self:
290 if has_self:
290 argspec['args'] = argspec['args'][1:]
291 argspec['args'] = argspec['args'][1:]
291
292
292 call_line = oinfo['name']+format_argspec(argspec)
293 call_line = oinfo['name']+format_argspec(argspec)
293
294
294 # Now get docstring.
295 # Now get docstring.
295 # The priority is: call docstring, constructor docstring, main one.
296 # The priority is: call docstring, constructor docstring, main one.
296 doc = oinfo.get('call_docstring')
297 doc = oinfo.get('call_docstring')
297 if doc is None:
298 if doc is None:
298 doc = oinfo.get('init_docstring')
299 doc = oinfo.get('init_docstring')
299 if doc is None:
300 if doc is None:
300 doc = oinfo.get('docstring','')
301 doc = oinfo.get('docstring','')
301
302
302 return call_line, doc
303 return call_line, doc
303
304
304
305
305 def find_file(obj):
306 def find_file(obj):
306 """Find the absolute path to the file where an object was defined.
307 """Find the absolute path to the file where an object was defined.
307
308
308 This is essentially a robust wrapper around `inspect.getabsfile`.
309 This is essentially a robust wrapper around `inspect.getabsfile`.
309
310
310 Returns None if no file can be found.
311 Returns None if no file can be found.
311
312
312 Parameters
313 Parameters
313 ----------
314 ----------
314 obj : any Python object
315 obj : any Python object
315
316
316 Returns
317 Returns
317 -------
318 -------
318 fname : str
319 fname : str
319 The absolute path to the file where the object was defined.
320 The absolute path to the file where the object was defined.
320 """
321 """
321 # get source if obj was decorated with @decorator
322 # get source if obj was decorated with @decorator
322 if safe_hasattr(obj, '__wrapped__'):
323 if safe_hasattr(obj, '__wrapped__'):
323 obj = obj.__wrapped__
324 obj = obj.__wrapped__
324
325
325 fname = None
326 fname = None
326 try:
327 try:
327 fname = inspect.getabsfile(obj)
328 fname = inspect.getabsfile(obj)
328 except TypeError:
329 except TypeError:
329 # For an instance, the file that matters is where its class was
330 # For an instance, the file that matters is where its class was
330 # declared.
331 # declared.
331 if hasattr(obj, '__class__'):
332 if hasattr(obj, '__class__'):
332 try:
333 try:
333 fname = inspect.getabsfile(obj.__class__)
334 fname = inspect.getabsfile(obj.__class__)
334 except TypeError:
335 except TypeError:
335 # Can happen for builtins
336 # Can happen for builtins
336 pass
337 pass
337 except:
338 except:
338 pass
339 pass
339 return cast_unicode(fname)
340 return cast_unicode(fname)
340
341
341
342
342 def find_source_lines(obj):
343 def find_source_lines(obj):
343 """Find the line number in a file where an object was defined.
344 """Find the line number in a file where an object was defined.
344
345
345 This is essentially a robust wrapper around `inspect.getsourcelines`.
346 This is essentially a robust wrapper around `inspect.getsourcelines`.
346
347
347 Returns None if no file can be found.
348 Returns None if no file can be found.
348
349
349 Parameters
350 Parameters
350 ----------
351 ----------
351 obj : any Python object
352 obj : any Python object
352
353
353 Returns
354 Returns
354 -------
355 -------
355 lineno : int
356 lineno : int
356 The line number where the object definition starts.
357 The line number where the object definition starts.
357 """
358 """
358 # get source if obj was decorated with @decorator
359 # get source if obj was decorated with @decorator
359 if safe_hasattr(obj, '__wrapped__'):
360 if safe_hasattr(obj, '__wrapped__'):
360 obj = obj.__wrapped__
361 obj = obj.__wrapped__
361
362
362 try:
363 try:
363 try:
364 try:
364 lineno = inspect.getsourcelines(obj)[1]
365 lineno = inspect.getsourcelines(obj)[1]
365 except TypeError:
366 except TypeError:
366 # For instances, try the class object like getsource() does
367 # For instances, try the class object like getsource() does
367 if hasattr(obj, '__class__'):
368 if hasattr(obj, '__class__'):
368 lineno = inspect.getsourcelines(obj.__class__)[1]
369 lineno = inspect.getsourcelines(obj.__class__)[1]
369 else:
370 else:
370 lineno = None
371 lineno = None
371 except:
372 except:
372 return None
373 return None
373
374
374 return lineno
375 return lineno
375
376
376
377
377 class Inspector:
378 class Inspector:
378 def __init__(self, color_table=InspectColors,
379 def __init__(self, color_table=InspectColors,
379 code_color_table=PyColorize.ANSICodeColors,
380 code_color_table=PyColorize.ANSICodeColors,
380 scheme='NoColor',
381 scheme='NoColor',
381 str_detail_level=0):
382 str_detail_level=0):
382 self.color_table = color_table
383 self.color_table = color_table
383 self.parser = PyColorize.Parser(code_color_table,out='str')
384 self.parser = PyColorize.Parser(code_color_table,out='str')
384 self.format = self.parser.format
385 self.format = self.parser.format
385 self.str_detail_level = str_detail_level
386 self.str_detail_level = str_detail_level
386 self.set_active_scheme(scheme)
387 self.set_active_scheme(scheme)
387
388
388 def _getdef(self,obj,oname=''):
389 def _getdef(self,obj,oname=''):
389 """Return the call signature for any callable object.
390 """Return the call signature for any callable object.
390
391
391 If any exception is generated, None is returned instead and the
392 If any exception is generated, None is returned instead and the
392 exception is suppressed."""
393 exception is suppressed."""
393 try:
394 try:
394 hdef = oname + str(signature(obj))
395 hdef = oname + str(signature(obj))
395 return cast_unicode(hdef)
396 return cast_unicode(hdef)
396 except:
397 except:
397 return None
398 return None
398
399
399 def __head(self,h):
400 def __head(self,h):
400 """Return a header string with proper colors."""
401 """Return a header string with proper colors."""
401 return '%s%s%s' % (self.color_table.active_colors.header,h,
402 return '%s%s%s' % (self.color_table.active_colors.header,h,
402 self.color_table.active_colors.normal)
403 self.color_table.active_colors.normal)
403
404
404 def set_active_scheme(self, scheme):
405 def set_active_scheme(self, scheme):
405 self.color_table.set_active_scheme(scheme)
406 self.color_table.set_active_scheme(scheme)
406 self.parser.color_table.set_active_scheme(scheme)
407 self.parser.color_table.set_active_scheme(scheme)
407
408
408 def noinfo(self, msg, oname):
409 def noinfo(self, msg, oname):
409 """Generic message when no information is found."""
410 """Generic message when no information is found."""
410 print('No %s found' % msg, end=' ')
411 print('No %s found' % msg, end=' ')
411 if oname:
412 if oname:
412 print('for %s' % oname)
413 print('for %s' % oname)
413 else:
414 else:
414 print()
415 print()
415
416
416 def pdef(self, obj, oname=''):
417 def pdef(self, obj, oname=''):
417 """Print the call signature for any callable object.
418 """Print the call signature for any callable object.
418
419
419 If the object is a class, print the constructor information."""
420 If the object is a class, print the constructor information."""
420
421
421 if not callable(obj):
422 if not callable(obj):
422 print('Object is not callable.')
423 print('Object is not callable.')
423 return
424 return
424
425
425 header = ''
426 header = ''
426
427
427 if inspect.isclass(obj):
428 if inspect.isclass(obj):
428 header = self.__head('Class constructor information:\n')
429 header = self.__head('Class constructor information:\n')
429 obj = obj.__init__
430 obj = obj.__init__
430 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
431 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
431 obj = obj.__call__
432 obj = obj.__call__
432
433
433 output = self._getdef(obj,oname)
434 output = self._getdef(obj,oname)
434 if output is None:
435 if output is None:
435 self.noinfo('definition header',oname)
436 self.noinfo('definition header',oname)
436 else:
437 else:
437 print(header,self.format(output), end=' ', file=io.stdout)
438 print(header,self.format(output), end=' ', file=io.stdout)
438
439
439 # In Python 3, all classes are new-style, so they all have __init__.
440 # In Python 3, all classes are new-style, so they all have __init__.
440 @skip_doctest_py3
441 @skip_doctest_py3
441 def pdoc(self,obj,oname='',formatter = None):
442 def pdoc(self,obj,oname='',formatter = None):
442 """Print the docstring for any object.
443 """Print the docstring for any object.
443
444
444 Optional:
445 Optional:
445 -formatter: a function to run the docstring through for specially
446 -formatter: a function to run the docstring through for specially
446 formatted docstrings.
447 formatted docstrings.
447
448
448 Examples
449 Examples
449 --------
450 --------
450
451
451 In [1]: class NoInit:
452 In [1]: class NoInit:
452 ...: pass
453 ...: pass
453
454
454 In [2]: class NoDoc:
455 In [2]: class NoDoc:
455 ...: def __init__(self):
456 ...: def __init__(self):
456 ...: pass
457 ...: pass
457
458
458 In [3]: %pdoc NoDoc
459 In [3]: %pdoc NoDoc
459 No documentation found for NoDoc
460 No documentation found for NoDoc
460
461
461 In [4]: %pdoc NoInit
462 In [4]: %pdoc NoInit
462 No documentation found for NoInit
463 No documentation found for NoInit
463
464
464 In [5]: obj = NoInit()
465 In [5]: obj = NoInit()
465
466
466 In [6]: %pdoc obj
467 In [6]: %pdoc obj
467 No documentation found for obj
468 No documentation found for obj
468
469
469 In [5]: obj2 = NoDoc()
470 In [5]: obj2 = NoDoc()
470
471
471 In [6]: %pdoc obj2
472 In [6]: %pdoc obj2
472 No documentation found for obj2
473 No documentation found for obj2
473 """
474 """
474
475
475 head = self.__head # For convenience
476 head = self.__head # For convenience
476 lines = []
477 lines = []
477 ds = getdoc(obj)
478 ds = getdoc(obj)
478 if formatter:
479 if formatter:
479 ds = formatter(ds)
480 ds = formatter(ds)
480 if ds:
481 if ds:
481 lines.append(head("Class docstring:"))
482 lines.append(head("Class docstring:"))
482 lines.append(indent(ds))
483 lines.append(indent(ds))
483 if inspect.isclass(obj) and hasattr(obj, '__init__'):
484 if inspect.isclass(obj) and hasattr(obj, '__init__'):
484 init_ds = getdoc(obj.__init__)
485 init_ds = getdoc(obj.__init__)
485 if init_ds is not None:
486 if init_ds is not None:
486 lines.append(head("Init docstring:"))
487 lines.append(head("Init docstring:"))
487 lines.append(indent(init_ds))
488 lines.append(indent(init_ds))
488 elif hasattr(obj,'__call__'):
489 elif hasattr(obj,'__call__'):
489 call_ds = getdoc(obj.__call__)
490 call_ds = getdoc(obj.__call__)
490 if call_ds:
491 if call_ds:
491 lines.append(head("Call docstring:"))
492 lines.append(head("Call docstring:"))
492 lines.append(indent(call_ds))
493 lines.append(indent(call_ds))
493
494
494 if not lines:
495 if not lines:
495 self.noinfo('documentation',oname)
496 self.noinfo('documentation',oname)
496 else:
497 else:
497 page.page('\n'.join(lines))
498 page.page('\n'.join(lines))
498
499
499 def psource(self, obj, oname=''):
500 def psource(self, obj, oname=''):
500 """Print the source code for an object."""
501 """Print the source code for an object."""
501
502
502 # Flush the source cache because inspect can return out-of-date source
503 # Flush the source cache because inspect can return out-of-date source
503 linecache.checkcache()
504 linecache.checkcache()
504 try:
505 try:
505 src = getsource(obj, oname=oname)
506 src = getsource(obj, oname=oname)
506 except Exception:
507 except Exception:
507 src = None
508 src = None
508
509
509 if src is None:
510 if src is None:
510 self.noinfo('source', oname)
511 self.noinfo('source', oname)
511 else:
512 else:
512 page.page(self.format(src))
513 page.page(self.format(src))
513
514
514 def pfile(self, obj, oname=''):
515 def pfile(self, obj, oname=''):
515 """Show the whole file where an object was defined."""
516 """Show the whole file where an object was defined."""
516
517
517 lineno = find_source_lines(obj)
518 lineno = find_source_lines(obj)
518 if lineno is None:
519 if lineno is None:
519 self.noinfo('file', oname)
520 self.noinfo('file', oname)
520 return
521 return
521
522
522 ofile = find_file(obj)
523 ofile = find_file(obj)
523 # run contents of file through pager starting at line where the object
524 # run contents of file through pager starting at line where the object
524 # is defined, as long as the file isn't binary and is actually on the
525 # is defined, as long as the file isn't binary and is actually on the
525 # filesystem.
526 # filesystem.
526 if ofile.endswith(('.so', '.dll', '.pyd')):
527 if ofile.endswith(('.so', '.dll', '.pyd')):
527 print('File %r is binary, not printing.' % ofile)
528 print('File %r is binary, not printing.' % ofile)
528 elif not os.path.isfile(ofile):
529 elif not os.path.isfile(ofile):
529 print('File %r does not exist, not printing.' % ofile)
530 print('File %r does not exist, not printing.' % ofile)
530 else:
531 else:
531 # Print only text files, not extension binaries. Note that
532 # Print only text files, not extension binaries. Note that
532 # getsourcelines returns lineno with 1-offset and page() uses
533 # getsourcelines returns lineno with 1-offset and page() uses
533 # 0-offset, so we must adjust.
534 # 0-offset, so we must adjust.
534 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
535 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
535
536
536 def _format_fields(self, fields, title_width=0):
537 def _format_fields(self, fields, title_width=0):
537 """Formats a list of fields for display.
538 """Formats a list of fields for display.
538
539
539 Parameters
540 Parameters
540 ----------
541 ----------
541 fields : list
542 fields : list
542 A list of 2-tuples: (field_title, field_content)
543 A list of 2-tuples: (field_title, field_content)
543 title_width : int
544 title_width : int
544 How many characters to pad titles to. Default to longest title.
545 How many characters to pad titles to. Default to longest title.
545 """
546 """
546 out = []
547 out = []
547 header = self.__head
548 header = self.__head
548 if title_width == 0:
549 if title_width == 0:
549 title_width = max(len(title) + 2 for title, _ in fields)
550 title_width = max(len(title) + 2 for title, _ in fields)
550 for title, content in fields:
551 for title, content in fields:
551 if len(content.splitlines()) > 1:
552 if len(content.splitlines()) > 1:
552 title = header(title + ":") + "\n"
553 title = header(title + ":") + "\n"
553 else:
554 else:
554 title = header((title+":").ljust(title_width))
555 title = header((title+":").ljust(title_width))
555 out.append(cast_unicode(title) + cast_unicode(content))
556 out.append(cast_unicode(title) + cast_unicode(content))
556 return "\n".join(out)
557 return "\n".join(out)
557
558 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
559 pinfo_fields1 = [("Type", "type_name"),
560 ]
561
562 pinfo_fields2 = [("String form", "string_form"),
563 ]
564
565 pinfo_fields3 = [("Length", "length"),
566 ("File", "file"),
567 ("Definition", "definition"),
568 ]
569
570 pinfo_fields_obj = [("Class docstring", "class_docstring"),
571 ("Init docstring", "init_docstring"),
572 ("Call def", "call_def"),
573 ("Call docstring", "call_docstring")]
574
558
575 def _format_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
559 def _format_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
576 """Format an info dict as text"""
560 """Format an info dict as text"""
577 info = self.info(obj, oname=oname, formatter=formatter,
561 info = self.info(obj, oname=oname, formatter=formatter,
578 info=info, detail_level=detail_level)
562 info=info, detail_level=detail_level)
579 displayfields = []
563 displayfields = []
580 def add_fields(fields):
564 def add_fields(fields):
581 for title, key in fields:
565 for title, key in fields:
582 field = info[key]
566 field = info[key]
583 if field is not None:
567 if field is not None:
584 displayfields.append((title, field.rstrip()))
568 displayfields.append((title, field.rstrip()))
585
569
586 add_fields(self.pinfo_fields1)
570 if info['isalias']:
587
571 add_fields([('Repr', "string_form")])
588 # Base class for old-style instances
572
589 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
573 elif info['ismagic']:
590 displayfields.append(("Base Class", info['base_class'].rstrip()))
574 add_fields([("Docstring", "docstring"),
591
575 ("File", "file")
592 add_fields(self.pinfo_fields2)
576 ])
593
577
594 # Namespace
578 elif info['isclass'] or is_simple_callable(obj):
595 if info['namespace'] != 'Interactive':
579 # Functions, methods, classes
596 displayfields.append(("Namespace", info['namespace'].rstrip()))
580 add_fields([("Signature", "definition"),
597
581 ("Init signature", "init_definition"),
598 add_fields(self.pinfo_fields3)
582 ])
599 if info['isclass'] and info['init_definition']:
583 if detail_level > 0 and info['source'] is not None:
600 displayfields.append(("Init definition",
584 add_fields([("Source", "source")])
601 info['init_definition'].rstrip()))
585 else:
602
586 add_fields([("Docstring", "docstring"),
603 # Source or docstring, depending on detail level and whether
587 ("Init docstring", "init_docstring"),
604 # source found.
588 ])
605 if detail_level > 0 and info['source'] is not None:
589
606 displayfields.append(("Source",
590 add_fields([('File', 'file'),
607 self.format(cast_unicode(info['source']))))
591 ('Type', 'type_name'),
608 elif info['docstring'] is not None:
592 ])
609 displayfields.append(("Docstring", info["docstring"]))
593
610
611 # Constructor info for classes
612 if info['isclass']:
613 if info['init_docstring'] is not None:
614 displayfields.append(("Init docstring",
615 info['init_docstring']))
616
617 # Info for objects:
618 else:
594 else:
619 add_fields(self.pinfo_fields_obj)
595 # General Python objects
596 add_fields([("Type", "type_name")])
597
598 # Base class for old-style instances
599 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
600 displayfields.append(("Base Class", info['base_class'].rstrip()))
601
602 add_fields([("String form", "string_form")])
603
604 # Namespace
605 if info['namespace'] != 'Interactive':
606 displayfields.append(("Namespace", info['namespace'].rstrip()))
607
608 add_fields([("Length", "length"),
609 ("File", "file"),
610 ("Signature", "definition"),
611 ])
612
613 # Source or docstring, depending on detail level and whether
614 # source found.
615 if detail_level > 0 and info['source'] is not None:
616 displayfields.append(("Source",
617 self.format(cast_unicode(info['source']))))
618 elif info['docstring'] is not None:
619 displayfields.append(("Docstring", info["docstring"]))
620
621 add_fields([("Class docstring", "class_docstring"),
622 ("Init docstring", "init_docstring"),
623 ("Call signature", "call_def"),
624 ("Call docstring", "call_docstring")])
620
625
621 if displayfields:
626 if displayfields:
622 return self._format_fields(displayfields)
627 return self._format_fields(displayfields)
623 else:
628 else:
624 return u''
629 return u''
625
630
626 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
631 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
627 """Show detailed information about an object.
632 """Show detailed information about an object.
628
633
629 Optional arguments:
634 Optional arguments:
630
635
631 - oname: name of the variable pointing to the object.
636 - oname: name of the variable pointing to the object.
632
637
633 - formatter: special formatter for docstrings (see pdoc)
638 - formatter: special formatter for docstrings (see pdoc)
634
639
635 - info: a structure with some information fields which may have been
640 - info: a structure with some information fields which may have been
636 precomputed already.
641 precomputed already.
637
642
638 - detail_level: if set to 1, more information is given.
643 - detail_level: if set to 1, more information is given.
639 """
644 """
640 text = self._format_info(obj, oname, formatter, info, detail_level)
645 text = self._format_info(obj, oname, formatter, info, detail_level)
641 if text:
646 if text:
642 page.page(text)
647 page.page(text)
643
648
644 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
649 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
645 """Compute a dict with detailed information about an object.
650 """Compute a dict with detailed information about an object.
646
651
647 Optional arguments:
652 Optional arguments:
648
653
649 - oname: name of the variable pointing to the object.
654 - oname: name of the variable pointing to the object.
650
655
651 - formatter: special formatter for docstrings (see pdoc)
656 - formatter: special formatter for docstrings (see pdoc)
652
657
653 - info: a structure with some information fields which may have been
658 - info: a structure with some information fields which may have been
654 precomputed already.
659 precomputed already.
655
660
656 - detail_level: if set to 1, more information is given.
661 - detail_level: if set to 1, more information is given.
657 """
662 """
658
663
659 obj_type = type(obj)
664 obj_type = type(obj)
660
665
661 if info is None:
666 if info is None:
662 ismagic = 0
667 ismagic = 0
663 isalias = 0
668 isalias = 0
664 ospace = ''
669 ospace = ''
665 else:
670 else:
666 ismagic = info.ismagic
671 ismagic = info.ismagic
667 isalias = info.isalias
672 isalias = info.isalias
668 ospace = info.namespace
673 ospace = info.namespace
669
674
670 # Get docstring, special-casing aliases:
675 # Get docstring, special-casing aliases:
671 if isalias:
676 if isalias:
672 if not callable(obj):
677 if not callable(obj):
673 try:
678 try:
674 ds = "Alias to the system command:\n %s" % obj[1]
679 ds = "Alias to the system command:\n %s" % obj[1]
675 except:
680 except:
676 ds = "Alias: " + str(obj)
681 ds = "Alias: " + str(obj)
677 else:
682 else:
678 ds = "Alias to " + str(obj)
683 ds = "Alias to " + str(obj)
679 if obj.__doc__:
684 if obj.__doc__:
680 ds += "\nDocstring:\n" + obj.__doc__
685 ds += "\nDocstring:\n" + obj.__doc__
681 else:
686 else:
682 ds = getdoc(obj)
687 ds = getdoc(obj)
683 if ds is None:
688 if ds is None:
684 ds = '<no docstring>'
689 ds = '<no docstring>'
685 if formatter is not None:
690 if formatter is not None:
686 ds = formatter(ds)
691 ds = formatter(ds)
687
692
688 # store output in a dict, we initialize it here and fill it as we go
693 # store output in a dict, we initialize it here and fill it as we go
689 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
694 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
690
695
691 string_max = 200 # max size of strings to show (snipped if longer)
696 string_max = 200 # max size of strings to show (snipped if longer)
692 shalf = int((string_max -5)/2)
697 shalf = int((string_max -5)/2)
693
698
694 if ismagic:
699 if ismagic:
695 obj_type_name = 'Magic function'
700 obj_type_name = 'Magic function'
696 elif isalias:
701 elif isalias:
697 obj_type_name = 'System alias'
702 obj_type_name = 'System alias'
698 else:
703 else:
699 obj_type_name = obj_type.__name__
704 obj_type_name = obj_type.__name__
700 out['type_name'] = obj_type_name
705 out['type_name'] = obj_type_name
701
706
702 try:
707 try:
703 bclass = obj.__class__
708 bclass = obj.__class__
704 out['base_class'] = str(bclass)
709 out['base_class'] = str(bclass)
705 except: pass
710 except: pass
706
711
707 # String form, but snip if too long in ? form (full in ??)
712 # String form, but snip if too long in ? form (full in ??)
708 if detail_level >= self.str_detail_level:
713 if detail_level >= self.str_detail_level:
709 try:
714 try:
710 ostr = str(obj)
715 ostr = str(obj)
711 str_head = 'string_form'
716 str_head = 'string_form'
712 if not detail_level and len(ostr)>string_max:
717 if not detail_level and len(ostr)>string_max:
713 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
718 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
714 ostr = ("\n" + " " * len(str_head.expandtabs())).\
719 ostr = ("\n" + " " * len(str_head.expandtabs())).\
715 join(q.strip() for q in ostr.split("\n"))
720 join(q.strip() for q in ostr.split("\n"))
716 out[str_head] = ostr
721 out[str_head] = ostr
717 except:
722 except:
718 pass
723 pass
719
724
720 if ospace:
725 if ospace:
721 out['namespace'] = ospace
726 out['namespace'] = ospace
722
727
723 # Length (for strings and lists)
728 # Length (for strings and lists)
724 try:
729 try:
725 out['length'] = str(len(obj))
730 out['length'] = str(len(obj))
726 except: pass
731 except: pass
727
732
728 # Filename where object was defined
733 # Filename where object was defined
729 binary_file = False
734 binary_file = False
730 fname = find_file(obj)
735 fname = find_file(obj)
731 if fname is None:
736 if fname is None:
732 # if anything goes wrong, we don't want to show source, so it's as
737 # if anything goes wrong, we don't want to show source, so it's as
733 # if the file was binary
738 # if the file was binary
734 binary_file = True
739 binary_file = True
735 else:
740 else:
736 if fname.endswith(('.so', '.dll', '.pyd')):
741 if fname.endswith(('.so', '.dll', '.pyd')):
737 binary_file = True
742 binary_file = True
738 elif fname.endswith('<string>'):
743 elif fname.endswith('<string>'):
739 fname = 'Dynamically generated function. No source code available.'
744 fname = 'Dynamically generated function. No source code available.'
740 out['file'] = fname
745 out['file'] = compress_user(fname)
741
746
742 # Original source code for a callable, class or property.
747 # Original source code for a callable, class or property.
743 if detail_level:
748 if detail_level:
744 # Flush the source cache because inspect can return out-of-date
749 # Flush the source cache because inspect can return out-of-date
745 # source
750 # source
746 linecache.checkcache()
751 linecache.checkcache()
747 try:
752 try:
748 if isinstance(obj, property) or not binary_file:
753 if isinstance(obj, property) or not binary_file:
749 src = getsource(obj, oname)
754 src = getsource(obj, oname)
750 if src is not None:
755 if src is not None:
751 src = src.rstrip()
756 src = src.rstrip()
752 out['source'] = src
757 out['source'] = src
753
758
754 except Exception:
759 except Exception:
755 pass
760 pass
756
761
757 # Add docstring only if no source is to be shown (avoid repetitions).
762 # Add docstring only if no source is to be shown (avoid repetitions).
758 if ds and out.get('source', None) is None:
763 if ds and out.get('source', None) is None:
759 out['docstring'] = ds
764 out['docstring'] = ds
760
765
761 # Constructor docstring for classes
766 # Constructor docstring for classes
762 if inspect.isclass(obj):
767 if inspect.isclass(obj):
763 out['isclass'] = True
768 out['isclass'] = True
764 # reconstruct the function definition and print it:
769 # reconstruct the function definition and print it:
765 try:
770 try:
766 obj_init = obj.__init__
771 obj_init = obj.__init__
767 except AttributeError:
772 except AttributeError:
768 init_def = init_ds = None
773 init_def = init_ds = None
769 else:
774 else:
770 init_def = self._getdef(obj_init,oname)
775 init_def = self._getdef(obj_init,oname)
771 init_ds = getdoc(obj_init)
776 init_ds = getdoc(obj_init)
772 # Skip Python's auto-generated docstrings
777 # Skip Python's auto-generated docstrings
773 if init_ds == _object_init_docstring:
778 if init_ds == _object_init_docstring:
774 init_ds = None
779 init_ds = None
775
780
776 if init_def or init_ds:
781 if init_def or init_ds:
777 if init_def:
782 if init_def:
778 out['init_definition'] = self.format(init_def)
783 out['init_definition'] = self.format(init_def)
779 if init_ds:
784 if init_ds:
780 out['init_docstring'] = init_ds
785 out['init_docstring'] = init_ds
781
786
782 # and class docstring for instances:
787 # and class docstring for instances:
783 else:
788 else:
784 # reconstruct the function definition and print it:
789 # reconstruct the function definition and print it:
785 defln = self._getdef(obj, oname)
790 defln = self._getdef(obj, oname)
786 if defln:
791 if defln:
787 out['definition'] = self.format(defln)
792 out['definition'] = self.format(defln)
788
793
789 # First, check whether the instance docstring is identical to the
794 # First, check whether the instance docstring is identical to the
790 # class one, and print it separately if they don't coincide. In
795 # class one, and print it separately if they don't coincide. In
791 # most cases they will, but it's nice to print all the info for
796 # most cases they will, but it's nice to print all the info for
792 # objects which use instance-customized docstrings.
797 # objects which use instance-customized docstrings.
793 if ds:
798 if ds:
794 try:
799 try:
795 cls = getattr(obj,'__class__')
800 cls = getattr(obj,'__class__')
796 except:
801 except:
797 class_ds = None
802 class_ds = None
798 else:
803 else:
799 class_ds = getdoc(cls)
804 class_ds = getdoc(cls)
800 # Skip Python's auto-generated docstrings
805 # Skip Python's auto-generated docstrings
801 if class_ds in _builtin_type_docstrings:
806 if class_ds in _builtin_type_docstrings:
802 class_ds = None
807 class_ds = None
803 if class_ds and ds != class_ds:
808 if class_ds and ds != class_ds:
804 out['class_docstring'] = class_ds
809 out['class_docstring'] = class_ds
805
810
806 # Next, try to show constructor docstrings
811 # Next, try to show constructor docstrings
807 try:
812 try:
808 init_ds = getdoc(obj.__init__)
813 init_ds = getdoc(obj.__init__)
809 # Skip Python's auto-generated docstrings
814 # Skip Python's auto-generated docstrings
810 if init_ds == _object_init_docstring:
815 if init_ds == _object_init_docstring:
811 init_ds = None
816 init_ds = None
812 except AttributeError:
817 except AttributeError:
813 init_ds = None
818 init_ds = None
814 if init_ds:
819 if init_ds:
815 out['init_docstring'] = init_ds
820 out['init_docstring'] = init_ds
816
821
817 # Call form docstring for callable instances
822 # Call form docstring for callable instances
818 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
823 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
819 call_def = self._getdef(obj.__call__, oname)
824 call_def = self._getdef(obj.__call__, oname)
820 if call_def:
825 if call_def:
821 call_def = self.format(call_def)
826 call_def = self.format(call_def)
822 # it may never be the case that call def and definition differ,
827 # it may never be the case that call def and definition differ,
823 # but don't include the same signature twice
828 # but don't include the same signature twice
824 if call_def != out.get('definition'):
829 if call_def != out.get('definition'):
825 out['call_def'] = call_def
830 out['call_def'] = call_def
826 call_ds = getdoc(obj.__call__)
831 call_ds = getdoc(obj.__call__)
827 # Skip Python's auto-generated docstrings
832 # Skip Python's auto-generated docstrings
828 if call_ds == _func_call_docstring:
833 if call_ds == _func_call_docstring:
829 call_ds = None
834 call_ds = None
830 if call_ds:
835 if call_ds:
831 out['call_docstring'] = call_ds
836 out['call_docstring'] = call_ds
832
837
833 # Compute the object's argspec as a callable. The key is to decide
838 # Compute the object's argspec as a callable. The key is to decide
834 # whether to pull it from the object itself, from its __init__ or
839 # whether to pull it from the object itself, from its __init__ or
835 # from its __call__ method.
840 # from its __call__ method.
836
841
837 if inspect.isclass(obj):
842 if inspect.isclass(obj):
838 # Old-style classes need not have an __init__
843 # Old-style classes need not have an __init__
839 callable_obj = getattr(obj, "__init__", None)
844 callable_obj = getattr(obj, "__init__", None)
840 elif callable(obj):
845 elif callable(obj):
841 callable_obj = obj
846 callable_obj = obj
842 else:
847 else:
843 callable_obj = None
848 callable_obj = None
844
849
845 if callable_obj:
850 if callable_obj:
846 try:
851 try:
847 argspec = getargspec(callable_obj)
852 argspec = getargspec(callable_obj)
848 except (TypeError, AttributeError):
853 except (TypeError, AttributeError):
849 # For extensions/builtins we can't retrieve the argspec
854 # For extensions/builtins we can't retrieve the argspec
850 pass
855 pass
851 else:
856 else:
852 # named tuples' _asdict() method returns an OrderedDict, but we
857 # named tuples' _asdict() method returns an OrderedDict, but we
853 # we want a normal
858 # we want a normal
854 out['argspec'] = argspec_dict = dict(argspec._asdict())
859 out['argspec'] = argspec_dict = dict(argspec._asdict())
855 # We called this varkw before argspec became a named tuple.
860 # We called this varkw before argspec became a named tuple.
856 # With getfullargspec it's also called varkw.
861 # With getfullargspec it's also called varkw.
857 if 'varkw' not in argspec_dict:
862 if 'varkw' not in argspec_dict:
858 argspec_dict['varkw'] = argspec_dict.pop('keywords')
863 argspec_dict['varkw'] = argspec_dict.pop('keywords')
859
864
860 return object_info(**out)
865 return object_info(**out)
861
866
862 def psearch(self,pattern,ns_table,ns_search=[],
867 def psearch(self,pattern,ns_table,ns_search=[],
863 ignore_case=False,show_all=False):
868 ignore_case=False,show_all=False):
864 """Search namespaces with wildcards for objects.
869 """Search namespaces with wildcards for objects.
865
870
866 Arguments:
871 Arguments:
867
872
868 - pattern: string containing shell-like wildcards to use in namespace
873 - pattern: string containing shell-like wildcards to use in namespace
869 searches and optionally a type specification to narrow the search to
874 searches and optionally a type specification to narrow the search to
870 objects of that type.
875 objects of that type.
871
876
872 - ns_table: dict of name->namespaces for search.
877 - ns_table: dict of name->namespaces for search.
873
878
874 Optional arguments:
879 Optional arguments:
875
880
876 - ns_search: list of namespace names to include in search.
881 - ns_search: list of namespace names to include in search.
877
882
878 - ignore_case(False): make the search case-insensitive.
883 - ignore_case(False): make the search case-insensitive.
879
884
880 - show_all(False): show all names, including those starting with
885 - show_all(False): show all names, including those starting with
881 underscores.
886 underscores.
882 """
887 """
883 #print 'ps pattern:<%r>' % pattern # dbg
888 #print 'ps pattern:<%r>' % pattern # dbg
884
889
885 # defaults
890 # defaults
886 type_pattern = 'all'
891 type_pattern = 'all'
887 filter = ''
892 filter = ''
888
893
889 cmds = pattern.split()
894 cmds = pattern.split()
890 len_cmds = len(cmds)
895 len_cmds = len(cmds)
891 if len_cmds == 1:
896 if len_cmds == 1:
892 # Only filter pattern given
897 # Only filter pattern given
893 filter = cmds[0]
898 filter = cmds[0]
894 elif len_cmds == 2:
899 elif len_cmds == 2:
895 # Both filter and type specified
900 # Both filter and type specified
896 filter,type_pattern = cmds
901 filter,type_pattern = cmds
897 else:
902 else:
898 raise ValueError('invalid argument string for psearch: <%s>' %
903 raise ValueError('invalid argument string for psearch: <%s>' %
899 pattern)
904 pattern)
900
905
901 # filter search namespaces
906 # filter search namespaces
902 for name in ns_search:
907 for name in ns_search:
903 if name not in ns_table:
908 if name not in ns_table:
904 raise ValueError('invalid namespace <%s>. Valid names: %s' %
909 raise ValueError('invalid namespace <%s>. Valid names: %s' %
905 (name,ns_table.keys()))
910 (name,ns_table.keys()))
906
911
907 #print 'type_pattern:',type_pattern # dbg
912 #print 'type_pattern:',type_pattern # dbg
908 search_result, namespaces_seen = set(), set()
913 search_result, namespaces_seen = set(), set()
909 for ns_name in ns_search:
914 for ns_name in ns_search:
910 ns = ns_table[ns_name]
915 ns = ns_table[ns_name]
911 # Normally, locals and globals are the same, so we just check one.
916 # Normally, locals and globals are the same, so we just check one.
912 if id(ns) in namespaces_seen:
917 if id(ns) in namespaces_seen:
913 continue
918 continue
914 namespaces_seen.add(id(ns))
919 namespaces_seen.add(id(ns))
915 tmp_res = list_namespace(ns, type_pattern, filter,
920 tmp_res = list_namespace(ns, type_pattern, filter,
916 ignore_case=ignore_case, show_all=show_all)
921 ignore_case=ignore_case, show_all=show_all)
917 search_result.update(tmp_res)
922 search_result.update(tmp_res)
918
923
919 page.page('\n'.join(sorted(search_result)))
924 page.page('\n'.join(sorted(search_result)))
@@ -1,437 +1,422 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5
6 Authors
7 -------
8
9 * Min Ragan-Kelley
10 """
5 """
11
6
12 #-----------------------------------------------------------------------------
7 # Copyright (c) IPython Development Team.
13 # Copyright (C) 2008-2011 The IPython Development Team
8 # Distributed under the terms of the Modified BSD License.
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
9
23 from __future__ import absolute_import
10 from __future__ import absolute_import
24 from __future__ import print_function
11 from __future__ import print_function
25
12
26 import glob
13 import glob
27 import os
14 import os
28 import sys
15 import sys
29
16
30 from IPython.config.application import boolean_flag
17 from IPython.config.application import boolean_flag
31 from IPython.config.configurable import Configurable
18 from IPython.config.configurable import Configurable
32 from IPython.config.loader import Config
19 from IPython.config.loader import Config
33 from IPython.core import pylabtools
20 from IPython.core import pylabtools
34 from IPython.utils import py3compat
21 from IPython.utils import py3compat
35 from IPython.utils.contexts import preserve_keys
22 from IPython.utils.contexts import preserve_keys
36 from IPython.utils.path import filefind
23 from IPython.utils.path import filefind
37 from IPython.utils.traitlets import (
24 from IPython.utils.traitlets import (
38 Unicode, Instance, List, Bool, CaselessStrEnum
25 Unicode, Instance, List, Bool, CaselessStrEnum
39 )
26 )
40 from IPython.lib.inputhook import guis
27 from IPython.lib.inputhook import guis
41
28
42 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
43 # Aliases and Flags
30 # Aliases and Flags
44 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
45
32
46 gui_keys = tuple(sorted([ key for key in guis if key is not None ]))
33 gui_keys = tuple(sorted([ key for key in guis if key is not None ]))
47
34
48 backend_keys = sorted(pylabtools.backends.keys())
35 backend_keys = sorted(pylabtools.backends.keys())
49 backend_keys.insert(0, 'auto')
36 backend_keys.insert(0, 'auto')
50
37
51 shell_flags = {}
38 shell_flags = {}
52
39
53 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
54 addflag('autoindent', 'InteractiveShell.autoindent',
41 addflag('autoindent', 'InteractiveShell.autoindent',
55 'Turn on autoindenting.', 'Turn off autoindenting.'
42 'Turn on autoindenting.', 'Turn off autoindenting.'
56 )
43 )
57 addflag('automagic', 'InteractiveShell.automagic',
44 addflag('automagic', 'InteractiveShell.automagic',
58 """Turn on the auto calling of magic commands. Type %%magic at the
45 """Turn on the auto calling of magic commands. Type %%magic at the
59 IPython prompt for more information.""",
46 IPython prompt for more information.""",
60 'Turn off the auto calling of magic commands.'
47 'Turn off the auto calling of magic commands.'
61 )
48 )
62 addflag('pdb', 'InteractiveShell.pdb',
49 addflag('pdb', 'InteractiveShell.pdb',
63 "Enable auto calling the pdb debugger after every exception.",
50 "Enable auto calling the pdb debugger after every exception.",
64 "Disable auto calling the pdb debugger after every exception."
51 "Disable auto calling the pdb debugger after every exception."
65 )
52 )
66 # pydb flag doesn't do any config, as core.debugger switches on import,
53 # pydb flag doesn't do any config, as core.debugger switches on import,
67 # which is before parsing. This just allows the flag to be passed.
54 # which is before parsing. This just allows the flag to be passed.
68 shell_flags.update(dict(
55 shell_flags.update(dict(
69 pydb = ({},
56 pydb = ({},
70 """Use the third party 'pydb' package as debugger, instead of pdb.
57 """Use the third party 'pydb' package as debugger, instead of pdb.
71 Requires that pydb is installed."""
58 Requires that pydb is installed."""
72 )
59 )
73 ))
60 ))
74 addflag('pprint', 'PlainTextFormatter.pprint',
61 addflag('pprint', 'PlainTextFormatter.pprint',
75 "Enable auto pretty printing of results.",
62 "Enable auto pretty printing of results.",
76 "Disable auto pretty printing of results."
63 "Disable auto pretty printing of results."
77 )
64 )
78 addflag('color-info', 'InteractiveShell.color_info',
65 addflag('color-info', 'InteractiveShell.color_info',
79 """IPython can display information about objects via a set of functions,
66 """IPython can display information about objects via a set of functions,
80 and optionally can use colors for this, syntax highlighting
67 and optionally can use colors for this, syntax highlighting
81 source code and various other elements. This is on by default, but can cause
68 source code and various other elements. This is on by default, but can cause
82 problems with some pagers. If you see such problems, you can disable the
69 problems with some pagers. If you see such problems, you can disable the
83 colours.""",
70 colours.""",
84 "Disable using colors for info related things."
71 "Disable using colors for info related things."
85 )
72 )
86 addflag('deep-reload', 'InteractiveShell.deep_reload',
73 addflag('deep-reload', 'InteractiveShell.deep_reload',
87 """Enable deep (recursive) reloading by default. IPython can use the
74 """Enable deep (recursive) reloading by default. IPython can use the
88 deep_reload module which reloads changes in modules recursively (it
75 deep_reload module which reloads changes in modules recursively (it
89 replaces the reload() function, so you don't need to change anything to
76 replaces the reload() function, so you don't need to change anything to
90 use it). deep_reload() forces a full reload of modules whose code may
77 use it). deep_reload() forces a full reload of modules whose code may
91 have changed, which the default reload() function does not. When
78 have changed, which the default reload() function does not. When
92 deep_reload is off, IPython will use the normal reload(), but
79 deep_reload is off, IPython will use the normal reload(), but
93 deep_reload will still be available as dreload(). This feature is off
80 deep_reload will still be available as dreload(). This feature is off
94 by default [which means that you have both normal reload() and
81 by default [which means that you have both normal reload() and
95 dreload()].""",
82 dreload()].""",
96 "Disable deep (recursive) reloading by default."
83 "Disable deep (recursive) reloading by default."
97 )
84 )
98 nosep_config = Config()
85 nosep_config = Config()
99 nosep_config.InteractiveShell.separate_in = ''
86 nosep_config.InteractiveShell.separate_in = ''
100 nosep_config.InteractiveShell.separate_out = ''
87 nosep_config.InteractiveShell.separate_out = ''
101 nosep_config.InteractiveShell.separate_out2 = ''
88 nosep_config.InteractiveShell.separate_out2 = ''
102
89
103 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
90 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
104 shell_flags['pylab'] = (
91 shell_flags['pylab'] = (
105 {'InteractiveShellApp' : {'pylab' : 'auto'}},
92 {'InteractiveShellApp' : {'pylab' : 'auto'}},
106 """Pre-load matplotlib and numpy for interactive use with
93 """Pre-load matplotlib and numpy for interactive use with
107 the default matplotlib backend."""
94 the default matplotlib backend."""
108 )
95 )
109 shell_flags['matplotlib'] = (
96 shell_flags['matplotlib'] = (
110 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
97 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
111 """Configure matplotlib for interactive use with
98 """Configure matplotlib for interactive use with
112 the default matplotlib backend."""
99 the default matplotlib backend."""
113 )
100 )
114
101
115 # it's possible we don't want short aliases for *all* of these:
102 # it's possible we don't want short aliases for *all* of these:
116 shell_aliases = dict(
103 shell_aliases = dict(
117 autocall='InteractiveShell.autocall',
104 autocall='InteractiveShell.autocall',
118 colors='InteractiveShell.colors',
105 colors='InteractiveShell.colors',
119 logfile='InteractiveShell.logfile',
106 logfile='InteractiveShell.logfile',
120 logappend='InteractiveShell.logappend',
107 logappend='InteractiveShell.logappend',
121 c='InteractiveShellApp.code_to_run',
108 c='InteractiveShellApp.code_to_run',
122 m='InteractiveShellApp.module_to_run',
109 m='InteractiveShellApp.module_to_run',
123 ext='InteractiveShellApp.extra_extension',
110 ext='InteractiveShellApp.extra_extension',
124 gui='InteractiveShellApp.gui',
111 gui='InteractiveShellApp.gui',
125 pylab='InteractiveShellApp.pylab',
112 pylab='InteractiveShellApp.pylab',
126 matplotlib='InteractiveShellApp.matplotlib',
113 matplotlib='InteractiveShellApp.matplotlib',
127 )
114 )
128 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
115 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
129
116
130 #-----------------------------------------------------------------------------
117 #-----------------------------------------------------------------------------
131 # Main classes and functions
118 # Main classes and functions
132 #-----------------------------------------------------------------------------
119 #-----------------------------------------------------------------------------
133
120
134 class InteractiveShellApp(Configurable):
121 class InteractiveShellApp(Configurable):
135 """A Mixin for applications that start InteractiveShell instances.
122 """A Mixin for applications that start InteractiveShell instances.
136
123
137 Provides configurables for loading extensions and executing files
124 Provides configurables for loading extensions and executing files
138 as part of configuring a Shell environment.
125 as part of configuring a Shell environment.
139
126
140 The following methods should be called by the :meth:`initialize` method
127 The following methods should be called by the :meth:`initialize` method
141 of the subclass:
128 of the subclass:
142
129
143 - :meth:`init_path`
130 - :meth:`init_path`
144 - :meth:`init_shell` (to be implemented by the subclass)
131 - :meth:`init_shell` (to be implemented by the subclass)
145 - :meth:`init_gui_pylab`
132 - :meth:`init_gui_pylab`
146 - :meth:`init_extensions`
133 - :meth:`init_extensions`
147 - :meth:`init_code`
134 - :meth:`init_code`
148 """
135 """
149 extensions = List(Unicode, config=True,
136 extensions = List(Unicode, config=True,
150 help="A list of dotted module names of IPython extensions to load."
137 help="A list of dotted module names of IPython extensions to load."
151 )
138 )
152 extra_extension = Unicode('', config=True,
139 extra_extension = Unicode('', config=True,
153 help="dotted module name of an IPython extension to load."
140 help="dotted module name of an IPython extension to load."
154 )
141 )
155 def _extra_extension_changed(self, name, old, new):
156 if new:
157 # add to self.extensions
158 self.extensions.append(new)
159
142
160 # Extensions that are always loaded (not configurable)
143 # Extensions that are always loaded (not configurable)
161 default_extensions = List(Unicode, [u'storemagic'], config=False)
144 default_extensions = List(Unicode, [u'storemagic'], config=False)
162
145
163 hide_initial_ns = Bool(True, config=True,
146 hide_initial_ns = Bool(True, config=True,
164 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
147 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
165 be hidden from tools like %who?"""
148 be hidden from tools like %who?"""
166 )
149 )
167
150
168 exec_files = List(Unicode, config=True,
151 exec_files = List(Unicode, config=True,
169 help="""List of files to run at IPython startup."""
152 help="""List of files to run at IPython startup."""
170 )
153 )
171 exec_PYTHONSTARTUP = Bool(True, config=True,
154 exec_PYTHONSTARTUP = Bool(True, config=True,
172 help="""Run the file referenced by the PYTHONSTARTUP environment
155 help="""Run the file referenced by the PYTHONSTARTUP environment
173 variable at IPython startup."""
156 variable at IPython startup."""
174 )
157 )
175 file_to_run = Unicode('', config=True,
158 file_to_run = Unicode('', config=True,
176 help="""A file to be run""")
159 help="""A file to be run""")
177
160
178 exec_lines = List(Unicode, config=True,
161 exec_lines = List(Unicode, config=True,
179 help="""lines of code to run at IPython startup."""
162 help="""lines of code to run at IPython startup."""
180 )
163 )
181 code_to_run = Unicode('', config=True,
164 code_to_run = Unicode('', config=True,
182 help="Execute the given command string."
165 help="Execute the given command string."
183 )
166 )
184 module_to_run = Unicode('', config=True,
167 module_to_run = Unicode('', config=True,
185 help="Run the module as a script."
168 help="Run the module as a script."
186 )
169 )
187 gui = CaselessStrEnum(gui_keys, config=True,
170 gui = CaselessStrEnum(gui_keys, config=True,
188 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
171 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
189 )
172 )
190 matplotlib = CaselessStrEnum(backend_keys,
173 matplotlib = CaselessStrEnum(backend_keys,
191 config=True,
174 config=True,
192 help="""Configure matplotlib for interactive use with
175 help="""Configure matplotlib for interactive use with
193 the default matplotlib backend."""
176 the default matplotlib backend."""
194 )
177 )
195 pylab = CaselessStrEnum(backend_keys,
178 pylab = CaselessStrEnum(backend_keys,
196 config=True,
179 config=True,
197 help="""Pre-load matplotlib and numpy for interactive use,
180 help="""Pre-load matplotlib and numpy for interactive use,
198 selecting a particular matplotlib backend and loop integration.
181 selecting a particular matplotlib backend and loop integration.
199 """
182 """
200 )
183 )
201 pylab_import_all = Bool(True, config=True,
184 pylab_import_all = Bool(True, config=True,
202 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
185 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
203 and an ``import *`` is done from numpy and pylab, when using pylab mode.
186 and an ``import *`` is done from numpy and pylab, when using pylab mode.
204
187
205 When False, pylab mode should not import any names into the user namespace.
188 When False, pylab mode should not import any names into the user namespace.
206 """
189 """
207 )
190 )
208 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
191 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
209
192
210 user_ns = Instance(dict, args=None, allow_none=True)
193 user_ns = Instance(dict, args=None, allow_none=True)
211 def _user_ns_changed(self, name, old, new):
194 def _user_ns_changed(self, name, old, new):
212 if self.shell is not None:
195 if self.shell is not None:
213 self.shell.user_ns = new
196 self.shell.user_ns = new
214 self.shell.init_user_ns()
197 self.shell.init_user_ns()
215
198
216 def init_path(self):
199 def init_path(self):
217 """Add current working directory, '', to sys.path"""
200 """Add current working directory, '', to sys.path"""
218 if sys.path[0] != '':
201 if sys.path[0] != '':
219 sys.path.insert(0, '')
202 sys.path.insert(0, '')
220
203
221 def init_shell(self):
204 def init_shell(self):
222 raise NotImplementedError("Override in subclasses")
205 raise NotImplementedError("Override in subclasses")
223
206
224 def init_gui_pylab(self):
207 def init_gui_pylab(self):
225 """Enable GUI event loop integration, taking pylab into account."""
208 """Enable GUI event loop integration, taking pylab into account."""
226 enable = False
209 enable = False
227 shell = self.shell
210 shell = self.shell
228 if self.pylab:
211 if self.pylab:
229 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
212 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
230 key = self.pylab
213 key = self.pylab
231 elif self.matplotlib:
214 elif self.matplotlib:
232 enable = shell.enable_matplotlib
215 enable = shell.enable_matplotlib
233 key = self.matplotlib
216 key = self.matplotlib
234 elif self.gui:
217 elif self.gui:
235 enable = shell.enable_gui
218 enable = shell.enable_gui
236 key = self.gui
219 key = self.gui
237
220
238 if not enable:
221 if not enable:
239 return
222 return
240
223
241 try:
224 try:
242 r = enable(key)
225 r = enable(key)
243 except ImportError:
226 except ImportError:
244 self.log.warn("Eventloop or matplotlib integration failed. Is matplotlib installed?")
227 self.log.warn("Eventloop or matplotlib integration failed. Is matplotlib installed?")
245 self.shell.showtraceback()
228 self.shell.showtraceback()
246 return
229 return
247 except Exception:
230 except Exception:
248 self.log.warn("GUI event loop or pylab initialization failed")
231 self.log.warn("GUI event loop or pylab initialization failed")
249 self.shell.showtraceback()
232 self.shell.showtraceback()
250 return
233 return
251
234
252 if isinstance(r, tuple):
235 if isinstance(r, tuple):
253 gui, backend = r[:2]
236 gui, backend = r[:2]
254 self.log.info("Enabling GUI event loop integration, "
237 self.log.info("Enabling GUI event loop integration, "
255 "eventloop=%s, matplotlib=%s", gui, backend)
238 "eventloop=%s, matplotlib=%s", gui, backend)
256 if key == "auto":
239 if key == "auto":
257 print("Using matplotlib backend: %s" % backend)
240 print("Using matplotlib backend: %s" % backend)
258 else:
241 else:
259 gui = r
242 gui = r
260 self.log.info("Enabling GUI event loop integration, "
243 self.log.info("Enabling GUI event loop integration, "
261 "eventloop=%s", gui)
244 "eventloop=%s", gui)
262
245
263 def init_extensions(self):
246 def init_extensions(self):
264 """Load all IPython extensions in IPythonApp.extensions.
247 """Load all IPython extensions in IPythonApp.extensions.
265
248
266 This uses the :meth:`ExtensionManager.load_extensions` to load all
249 This uses the :meth:`ExtensionManager.load_extensions` to load all
267 the extensions listed in ``self.extensions``.
250 the extensions listed in ``self.extensions``.
268 """
251 """
269 try:
252 try:
270 self.log.debug("Loading IPython extensions...")
253 self.log.debug("Loading IPython extensions...")
271 extensions = self.default_extensions + self.extensions
254 extensions = self.default_extensions + self.extensions
255 if self.extra_extension:
256 extensions.append(self.extra_extension)
272 for ext in extensions:
257 for ext in extensions:
273 try:
258 try:
274 self.log.info("Loading IPython extension: %s" % ext)
259 self.log.info("Loading IPython extension: %s" % ext)
275 self.shell.extension_manager.load_extension(ext)
260 self.shell.extension_manager.load_extension(ext)
276 except:
261 except:
277 msg = ("Error in loading extension: {ext}\n"
262 msg = ("Error in loading extension: {ext}\n"
278 "Check your config files in {location}".format(
263 "Check your config files in {location}".format(
279 ext=ext,
264 ext=ext,
280 location=self.profile_dir.location
265 location=self.profile_dir.location
281 ))
266 ))
282 self.log.warn(msg, exc_info=True)
267 self.log.warn(msg, exc_info=True)
283 except:
268 except:
284 self.log.warn("Unknown error in loading extensions:", exc_info=True)
269 self.log.warn("Unknown error in loading extensions:", exc_info=True)
285
270
286 def init_code(self):
271 def init_code(self):
287 """run the pre-flight code, specified via exec_lines"""
272 """run the pre-flight code, specified via exec_lines"""
288 self._run_startup_files()
273 self._run_startup_files()
289 self._run_exec_lines()
274 self._run_exec_lines()
290 self._run_exec_files()
275 self._run_exec_files()
291
276
292 # Hide variables defined here from %who etc.
277 # Hide variables defined here from %who etc.
293 if self.hide_initial_ns:
278 if self.hide_initial_ns:
294 self.shell.user_ns_hidden.update(self.shell.user_ns)
279 self.shell.user_ns_hidden.update(self.shell.user_ns)
295
280
296 # command-line execution (ipython -i script.py, ipython -m module)
281 # command-line execution (ipython -i script.py, ipython -m module)
297 # should *not* be excluded from %whos
282 # should *not* be excluded from %whos
298 self._run_cmd_line_code()
283 self._run_cmd_line_code()
299 self._run_module()
284 self._run_module()
300
285
301 # flush output, so itwon't be attached to the first cell
286 # flush output, so itwon't be attached to the first cell
302 sys.stdout.flush()
287 sys.stdout.flush()
303 sys.stderr.flush()
288 sys.stderr.flush()
304
289
305 def _run_exec_lines(self):
290 def _run_exec_lines(self):
306 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
291 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
307 if not self.exec_lines:
292 if not self.exec_lines:
308 return
293 return
309 try:
294 try:
310 self.log.debug("Running code from IPythonApp.exec_lines...")
295 self.log.debug("Running code from IPythonApp.exec_lines...")
311 for line in self.exec_lines:
296 for line in self.exec_lines:
312 try:
297 try:
313 self.log.info("Running code in user namespace: %s" %
298 self.log.info("Running code in user namespace: %s" %
314 line)
299 line)
315 self.shell.run_cell(line, store_history=False)
300 self.shell.run_cell(line, store_history=False)
316 except:
301 except:
317 self.log.warn("Error in executing line in user "
302 self.log.warn("Error in executing line in user "
318 "namespace: %s" % line)
303 "namespace: %s" % line)
319 self.shell.showtraceback()
304 self.shell.showtraceback()
320 except:
305 except:
321 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
306 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
322 self.shell.showtraceback()
307 self.shell.showtraceback()
323
308
324 def _exec_file(self, fname, shell_futures=False):
309 def _exec_file(self, fname, shell_futures=False):
325 try:
310 try:
326 full_filename = filefind(fname, [u'.', self.ipython_dir])
311 full_filename = filefind(fname, [u'.', self.ipython_dir])
327 except IOError as e:
312 except IOError as e:
328 self.log.warn("File not found: %r"%fname)
313 self.log.warn("File not found: %r"%fname)
329 return
314 return
330 # Make sure that the running script gets a proper sys.argv as if it
315 # Make sure that the running script gets a proper sys.argv as if it
331 # were run from a system shell.
316 # were run from a system shell.
332 save_argv = sys.argv
317 save_argv = sys.argv
333 sys.argv = [full_filename] + self.extra_args[1:]
318 sys.argv = [full_filename] + self.extra_args[1:]
334 # protect sys.argv from potential unicode strings on Python 2:
319 # protect sys.argv from potential unicode strings on Python 2:
335 if not py3compat.PY3:
320 if not py3compat.PY3:
336 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
321 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
337 try:
322 try:
338 if os.path.isfile(full_filename):
323 if os.path.isfile(full_filename):
339 self.log.info("Running file in user namespace: %s" %
324 self.log.info("Running file in user namespace: %s" %
340 full_filename)
325 full_filename)
341 # Ensure that __file__ is always defined to match Python
326 # Ensure that __file__ is always defined to match Python
342 # behavior.
327 # behavior.
343 with preserve_keys(self.shell.user_ns, '__file__'):
328 with preserve_keys(self.shell.user_ns, '__file__'):
344 self.shell.user_ns['__file__'] = fname
329 self.shell.user_ns['__file__'] = fname
345 if full_filename.endswith('.ipy'):
330 if full_filename.endswith('.ipy'):
346 self.shell.safe_execfile_ipy(full_filename,
331 self.shell.safe_execfile_ipy(full_filename,
347 shell_futures=shell_futures)
332 shell_futures=shell_futures)
348 else:
333 else:
349 # default to python, even without extension
334 # default to python, even without extension
350 self.shell.safe_execfile(full_filename,
335 self.shell.safe_execfile(full_filename,
351 self.shell.user_ns,
336 self.shell.user_ns,
352 shell_futures=shell_futures)
337 shell_futures=shell_futures)
353 finally:
338 finally:
354 sys.argv = save_argv
339 sys.argv = save_argv
355
340
356 def _run_startup_files(self):
341 def _run_startup_files(self):
357 """Run files from profile startup directory"""
342 """Run files from profile startup directory"""
358 startup_dir = self.profile_dir.startup_dir
343 startup_dir = self.profile_dir.startup_dir
359 startup_files = []
344 startup_files = []
360
345
361 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
346 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
362 not (self.file_to_run or self.code_to_run or self.module_to_run):
347 not (self.file_to_run or self.code_to_run or self.module_to_run):
363 python_startup = os.environ['PYTHONSTARTUP']
348 python_startup = os.environ['PYTHONSTARTUP']
364 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
349 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
365 try:
350 try:
366 self._exec_file(python_startup)
351 self._exec_file(python_startup)
367 except:
352 except:
368 self.log.warn("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
353 self.log.warn("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
369 self.shell.showtraceback()
354 self.shell.showtraceback()
370 finally:
355 finally:
371 # Many PYTHONSTARTUP files set up the readline completions,
356 # Many PYTHONSTARTUP files set up the readline completions,
372 # but this is often at odds with IPython's own completions.
357 # but this is often at odds with IPython's own completions.
373 # Do not allow PYTHONSTARTUP to set up readline.
358 # Do not allow PYTHONSTARTUP to set up readline.
374 if self.shell.has_readline:
359 if self.shell.has_readline:
375 self.shell.set_readline_completer()
360 self.shell.set_readline_completer()
376
361
377 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
362 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
378 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
363 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
379 if not startup_files:
364 if not startup_files:
380 return
365 return
381
366
382 self.log.debug("Running startup files from %s...", startup_dir)
367 self.log.debug("Running startup files from %s...", startup_dir)
383 try:
368 try:
384 for fname in sorted(startup_files):
369 for fname in sorted(startup_files):
385 self._exec_file(fname)
370 self._exec_file(fname)
386 except:
371 except:
387 self.log.warn("Unknown error in handling startup files:")
372 self.log.warn("Unknown error in handling startup files:")
388 self.shell.showtraceback()
373 self.shell.showtraceback()
389
374
390 def _run_exec_files(self):
375 def _run_exec_files(self):
391 """Run files from IPythonApp.exec_files"""
376 """Run files from IPythonApp.exec_files"""
392 if not self.exec_files:
377 if not self.exec_files:
393 return
378 return
394
379
395 self.log.debug("Running files in IPythonApp.exec_files...")
380 self.log.debug("Running files in IPythonApp.exec_files...")
396 try:
381 try:
397 for fname in self.exec_files:
382 for fname in self.exec_files:
398 self._exec_file(fname)
383 self._exec_file(fname)
399 except:
384 except:
400 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
385 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
401 self.shell.showtraceback()
386 self.shell.showtraceback()
402
387
403 def _run_cmd_line_code(self):
388 def _run_cmd_line_code(self):
404 """Run code or file specified at the command-line"""
389 """Run code or file specified at the command-line"""
405 if self.code_to_run:
390 if self.code_to_run:
406 line = self.code_to_run
391 line = self.code_to_run
407 try:
392 try:
408 self.log.info("Running code given at command line (c=): %s" %
393 self.log.info("Running code given at command line (c=): %s" %
409 line)
394 line)
410 self.shell.run_cell(line, store_history=False)
395 self.shell.run_cell(line, store_history=False)
411 except:
396 except:
412 self.log.warn("Error in executing line in user namespace: %s" %
397 self.log.warn("Error in executing line in user namespace: %s" %
413 line)
398 line)
414 self.shell.showtraceback()
399 self.shell.showtraceback()
415
400
416 # Like Python itself, ignore the second if the first of these is present
401 # Like Python itself, ignore the second if the first of these is present
417 elif self.file_to_run:
402 elif self.file_to_run:
418 fname = self.file_to_run
403 fname = self.file_to_run
419 try:
404 try:
420 self._exec_file(fname, shell_futures=True)
405 self._exec_file(fname, shell_futures=True)
421 except:
406 except:
422 self.log.warn("Error in executing file in user namespace: %s" %
407 self.log.warn("Error in executing file in user namespace: %s" %
423 fname)
408 fname)
424 self.shell.showtraceback()
409 self.shell.showtraceback()
425
410
426 def _run_module(self):
411 def _run_module(self):
427 """Run module specified at the command-line."""
412 """Run module specified at the command-line."""
428 if self.module_to_run:
413 if self.module_to_run:
429 # Make sure that the module gets a proper sys.argv as if it were
414 # Make sure that the module gets a proper sys.argv as if it were
430 # run using `python -m`.
415 # run using `python -m`.
431 save_argv = sys.argv
416 save_argv = sys.argv
432 sys.argv = [sys.executable] + self.extra_args
417 sys.argv = [sys.executable] + self.extra_args
433 try:
418 try:
434 self.shell.safe_run_module(self.module_to_run,
419 self.shell.safe_run_module(self.module_to_run,
435 self.shell.user_ns)
420 self.shell.user_ns)
436 finally:
421 finally:
437 sys.argv = save_argv
422 sys.argv = save_argv
@@ -1,373 +1,374 b''
1 """Tests for the object inspection functionality.
1 """Tests for the object inspection functionality.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010-2011 The IPython Development Team.
4 # Copyright (C) 2010-2011 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the BSD License.
6 # Distributed under the terms of the BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib imports
16 # Stdlib imports
17 import os
17 import os
18 import re
18 import re
19
19
20 # Third-party imports
20 # Third-party imports
21 import nose.tools as nt
21 import nose.tools as nt
22
22
23 # Our own imports
23 # Our own imports
24 from .. import oinspect
24 from .. import oinspect
25 from IPython.core.magic import (Magics, magics_class, line_magic,
25 from IPython.core.magic import (Magics, magics_class, line_magic,
26 cell_magic, line_cell_magic,
26 cell_magic, line_cell_magic,
27 register_line_magic, register_cell_magic,
27 register_line_magic, register_cell_magic,
28 register_line_cell_magic)
28 register_line_cell_magic)
29 from IPython.external.decorator import decorator
29 from IPython.external.decorator import decorator
30 from IPython.testing.decorators import skipif
30 from IPython.testing.decorators import skipif
31 from IPython.utils.path import compress_user
31 from IPython.utils import py3compat
32 from IPython.utils import py3compat
32
33
33
34
34 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
35 # Globals and constants
36 # Globals and constants
36 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
37
38
38 inspector = oinspect.Inspector()
39 inspector = oinspect.Inspector()
39 ip = get_ipython()
40 ip = get_ipython()
40
41
41 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
42 # Local utilities
43 # Local utilities
43 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
44
45
45 # WARNING: since this test checks the line number where a function is
46 # WARNING: since this test checks the line number where a function is
46 # defined, if any code is inserted above, the following line will need to be
47 # defined, if any code is inserted above, the following line will need to be
47 # updated. Do NOT insert any whitespace between the next line and the function
48 # updated. Do NOT insert any whitespace between the next line and the function
48 # definition below.
49 # definition below.
49 THIS_LINE_NUMBER = 49 # Put here the actual number of this line
50 THIS_LINE_NUMBER = 50 # Put here the actual number of this line
50 def test_find_source_lines():
51 def test_find_source_lines():
51 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
52 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
52 THIS_LINE_NUMBER+1)
53 THIS_LINE_NUMBER+1)
53
54
54
55
55 # A couple of utilities to ensure these tests work the same from a source or a
56 # A couple of utilities to ensure these tests work the same from a source or a
56 # binary install
57 # binary install
57 def pyfile(fname):
58 def pyfile(fname):
58 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
59 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
59
60
60
61
61 def match_pyfiles(f1, f2):
62 def match_pyfiles(f1, f2):
62 nt.assert_equal(pyfile(f1), pyfile(f2))
63 nt.assert_equal(pyfile(f1), pyfile(f2))
63
64
64
65
65 def test_find_file():
66 def test_find_file():
66 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
67 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
67
68
68
69
69 def test_find_file_decorated1():
70 def test_find_file_decorated1():
70
71
71 @decorator
72 @decorator
72 def noop1(f):
73 def noop1(f):
73 def wrapper():
74 def wrapper():
74 return f(*a, **kw)
75 return f(*a, **kw)
75 return wrapper
76 return wrapper
76
77
77 @noop1
78 @noop1
78 def f(x):
79 def f(x):
79 "My docstring"
80 "My docstring"
80
81
81 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
82 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
82 nt.assert_equal(f.__doc__, "My docstring")
83 nt.assert_equal(f.__doc__, "My docstring")
83
84
84
85
85 def test_find_file_decorated2():
86 def test_find_file_decorated2():
86
87
87 @decorator
88 @decorator
88 def noop2(f, *a, **kw):
89 def noop2(f, *a, **kw):
89 return f(*a, **kw)
90 return f(*a, **kw)
90
91
91 @noop2
92 @noop2
92 def f(x):
93 def f(x):
93 "My docstring 2"
94 "My docstring 2"
94
95
95 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
96 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
96 nt.assert_equal(f.__doc__, "My docstring 2")
97 nt.assert_equal(f.__doc__, "My docstring 2")
97
98
98
99
99 def test_find_file_magic():
100 def test_find_file_magic():
100 run = ip.find_line_magic('run')
101 run = ip.find_line_magic('run')
101 nt.assert_not_equal(oinspect.find_file(run), None)
102 nt.assert_not_equal(oinspect.find_file(run), None)
102
103
103
104
104 # A few generic objects we can then inspect in the tests below
105 # A few generic objects we can then inspect in the tests below
105
106
106 class Call(object):
107 class Call(object):
107 """This is the class docstring."""
108 """This is the class docstring."""
108
109
109 def __init__(self, x, y=1):
110 def __init__(self, x, y=1):
110 """This is the constructor docstring."""
111 """This is the constructor docstring."""
111
112
112 def __call__(self, *a, **kw):
113 def __call__(self, *a, **kw):
113 """This is the call docstring."""
114 """This is the call docstring."""
114
115
115 def method(self, x, z=2):
116 def method(self, x, z=2):
116 """Some method's docstring"""
117 """Some method's docstring"""
117
118
118 class SimpleClass(object):
119 class SimpleClass(object):
119 def method(self, x, z=2):
120 def method(self, x, z=2):
120 """Some method's docstring"""
121 """Some method's docstring"""
121
122
122
123
123 class OldStyle:
124 class OldStyle:
124 """An old-style class for testing."""
125 """An old-style class for testing."""
125 pass
126 pass
126
127
127
128
128 def f(x, y=2, *a, **kw):
129 def f(x, y=2, *a, **kw):
129 """A simple function."""
130 """A simple function."""
130
131
131
132
132 def g(y, z=3, *a, **kw):
133 def g(y, z=3, *a, **kw):
133 pass # no docstring
134 pass # no docstring
134
135
135
136
136 @register_line_magic
137 @register_line_magic
137 def lmagic(line):
138 def lmagic(line):
138 "A line magic"
139 "A line magic"
139
140
140
141
141 @register_cell_magic
142 @register_cell_magic
142 def cmagic(line, cell):
143 def cmagic(line, cell):
143 "A cell magic"
144 "A cell magic"
144
145
145
146
146 @register_line_cell_magic
147 @register_line_cell_magic
147 def lcmagic(line, cell=None):
148 def lcmagic(line, cell=None):
148 "A line/cell magic"
149 "A line/cell magic"
149
150
150
151
151 @magics_class
152 @magics_class
152 class SimpleMagics(Magics):
153 class SimpleMagics(Magics):
153 @line_magic
154 @line_magic
154 def Clmagic(self, cline):
155 def Clmagic(self, cline):
155 "A class-based line magic"
156 "A class-based line magic"
156
157
157 @cell_magic
158 @cell_magic
158 def Ccmagic(self, cline, ccell):
159 def Ccmagic(self, cline, ccell):
159 "A class-based cell magic"
160 "A class-based cell magic"
160
161
161 @line_cell_magic
162 @line_cell_magic
162 def Clcmagic(self, cline, ccell=None):
163 def Clcmagic(self, cline, ccell=None):
163 "A class-based line/cell magic"
164 "A class-based line/cell magic"
164
165
165
166
166 class Awkward(object):
167 class Awkward(object):
167 def __getattr__(self, name):
168 def __getattr__(self, name):
168 raise Exception(name)
169 raise Exception(name)
169
170
170
171
171 def check_calltip(obj, name, call, docstring):
172 def check_calltip(obj, name, call, docstring):
172 """Generic check pattern all calltip tests will use"""
173 """Generic check pattern all calltip tests will use"""
173 info = inspector.info(obj, name)
174 info = inspector.info(obj, name)
174 call_line, ds = oinspect.call_tip(info)
175 call_line, ds = oinspect.call_tip(info)
175 nt.assert_equal(call_line, call)
176 nt.assert_equal(call_line, call)
176 nt.assert_equal(ds, docstring)
177 nt.assert_equal(ds, docstring)
177
178
178 #-----------------------------------------------------------------------------
179 #-----------------------------------------------------------------------------
179 # Tests
180 # Tests
180 #-----------------------------------------------------------------------------
181 #-----------------------------------------------------------------------------
181
182
182 def test_calltip_class():
183 def test_calltip_class():
183 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
184 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
184
185
185
186
186 def test_calltip_instance():
187 def test_calltip_instance():
187 c = Call(1)
188 c = Call(1)
188 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
189 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
189
190
190
191
191 def test_calltip_method():
192 def test_calltip_method():
192 c = Call(1)
193 c = Call(1)
193 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
194 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
194
195
195
196
196 def test_calltip_function():
197 def test_calltip_function():
197 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
198 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
198
199
199
200
200 def test_calltip_function2():
201 def test_calltip_function2():
201 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
202 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
202
203
203
204
204 def test_calltip_builtin():
205 def test_calltip_builtin():
205 check_calltip(sum, 'sum', None, sum.__doc__)
206 check_calltip(sum, 'sum', None, sum.__doc__)
206
207
207
208
208 def test_calltip_line_magic():
209 def test_calltip_line_magic():
209 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
210 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
210
211
211
212
212 def test_calltip_cell_magic():
213 def test_calltip_cell_magic():
213 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
214 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
214
215
215
216
216 def test_calltip_line_cell_magic():
217 def test_calltip_line_cell_magic():
217 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
218 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
218 "A line/cell magic")
219 "A line/cell magic")
219
220
220
221
221 def test_class_magics():
222 def test_class_magics():
222 cm = SimpleMagics(ip)
223 cm = SimpleMagics(ip)
223 ip.register_magics(cm)
224 ip.register_magics(cm)
224 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
225 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
225 "A class-based line magic")
226 "A class-based line magic")
226 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
227 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
227 "A class-based cell magic")
228 "A class-based cell magic")
228 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
229 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
229 "A class-based line/cell magic")
230 "A class-based line/cell magic")
230
231
231
232
232 def test_info():
233 def test_info():
233 "Check that Inspector.info fills out various fields as expected."
234 "Check that Inspector.info fills out various fields as expected."
234 i = inspector.info(Call, oname='Call')
235 i = inspector.info(Call, oname='Call')
235 nt.assert_equal(i['type_name'], 'type')
236 nt.assert_equal(i['type_name'], 'type')
236 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
237 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
237 nt.assert_equal(i['base_class'], expted_class)
238 nt.assert_equal(i['base_class'], expted_class)
238 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
239 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
239 fname = __file__
240 fname = __file__
240 if fname.endswith(".pyc"):
241 if fname.endswith(".pyc"):
241 fname = fname[:-1]
242 fname = fname[:-1]
242 # case-insensitive comparison needed on some filesystems
243 # case-insensitive comparison needed on some filesystems
243 # e.g. Windows:
244 # e.g. Windows:
244 nt.assert_equal(i['file'].lower(), fname.lower())
245 nt.assert_equal(i['file'].lower(), compress_user(fname.lower()))
245 nt.assert_equal(i['definition'], None)
246 nt.assert_equal(i['definition'], None)
246 nt.assert_equal(i['docstring'], Call.__doc__)
247 nt.assert_equal(i['docstring'], Call.__doc__)
247 nt.assert_equal(i['source'], None)
248 nt.assert_equal(i['source'], None)
248 nt.assert_true(i['isclass'])
249 nt.assert_true(i['isclass'])
249 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
250 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
250 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
251 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
251
252
252 i = inspector.info(Call, detail_level=1)
253 i = inspector.info(Call, detail_level=1)
253 nt.assert_not_equal(i['source'], None)
254 nt.assert_not_equal(i['source'], None)
254 nt.assert_equal(i['docstring'], None)
255 nt.assert_equal(i['docstring'], None)
255
256
256 c = Call(1)
257 c = Call(1)
257 c.__doc__ = "Modified instance docstring"
258 c.__doc__ = "Modified instance docstring"
258 i = inspector.info(c)
259 i = inspector.info(c)
259 nt.assert_equal(i['type_name'], 'Call')
260 nt.assert_equal(i['type_name'], 'Call')
260 nt.assert_equal(i['docstring'], "Modified instance docstring")
261 nt.assert_equal(i['docstring'], "Modified instance docstring")
261 nt.assert_equal(i['class_docstring'], Call.__doc__)
262 nt.assert_equal(i['class_docstring'], Call.__doc__)
262 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
263 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
263 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
264 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
264
265
265 # Test old-style classes, which for example may not have an __init__ method.
266 # Test old-style classes, which for example may not have an __init__ method.
266 if not py3compat.PY3:
267 if not py3compat.PY3:
267 i = inspector.info(OldStyle)
268 i = inspector.info(OldStyle)
268 nt.assert_equal(i['type_name'], 'classobj')
269 nt.assert_equal(i['type_name'], 'classobj')
269
270
270 i = inspector.info(OldStyle())
271 i = inspector.info(OldStyle())
271 nt.assert_equal(i['type_name'], 'instance')
272 nt.assert_equal(i['type_name'], 'instance')
272 nt.assert_equal(i['docstring'], OldStyle.__doc__)
273 nt.assert_equal(i['docstring'], OldStyle.__doc__)
273
274
274 def test_info_awkward():
275 def test_info_awkward():
275 # Just test that this doesn't throw an error.
276 # Just test that this doesn't throw an error.
276 i = inspector.info(Awkward())
277 i = inspector.info(Awkward())
277
278
278 def test_calldef_none():
279 def test_calldef_none():
279 # We should ignore __call__ for all of these.
280 # We should ignore __call__ for all of these.
280 for obj in [f, SimpleClass().method, any, str.upper]:
281 for obj in [f, SimpleClass().method, any, str.upper]:
281 print(obj)
282 print(obj)
282 i = inspector.info(obj)
283 i = inspector.info(obj)
283 nt.assert_is(i['call_def'], None)
284 nt.assert_is(i['call_def'], None)
284
285
285 if py3compat.PY3:
286 if py3compat.PY3:
286 exec("def f_kwarg(pos, *, kwonly): pass")
287 exec("def f_kwarg(pos, *, kwonly): pass")
287
288
288 @skipif(not py3compat.PY3)
289 @skipif(not py3compat.PY3)
289 def test_definition_kwonlyargs():
290 def test_definition_kwonlyargs():
290 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
291 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
291 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n")
292 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n")
292
293
293 def test_getdoc():
294 def test_getdoc():
294 class A(object):
295 class A(object):
295 """standard docstring"""
296 """standard docstring"""
296 pass
297 pass
297
298
298 class B(object):
299 class B(object):
299 """standard docstring"""
300 """standard docstring"""
300 def getdoc(self):
301 def getdoc(self):
301 return "custom docstring"
302 return "custom docstring"
302
303
303 class C(object):
304 class C(object):
304 """standard docstring"""
305 """standard docstring"""
305 def getdoc(self):
306 def getdoc(self):
306 return None
307 return None
307
308
308 a = A()
309 a = A()
309 b = B()
310 b = B()
310 c = C()
311 c = C()
311
312
312 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
313 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
313 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
314 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
314 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
315 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
315
316
316
317
317 def test_empty_property_has_no_source():
318 def test_empty_property_has_no_source():
318 i = inspector.info(property(), detail_level=1)
319 i = inspector.info(property(), detail_level=1)
319 nt.assert_is(i['source'], None)
320 nt.assert_is(i['source'], None)
320
321
321
322
322 def test_property_sources():
323 def test_property_sources():
323 import zlib
324 import zlib
324
325
325 class A(object):
326 class A(object):
326 @property
327 @property
327 def foo(self):
328 def foo(self):
328 return 'bar'
329 return 'bar'
329
330
330 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
331 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
331
332
332 id = property(id)
333 id = property(id)
333 compress = property(zlib.compress)
334 compress = property(zlib.compress)
334
335
335 i = inspector.info(A.foo, detail_level=1)
336 i = inspector.info(A.foo, detail_level=1)
336 nt.assert_in('def foo(self):', i['source'])
337 nt.assert_in('def foo(self):', i['source'])
337 nt.assert_in('lambda self, v:', i['source'])
338 nt.assert_in('lambda self, v:', i['source'])
338
339
339 i = inspector.info(A.id, detail_level=1)
340 i = inspector.info(A.id, detail_level=1)
340 nt.assert_in('fget = <function id>', i['source'])
341 nt.assert_in('fget = <function id>', i['source'])
341
342
342 i = inspector.info(A.compress, detail_level=1)
343 i = inspector.info(A.compress, detail_level=1)
343 nt.assert_in('fget = <function zlib.compress>', i['source'])
344 nt.assert_in('fget = <function zlib.compress>', i['source'])
344
345
345
346
346 def test_property_docstring_is_in_info_for_detail_level_0():
347 def test_property_docstring_is_in_info_for_detail_level_0():
347 class A(object):
348 class A(object):
348 @property
349 @property
349 def foobar():
350 def foobar():
350 """This is `foobar` property."""
351 """This is `foobar` property."""
351 pass
352 pass
352
353
353 ip.user_ns['a_obj'] = A()
354 ip.user_ns['a_obj'] = A()
354 nt.assert_equals(
355 nt.assert_equals(
355 'This is `foobar` property.',
356 'This is `foobar` property.',
356 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
357 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
357
358
358 ip.user_ns['a_cls'] = A
359 ip.user_ns['a_cls'] = A
359 nt.assert_equals(
360 nt.assert_equals(
360 'This is `foobar` property.',
361 'This is `foobar` property.',
361 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
362 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
362
363
363
364
364 def test_pdef():
365 def test_pdef():
365 # See gh-1914
366 # See gh-1914
366 def foo(): pass
367 def foo(): pass
367 inspector.pdef(foo, 'foo')
368 inspector.pdef(foo, 'foo')
368
369
369 def test_pinfo_nonascii():
370 def test_pinfo_nonascii():
370 # See gh-1177
371 # See gh-1177
371 from . import nonascii2
372 from . import nonascii2
372 ip.user_ns['nonascii2'] = nonascii2
373 ip.user_ns['nonascii2'] = nonascii2
373 ip._inspect('pinfo', 'nonascii2', detail_level=1)
374 ip._inspect('pinfo', 'nonascii2', detail_level=1)
@@ -1,217 +1,219 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 ], function(IPython, $, utils) {
8 ], function(IPython, $, utils) {
9 "use strict";
9 "use strict";
10
10
11 //-----------------------------------------------------------------------
11 //-----------------------------------------------------------------------
12 // CommManager class
12 // CommManager class
13 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14
14
15 var CommManager = function (kernel) {
15 var CommManager = function (kernel) {
16 this.comms = {};
16 this.comms = {};
17 this.targets = {};
17 this.targets = {};
18 if (kernel !== undefined) {
18 if (kernel !== undefined) {
19 this.init_kernel(kernel);
19 this.init_kernel(kernel);
20 }
20 }
21 };
21 };
22
22
23 CommManager.prototype.init_kernel = function (kernel) {
23 CommManager.prototype.init_kernel = function (kernel) {
24 /**
24 /**
25 * connect the kernel, and register message handlers
25 * connect the kernel, and register message handlers
26 */
26 */
27 this.kernel = kernel;
27 this.kernel = kernel;
28 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
28 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
29 for (var i = 0; i < msg_types.length; i++) {
29 for (var i = 0; i < msg_types.length; i++) {
30 var msg_type = msg_types[i];
30 var msg_type = msg_types[i];
31 kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
31 kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
32 }
32 }
33 };
33 };
34
34
35 CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata) {
35 CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata) {
36 /**
36 /**
37 * Create a new Comm, register it, and open its Kernel-side counterpart
37 * Create a new Comm, register it, and open its Kernel-side counterpart
38 * Mimics the auto-registration in `Comm.__init__` in the IPython Comm
38 * Mimics the auto-registration in `Comm.__init__` in the IPython Comm
39 */
39 */
40 var comm = new Comm(target_name);
40 var comm = new Comm(target_name);
41 this.register_comm(comm);
41 this.register_comm(comm);
42 comm.open(data, callbacks, metadata);
42 comm.open(data, callbacks, metadata);
43 return comm;
43 return comm;
44 };
44 };
45
45
46 CommManager.prototype.register_target = function (target_name, f) {
46 CommManager.prototype.register_target = function (target_name, f) {
47 /**
47 /**
48 * Register a target function for a given target name
48 * Register a target function for a given target name
49 */
49 */
50 this.targets[target_name] = f;
50 this.targets[target_name] = f;
51 };
51 };
52
52
53 CommManager.prototype.unregister_target = function (target_name, f) {
53 CommManager.prototype.unregister_target = function (target_name, f) {
54 /**
54 /**
55 * Unregister a target function for a given target name
55 * Unregister a target function for a given target name
56 */
56 */
57 delete this.targets[target_name];
57 delete this.targets[target_name];
58 };
58 };
59
59
60 CommManager.prototype.register_comm = function (comm) {
60 CommManager.prototype.register_comm = function (comm) {
61 /**
61 /**
62 * Register a comm in the mapping
62 * Register a comm in the mapping
63 */
63 */
64 this.comms[comm.comm_id] = Promise.resolve(comm);
64 this.comms[comm.comm_id] = Promise.resolve(comm);
65 comm.kernel = this.kernel;
65 comm.kernel = this.kernel;
66 return comm.comm_id;
66 return comm.comm_id;
67 };
67 };
68
68
69 CommManager.prototype.unregister_comm = function (comm) {
69 CommManager.prototype.unregister_comm = function (comm) {
70 /**
70 /**
71 * Remove a comm from the mapping
71 * Remove a comm from the mapping
72 */
72 */
73 delete this.comms[comm.comm_id];
73 delete this.comms[comm.comm_id];
74 };
74 };
75
75
76 // comm message handlers
76 // comm message handlers
77
77
78 CommManager.prototype.comm_open = function (msg) {
78 CommManager.prototype.comm_open = function (msg) {
79 var content = msg.content;
79 var content = msg.content;
80 var that = this;
80 var that = this;
81 var comm_id = content.comm_id;
81 var comm_id = content.comm_id;
82
82
83 this.comms[comm_id] = utils.load_class(content.target_name, content.target_module,
83 this.comms[comm_id] = utils.load_class(content.target_name, content.target_module,
84 this.targets).then(function(target) {
84 this.targets).then(function(target) {
85 var comm = new Comm(content.target_name, comm_id);
85 var comm = new Comm(content.target_name, comm_id);
86 comm.kernel = that.kernel;
86 comm.kernel = that.kernel;
87 try {
87 try {
88 var response = target(comm, msg);
88 var response = target(comm, msg);
89 } catch (e) {
89 } catch (e) {
90 comm.close();
90 comm.close();
91 that.unregister_comm(comm);
91 that.unregister_comm(comm);
92 var wrapped_error = new utils.WrappedError("Exception opening new comm", e);
92 var wrapped_error = new utils.WrappedError("Exception opening new comm", e);
93 console.error(wrapped_error);
93 console.error(wrapped_error);
94 return Promise.reject(wrapped_error);
94 return Promise.reject(wrapped_error);
95 }
95 }
96 // Regardless of the target return value, we need to
96 // Regardless of the target return value, we need to
97 // then return the comm
97 // then return the comm
98 return Promise.resolve(response).then(function() {return comm;});
98 return Promise.resolve(response).then(function() {return comm;});
99 }, utils.reject('Could not open comm', true));
99 }, utils.reject('Could not open comm', true));
100 return this.comms[comm_id];
100 return this.comms[comm_id];
101 };
101 };
102
102
103 CommManager.prototype.comm_close = function(msg) {
103 CommManager.prototype.comm_close = function(msg) {
104 var content = msg.content;
104 var content = msg.content;
105 if (this.comms[content.comm_id] === undefined) {
105 if (this.comms[content.comm_id] === undefined) {
106 console.error('Comm promise not found for comm id ' + content.comm_id);
106 console.error('Comm promise not found for comm id ' + content.comm_id);
107 return;
107 return;
108 }
108 }
109 var that = this;
109 var that = this;
110 this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
110 this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
111 that.unregister_comm(comm);
111 that.unregister_comm(comm);
112 try {
112 try {
113 comm.handle_close(msg);
113 comm.handle_close(msg);
114 } catch (e) {
114 } catch (e) {
115 console.log("Exception closing comm: ", e, e.stack, msg);
115 console.log("Exception closing comm: ", e, e.stack, msg);
116 }
116 }
117 // don't return a comm, so that further .then() functions
117 // don't return a comm, so that further .then() functions
118 // get an undefined comm input
118 // get an undefined comm input
119 });
119 });
120 return this.comms[content.comm_id];
120 };
121 };
121
122
122 CommManager.prototype.comm_msg = function(msg) {
123 CommManager.prototype.comm_msg = function(msg) {
123 var content = msg.content;
124 var content = msg.content;
124 if (this.comms[content.comm_id] === undefined) {
125 if (this.comms[content.comm_id] === undefined) {
125 console.error('Comm promise not found for comm id ' + content.comm_id);
126 console.error('Comm promise not found for comm id ' + content.comm_id);
126 return;
127 return;
127 }
128 }
128
129
129 this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
130 this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
130 try {
131 try {
131 comm.handle_msg(msg);
132 comm.handle_msg(msg);
132 } catch (e) {
133 } catch (e) {
133 console.log("Exception handling comm msg: ", e, e.stack, msg);
134 console.log("Exception handling comm msg: ", e, e.stack, msg);
134 }
135 }
135 return comm;
136 return comm;
136 });
137 });
138 return this.comms[content.comm_id];
137 };
139 };
138
140
139 //-----------------------------------------------------------------------
141 //-----------------------------------------------------------------------
140 // Comm base class
142 // Comm base class
141 //-----------------------------------------------------------------------
143 //-----------------------------------------------------------------------
142
144
143 var Comm = function (target_name, comm_id) {
145 var Comm = function (target_name, comm_id) {
144 this.target_name = target_name;
146 this.target_name = target_name;
145 this.comm_id = comm_id || utils.uuid();
147 this.comm_id = comm_id || utils.uuid();
146 this._msg_callback = this._close_callback = null;
148 this._msg_callback = this._close_callback = null;
147 };
149 };
148
150
149 // methods for sending messages
151 // methods for sending messages
150 Comm.prototype.open = function (data, callbacks, metadata) {
152 Comm.prototype.open = function (data, callbacks, metadata) {
151 var content = {
153 var content = {
152 comm_id : this.comm_id,
154 comm_id : this.comm_id,
153 target_name : this.target_name,
155 target_name : this.target_name,
154 data : data || {},
156 data : data || {},
155 };
157 };
156 return this.kernel.send_shell_message("comm_open", content, callbacks, metadata);
158 return this.kernel.send_shell_message("comm_open", content, callbacks, metadata);
157 };
159 };
158
160
159 Comm.prototype.send = function (data, callbacks, metadata, buffers) {
161 Comm.prototype.send = function (data, callbacks, metadata, buffers) {
160 var content = {
162 var content = {
161 comm_id : this.comm_id,
163 comm_id : this.comm_id,
162 data : data || {},
164 data : data || {},
163 };
165 };
164 return this.kernel.send_shell_message("comm_msg", content, callbacks, metadata, buffers);
166 return this.kernel.send_shell_message("comm_msg", content, callbacks, metadata, buffers);
165 };
167 };
166
168
167 Comm.prototype.close = function (data, callbacks, metadata) {
169 Comm.prototype.close = function (data, callbacks, metadata) {
168 var content = {
170 var content = {
169 comm_id : this.comm_id,
171 comm_id : this.comm_id,
170 data : data || {},
172 data : data || {},
171 };
173 };
172 return this.kernel.send_shell_message("comm_close", content, callbacks, metadata);
174 return this.kernel.send_shell_message("comm_close", content, callbacks, metadata);
173 };
175 };
174
176
175 // methods for registering callbacks for incoming messages
177 // methods for registering callbacks for incoming messages
176 Comm.prototype._register_callback = function (key, callback) {
178 Comm.prototype._register_callback = function (key, callback) {
177 this['_' + key + '_callback'] = callback;
179 this['_' + key + '_callback'] = callback;
178 };
180 };
179
181
180 Comm.prototype.on_msg = function (callback) {
182 Comm.prototype.on_msg = function (callback) {
181 this._register_callback('msg', callback);
183 this._register_callback('msg', callback);
182 };
184 };
183
185
184 Comm.prototype.on_close = function (callback) {
186 Comm.prototype.on_close = function (callback) {
185 this._register_callback('close', callback);
187 this._register_callback('close', callback);
186 };
188 };
187
189
188 // methods for handling incoming messages
190 // methods for handling incoming messages
189
191
190 Comm.prototype._callback = function (key, msg) {
192 Comm.prototype._callback = function (key, msg) {
191 var callback = this['_' + key + '_callback'];
193 var callback = this['_' + key + '_callback'];
192 if (callback) {
194 if (callback) {
193 try {
195 try {
194 callback(msg);
196 callback(msg);
195 } catch (e) {
197 } catch (e) {
196 console.log("Exception in Comm callback", e, e.stack, msg);
198 console.log("Exception in Comm callback", e, e.stack, msg);
197 }
199 }
198 }
200 }
199 };
201 };
200
202
201 Comm.prototype.handle_msg = function (msg) {
203 Comm.prototype.handle_msg = function (msg) {
202 this._callback('msg', msg);
204 this._callback('msg', msg);
203 };
205 };
204
206
205 Comm.prototype.handle_close = function (msg) {
207 Comm.prototype.handle_close = function (msg) {
206 this._callback('close', msg);
208 this._callback('close', msg);
207 };
209 };
208
210
209 // For backwards compatability.
211 // For backwards compatability.
210 IPython.CommManager = CommManager;
212 IPython.CommManager = CommManager;
211 IPython.Comm = Comm;
213 IPython.Comm = Comm;
212
214
213 return {
215 return {
214 'CommManager': CommManager,
216 'CommManager': CommManager,
215 'Comm': Comm
217 'Comm': Comm
216 };
218 };
217 });
219 });
@@ -1,1052 +1,1064 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 './comm',
8 './comm',
9 './serialize',
9 './serialize',
10 'widgets/js/init'
10 'widgets/js/init'
11 ], function(IPython, $, utils, comm, serialize, widgetmanager) {
11 ], function(IPython, $, utils, comm, serialize, widgetmanager) {
12 "use strict";
12 "use strict";
13
13
14 /**
14 /**
15 * A Kernel class to communicate with the Python kernel. This
15 * A Kernel class to communicate with the Python kernel. This
16 * should generally not be constructed directly, but be created
16 * should generally not be constructed directly, but be created
17 * by. the `Session` object. Once created, this object should be
17 * by. the `Session` object. Once created, this object should be
18 * used to communicate with the kernel.
18 * used to communicate with the kernel.
19 *
19 *
20 * @class Kernel
20 * @class Kernel
21 * @param {string} kernel_service_url - the URL to access the kernel REST api
21 * @param {string} kernel_service_url - the URL to access the kernel REST api
22 * @param {string} ws_url - the websockets URL
22 * @param {string} ws_url - the websockets URL
23 * @param {Notebook} notebook - notebook object
23 * @param {Notebook} notebook - notebook object
24 * @param {string} name - the kernel type (e.g. python3)
24 * @param {string} name - the kernel type (e.g. python3)
25 */
25 */
26 var Kernel = function (kernel_service_url, ws_url, notebook, name) {
26 var Kernel = function (kernel_service_url, ws_url, notebook, name) {
27 this.events = notebook.events;
27 this.events = notebook.events;
28
28
29 this.id = null;
29 this.id = null;
30 this.name = name;
30 this.name = name;
31 this.ws = null;
31 this.ws = null;
32
32
33 this.kernel_service_url = kernel_service_url;
33 this.kernel_service_url = kernel_service_url;
34 this.kernel_url = null;
34 this.kernel_url = null;
35 this.ws_url = ws_url || IPython.utils.get_body_data("wsUrl");
35 this.ws_url = ws_url || IPython.utils.get_body_data("wsUrl");
36 if (!this.ws_url) {
36 if (!this.ws_url) {
37 // trailing 's' in https will become wss for secure web sockets
37 // trailing 's' in https will become wss for secure web sockets
38 this.ws_url = location.protocol.replace('http', 'ws') + "//" + location.host;
38 this.ws_url = location.protocol.replace('http', 'ws') + "//" + location.host;
39 }
39 }
40
40
41 this.username = "username";
41 this.username = "username";
42 this.session_id = utils.uuid();
42 this.session_id = utils.uuid();
43 this._msg_callbacks = {};
43 this._msg_callbacks = {};
44 this._msg_queue = Promise.resolve();
44 this.info_reply = {}; // kernel_info_reply stored here after starting
45 this.info_reply = {}; // kernel_info_reply stored here after starting
45
46
46 if (typeof(WebSocket) !== 'undefined') {
47 if (typeof(WebSocket) !== 'undefined') {
47 this.WebSocket = WebSocket;
48 this.WebSocket = WebSocket;
48 } else if (typeof(MozWebSocket) !== 'undefined') {
49 } else if (typeof(MozWebSocket) !== 'undefined') {
49 this.WebSocket = MozWebSocket;
50 this.WebSocket = MozWebSocket;
50 } else {
51 } else {
51 alert('Your browser does not have WebSocket support, please try Chrome, Safari or Firefox ≥ 6. Firefox 4 and 5 are also supported by you have to enable WebSockets in about:config.');
52 alert('Your browser does not have WebSocket support, please try Chrome, Safari or Firefox ≥ 6. Firefox 4 and 5 are also supported by you have to enable WebSockets in about:config.');
52 }
53 }
53
54
54 this.bind_events();
55 this.bind_events();
55 this.init_iopub_handlers();
56 this.init_iopub_handlers();
56 this.comm_manager = new comm.CommManager(this);
57 this.comm_manager = new comm.CommManager(this);
57 this.widget_manager = new widgetmanager.WidgetManager(this.comm_manager, notebook);
58 this.widget_manager = new widgetmanager.WidgetManager(this.comm_manager, notebook);
58
59
59 this.last_msg_id = null;
60 this.last_msg_id = null;
60 this.last_msg_callbacks = {};
61 this.last_msg_callbacks = {};
61
62
62 this._autorestart_attempt = 0;
63 this._autorestart_attempt = 0;
63 this._reconnect_attempt = 0;
64 this._reconnect_attempt = 0;
64 this.reconnect_limit = 7;
65 this.reconnect_limit = 7;
65 };
66 };
66
67
67 /**
68 /**
68 * @function _get_msg
69 * @function _get_msg
69 */
70 */
70 Kernel.prototype._get_msg = function (msg_type, content, metadata, buffers) {
71 Kernel.prototype._get_msg = function (msg_type, content, metadata, buffers) {
71 var msg = {
72 var msg = {
72 header : {
73 header : {
73 msg_id : utils.uuid(),
74 msg_id : utils.uuid(),
74 username : this.username,
75 username : this.username,
75 session : this.session_id,
76 session : this.session_id,
76 msg_type : msg_type,
77 msg_type : msg_type,
77 version : "5.0"
78 version : "5.0"
78 },
79 },
79 metadata : metadata || {},
80 metadata : metadata || {},
80 content : content,
81 content : content,
81 buffers : buffers || [],
82 buffers : buffers || [],
82 parent_header : {}
83 parent_header : {}
83 };
84 };
84 return msg;
85 return msg;
85 };
86 };
86
87
87 /**
88 /**
88 * @function bind_events
89 * @function bind_events
89 */
90 */
90 Kernel.prototype.bind_events = function () {
91 Kernel.prototype.bind_events = function () {
91 var that = this;
92 var that = this;
92 this.events.on('send_input_reply.Kernel', function(evt, data) {
93 this.events.on('send_input_reply.Kernel', function(evt, data) {
93 that.send_input_reply(data);
94 that.send_input_reply(data);
94 });
95 });
95
96
96 var record_status = function (evt, info) {
97 var record_status = function (evt, info) {
97 console.log('Kernel: ' + evt.type + ' (' + info.kernel.id + ')');
98 console.log('Kernel: ' + evt.type + ' (' + info.kernel.id + ')');
98 };
99 };
99
100
100 this.events.on('kernel_created.Kernel', record_status);
101 this.events.on('kernel_created.Kernel', record_status);
101 this.events.on('kernel_reconnecting.Kernel', record_status);
102 this.events.on('kernel_reconnecting.Kernel', record_status);
102 this.events.on('kernel_connected.Kernel', record_status);
103 this.events.on('kernel_connected.Kernel', record_status);
103 this.events.on('kernel_starting.Kernel', record_status);
104 this.events.on('kernel_starting.Kernel', record_status);
104 this.events.on('kernel_restarting.Kernel', record_status);
105 this.events.on('kernel_restarting.Kernel', record_status);
105 this.events.on('kernel_autorestarting.Kernel', record_status);
106 this.events.on('kernel_autorestarting.Kernel', record_status);
106 this.events.on('kernel_interrupting.Kernel', record_status);
107 this.events.on('kernel_interrupting.Kernel', record_status);
107 this.events.on('kernel_disconnected.Kernel', record_status);
108 this.events.on('kernel_disconnected.Kernel', record_status);
108 // these are commented out because they are triggered a lot, but can
109 // these are commented out because they are triggered a lot, but can
109 // be uncommented for debugging purposes
110 // be uncommented for debugging purposes
110 //this.events.on('kernel_idle.Kernel', record_status);
111 //this.events.on('kernel_idle.Kernel', record_status);
111 //this.events.on('kernel_busy.Kernel', record_status);
112 //this.events.on('kernel_busy.Kernel', record_status);
112 this.events.on('kernel_ready.Kernel', record_status);
113 this.events.on('kernel_ready.Kernel', record_status);
113 this.events.on('kernel_killed.Kernel', record_status);
114 this.events.on('kernel_killed.Kernel', record_status);
114 this.events.on('kernel_dead.Kernel', record_status);
115 this.events.on('kernel_dead.Kernel', record_status);
115
116
116 this.events.on('kernel_ready.Kernel', function () {
117 this.events.on('kernel_ready.Kernel', function () {
117 that._autorestart_attempt = 0;
118 that._autorestart_attempt = 0;
118 });
119 });
119 this.events.on('kernel_connected.Kernel', function () {
120 this.events.on('kernel_connected.Kernel', function () {
120 that._reconnect_attempt = 0;
121 that._reconnect_attempt = 0;
121 });
122 });
122 };
123 };
123
124
124 /**
125 /**
125 * Initialize the iopub handlers.
126 * Initialize the iopub handlers.
126 *
127 *
127 * @function init_iopub_handlers
128 * @function init_iopub_handlers
128 */
129 */
129 Kernel.prototype.init_iopub_handlers = function () {
130 Kernel.prototype.init_iopub_handlers = function () {
130 var output_msg_types = ['stream', 'display_data', 'execute_result', 'error'];
131 var output_msg_types = ['stream', 'display_data', 'execute_result', 'error'];
131 this._iopub_handlers = {};
132 this._iopub_handlers = {};
132 this.register_iopub_handler('status', $.proxy(this._handle_status_message, this));
133 this.register_iopub_handler('status', $.proxy(this._handle_status_message, this));
133 this.register_iopub_handler('clear_output', $.proxy(this._handle_clear_output, this));
134 this.register_iopub_handler('clear_output', $.proxy(this._handle_clear_output, this));
134 this.register_iopub_handler('execute_input', $.proxy(this._handle_input_message, this));
135 this.register_iopub_handler('execute_input', $.proxy(this._handle_input_message, this));
135
136
136 for (var i=0; i < output_msg_types.length; i++) {
137 for (var i=0; i < output_msg_types.length; i++) {
137 this.register_iopub_handler(output_msg_types[i], $.proxy(this._handle_output_message, this));
138 this.register_iopub_handler(output_msg_types[i], $.proxy(this._handle_output_message, this));
138 }
139 }
139 };
140 };
140
141
141 /**
142 /**
142 * GET /api/kernels
143 * GET /api/kernels
143 *
144 *
144 * Get the list of running kernels.
145 * Get the list of running kernels.
145 *
146 *
146 * @function list
147 * @function list
147 * @param {function} [success] - function executed on ajax success
148 * @param {function} [success] - function executed on ajax success
148 * @param {function} [error] - functon executed on ajax error
149 * @param {function} [error] - functon executed on ajax error
149 */
150 */
150 Kernel.prototype.list = function (success, error) {
151 Kernel.prototype.list = function (success, error) {
151 $.ajax(this.kernel_service_url, {
152 $.ajax(this.kernel_service_url, {
152 processData: false,
153 processData: false,
153 cache: false,
154 cache: false,
154 type: "GET",
155 type: "GET",
155 dataType: "json",
156 dataType: "json",
156 success: success,
157 success: success,
157 error: this._on_error(error)
158 error: this._on_error(error)
158 });
159 });
159 };
160 };
160
161
161 /**
162 /**
162 * POST /api/kernels
163 * POST /api/kernels
163 *
164 *
164 * Start a new kernel.
165 * Start a new kernel.
165 *
166 *
166 * In general this shouldn't be used -- the kernel should be
167 * In general this shouldn't be used -- the kernel should be
167 * started through the session API. If you use this function and
168 * started through the session API. If you use this function and
168 * are also using the session API then your session and kernel
169 * are also using the session API then your session and kernel
169 * WILL be out of sync!
170 * WILL be out of sync!
170 *
171 *
171 * @function start
172 * @function start
172 * @param {params} [Object] - parameters to include in the query string
173 * @param {params} [Object] - parameters to include in the query string
173 * @param {function} [success] - function executed on ajax success
174 * @param {function} [success] - function executed on ajax success
174 * @param {function} [error] - functon executed on ajax error
175 * @param {function} [error] - functon executed on ajax error
175 */
176 */
176 Kernel.prototype.start = function (params, success, error) {
177 Kernel.prototype.start = function (params, success, error) {
177 var url = this.kernel_service_url;
178 var url = this.kernel_service_url;
178 var qs = $.param(params || {}); // query string for sage math stuff
179 var qs = $.param(params || {}); // query string for sage math stuff
179 if (qs !== "") {
180 if (qs !== "") {
180 url = url + "?" + qs;
181 url = url + "?" + qs;
181 }
182 }
182
183
183 this.events.trigger('kernel_starting.Kernel', {kernel: this});
184 this.events.trigger('kernel_starting.Kernel', {kernel: this});
184 var that = this;
185 var that = this;
185 var on_success = function (data, status, xhr) {
186 var on_success = function (data, status, xhr) {
186 that.events.trigger('kernel_created.Kernel', {kernel: that});
187 that.events.trigger('kernel_created.Kernel', {kernel: that});
187 that._kernel_created(data);
188 that._kernel_created(data);
188 if (success) {
189 if (success) {
189 success(data, status, xhr);
190 success(data, status, xhr);
190 }
191 }
191 };
192 };
192
193
193 $.ajax(url, {
194 $.ajax(url, {
194 processData: false,
195 processData: false,
195 cache: false,
196 cache: false,
196 type: "POST",
197 type: "POST",
197 data: JSON.stringify({name: this.name}),
198 data: JSON.stringify({name: this.name}),
198 dataType: "json",
199 dataType: "json",
199 success: this._on_success(on_success),
200 success: this._on_success(on_success),
200 error: this._on_error(error)
201 error: this._on_error(error)
201 });
202 });
202
203
203 return url;
204 return url;
204 };
205 };
205
206
206 /**
207 /**
207 * GET /api/kernels/[:kernel_id]
208 * GET /api/kernels/[:kernel_id]
208 *
209 *
209 * Get information about the kernel.
210 * Get information about the kernel.
210 *
211 *
211 * @function get_info
212 * @function get_info
212 * @param {function} [success] - function executed on ajax success
213 * @param {function} [success] - function executed on ajax success
213 * @param {function} [error] - functon executed on ajax error
214 * @param {function} [error] - functon executed on ajax error
214 */
215 */
215 Kernel.prototype.get_info = function (success, error) {
216 Kernel.prototype.get_info = function (success, error) {
216 $.ajax(this.kernel_url, {
217 $.ajax(this.kernel_url, {
217 processData: false,
218 processData: false,
218 cache: false,
219 cache: false,
219 type: "GET",
220 type: "GET",
220 dataType: "json",
221 dataType: "json",
221 success: this._on_success(success),
222 success: this._on_success(success),
222 error: this._on_error(error)
223 error: this._on_error(error)
223 });
224 });
224 };
225 };
225
226
226 /**
227 /**
227 * DELETE /api/kernels/[:kernel_id]
228 * DELETE /api/kernels/[:kernel_id]
228 *
229 *
229 * Shutdown the kernel.
230 * Shutdown the kernel.
230 *
231 *
231 * If you are also using sessions, then this function shoul NOT be
232 * If you are also using sessions, then this function shoul NOT be
232 * used. Instead, use Session.delete. Otherwise, the session and
233 * used. Instead, use Session.delete. Otherwise, the session and
233 * kernel WILL be out of sync.
234 * kernel WILL be out of sync.
234 *
235 *
235 * @function kill
236 * @function kill
236 * @param {function} [success] - function executed on ajax success
237 * @param {function} [success] - function executed on ajax success
237 * @param {function} [error] - functon executed on ajax error
238 * @param {function} [error] - functon executed on ajax error
238 */
239 */
239 Kernel.prototype.kill = function (success, error) {
240 Kernel.prototype.kill = function (success, error) {
240 this.events.trigger('kernel_killed.Kernel', {kernel: this});
241 this.events.trigger('kernel_killed.Kernel', {kernel: this});
241 this._kernel_dead();
242 this._kernel_dead();
242 $.ajax(this.kernel_url, {
243 $.ajax(this.kernel_url, {
243 processData: false,
244 processData: false,
244 cache: false,
245 cache: false,
245 type: "DELETE",
246 type: "DELETE",
246 dataType: "json",
247 dataType: "json",
247 success: this._on_success(success),
248 success: this._on_success(success),
248 error: this._on_error(error)
249 error: this._on_error(error)
249 });
250 });
250 };
251 };
251
252
252 /**
253 /**
253 * POST /api/kernels/[:kernel_id]/interrupt
254 * POST /api/kernels/[:kernel_id]/interrupt
254 *
255 *
255 * Interrupt the kernel.
256 * Interrupt the kernel.
256 *
257 *
257 * @function interrupt
258 * @function interrupt
258 * @param {function} [success] - function executed on ajax success
259 * @param {function} [success] - function executed on ajax success
259 * @param {function} [error] - functon executed on ajax error
260 * @param {function} [error] - functon executed on ajax error
260 */
261 */
261 Kernel.prototype.interrupt = function (success, error) {
262 Kernel.prototype.interrupt = function (success, error) {
262 this.events.trigger('kernel_interrupting.Kernel', {kernel: this});
263 this.events.trigger('kernel_interrupting.Kernel', {kernel: this});
263
264
264 var that = this;
265 var that = this;
265 var on_success = function (data, status, xhr) {
266 var on_success = function (data, status, xhr) {
266 /**
267 /**
267 * get kernel info so we know what state the kernel is in
268 * get kernel info so we know what state the kernel is in
268 */
269 */
269 that.kernel_info();
270 that.kernel_info();
270 if (success) {
271 if (success) {
271 success(data, status, xhr);
272 success(data, status, xhr);
272 }
273 }
273 };
274 };
274
275
275 var url = utils.url_join_encode(this.kernel_url, 'interrupt');
276 var url = utils.url_join_encode(this.kernel_url, 'interrupt');
276 $.ajax(url, {
277 $.ajax(url, {
277 processData: false,
278 processData: false,
278 cache: false,
279 cache: false,
279 type: "POST",
280 type: "POST",
280 dataType: "json",
281 dataType: "json",
281 success: this._on_success(on_success),
282 success: this._on_success(on_success),
282 error: this._on_error(error)
283 error: this._on_error(error)
283 });
284 });
284 };
285 };
285
286
286 Kernel.prototype.restart = function (success, error) {
287 Kernel.prototype.restart = function (success, error) {
287 /**
288 /**
288 * POST /api/kernels/[:kernel_id]/restart
289 * POST /api/kernels/[:kernel_id]/restart
289 *
290 *
290 * Restart the kernel.
291 * Restart the kernel.
291 *
292 *
292 * @function interrupt
293 * @function interrupt
293 * @param {function} [success] - function executed on ajax success
294 * @param {function} [success] - function executed on ajax success
294 * @param {function} [error] - functon executed on ajax error
295 * @param {function} [error] - functon executed on ajax error
295 */
296 */
296 this.events.trigger('kernel_restarting.Kernel', {kernel: this});
297 this.events.trigger('kernel_restarting.Kernel', {kernel: this});
297 this.stop_channels();
298 this.stop_channels();
298
299
299 var that = this;
300 var that = this;
300 var on_success = function (data, status, xhr) {
301 var on_success = function (data, status, xhr) {
301 that.events.trigger('kernel_created.Kernel', {kernel: that});
302 that.events.trigger('kernel_created.Kernel', {kernel: that});
302 that._kernel_created(data);
303 that._kernel_created(data);
303 if (success) {
304 if (success) {
304 success(data, status, xhr);
305 success(data, status, xhr);
305 }
306 }
306 };
307 };
307
308
308 var on_error = function (xhr, status, err) {
309 var on_error = function (xhr, status, err) {
309 that.events.trigger('kernel_dead.Kernel', {kernel: that});
310 that.events.trigger('kernel_dead.Kernel', {kernel: that});
310 that._kernel_dead();
311 that._kernel_dead();
311 if (error) {
312 if (error) {
312 error(xhr, status, err);
313 error(xhr, status, err);
313 }
314 }
314 };
315 };
315
316
316 var url = utils.url_join_encode(this.kernel_url, 'restart');
317 var url = utils.url_join_encode(this.kernel_url, 'restart');
317 $.ajax(url, {
318 $.ajax(url, {
318 processData: false,
319 processData: false,
319 cache: false,
320 cache: false,
320 type: "POST",
321 type: "POST",
321 dataType: "json",
322 dataType: "json",
322 success: this._on_success(on_success),
323 success: this._on_success(on_success),
323 error: this._on_error(on_error)
324 error: this._on_error(on_error)
324 });
325 });
325 };
326 };
326
327
327 Kernel.prototype.reconnect = function () {
328 Kernel.prototype.reconnect = function () {
328 /**
329 /**
329 * Reconnect to a disconnected kernel. This is not actually a
330 * Reconnect to a disconnected kernel. This is not actually a
330 * standard HTTP request, but useful function nonetheless for
331 * standard HTTP request, but useful function nonetheless for
331 * reconnecting to the kernel if the connection is somehow lost.
332 * reconnecting to the kernel if the connection is somehow lost.
332 *
333 *
333 * @function reconnect
334 * @function reconnect
334 */
335 */
335 if (this.is_connected()) {
336 if (this.is_connected()) {
336 return;
337 return;
337 }
338 }
338 this._reconnect_attempt = this._reconnect_attempt + 1;
339 this._reconnect_attempt = this._reconnect_attempt + 1;
339 this.events.trigger('kernel_reconnecting.Kernel', {
340 this.events.trigger('kernel_reconnecting.Kernel', {
340 kernel: this,
341 kernel: this,
341 attempt: this._reconnect_attempt,
342 attempt: this._reconnect_attempt,
342 });
343 });
343 this.start_channels();
344 this.start_channels();
344 };
345 };
345
346
346 Kernel.prototype._on_success = function (success) {
347 Kernel.prototype._on_success = function (success) {
347 /**
348 /**
348 * Handle a successful AJAX request by updating the kernel id and
349 * Handle a successful AJAX request by updating the kernel id and
349 * name from the response, and then optionally calling a provided
350 * name from the response, and then optionally calling a provided
350 * callback.
351 * callback.
351 *
352 *
352 * @function _on_success
353 * @function _on_success
353 * @param {function} success - callback
354 * @param {function} success - callback
354 */
355 */
355 var that = this;
356 var that = this;
356 return function (data, status, xhr) {
357 return function (data, status, xhr) {
357 if (data) {
358 if (data) {
358 that.id = data.id;
359 that.id = data.id;
359 that.name = data.name;
360 that.name = data.name;
360 }
361 }
361 that.kernel_url = utils.url_join_encode(that.kernel_service_url, that.id);
362 that.kernel_url = utils.url_join_encode(that.kernel_service_url, that.id);
362 if (success) {
363 if (success) {
363 success(data, status, xhr);
364 success(data, status, xhr);
364 }
365 }
365 };
366 };
366 };
367 };
367
368
368 Kernel.prototype._on_error = function (error) {
369 Kernel.prototype._on_error = function (error) {
369 /**
370 /**
370 * Handle a failed AJAX request by logging the error message, and
371 * Handle a failed AJAX request by logging the error message, and
371 * then optionally calling a provided callback.
372 * then optionally calling a provided callback.
372 *
373 *
373 * @function _on_error
374 * @function _on_error
374 * @param {function} error - callback
375 * @param {function} error - callback
375 */
376 */
376 return function (xhr, status, err) {
377 return function (xhr, status, err) {
377 utils.log_ajax_error(xhr, status, err);
378 utils.log_ajax_error(xhr, status, err);
378 if (error) {
379 if (error) {
379 error(xhr, status, err);
380 error(xhr, status, err);
380 }
381 }
381 };
382 };
382 };
383 };
383
384
384 Kernel.prototype._kernel_created = function (data) {
385 Kernel.prototype._kernel_created = function (data) {
385 /**
386 /**
386 * Perform necessary tasks once the kernel has been started,
387 * Perform necessary tasks once the kernel has been started,
387 * including actually connecting to the kernel.
388 * including actually connecting to the kernel.
388 *
389 *
389 * @function _kernel_created
390 * @function _kernel_created
390 * @param {Object} data - information about the kernel including id
391 * @param {Object} data - information about the kernel including id
391 */
392 */
392 this.id = data.id;
393 this.id = data.id;
393 this.kernel_url = utils.url_join_encode(this.kernel_service_url, this.id);
394 this.kernel_url = utils.url_join_encode(this.kernel_service_url, this.id);
394 this.start_channels();
395 this.start_channels();
395 };
396 };
396
397
397 Kernel.prototype._kernel_connected = function () {
398 Kernel.prototype._kernel_connected = function () {
398 /**
399 /**
399 * Perform necessary tasks once the connection to the kernel has
400 * Perform necessary tasks once the connection to the kernel has
400 * been established. This includes requesting information about
401 * been established. This includes requesting information about
401 * the kernel.
402 * the kernel.
402 *
403 *
403 * @function _kernel_connected
404 * @function _kernel_connected
404 */
405 */
405 this.events.trigger('kernel_connected.Kernel', {kernel: this});
406 this.events.trigger('kernel_connected.Kernel', {kernel: this});
406 // get kernel info so we know what state the kernel is in
407 // get kernel info so we know what state the kernel is in
407 var that = this;
408 var that = this;
408 this.kernel_info(function (reply) {
409 this.kernel_info(function (reply) {
409 that.info_reply = reply.content;
410 that.info_reply = reply.content;
410 that.events.trigger('kernel_ready.Kernel', {kernel: that});
411 that.events.trigger('kernel_ready.Kernel', {kernel: that});
411 });
412 });
412 };
413 };
413
414
414 Kernel.prototype._kernel_dead = function () {
415 Kernel.prototype._kernel_dead = function () {
415 /**
416 /**
416 * Perform necessary tasks after the kernel has died. This closing
417 * Perform necessary tasks after the kernel has died. This closing
417 * communication channels to the kernel if they are still somehow
418 * communication channels to the kernel if they are still somehow
418 * open.
419 * open.
419 *
420 *
420 * @function _kernel_dead
421 * @function _kernel_dead
421 */
422 */
422 this.stop_channels();
423 this.stop_channels();
423 };
424 };
424
425
425 Kernel.prototype.start_channels = function () {
426 Kernel.prototype.start_channels = function () {
426 /**
427 /**
427 * Start the websocket channels.
428 * Start the websocket channels.
428 * Will stop and restart them if they already exist.
429 * Will stop and restart them if they already exist.
429 *
430 *
430 * @function start_channels
431 * @function start_channels
431 */
432 */
432 var that = this;
433 var that = this;
433 this.stop_channels();
434 this.stop_channels();
434 var ws_host_url = this.ws_url + this.kernel_url;
435 var ws_host_url = this.ws_url + this.kernel_url;
435
436
436 console.log("Starting WebSockets:", ws_host_url);
437 console.log("Starting WebSockets:", ws_host_url);
437
438
438 this.ws = new this.WebSocket([
439 this.ws = new this.WebSocket([
439 that.ws_url,
440 that.ws_url,
440 utils.url_join_encode(that.kernel_url, 'channels'),
441 utils.url_join_encode(that.kernel_url, 'channels'),
441 "?session_id=" + that.session_id
442 "?session_id=" + that.session_id
442 ].join('')
443 ].join('')
443 );
444 );
444
445
445 var already_called_onclose = false; // only alert once
446 var already_called_onclose = false; // only alert once
446 var ws_closed_early = function(evt){
447 var ws_closed_early = function(evt){
447 if (already_called_onclose){
448 if (already_called_onclose){
448 return;
449 return;
449 }
450 }
450 already_called_onclose = true;
451 already_called_onclose = true;
451 if ( ! evt.wasClean ){
452 if ( ! evt.wasClean ){
452 // If the websocket was closed early, that could mean
453 // If the websocket was closed early, that could mean
453 // that the kernel is actually dead. Try getting
454 // that the kernel is actually dead. Try getting
454 // information about the kernel from the API call --
455 // information about the kernel from the API call --
455 // if that fails, then assume the kernel is dead,
456 // if that fails, then assume the kernel is dead,
456 // otherwise just follow the typical websocket closed
457 // otherwise just follow the typical websocket closed
457 // protocol.
458 // protocol.
458 that.get_info(function () {
459 that.get_info(function () {
459 that._ws_closed(ws_host_url, false);
460 that._ws_closed(ws_host_url, false);
460 }, function () {
461 }, function () {
461 that.events.trigger('kernel_dead.Kernel', {kernel: that});
462 that.events.trigger('kernel_dead.Kernel', {kernel: that});
462 that._kernel_dead();
463 that._kernel_dead();
463 });
464 });
464 }
465 }
465 };
466 };
466 var ws_closed_late = function(evt){
467 var ws_closed_late = function(evt){
467 if (already_called_onclose){
468 if (already_called_onclose){
468 return;
469 return;
469 }
470 }
470 already_called_onclose = true;
471 already_called_onclose = true;
471 if ( ! evt.wasClean ){
472 if ( ! evt.wasClean ){
472 that._ws_closed(ws_host_url, false);
473 that._ws_closed(ws_host_url, false);
473 }
474 }
474 };
475 };
475 var ws_error = function(evt){
476 var ws_error = function(evt){
476 if (already_called_onclose){
477 if (already_called_onclose){
477 return;
478 return;
478 }
479 }
479 already_called_onclose = true;
480 already_called_onclose = true;
480 that._ws_closed(ws_host_url, true);
481 that._ws_closed(ws_host_url, true);
481 };
482 };
482
483
483 this.ws.onopen = $.proxy(this._ws_opened, this);
484 this.ws.onopen = $.proxy(this._ws_opened, this);
484 this.ws.onclose = ws_closed_early;
485 this.ws.onclose = ws_closed_early;
485 this.ws.onerror = ws_error;
486 this.ws.onerror = ws_error;
486 // switch from early-close to late-close message after 1s
487 // switch from early-close to late-close message after 1s
487 setTimeout(function() {
488 setTimeout(function() {
488 if (that.ws !== null) {
489 if (that.ws !== null) {
489 that.ws.onclose = ws_closed_late;
490 that.ws.onclose = ws_closed_late;
490 }
491 }
491 }, 1000);
492 }, 1000);
492 this.ws.onmessage = $.proxy(this._handle_ws_message, this);
493 this.ws.onmessage = $.proxy(this._handle_ws_message, this);
493 };
494 };
494
495
495 Kernel.prototype._ws_opened = function (evt) {
496 Kernel.prototype._ws_opened = function (evt) {
496 /**
497 /**
497 * Handle a websocket entering the open state,
498 * Handle a websocket entering the open state,
498 * signaling that the kernel is connected when websocket is open.
499 * signaling that the kernel is connected when websocket is open.
499 *
500 *
500 * @function _ws_opened
501 * @function _ws_opened
501 */
502 */
502 if (this.is_connected()) {
503 if (this.is_connected()) {
503 // all events ready, trigger started event.
504 // all events ready, trigger started event.
504 this._kernel_connected();
505 this._kernel_connected();
505 }
506 }
506 };
507 };
507
508
508 Kernel.prototype._ws_closed = function(ws_url, error) {
509 Kernel.prototype._ws_closed = function(ws_url, error) {
509 /**
510 /**
510 * Handle a websocket entering the closed state. If the websocket
511 * Handle a websocket entering the closed state. If the websocket
511 * was not closed due to an error, try to reconnect to the kernel.
512 * was not closed due to an error, try to reconnect to the kernel.
512 *
513 *
513 * @function _ws_closed
514 * @function _ws_closed
514 * @param {string} ws_url - the websocket url
515 * @param {string} ws_url - the websocket url
515 * @param {bool} error - whether the connection was closed due to an error
516 * @param {bool} error - whether the connection was closed due to an error
516 */
517 */
517 this.stop_channels();
518 this.stop_channels();
518
519
519 this.events.trigger('kernel_disconnected.Kernel', {kernel: this});
520 this.events.trigger('kernel_disconnected.Kernel', {kernel: this});
520 if (error) {
521 if (error) {
521 console.log('WebSocket connection failed: ', ws_url);
522 console.log('WebSocket connection failed: ', ws_url);
522 this.events.trigger('kernel_connection_failed.Kernel', {kernel: this, ws_url: ws_url, attempt: this._reconnect_attempt});
523 this.events.trigger('kernel_connection_failed.Kernel', {kernel: this, ws_url: ws_url, attempt: this._reconnect_attempt});
523 }
524 }
524 this._schedule_reconnect();
525 this._schedule_reconnect();
525 };
526 };
526
527
527 Kernel.prototype._schedule_reconnect = function () {
528 Kernel.prototype._schedule_reconnect = function () {
528 /**
529 /**
529 * function to call when kernel connection is lost
530 * function to call when kernel connection is lost
530 * schedules reconnect, or fires 'connection_dead' if reconnect limit is hit
531 * schedules reconnect, or fires 'connection_dead' if reconnect limit is hit
531 */
532 */
532 if (this._reconnect_attempt < this.reconnect_limit) {
533 if (this._reconnect_attempt < this.reconnect_limit) {
533 var timeout = Math.pow(2, this._reconnect_attempt);
534 var timeout = Math.pow(2, this._reconnect_attempt);
534 console.log("Connection lost, reconnecting in " + timeout + " seconds.");
535 console.log("Connection lost, reconnecting in " + timeout + " seconds.");
535 setTimeout($.proxy(this.reconnect, this), 1e3 * timeout);
536 setTimeout($.proxy(this.reconnect, this), 1e3 * timeout);
536 } else {
537 } else {
537 this.events.trigger('kernel_connection_dead.Kernel', {
538 this.events.trigger('kernel_connection_dead.Kernel', {
538 kernel: this,
539 kernel: this,
539 reconnect_attempt: this._reconnect_attempt,
540 reconnect_attempt: this._reconnect_attempt,
540 });
541 });
541 console.log("Failed to reconnect, giving up.");
542 console.log("Failed to reconnect, giving up.");
542 }
543 }
543 };
544 };
544
545
545 Kernel.prototype.stop_channels = function () {
546 Kernel.prototype.stop_channels = function () {
546 /**
547 /**
547 * Close the websocket. After successful close, the value
548 * Close the websocket. After successful close, the value
548 * in `this.ws` will be null.
549 * in `this.ws` will be null.
549 *
550 *
550 * @function stop_channels
551 * @function stop_channels
551 */
552 */
552 var that = this;
553 var that = this;
553 var close = function () {
554 var close = function () {
554 if (that.ws && that.ws.readyState === WebSocket.CLOSED) {
555 if (that.ws && that.ws.readyState === WebSocket.CLOSED) {
555 that.ws = null;
556 that.ws = null;
556 }
557 }
557 };
558 };
558 if (this.ws !== null) {
559 if (this.ws !== null) {
559 if (this.ws.readyState === WebSocket.OPEN) {
560 if (this.ws.readyState === WebSocket.OPEN) {
560 this.ws.onclose = close;
561 this.ws.onclose = close;
561 this.ws.close();
562 this.ws.close();
562 } else {
563 } else {
563 close();
564 close();
564 }
565 }
565 }
566 }
566 };
567 };
567
568
568 Kernel.prototype.is_connected = function () {
569 Kernel.prototype.is_connected = function () {
569 /**
570 /**
570 * Check whether there is a connection to the kernel. This
571 * Check whether there is a connection to the kernel. This
571 * function only returns true if websocket has been
572 * function only returns true if websocket has been
572 * created and has a state of WebSocket.OPEN.
573 * created and has a state of WebSocket.OPEN.
573 *
574 *
574 * @function is_connected
575 * @function is_connected
575 * @returns {bool} - whether there is a connection
576 * @returns {bool} - whether there is a connection
576 */
577 */
577 // if any channel is not ready, then we're not connected
578 // if any channel is not ready, then we're not connected
578 if (this.ws === null) {
579 if (this.ws === null) {
579 return false;
580 return false;
580 }
581 }
581 if (this.ws.readyState !== WebSocket.OPEN) {
582 if (this.ws.readyState !== WebSocket.OPEN) {
582 return false;
583 return false;
583 }
584 }
584 return true;
585 return true;
585 };
586 };
586
587
587 Kernel.prototype.is_fully_disconnected = function () {
588 Kernel.prototype.is_fully_disconnected = function () {
588 /**
589 /**
589 * Check whether the connection to the kernel has been completely
590 * Check whether the connection to the kernel has been completely
590 * severed. This function only returns true if all channel objects
591 * severed. This function only returns true if all channel objects
591 * are null.
592 * are null.
592 *
593 *
593 * @function is_fully_disconnected
594 * @function is_fully_disconnected
594 * @returns {bool} - whether the kernel is fully disconnected
595 * @returns {bool} - whether the kernel is fully disconnected
595 */
596 */
596 return (this.ws === null);
597 return (this.ws === null);
597 };
598 };
598
599
599 Kernel.prototype.send_shell_message = function (msg_type, content, callbacks, metadata, buffers) {
600 Kernel.prototype.send_shell_message = function (msg_type, content, callbacks, metadata, buffers) {
600 /**
601 /**
601 * Send a message on the Kernel's shell channel
602 * Send a message on the Kernel's shell channel
602 *
603 *
603 * @function send_shell_message
604 * @function send_shell_message
604 */
605 */
605 if (!this.is_connected()) {
606 if (!this.is_connected()) {
606 throw new Error("kernel is not connected");
607 throw new Error("kernel is not connected");
607 }
608 }
608 var msg = this._get_msg(msg_type, content, metadata, buffers);
609 var msg = this._get_msg(msg_type, content, metadata, buffers);
609 msg.channel = 'shell';
610 msg.channel = 'shell';
610 this.ws.send(serialize.serialize(msg));
611 this.ws.send(serialize.serialize(msg));
611 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
612 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
612 return msg.header.msg_id;
613 return msg.header.msg_id;
613 };
614 };
614
615
615 Kernel.prototype.kernel_info = function (callback) {
616 Kernel.prototype.kernel_info = function (callback) {
616 /**
617 /**
617 * Get kernel info
618 * Get kernel info
618 *
619 *
619 * @function kernel_info
620 * @function kernel_info
620 * @param callback {function}
621 * @param callback {function}
621 *
622 *
622 * When calling this method, pass a callback function that expects one argument.
623 * When calling this method, pass a callback function that expects one argument.
623 * The callback will be passed the complete `kernel_info_reply` message documented
624 * The callback will be passed the complete `kernel_info_reply` message documented
624 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#kernel-info)
625 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#kernel-info)
625 */
626 */
626 var callbacks;
627 var callbacks;
627 if (callback) {
628 if (callback) {
628 callbacks = { shell : { reply : callback } };
629 callbacks = { shell : { reply : callback } };
629 }
630 }
630 return this.send_shell_message("kernel_info_request", {}, callbacks);
631 return this.send_shell_message("kernel_info_request", {}, callbacks);
631 };
632 };
632
633
633 Kernel.prototype.inspect = function (code, cursor_pos, callback) {
634 Kernel.prototype.inspect = function (code, cursor_pos, callback) {
634 /**
635 /**
635 * Get info on an object
636 * Get info on an object
636 *
637 *
637 * When calling this method, pass a callback function that expects one argument.
638 * When calling this method, pass a callback function that expects one argument.
638 * The callback will be passed the complete `inspect_reply` message documented
639 * The callback will be passed the complete `inspect_reply` message documented
639 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#object-information)
640 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#object-information)
640 *
641 *
641 * @function inspect
642 * @function inspect
642 * @param code {string}
643 * @param code {string}
643 * @param cursor_pos {integer}
644 * @param cursor_pos {integer}
644 * @param callback {function}
645 * @param callback {function}
645 */
646 */
646 var callbacks;
647 var callbacks;
647 if (callback) {
648 if (callback) {
648 callbacks = { shell : { reply : callback } };
649 callbacks = { shell : { reply : callback } };
649 }
650 }
650
651
651 var content = {
652 var content = {
652 code : code,
653 code : code,
653 cursor_pos : cursor_pos,
654 cursor_pos : cursor_pos,
654 detail_level : 0
655 detail_level : 0
655 };
656 };
656 return this.send_shell_message("inspect_request", content, callbacks);
657 return this.send_shell_message("inspect_request", content, callbacks);
657 };
658 };
658
659
659 Kernel.prototype.execute = function (code, callbacks, options) {
660 Kernel.prototype.execute = function (code, callbacks, options) {
660 /**
661 /**
661 * Execute given code into kernel, and pass result to callback.
662 * Execute given code into kernel, and pass result to callback.
662 *
663 *
663 * @async
664 * @async
664 * @function execute
665 * @function execute
665 * @param {string} code
666 * @param {string} code
666 * @param [callbacks] {Object} With the following keys (all optional)
667 * @param [callbacks] {Object} With the following keys (all optional)
667 * @param callbacks.shell.reply {function}
668 * @param callbacks.shell.reply {function}
668 * @param callbacks.shell.payload.[payload_name] {function}
669 * @param callbacks.shell.payload.[payload_name] {function}
669 * @param callbacks.iopub.output {function}
670 * @param callbacks.iopub.output {function}
670 * @param callbacks.iopub.clear_output {function}
671 * @param callbacks.iopub.clear_output {function}
671 * @param callbacks.input {function}
672 * @param callbacks.input {function}
672 * @param {object} [options]
673 * @param {object} [options]
673 * @param [options.silent=false] {Boolean}
674 * @param [options.silent=false] {Boolean}
674 * @param [options.user_expressions=empty_dict] {Dict}
675 * @param [options.user_expressions=empty_dict] {Dict}
675 * @param [options.allow_stdin=false] {Boolean} true|false
676 * @param [options.allow_stdin=false] {Boolean} true|false
676 *
677 *
677 * @example
678 * @example
678 *
679 *
679 * The options object should contain the options for the execute
680 * The options object should contain the options for the execute
680 * call. Its default values are:
681 * call. Its default values are:
681 *
682 *
682 * options = {
683 * options = {
683 * silent : true,
684 * silent : true,
684 * user_expressions : {},
685 * user_expressions : {},
685 * allow_stdin : false
686 * allow_stdin : false
686 * }
687 * }
687 *
688 *
688 * When calling this method pass a callbacks structure of the
689 * When calling this method pass a callbacks structure of the
689 * form:
690 * form:
690 *
691 *
691 * callbacks = {
692 * callbacks = {
692 * shell : {
693 * shell : {
693 * reply : execute_reply_callback,
694 * reply : execute_reply_callback,
694 * payload : {
695 * payload : {
695 * set_next_input : set_next_input_callback,
696 * set_next_input : set_next_input_callback,
696 * }
697 * }
697 * },
698 * },
698 * iopub : {
699 * iopub : {
699 * output : output_callback,
700 * output : output_callback,
700 * clear_output : clear_output_callback,
701 * clear_output : clear_output_callback,
701 * },
702 * },
702 * input : raw_input_callback
703 * input : raw_input_callback
703 * }
704 * }
704 *
705 *
705 * Each callback will be passed the entire message as a single
706 * Each callback will be passed the entire message as a single
706 * arugment. Payload handlers will be passed the corresponding
707 * arugment. Payload handlers will be passed the corresponding
707 * payload and the execute_reply message.
708 * payload and the execute_reply message.
708 */
709 */
709 var content = {
710 var content = {
710 code : code,
711 code : code,
711 silent : true,
712 silent : true,
712 store_history : false,
713 store_history : false,
713 user_expressions : {},
714 user_expressions : {},
714 allow_stdin : false
715 allow_stdin : false
715 };
716 };
716 callbacks = callbacks || {};
717 callbacks = callbacks || {};
717 if (callbacks.input !== undefined) {
718 if (callbacks.input !== undefined) {
718 content.allow_stdin = true;
719 content.allow_stdin = true;
719 }
720 }
720 $.extend(true, content, options);
721 $.extend(true, content, options);
721 this.events.trigger('execution_request.Kernel', {kernel: this, content: content});
722 this.events.trigger('execution_request.Kernel', {kernel: this, content: content});
722 return this.send_shell_message("execute_request", content, callbacks);
723 return this.send_shell_message("execute_request", content, callbacks);
723 };
724 };
724
725
725 /**
726 /**
726 * When calling this method, pass a function to be called with the
727 * When calling this method, pass a function to be called with the
727 * `complete_reply` message as its only argument when it arrives.
728 * `complete_reply` message as its only argument when it arrives.
728 *
729 *
729 * `complete_reply` is documented
730 * `complete_reply` is documented
730 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#complete)
731 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#complete)
731 *
732 *
732 * @function complete
733 * @function complete
733 * @param code {string}
734 * @param code {string}
734 * @param cursor_pos {integer}
735 * @param cursor_pos {integer}
735 * @param callback {function}
736 * @param callback {function}
736 */
737 */
737 Kernel.prototype.complete = function (code, cursor_pos, callback) {
738 Kernel.prototype.complete = function (code, cursor_pos, callback) {
738 var callbacks;
739 var callbacks;
739 if (callback) {
740 if (callback) {
740 callbacks = { shell : { reply : callback } };
741 callbacks = { shell : { reply : callback } };
741 }
742 }
742 var content = {
743 var content = {
743 code : code,
744 code : code,
744 cursor_pos : cursor_pos
745 cursor_pos : cursor_pos
745 };
746 };
746 return this.send_shell_message("complete_request", content, callbacks);
747 return this.send_shell_message("complete_request", content, callbacks);
747 };
748 };
748
749
749 /**
750 /**
750 * @function send_input_reply
751 * @function send_input_reply
751 */
752 */
752 Kernel.prototype.send_input_reply = function (input) {
753 Kernel.prototype.send_input_reply = function (input) {
753 if (!this.is_connected()) {
754 if (!this.is_connected()) {
754 throw new Error("kernel is not connected");
755 throw new Error("kernel is not connected");
755 }
756 }
756 var content = {
757 var content = {
757 value : input
758 value : input
758 };
759 };
759 this.events.trigger('input_reply.Kernel', {kernel: this, content: content});
760 this.events.trigger('input_reply.Kernel', {kernel: this, content: content});
760 var msg = this._get_msg("input_reply", content);
761 var msg = this._get_msg("input_reply", content);
761 msg.channel = 'stdin';
762 msg.channel = 'stdin';
762 this.ws.send(serialize.serialize(msg));
763 this.ws.send(serialize.serialize(msg));
763 return msg.header.msg_id;
764 return msg.header.msg_id;
764 };
765 };
765
766
766 /**
767 /**
767 * @function register_iopub_handler
768 * @function register_iopub_handler
768 */
769 */
769 Kernel.prototype.register_iopub_handler = function (msg_type, callback) {
770 Kernel.prototype.register_iopub_handler = function (msg_type, callback) {
770 this._iopub_handlers[msg_type] = callback;
771 this._iopub_handlers[msg_type] = callback;
771 };
772 };
772
773
773 /**
774 /**
774 * Get the iopub handler for a specific message type.
775 * Get the iopub handler for a specific message type.
775 *
776 *
776 * @function get_iopub_handler
777 * @function get_iopub_handler
777 */
778 */
778 Kernel.prototype.get_iopub_handler = function (msg_type) {
779 Kernel.prototype.get_iopub_handler = function (msg_type) {
779 return this._iopub_handlers[msg_type];
780 return this._iopub_handlers[msg_type];
780 };
781 };
781
782
782 /**
783 /**
783 * Get callbacks for a specific message.
784 * Get callbacks for a specific message.
784 *
785 *
785 * @function get_callbacks_for_msg
786 * @function get_callbacks_for_msg
786 */
787 */
787 Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
788 Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
788 if (msg_id == this.last_msg_id) {
789 if (msg_id == this.last_msg_id) {
789 return this.last_msg_callbacks;
790 return this.last_msg_callbacks;
790 } else {
791 } else {
791 return this._msg_callbacks[msg_id];
792 return this._msg_callbacks[msg_id];
792 }
793 }
793 };
794 };
794
795
795 /**
796 /**
796 * Clear callbacks for a specific message.
797 * Clear callbacks for a specific message.
797 *
798 *
798 * @function clear_callbacks_for_msg
799 * @function clear_callbacks_for_msg
799 */
800 */
800 Kernel.prototype.clear_callbacks_for_msg = function (msg_id) {
801 Kernel.prototype.clear_callbacks_for_msg = function (msg_id) {
801 if (this._msg_callbacks[msg_id] !== undefined ) {
802 if (this._msg_callbacks[msg_id] !== undefined ) {
802 delete this._msg_callbacks[msg_id];
803 delete this._msg_callbacks[msg_id];
803 }
804 }
804 };
805 };
805
806
806 /**
807 /**
807 * @function _finish_shell
808 * @function _finish_shell
808 */
809 */
809 Kernel.prototype._finish_shell = function (msg_id) {
810 Kernel.prototype._finish_shell = function (msg_id) {
810 var callbacks = this._msg_callbacks[msg_id];
811 var callbacks = this._msg_callbacks[msg_id];
811 if (callbacks !== undefined) {
812 if (callbacks !== undefined) {
812 callbacks.shell_done = true;
813 callbacks.shell_done = true;
813 if (callbacks.iopub_done) {
814 if (callbacks.iopub_done) {
814 this.clear_callbacks_for_msg(msg_id);
815 this.clear_callbacks_for_msg(msg_id);
815 }
816 }
816 }
817 }
817 };
818 };
818
819
819 /**
820 /**
820 * @function _finish_iopub
821 * @function _finish_iopub
821 */
822 */
822 Kernel.prototype._finish_iopub = function (msg_id) {
823 Kernel.prototype._finish_iopub = function (msg_id) {
823 var callbacks = this._msg_callbacks[msg_id];
824 var callbacks = this._msg_callbacks[msg_id];
824 if (callbacks !== undefined) {
825 if (callbacks !== undefined) {
825 callbacks.iopub_done = true;
826 callbacks.iopub_done = true;
826 if (callbacks.shell_done) {
827 if (callbacks.shell_done) {
827 this.clear_callbacks_for_msg(msg_id);
828 this.clear_callbacks_for_msg(msg_id);
828 }
829 }
829 }
830 }
830 };
831 };
831
832
832 /**
833 /**
833 * Set callbacks for a particular message.
834 * Set callbacks for a particular message.
834 * Callbacks should be a struct of the following form:
835 * Callbacks should be a struct of the following form:
835 * shell : {
836 * shell : {
836 *
837 *
837 * }
838 * }
838 *
839 *
839 * @function set_callbacks_for_msg
840 * @function set_callbacks_for_msg
840 */
841 */
841 Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
842 Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
842 this.last_msg_id = msg_id;
843 this.last_msg_id = msg_id;
843 if (callbacks) {
844 if (callbacks) {
844 // shallow-copy mapping, because we will modify it at the top level
845 // shallow-copy mapping, because we will modify it at the top level
845 var cbcopy = this._msg_callbacks[msg_id] = this.last_msg_callbacks = {};
846 var cbcopy = this._msg_callbacks[msg_id] = this.last_msg_callbacks = {};
846 cbcopy.shell = callbacks.shell;
847 cbcopy.shell = callbacks.shell;
847 cbcopy.iopub = callbacks.iopub;
848 cbcopy.iopub = callbacks.iopub;
848 cbcopy.input = callbacks.input;
849 cbcopy.input = callbacks.input;
849 cbcopy.shell_done = (!callbacks.shell);
850 cbcopy.shell_done = (!callbacks.shell);
850 cbcopy.iopub_done = (!callbacks.iopub);
851 cbcopy.iopub_done = (!callbacks.iopub);
851 } else {
852 } else {
852 this.last_msg_callbacks = {};
853 this.last_msg_callbacks = {};
853 }
854 }
854 };
855 };
855
856
856 Kernel.prototype._handle_ws_message = function (e) {
857 Kernel.prototype._handle_ws_message = function (e) {
857 serialize.deserialize(e.data, $.proxy(this._finish_ws_message, this));
858 var that = this;
859 this._msg_queue = this._msg_queue.then(function() {
860 return serialize.deserialize(e.data);
861 }).then(function(msg) {return that._finish_ws_message(msg);})
862 .catch(utils.reject("Couldn't process kernel message", true));
858 };
863 };
859
864
860 Kernel.prototype._finish_ws_message = function (msg) {
865 Kernel.prototype._finish_ws_message = function (msg) {
861 switch (msg.channel) {
866 switch (msg.channel) {
862 case 'shell':
867 case 'shell':
863 this._handle_shell_reply(msg);
868 return this._handle_shell_reply(msg);
864 break;
869 break;
865 case 'iopub':
870 case 'iopub':
866 this._handle_iopub_message(msg);
871 return this._handle_iopub_message(msg);
867 break;
872 break;
868 case 'stdin':
873 case 'stdin':
869 this._handle_input_request(msg);
874 return this._handle_input_request(msg);
870 break;
875 break;
871 default:
876 default:
872 console.error("unrecognized message channel", msg.channel, msg);
877 console.error("unrecognized message channel", msg.channel, msg);
873 }
878 }
874 };
879 };
875
880
876 Kernel.prototype._handle_shell_reply = function (reply) {
881 Kernel.prototype._handle_shell_reply = function (reply) {
877 this.events.trigger('shell_reply.Kernel', {kernel: this, reply:reply});
882 this.events.trigger('shell_reply.Kernel', {kernel: this, reply:reply});
883 var that = this;
878 var content = reply.content;
884 var content = reply.content;
879 var metadata = reply.metadata;
885 var metadata = reply.metadata;
880 var parent_id = reply.parent_header.msg_id;
886 var parent_id = reply.parent_header.msg_id;
881 var callbacks = this.get_callbacks_for_msg(parent_id);
887 var callbacks = this.get_callbacks_for_msg(parent_id);
888 var promise = Promise.resolve();
882 if (!callbacks || !callbacks.shell) {
889 if (!callbacks || !callbacks.shell) {
883 return;
890 return;
884 }
891 }
885 var shell_callbacks = callbacks.shell;
892 var shell_callbacks = callbacks.shell;
886
893
887 // signal that shell callbacks are done
894 // signal that shell callbacks are done
888 this._finish_shell(parent_id);
895 this._finish_shell(parent_id);
889
896
890 if (shell_callbacks.reply !== undefined) {
897 if (shell_callbacks.reply !== undefined) {
891 shell_callbacks.reply(reply);
898 promise = promise.then(function() {return shell_callbacks.reply(reply)});
892 }
899 }
893 if (content.payload && shell_callbacks.payload) {
900 if (content.payload && shell_callbacks.payload) {
894 this._handle_payloads(content.payload, shell_callbacks.payload, reply);
901 promise = promise.then(function() {
902 return that._handle_payloads(content.payload, shell_callbacks.payload, reply);
903 });
895 }
904 }
905 return promise;
896 };
906 };
897
907
898 /**
908 /**
899 * @function _handle_payloads
909 * @function _handle_payloads
900 */
910 */
901 Kernel.prototype._handle_payloads = function (payloads, payload_callbacks, msg) {
911 Kernel.prototype._handle_payloads = function (payloads, payload_callbacks, msg) {
912 var promise = [];
902 var l = payloads.length;
913 var l = payloads.length;
903 // Payloads are handled by triggering events because we don't want the Kernel
914 // Payloads are handled by triggering events because we don't want the Kernel
904 // to depend on the Notebook or Pager classes.
915 // to depend on the Notebook or Pager classes.
905 for (var i=0; i<l; i++) {
916 for (var i=0; i<l; i++) {
906 var payload = payloads[i];
917 var payload = payloads[i];
907 var callback = payload_callbacks[payload.source];
918 var callback = payload_callbacks[payload.source];
908 if (callback) {
919 if (callback) {
909 callback(payload, msg);
920 promise.push(callback(payload, msg));
910 }
921 }
911 }
922 }
923 return Promise.all(promise);
912 };
924 };
913
925
914 /**
926 /**
915 * @function _handle_status_message
927 * @function _handle_status_message
916 */
928 */
917 Kernel.prototype._handle_status_message = function (msg) {
929 Kernel.prototype._handle_status_message = function (msg) {
918 var execution_state = msg.content.execution_state;
930 var execution_state = msg.content.execution_state;
919 var parent_id = msg.parent_header.msg_id;
931 var parent_id = msg.parent_header.msg_id;
920
932
921 // dispatch status msg callbacks, if any
933 // dispatch status msg callbacks, if any
922 var callbacks = this.get_callbacks_for_msg(parent_id);
934 var callbacks = this.get_callbacks_for_msg(parent_id);
923 if (callbacks && callbacks.iopub && callbacks.iopub.status) {
935 if (callbacks && callbacks.iopub && callbacks.iopub.status) {
924 try {
936 try {
925 callbacks.iopub.status(msg);
937 callbacks.iopub.status(msg);
926 } catch (e) {
938 } catch (e) {
927 console.log("Exception in status msg handler", e, e.stack);
939 console.log("Exception in status msg handler", e, e.stack);
928 }
940 }
929 }
941 }
930
942
931 if (execution_state === 'busy') {
943 if (execution_state === 'busy') {
932 this.events.trigger('kernel_busy.Kernel', {kernel: this});
944 this.events.trigger('kernel_busy.Kernel', {kernel: this});
933
945
934 } else if (execution_state === 'idle') {
946 } else if (execution_state === 'idle') {
935 // signal that iopub callbacks are (probably) done
947 // signal that iopub callbacks are (probably) done
936 // async output may still arrive,
948 // async output may still arrive,
937 // but only for the most recent request
949 // but only for the most recent request
938 this._finish_iopub(parent_id);
950 this._finish_iopub(parent_id);
939
951
940 // trigger status_idle event
952 // trigger status_idle event
941 this.events.trigger('kernel_idle.Kernel', {kernel: this});
953 this.events.trigger('kernel_idle.Kernel', {kernel: this});
942
954
943 } else if (execution_state === 'starting') {
955 } else if (execution_state === 'starting') {
944 this.events.trigger('kernel_starting.Kernel', {kernel: this});
956 this.events.trigger('kernel_starting.Kernel', {kernel: this});
945 var that = this;
957 var that = this;
946 this.kernel_info(function (reply) {
958 this.kernel_info(function (reply) {
947 that.info_reply = reply.content;
959 that.info_reply = reply.content;
948 that.events.trigger('kernel_ready.Kernel', {kernel: that});
960 that.events.trigger('kernel_ready.Kernel', {kernel: that});
949 });
961 });
950
962
951 } else if (execution_state === 'restarting') {
963 } else if (execution_state === 'restarting') {
952 // autorestarting is distinct from restarting,
964 // autorestarting is distinct from restarting,
953 // in that it means the kernel died and the server is restarting it.
965 // in that it means the kernel died and the server is restarting it.
954 // kernel_restarting sets the notification widget,
966 // kernel_restarting sets the notification widget,
955 // autorestart shows the more prominent dialog.
967 // autorestart shows the more prominent dialog.
956 this._autorestart_attempt = this._autorestart_attempt + 1;
968 this._autorestart_attempt = this._autorestart_attempt + 1;
957 this.events.trigger('kernel_restarting.Kernel', {kernel: this});
969 this.events.trigger('kernel_restarting.Kernel', {kernel: this});
958 this.events.trigger('kernel_autorestarting.Kernel', {kernel: this, attempt: this._autorestart_attempt});
970 this.events.trigger('kernel_autorestarting.Kernel', {kernel: this, attempt: this._autorestart_attempt});
959
971
960 } else if (execution_state === 'dead') {
972 } else if (execution_state === 'dead') {
961 this.events.trigger('kernel_dead.Kernel', {kernel: this});
973 this.events.trigger('kernel_dead.Kernel', {kernel: this});
962 this._kernel_dead();
974 this._kernel_dead();
963 }
975 }
964 };
976 };
965
977
966 /**
978 /**
967 * Handle clear_output message
979 * Handle clear_output message
968 *
980 *
969 * @function _handle_clear_output
981 * @function _handle_clear_output
970 */
982 */
971 Kernel.prototype._handle_clear_output = function (msg) {
983 Kernel.prototype._handle_clear_output = function (msg) {
972 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
984 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
973 if (!callbacks || !callbacks.iopub) {
985 if (!callbacks || !callbacks.iopub) {
974 return;
986 return;
975 }
987 }
976 var callback = callbacks.iopub.clear_output;
988 var callback = callbacks.iopub.clear_output;
977 if (callback) {
989 if (callback) {
978 callback(msg);
990 callback(msg);
979 }
991 }
980 };
992 };
981
993
982 /**
994 /**
983 * handle an output message (execute_result, display_data, etc.)
995 * handle an output message (execute_result, display_data, etc.)
984 *
996 *
985 * @function _handle_output_message
997 * @function _handle_output_message
986 */
998 */
987 Kernel.prototype._handle_output_message = function (msg) {
999 Kernel.prototype._handle_output_message = function (msg) {
988 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
1000 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
989 if (!callbacks || !callbacks.iopub) {
1001 if (!callbacks || !callbacks.iopub) {
990 // The message came from another client. Let the UI decide what to
1002 // The message came from another client. Let the UI decide what to
991 // do with it.
1003 // do with it.
992 this.events.trigger('received_unsolicited_message.Kernel', msg);
1004 this.events.trigger('received_unsolicited_message.Kernel', msg);
993 return;
1005 return;
994 }
1006 }
995 var callback = callbacks.iopub.output;
1007 var callback = callbacks.iopub.output;
996 if (callback) {
1008 if (callback) {
997 callback(msg);
1009 callback(msg);
998 }
1010 }
999 };
1011 };
1000
1012
1001 /**
1013 /**
1002 * Handle an input message (execute_input).
1014 * Handle an input message (execute_input).
1003 *
1015 *
1004 * @function _handle_input message
1016 * @function _handle_input message
1005 */
1017 */
1006 Kernel.prototype._handle_input_message = function (msg) {
1018 Kernel.prototype._handle_input_message = function (msg) {
1007 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
1019 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
1008 if (!callbacks) {
1020 if (!callbacks) {
1009 // The message came from another client. Let the UI decide what to
1021 // The message came from another client. Let the UI decide what to
1010 // do with it.
1022 // do with it.
1011 this.events.trigger('received_unsolicited_message.Kernel', msg);
1023 this.events.trigger('received_unsolicited_message.Kernel', msg);
1012 }
1024 }
1013 };
1025 };
1014
1026
1015 /**
1027 /**
1016 * Dispatch IOPub messages to respective handlers. Each message
1028 * Dispatch IOPub messages to respective handlers. Each message
1017 * type should have a handler.
1029 * type should have a handler.
1018 *
1030 *
1019 * @function _handle_iopub_message
1031 * @function _handle_iopub_message
1020 */
1032 */
1021 Kernel.prototype._handle_iopub_message = function (msg) {
1033 Kernel.prototype._handle_iopub_message = function (msg) {
1022 var handler = this.get_iopub_handler(msg.header.msg_type);
1034 var handler = this.get_iopub_handler(msg.header.msg_type);
1023 if (handler !== undefined) {
1035 if (handler !== undefined) {
1024 handler(msg);
1036 return handler(msg);
1025 }
1037 }
1026 };
1038 };
1027
1039
1028 /**
1040 /**
1029 * @function _handle_input_request
1041 * @function _handle_input_request
1030 */
1042 */
1031 Kernel.prototype._handle_input_request = function (request) {
1043 Kernel.prototype._handle_input_request = function (request) {
1032 var header = request.header;
1044 var header = request.header;
1033 var content = request.content;
1045 var content = request.content;
1034 var metadata = request.metadata;
1046 var metadata = request.metadata;
1035 var msg_type = header.msg_type;
1047 var msg_type = header.msg_type;
1036 if (msg_type !== 'input_request') {
1048 if (msg_type !== 'input_request') {
1037 console.log("Invalid input request!", request);
1049 console.log("Invalid input request!", request);
1038 return;
1050 return;
1039 }
1051 }
1040 var callbacks = this.get_callbacks_for_msg(request.parent_header.msg_id);
1052 var callbacks = this.get_callbacks_for_msg(request.parent_header.msg_id);
1041 if (callbacks) {
1053 if (callbacks) {
1042 if (callbacks.input) {
1054 if (callbacks.input) {
1043 callbacks.input(request);
1055 callbacks.input(request);
1044 }
1056 }
1045 }
1057 }
1046 };
1058 };
1047
1059
1048 // Backwards compatability.
1060 // Backwards compatability.
1049 IPython.Kernel = Kernel;
1061 IPython.Kernel = Kernel;
1050
1062
1051 return {'Kernel': Kernel};
1063 return {'Kernel': Kernel};
1052 });
1064 });
@@ -1,120 +1,123 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'underscore',
5 'underscore',
6 ], function (_) {
6 ], function (_) {
7 "use strict";
7 "use strict";
8
8
9 var _deserialize_array_buffer = function (buf) {
9 var _deserialize_array_buffer = function (buf) {
10 var data = new DataView(buf);
10 var data = new DataView(buf);
11 // read the header: 1 + nbufs 32b integers
11 // read the header: 1 + nbufs 32b integers
12 var nbufs = data.getUint32(0);
12 var nbufs = data.getUint32(0);
13 var offsets = [];
13 var offsets = [];
14 var i;
14 var i;
15 for (i = 1; i <= nbufs; i++) {
15 for (i = 1; i <= nbufs; i++) {
16 offsets.push(data.getUint32(i * 4));
16 offsets.push(data.getUint32(i * 4));
17 }
17 }
18 var json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1]));
18 var json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1]));
19 var msg = JSON.parse(
19 var msg = JSON.parse(
20 (new TextDecoder('utf8')).decode(json_bytes)
20 (new TextDecoder('utf8')).decode(json_bytes)
21 );
21 );
22 // the remaining chunks are stored as DataViews in msg.buffers
22 // the remaining chunks are stored as DataViews in msg.buffers
23 msg.buffers = [];
23 msg.buffers = [];
24 var start, stop;
24 var start, stop;
25 for (i = 1; i < nbufs; i++) {
25 for (i = 1; i < nbufs; i++) {
26 start = offsets[i];
26 start = offsets[i];
27 stop = offsets[i+1] || buf.byteLength;
27 stop = offsets[i+1] || buf.byteLength;
28 msg.buffers.push(new DataView(buf.slice(start, stop)));
28 msg.buffers.push(new DataView(buf.slice(start, stop)));
29 }
29 }
30 return msg;
30 return msg;
31 };
31 };
32
32
33 var _deserialize_binary = function(data, callback) {
33 var _deserialize_binary = function(data) {
34 /**
34 /**
35 * deserialize the binary message format
35 * deserialize the binary message format
36 * callback will be called with a message whose buffers attribute
36 * callback will be called with a message whose buffers attribute
37 * will be an array of DataViews.
37 * will be an array of DataViews.
38 */
38 */
39 if (data instanceof Blob) {
39 if (data instanceof Blob) {
40 // data is Blob, have to deserialize from ArrayBuffer in reader callback
40 // data is Blob, have to deserialize from ArrayBuffer in reader callback
41 var reader = new FileReader();
41 var reader = new FileReader();
42 reader.onload = function () {
42 var promise = new Promise(function(resolve, reject) {
43 var msg = _deserialize_array_buffer(this.result);
43 reader.onload = function () {
44 callback(msg);
44 var msg = _deserialize_array_buffer(this.result);
45 };
45 resolve(msg);
46 };
47 });
46 reader.readAsArrayBuffer(data);
48 reader.readAsArrayBuffer(data);
49 return promise;
47 } else {
50 } else {
48 // data is ArrayBuffer, can deserialize directly
51 // data is ArrayBuffer, can deserialize directly
49 var msg = _deserialize_array_buffer(data);
52 var msg = _deserialize_array_buffer(data);
50 callback(msg);
53 return msg;
51 }
54 }
52 };
55 };
53
56
54 var deserialize = function (data, callback) {
57 var deserialize = function (data) {
55 /**
58 /**
56 * deserialize a message and pass the unpacked message object to callback
59 * deserialize a message and return a promise for the unpacked message
57 */
60 */
58 if (typeof data === "string") {
61 if (typeof data === "string") {
59 // text JSON message
62 // text JSON message
60 callback(JSON.parse(data));
63 return Promise.resolve(JSON.parse(data));
61 } else {
64 } else {
62 // binary message
65 // binary message
63 _deserialize_binary(data, callback);
66 return Promise.resolve(_deserialize_binary(data));
64 }
67 }
65 };
68 };
66
69
67 var _serialize_binary = function (msg) {
70 var _serialize_binary = function (msg) {
68 /**
71 /**
69 * implement the binary serialization protocol
72 * implement the binary serialization protocol
70 * serializes JSON message to ArrayBuffer
73 * serializes JSON message to ArrayBuffer
71 */
74 */
72 msg = _.clone(msg);
75 msg = _.clone(msg);
73 var offsets = [];
76 var offsets = [];
74 var buffers = [];
77 var buffers = [];
75 msg.buffers.map(function (buf) {
78 msg.buffers.map(function (buf) {
76 buffers.push(buf);
79 buffers.push(buf);
77 });
80 });
78 delete msg.buffers;
81 delete msg.buffers;
79 var json_utf8 = (new TextEncoder('utf8')).encode(JSON.stringify(msg));
82 var json_utf8 = (new TextEncoder('utf8')).encode(JSON.stringify(msg));
80 buffers.unshift(json_utf8);
83 buffers.unshift(json_utf8);
81 var nbufs = buffers.length;
84 var nbufs = buffers.length;
82 offsets.push(4 * (nbufs + 1));
85 offsets.push(4 * (nbufs + 1));
83 var i;
86 var i;
84 for (i = 0; i + 1 < buffers.length; i++) {
87 for (i = 0; i + 1 < buffers.length; i++) {
85 offsets.push(offsets[offsets.length-1] + buffers[i].byteLength);
88 offsets.push(offsets[offsets.length-1] + buffers[i].byteLength);
86 }
89 }
87 var msg_buf = new Uint8Array(
90 var msg_buf = new Uint8Array(
88 offsets[offsets.length-1] + buffers[buffers.length-1].byteLength
91 offsets[offsets.length-1] + buffers[buffers.length-1].byteLength
89 );
92 );
90 // use DataView.setUint32 for network byte-order
93 // use DataView.setUint32 for network byte-order
91 var view = new DataView(msg_buf.buffer);
94 var view = new DataView(msg_buf.buffer);
92 // write nbufs to first 4 bytes
95 // write nbufs to first 4 bytes
93 view.setUint32(0, nbufs);
96 view.setUint32(0, nbufs);
94 // write offsets to next 4 * nbufs bytes
97 // write offsets to next 4 * nbufs bytes
95 for (i = 0; i < offsets.length; i++) {
98 for (i = 0; i < offsets.length; i++) {
96 view.setUint32(4 * (i+1), offsets[i]);
99 view.setUint32(4 * (i+1), offsets[i]);
97 }
100 }
98 // write all the buffers at their respective offsets
101 // write all the buffers at their respective offsets
99 for (i = 0; i < buffers.length; i++) {
102 for (i = 0; i < buffers.length; i++) {
100 msg_buf.set(new Uint8Array(buffers[i].buffer), offsets[i]);
103 msg_buf.set(new Uint8Array(buffers[i].buffer), offsets[i]);
101 }
104 }
102
105
103 // return raw ArrayBuffer
106 // return raw ArrayBuffer
104 return msg_buf.buffer;
107 return msg_buf.buffer;
105 };
108 };
106
109
107 var serialize = function (msg) {
110 var serialize = function (msg) {
108 if (msg.buffers && msg.buffers.length) {
111 if (msg.buffers && msg.buffers.length) {
109 return _serialize_binary(msg);
112 return _serialize_binary(msg);
110 } else {
113 } else {
111 return JSON.stringify(msg);
114 return JSON.stringify(msg);
112 }
115 }
113 };
116 };
114
117
115 var exports = {
118 var exports = {
116 deserialize : deserialize,
119 deserialize : deserialize,
117 serialize: serialize
120 serialize: serialize
118 };
121 };
119 return exports;
122 return exports;
120 }); No newline at end of file
123 });
@@ -1,1582 +1,1580 b''
1 /*!
1 /*!
2 *
2 *
3 * IPython base
3 * IPython base
4 *
4 *
5 */
5 */
6 .modal.fade .modal-dialog {
6 .modal.fade .modal-dialog {
7 -webkit-transform: translate(0, 0);
7 -webkit-transform: translate(0, 0);
8 -ms-transform: translate(0, 0);
8 -ms-transform: translate(0, 0);
9 -o-transform: translate(0, 0);
9 -o-transform: translate(0, 0);
10 transform: translate(0, 0);
10 transform: translate(0, 0);
11 }
11 }
12 code {
12 code {
13 color: #000000;
13 color: #000000;
14 }
14 }
15 pre {
15 pre {
16 font-size: inherit;
16 font-size: inherit;
17 line-height: inherit;
17 line-height: inherit;
18 }
18 }
19 label {
19 label {
20 font-weight: normal;
20 font-weight: normal;
21 }
21 }
22 /* Make the page background atleast 100% the height of the view port */
22 /* Make the page background atleast 100% the height of the view port */
23 /* Make the page itself atleast 70% the height of the view port */
23 /* Make the page itself atleast 70% the height of the view port */
24 .border-box-sizing {
24 .border-box-sizing {
25 box-sizing: border-box;
25 box-sizing: border-box;
26 -moz-box-sizing: border-box;
26 -moz-box-sizing: border-box;
27 -webkit-box-sizing: border-box;
27 -webkit-box-sizing: border-box;
28 }
28 }
29 .corner-all {
29 .corner-all {
30 border-radius: 2px;
30 border-radius: 2px;
31 }
31 }
32 .no-padding {
32 .no-padding {
33 padding: 0px;
33 padding: 0px;
34 }
34 }
35 /* Flexible box model classes */
35 /* Flexible box model classes */
36 /* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
36 /* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
37 /* This file is a compatability layer. It allows the usage of flexible box
37 /* This file is a compatability layer. It allows the usage of flexible box
38 model layouts accross multiple browsers, including older browsers. The newest,
38 model layouts accross multiple browsers, including older browsers. The newest,
39 universal implementation of the flexible box model is used when available (see
39 universal implementation of the flexible box model is used when available (see
40 `Modern browsers` comments below). Browsers that are known to implement this
40 `Modern browsers` comments below). Browsers that are known to implement this
41 new spec completely include:
41 new spec completely include:
42
42
43 Firefox 28.0+
43 Firefox 28.0+
44 Chrome 29.0+
44 Chrome 29.0+
45 Internet Explorer 11+
45 Internet Explorer 11+
46 Opera 17.0+
46 Opera 17.0+
47
47
48 Browsers not listed, including Safari, are supported via the styling under the
48 Browsers not listed, including Safari, are supported via the styling under the
49 `Old browsers` comments below.
49 `Old browsers` comments below.
50 */
50 */
51 .hbox {
51 .hbox {
52 /* Old browsers */
52 /* Old browsers */
53 display: -webkit-box;
53 display: -webkit-box;
54 -webkit-box-orient: horizontal;
54 -webkit-box-orient: horizontal;
55 -webkit-box-align: stretch;
55 -webkit-box-align: stretch;
56 display: -moz-box;
56 display: -moz-box;
57 -moz-box-orient: horizontal;
57 -moz-box-orient: horizontal;
58 -moz-box-align: stretch;
58 -moz-box-align: stretch;
59 display: box;
59 display: box;
60 box-orient: horizontal;
60 box-orient: horizontal;
61 box-align: stretch;
61 box-align: stretch;
62 /* Modern browsers */
62 /* Modern browsers */
63 display: flex;
63 display: flex;
64 flex-direction: row;
64 flex-direction: row;
65 align-items: stretch;
65 align-items: stretch;
66 }
66 }
67 .hbox > * {
67 .hbox > * {
68 /* Old browsers */
68 /* Old browsers */
69 -webkit-box-flex: 0;
69 -webkit-box-flex: 0;
70 -moz-box-flex: 0;
70 -moz-box-flex: 0;
71 box-flex: 0;
71 box-flex: 0;
72 /* Modern browsers */
72 /* Modern browsers */
73 flex: none;
73 flex: none;
74 }
74 }
75 .vbox {
75 .vbox {
76 /* Old browsers */
76 /* Old browsers */
77 display: -webkit-box;
77 display: -webkit-box;
78 -webkit-box-orient: vertical;
78 -webkit-box-orient: vertical;
79 -webkit-box-align: stretch;
79 -webkit-box-align: stretch;
80 display: -moz-box;
80 display: -moz-box;
81 -moz-box-orient: vertical;
81 -moz-box-orient: vertical;
82 -moz-box-align: stretch;
82 -moz-box-align: stretch;
83 display: box;
83 display: box;
84 box-orient: vertical;
84 box-orient: vertical;
85 box-align: stretch;
85 box-align: stretch;
86 /* Modern browsers */
86 /* Modern browsers */
87 display: flex;
87 display: flex;
88 flex-direction: column;
88 flex-direction: column;
89 align-items: stretch;
89 align-items: stretch;
90 }
90 }
91 .vbox > * {
91 .vbox > * {
92 /* Old browsers */
92 /* Old browsers */
93 -webkit-box-flex: 0;
93 -webkit-box-flex: 0;
94 -moz-box-flex: 0;
94 -moz-box-flex: 0;
95 box-flex: 0;
95 box-flex: 0;
96 /* Modern browsers */
96 /* Modern browsers */
97 flex: none;
97 flex: none;
98 }
98 }
99 .hbox.reverse,
99 .hbox.reverse,
100 .vbox.reverse,
100 .vbox.reverse,
101 .reverse {
101 .reverse {
102 /* Old browsers */
102 /* Old browsers */
103 -webkit-box-direction: reverse;
103 -webkit-box-direction: reverse;
104 -moz-box-direction: reverse;
104 -moz-box-direction: reverse;
105 box-direction: reverse;
105 box-direction: reverse;
106 /* Modern browsers */
106 /* Modern browsers */
107 flex-direction: row-reverse;
107 flex-direction: row-reverse;
108 }
108 }
109 .hbox.box-flex0,
109 .hbox.box-flex0,
110 .vbox.box-flex0,
110 .vbox.box-flex0,
111 .box-flex0 {
111 .box-flex0 {
112 /* Old browsers */
112 /* Old browsers */
113 -webkit-box-flex: 0;
113 -webkit-box-flex: 0;
114 -moz-box-flex: 0;
114 -moz-box-flex: 0;
115 box-flex: 0;
115 box-flex: 0;
116 /* Modern browsers */
116 /* Modern browsers */
117 flex: none;
117 flex: none;
118 width: auto;
118 width: auto;
119 }
119 }
120 .hbox.box-flex1,
120 .hbox.box-flex1,
121 .vbox.box-flex1,
121 .vbox.box-flex1,
122 .box-flex1 {
122 .box-flex1 {
123 /* Old browsers */
123 /* Old browsers */
124 -webkit-box-flex: 1;
124 -webkit-box-flex: 1;
125 -moz-box-flex: 1;
125 -moz-box-flex: 1;
126 box-flex: 1;
126 box-flex: 1;
127 /* Modern browsers */
127 /* Modern browsers */
128 flex: 1;
128 flex: 1;
129 }
129 }
130 .hbox.box-flex,
130 .hbox.box-flex,
131 .vbox.box-flex,
131 .vbox.box-flex,
132 .box-flex {
132 .box-flex {
133 /* Old browsers */
133 /* Old browsers */
134 /* Old browsers */
134 /* Old browsers */
135 -webkit-box-flex: 1;
135 -webkit-box-flex: 1;
136 -moz-box-flex: 1;
136 -moz-box-flex: 1;
137 box-flex: 1;
137 box-flex: 1;
138 /* Modern browsers */
138 /* Modern browsers */
139 flex: 1;
139 flex: 1;
140 }
140 }
141 .hbox.box-flex2,
141 .hbox.box-flex2,
142 .vbox.box-flex2,
142 .vbox.box-flex2,
143 .box-flex2 {
143 .box-flex2 {
144 /* Old browsers */
144 /* Old browsers */
145 -webkit-box-flex: 2;
145 -webkit-box-flex: 2;
146 -moz-box-flex: 2;
146 -moz-box-flex: 2;
147 box-flex: 2;
147 box-flex: 2;
148 /* Modern browsers */
148 /* Modern browsers */
149 flex: 2;
149 flex: 2;
150 }
150 }
151 .box-group1 {
151 .box-group1 {
152 /* Deprecated */
152 /* Deprecated */
153 -webkit-box-flex-group: 1;
153 -webkit-box-flex-group: 1;
154 -moz-box-flex-group: 1;
154 -moz-box-flex-group: 1;
155 box-flex-group: 1;
155 box-flex-group: 1;
156 }
156 }
157 .box-group2 {
157 .box-group2 {
158 /* Deprecated */
158 /* Deprecated */
159 -webkit-box-flex-group: 2;
159 -webkit-box-flex-group: 2;
160 -moz-box-flex-group: 2;
160 -moz-box-flex-group: 2;
161 box-flex-group: 2;
161 box-flex-group: 2;
162 }
162 }
163 .hbox.start,
163 .hbox.start,
164 .vbox.start,
164 .vbox.start,
165 .start {
165 .start {
166 /* Old browsers */
166 /* Old browsers */
167 -webkit-box-pack: start;
167 -webkit-box-pack: start;
168 -moz-box-pack: start;
168 -moz-box-pack: start;
169 box-pack: start;
169 box-pack: start;
170 /* Modern browsers */
170 /* Modern browsers */
171 justify-content: flex-start;
171 justify-content: flex-start;
172 }
172 }
173 .hbox.end,
173 .hbox.end,
174 .vbox.end,
174 .vbox.end,
175 .end {
175 .end {
176 /* Old browsers */
176 /* Old browsers */
177 -webkit-box-pack: end;
177 -webkit-box-pack: end;
178 -moz-box-pack: end;
178 -moz-box-pack: end;
179 box-pack: end;
179 box-pack: end;
180 /* Modern browsers */
180 /* Modern browsers */
181 justify-content: flex-end;
181 justify-content: flex-end;
182 }
182 }
183 .hbox.center,
183 .hbox.center,
184 .vbox.center,
184 .vbox.center,
185 .center {
185 .center {
186 /* Old browsers */
186 /* Old browsers */
187 -webkit-box-pack: center;
187 -webkit-box-pack: center;
188 -moz-box-pack: center;
188 -moz-box-pack: center;
189 box-pack: center;
189 box-pack: center;
190 /* Modern browsers */
190 /* Modern browsers */
191 justify-content: center;
191 justify-content: center;
192 }
192 }
193 .hbox.baseline,
193 .hbox.baseline,
194 .vbox.baseline,
194 .vbox.baseline,
195 .baseline {
195 .baseline {
196 /* Old browsers */
196 /* Old browsers */
197 -webkit-box-pack: baseline;
197 -webkit-box-pack: baseline;
198 -moz-box-pack: baseline;
198 -moz-box-pack: baseline;
199 box-pack: baseline;
199 box-pack: baseline;
200 /* Modern browsers */
200 /* Modern browsers */
201 justify-content: baseline;
201 justify-content: baseline;
202 }
202 }
203 .hbox.stretch,
203 .hbox.stretch,
204 .vbox.stretch,
204 .vbox.stretch,
205 .stretch {
205 .stretch {
206 /* Old browsers */
206 /* Old browsers */
207 -webkit-box-pack: stretch;
207 -webkit-box-pack: stretch;
208 -moz-box-pack: stretch;
208 -moz-box-pack: stretch;
209 box-pack: stretch;
209 box-pack: stretch;
210 /* Modern browsers */
210 /* Modern browsers */
211 justify-content: stretch;
211 justify-content: stretch;
212 }
212 }
213 .hbox.align-start,
213 .hbox.align-start,
214 .vbox.align-start,
214 .vbox.align-start,
215 .align-start {
215 .align-start {
216 /* Old browsers */
216 /* Old browsers */
217 -webkit-box-align: start;
217 -webkit-box-align: start;
218 -moz-box-align: start;
218 -moz-box-align: start;
219 box-align: start;
219 box-align: start;
220 /* Modern browsers */
220 /* Modern browsers */
221 align-items: flex-start;
221 align-items: flex-start;
222 }
222 }
223 .hbox.align-end,
223 .hbox.align-end,
224 .vbox.align-end,
224 .vbox.align-end,
225 .align-end {
225 .align-end {
226 /* Old browsers */
226 /* Old browsers */
227 -webkit-box-align: end;
227 -webkit-box-align: end;
228 -moz-box-align: end;
228 -moz-box-align: end;
229 box-align: end;
229 box-align: end;
230 /* Modern browsers */
230 /* Modern browsers */
231 align-items: flex-end;
231 align-items: flex-end;
232 }
232 }
233 .hbox.align-center,
233 .hbox.align-center,
234 .vbox.align-center,
234 .vbox.align-center,
235 .align-center {
235 .align-center {
236 /* Old browsers */
236 /* Old browsers */
237 -webkit-box-align: center;
237 -webkit-box-align: center;
238 -moz-box-align: center;
238 -moz-box-align: center;
239 box-align: center;
239 box-align: center;
240 /* Modern browsers */
240 /* Modern browsers */
241 align-items: center;
241 align-items: center;
242 }
242 }
243 .hbox.align-baseline,
243 .hbox.align-baseline,
244 .vbox.align-baseline,
244 .vbox.align-baseline,
245 .align-baseline {
245 .align-baseline {
246 /* Old browsers */
246 /* Old browsers */
247 -webkit-box-align: baseline;
247 -webkit-box-align: baseline;
248 -moz-box-align: baseline;
248 -moz-box-align: baseline;
249 box-align: baseline;
249 box-align: baseline;
250 /* Modern browsers */
250 /* Modern browsers */
251 align-items: baseline;
251 align-items: baseline;
252 }
252 }
253 .hbox.align-stretch,
253 .hbox.align-stretch,
254 .vbox.align-stretch,
254 .vbox.align-stretch,
255 .align-stretch {
255 .align-stretch {
256 /* Old browsers */
256 /* Old browsers */
257 -webkit-box-align: stretch;
257 -webkit-box-align: stretch;
258 -moz-box-align: stretch;
258 -moz-box-align: stretch;
259 box-align: stretch;
259 box-align: stretch;
260 /* Modern browsers */
260 /* Modern browsers */
261 align-items: stretch;
261 align-items: stretch;
262 }
262 }
263 div.error {
263 div.error {
264 margin: 2em;
264 margin: 2em;
265 text-align: center;
265 text-align: center;
266 }
266 }
267 div.error > h1 {
267 div.error > h1 {
268 font-size: 500%;
268 font-size: 500%;
269 line-height: normal;
269 line-height: normal;
270 }
270 }
271 div.error > p {
271 div.error > p {
272 font-size: 200%;
272 font-size: 200%;
273 line-height: normal;
273 line-height: normal;
274 }
274 }
275 div.traceback-wrapper {
275 div.traceback-wrapper {
276 text-align: left;
276 text-align: left;
277 max-width: 800px;
277 max-width: 800px;
278 margin: auto;
278 margin: auto;
279 }
279 }
280 /*!
280 /*!
281 *
281 *
282 * IPython notebook
282 * IPython notebook
283 *
283 *
284 */
284 */
285 /* CSS font colors for translated ANSI colors. */
285 /* CSS font colors for translated ANSI colors. */
286 .ansibold {
286 .ansibold {
287 font-weight: bold;
287 font-weight: bold;
288 }
288 }
289 /* use dark versions for foreground, to improve visibility */
289 /* use dark versions for foreground, to improve visibility */
290 .ansiblack {
290 .ansiblack {
291 color: black;
291 color: black;
292 }
292 }
293 .ansired {
293 .ansired {
294 color: darkred;
294 color: darkred;
295 }
295 }
296 .ansigreen {
296 .ansigreen {
297 color: darkgreen;
297 color: darkgreen;
298 }
298 }
299 .ansiyellow {
299 .ansiyellow {
300 color: #c4a000;
300 color: #c4a000;
301 }
301 }
302 .ansiblue {
302 .ansiblue {
303 color: darkblue;
303 color: darkblue;
304 }
304 }
305 .ansipurple {
305 .ansipurple {
306 color: darkviolet;
306 color: darkviolet;
307 }
307 }
308 .ansicyan {
308 .ansicyan {
309 color: steelblue;
309 color: steelblue;
310 }
310 }
311 .ansigray {
311 .ansigray {
312 color: gray;
312 color: gray;
313 }
313 }
314 /* and light for background, for the same reason */
314 /* and light for background, for the same reason */
315 .ansibgblack {
315 .ansibgblack {
316 background-color: black;
316 background-color: black;
317 }
317 }
318 .ansibgred {
318 .ansibgred {
319 background-color: red;
319 background-color: red;
320 }
320 }
321 .ansibggreen {
321 .ansibggreen {
322 background-color: green;
322 background-color: green;
323 }
323 }
324 .ansibgyellow {
324 .ansibgyellow {
325 background-color: yellow;
325 background-color: yellow;
326 }
326 }
327 .ansibgblue {
327 .ansibgblue {
328 background-color: blue;
328 background-color: blue;
329 }
329 }
330 .ansibgpurple {
330 .ansibgpurple {
331 background-color: magenta;
331 background-color: magenta;
332 }
332 }
333 .ansibgcyan {
333 .ansibgcyan {
334 background-color: cyan;
334 background-color: cyan;
335 }
335 }
336 .ansibggray {
336 .ansibggray {
337 background-color: gray;
337 background-color: gray;
338 }
338 }
339 div.cell {
339 div.cell {
340 border: 1px solid transparent;
340 border: 1px solid transparent;
341 /* Old browsers */
341 /* Old browsers */
342 display: -webkit-box;
342 display: -webkit-box;
343 -webkit-box-orient: vertical;
343 -webkit-box-orient: vertical;
344 -webkit-box-align: stretch;
344 -webkit-box-align: stretch;
345 display: -moz-box;
345 display: -moz-box;
346 -moz-box-orient: vertical;
346 -moz-box-orient: vertical;
347 -moz-box-align: stretch;
347 -moz-box-align: stretch;
348 display: box;
348 display: box;
349 box-orient: vertical;
349 box-orient: vertical;
350 box-align: stretch;
350 box-align: stretch;
351 /* Modern browsers */
351 /* Modern browsers */
352 display: flex;
352 display: flex;
353 flex-direction: column;
353 flex-direction: column;
354 align-items: stretch;
354 align-items: stretch;
355 border-radius: 2px;
355 border-radius: 2px;
356 box-sizing: border-box;
356 box-sizing: border-box;
357 -moz-box-sizing: border-box;
357 -moz-box-sizing: border-box;
358 -webkit-box-sizing: border-box;
358 -webkit-box-sizing: border-box;
359 border-width: thin;
359 border-width: thin;
360 border-style: solid;
360 border-style: solid;
361 width: 100%;
361 width: 100%;
362 padding: 5px;
362 padding: 5px;
363 /* This acts as a spacer between cells, that is outside the border */
363 /* This acts as a spacer between cells, that is outside the border */
364 margin: 0px;
364 margin: 0px;
365 outline: none;
365 outline: none;
366 }
366 }
367 div.cell.selected {
367 div.cell.selected {
368 border-color: #ababab;
368 border-color: #ababab;
369 /* Don't border the cells when printing */
369 /* Don't border the cells when printing */
370 }
370 }
371 @media print {
371 @media print {
372 div.cell.selected {
372 div.cell.selected {
373 border-color: transparent;
373 border-color: transparent;
374 }
374 }
375 }
375 }
376 .edit_mode div.cell.selected {
376 .edit_mode div.cell.selected {
377 border-color: green;
377 border-color: green;
378 /* Don't border the cells when printing */
378 /* Don't border the cells when printing */
379 }
379 }
380 @media print {
380 @media print {
381 .edit_mode div.cell.selected {
381 .edit_mode div.cell.selected {
382 border-color: transparent;
382 border-color: transparent;
383 }
383 }
384 }
384 }
385 .prompt {
385 .prompt {
386 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
386 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
387 min-width: 14ex;
387 min-width: 14ex;
388 /* This padding is tuned to match the padding on the CodeMirror editor. */
388 /* This padding is tuned to match the padding on the CodeMirror editor. */
389 padding: 0.4em;
389 padding: 0.4em;
390 margin: 0px;
390 margin: 0px;
391 font-family: monospace;
391 font-family: monospace;
392 text-align: right;
392 text-align: right;
393 /* This has to match that of the the CodeMirror class line-height below */
393 /* This has to match that of the the CodeMirror class line-height below */
394 line-height: 1.21429em;
394 line-height: 1.21429em;
395 }
395 }
396 @media (max-width: 540px) {
396 @media (max-width: 540px) {
397 .prompt {
397 .prompt {
398 text-align: left;
398 text-align: left;
399 }
399 }
400 }
400 }
401 div.inner_cell {
401 div.inner_cell {
402 /* Old browsers */
402 /* Old browsers */
403 display: -webkit-box;
403 display: -webkit-box;
404 -webkit-box-orient: vertical;
404 -webkit-box-orient: vertical;
405 -webkit-box-align: stretch;
405 -webkit-box-align: stretch;
406 display: -moz-box;
406 display: -moz-box;
407 -moz-box-orient: vertical;
407 -moz-box-orient: vertical;
408 -moz-box-align: stretch;
408 -moz-box-align: stretch;
409 display: box;
409 display: box;
410 box-orient: vertical;
410 box-orient: vertical;
411 box-align: stretch;
411 box-align: stretch;
412 /* Modern browsers */
412 /* Modern browsers */
413 display: flex;
413 display: flex;
414 flex-direction: column;
414 flex-direction: column;
415 align-items: stretch;
415 align-items: stretch;
416 /* Old browsers */
416 /* Old browsers */
417 -webkit-box-flex: 1;
417 -webkit-box-flex: 1;
418 -moz-box-flex: 1;
418 -moz-box-flex: 1;
419 box-flex: 1;
419 box-flex: 1;
420 /* Modern browsers */
420 /* Modern browsers */
421 flex: 1;
421 flex: 1;
422 }
422 }
423 @-moz-document url-prefix() {
423 @-moz-document url-prefix() {
424 div.inner_cell {
424 div.inner_cell {
425 overflow-x: hidden;
425 overflow-x: hidden;
426 }
426 }
427 }
427 }
428 /* input_area and input_prompt must match in top border and margin for alignment */
428 /* input_area and input_prompt must match in top border and margin for alignment */
429 div.input_area {
429 div.input_area {
430 border: 1px solid #cfcfcf;
430 border: 1px solid #cfcfcf;
431 border-radius: 2px;
431 border-radius: 2px;
432 background: #f7f7f7;
432 background: #f7f7f7;
433 line-height: 1.21429em;
433 line-height: 1.21429em;
434 }
434 }
435 /* This is needed so that empty prompt areas can collapse to zero height when there
435 /* This is needed so that empty prompt areas can collapse to zero height when there
436 is no content in the output_subarea and the prompt. The main purpose of this is
436 is no content in the output_subarea and the prompt. The main purpose of this is
437 to make sure that empty JavaScript output_subareas have no height. */
437 to make sure that empty JavaScript output_subareas have no height. */
438 div.prompt:empty {
438 div.prompt:empty {
439 padding-top: 0;
439 padding-top: 0;
440 padding-bottom: 0;
440 padding-bottom: 0;
441 }
441 }
442 div.unrecognized_cell {
442 div.unrecognized_cell {
443 padding: 5px 5px 5px 0px;
443 padding: 5px 5px 5px 0px;
444 /* Old browsers */
444 /* Old browsers */
445 display: -webkit-box;
445 display: -webkit-box;
446 -webkit-box-orient: horizontal;
446 -webkit-box-orient: horizontal;
447 -webkit-box-align: stretch;
447 -webkit-box-align: stretch;
448 display: -moz-box;
448 display: -moz-box;
449 -moz-box-orient: horizontal;
449 -moz-box-orient: horizontal;
450 -moz-box-align: stretch;
450 -moz-box-align: stretch;
451 display: box;
451 display: box;
452 box-orient: horizontal;
452 box-orient: horizontal;
453 box-align: stretch;
453 box-align: stretch;
454 /* Modern browsers */
454 /* Modern browsers */
455 display: flex;
455 display: flex;
456 flex-direction: row;
456 flex-direction: row;
457 align-items: stretch;
457 align-items: stretch;
458 }
458 }
459 div.unrecognized_cell .inner_cell {
459 div.unrecognized_cell .inner_cell {
460 border-radius: 2px;
460 border-radius: 2px;
461 padding: 5px;
461 padding: 5px;
462 font-weight: bold;
462 font-weight: bold;
463 color: red;
463 color: red;
464 border: 1px solid #cfcfcf;
464 border: 1px solid #cfcfcf;
465 background: #eaeaea;
465 background: #eaeaea;
466 }
466 }
467 div.unrecognized_cell .inner_cell a {
467 div.unrecognized_cell .inner_cell a {
468 color: inherit;
468 color: inherit;
469 text-decoration: none;
469 text-decoration: none;
470 }
470 }
471 div.unrecognized_cell .inner_cell a:hover {
471 div.unrecognized_cell .inner_cell a:hover {
472 color: inherit;
472 color: inherit;
473 text-decoration: none;
473 text-decoration: none;
474 }
474 }
475 @media (max-width: 540px) {
475 @media (max-width: 540px) {
476 div.unrecognized_cell > div.prompt {
476 div.unrecognized_cell > div.prompt {
477 display: none;
477 display: none;
478 }
478 }
479 }
479 }
480 div.code_cell {
480 div.code_cell {
481 /* avoid page breaking on code cells when printing */
481 /* avoid page breaking on code cells when printing */
482 }
482 }
483 @media print {
483 @media print {
484 div.code_cell {
484 div.code_cell {
485 page-break-inside: avoid;
485 page-break-inside: avoid;
486 }
486 }
487 }
487 }
488 /* any special styling for code cells that are currently running goes here */
488 /* any special styling for code cells that are currently running goes here */
489 div.input {
489 div.input {
490 page-break-inside: avoid;
490 page-break-inside: avoid;
491 /* Old browsers */
491 /* Old browsers */
492 display: -webkit-box;
492 display: -webkit-box;
493 -webkit-box-orient: horizontal;
493 -webkit-box-orient: horizontal;
494 -webkit-box-align: stretch;
494 -webkit-box-align: stretch;
495 display: -moz-box;
495 display: -moz-box;
496 -moz-box-orient: horizontal;
496 -moz-box-orient: horizontal;
497 -moz-box-align: stretch;
497 -moz-box-align: stretch;
498 display: box;
498 display: box;
499 box-orient: horizontal;
499 box-orient: horizontal;
500 box-align: stretch;
500 box-align: stretch;
501 /* Modern browsers */
501 /* Modern browsers */
502 display: flex;
502 display: flex;
503 flex-direction: row;
503 flex-direction: row;
504 align-items: stretch;
504 align-items: stretch;
505 }
505 }
506 @media (max-width: 540px) {
506 @media (max-width: 540px) {
507 div.input {
507 div.input {
508 /* Old browsers */
508 /* Old browsers */
509 display: -webkit-box;
509 display: -webkit-box;
510 -webkit-box-orient: vertical;
510 -webkit-box-orient: vertical;
511 -webkit-box-align: stretch;
511 -webkit-box-align: stretch;
512 display: -moz-box;
512 display: -moz-box;
513 -moz-box-orient: vertical;
513 -moz-box-orient: vertical;
514 -moz-box-align: stretch;
514 -moz-box-align: stretch;
515 display: box;
515 display: box;
516 box-orient: vertical;
516 box-orient: vertical;
517 box-align: stretch;
517 box-align: stretch;
518 /* Modern browsers */
518 /* Modern browsers */
519 display: flex;
519 display: flex;
520 flex-direction: column;
520 flex-direction: column;
521 align-items: stretch;
521 align-items: stretch;
522 }
522 }
523 }
523 }
524 /* input_area and input_prompt must match in top border and margin for alignment */
524 /* input_area and input_prompt must match in top border and margin for alignment */
525 div.input_prompt {
525 div.input_prompt {
526 color: navy;
526 color: navy;
527 border-top: 1px solid transparent;
527 border-top: 1px solid transparent;
528 }
528 }
529 div.input_area > div.highlight {
529 div.input_area > div.highlight {
530 margin: 0.4em;
530 margin: 0.4em;
531 border: none;
531 border: none;
532 padding: 0px;
532 padding: 0px;
533 background-color: transparent;
533 background-color: transparent;
534 }
534 }
535 div.input_area > div.highlight > pre {
535 div.input_area > div.highlight > pre {
536 margin: 0px;
536 margin: 0px;
537 border: none;
537 border: none;
538 padding: 0px;
538 padding: 0px;
539 background-color: transparent;
539 background-color: transparent;
540 }
540 }
541 /* The following gets added to the <head> if it is detected that the user has a
541 /* The following gets added to the <head> if it is detected that the user has a
542 * monospace font with inconsistent normal/bold/italic height. See
542 * monospace font with inconsistent normal/bold/italic height. See
543 * notebookmain.js. Such fonts will have keywords vertically offset with
543 * notebookmain.js. Such fonts will have keywords vertically offset with
544 * respect to the rest of the text. The user should select a better font.
544 * respect to the rest of the text. The user should select a better font.
545 * See: https://github.com/ipython/ipython/issues/1503
545 * See: https://github.com/ipython/ipython/issues/1503
546 *
546 *
547 * .CodeMirror span {
547 * .CodeMirror span {
548 * vertical-align: bottom;
548 * vertical-align: bottom;
549 * }
549 * }
550 */
550 */
551 .CodeMirror {
551 .CodeMirror {
552 line-height: 1.21429em;
552 line-height: 1.21429em;
553 /* Changed from 1em to our global default */
553 /* Changed from 1em to our global default */
554 font-size: 14px;
554 font-size: 14px;
555 height: auto;
555 height: auto;
556 /* Changed to auto to autogrow */
556 /* Changed to auto to autogrow */
557 background: none;
557 background: none;
558 /* Changed from white to allow our bg to show through */
558 /* Changed from white to allow our bg to show through */
559 }
559 }
560 .CodeMirror-scroll {
560 .CodeMirror-scroll {
561 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
561 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
562 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
562 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
563 overflow-y: hidden;
563 overflow-y: hidden;
564 overflow-x: auto;
564 overflow-x: auto;
565 }
565 }
566 .CodeMirror-lines {
566 .CodeMirror-lines {
567 /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
567 /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
568 /* we have set a different line-height and want this to scale with that. */
568 /* we have set a different line-height and want this to scale with that. */
569 padding: 0.4em;
569 padding: 0.4em;
570 }
570 }
571 .CodeMirror-linenumber {
571 .CodeMirror-linenumber {
572 padding: 0 8px 0 4px;
572 padding: 0 8px 0 4px;
573 }
573 }
574 .CodeMirror-gutters {
574 .CodeMirror-gutters {
575 border-bottom-left-radius: 2px;
575 border-bottom-left-radius: 2px;
576 border-top-left-radius: 2px;
576 border-top-left-radius: 2px;
577 }
577 }
578 .CodeMirror pre {
578 .CodeMirror pre {
579 /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */
579 /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */
580 /* .CodeMirror-lines */
580 /* .CodeMirror-lines */
581 padding: 0;
581 padding: 0;
582 border: 0;
582 border: 0;
583 border-radius: 0;
583 border-radius: 0;
584 }
584 }
585 /*
585 /*
586
586
587 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
587 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
588 Adapted from GitHub theme
588 Adapted from GitHub theme
589
589
590 */
590 */
591 .highlight-base {
591 .highlight-base {
592 color: #000000;
592 color: #000000;
593 }
593 }
594 .highlight-variable {
594 .highlight-variable {
595 color: #000000;
595 color: #000000;
596 }
596 }
597 .highlight-variable-2 {
597 .highlight-variable-2 {
598 color: #1a1a1a;
598 color: #1a1a1a;
599 }
599 }
600 .highlight-variable-3 {
600 .highlight-variable-3 {
601 color: #333333;
601 color: #333333;
602 }
602 }
603 .highlight-string {
603 .highlight-string {
604 color: #BA2121;
604 color: #BA2121;
605 }
605 }
606 .highlight-comment {
606 .highlight-comment {
607 color: #408080;
607 color: #408080;
608 font-style: italic;
608 font-style: italic;
609 }
609 }
610 .highlight-number {
610 .highlight-number {
611 color: #080;
611 color: #080;
612 }
612 }
613 .highlight-atom {
613 .highlight-atom {
614 color: #88F;
614 color: #88F;
615 }
615 }
616 .highlight-keyword {
616 .highlight-keyword {
617 color: #008000;
617 color: #008000;
618 font-weight: bold;
618 font-weight: bold;
619 }
619 }
620 .highlight-builtin {
620 .highlight-builtin {
621 color: #008000;
621 color: #008000;
622 }
622 }
623 .highlight-error {
623 .highlight-error {
624 color: #f00;
624 color: #f00;
625 }
625 }
626 .highlight-operator {
626 .highlight-operator {
627 color: #AA22FF;
627 color: #AA22FF;
628 font-weight: bold;
628 font-weight: bold;
629 }
629 }
630 .highlight-meta {
630 .highlight-meta {
631 color: #AA22FF;
631 color: #AA22FF;
632 }
632 }
633 /* previously not defined, copying from default codemirror */
633 /* previously not defined, copying from default codemirror */
634 .highlight-def {
634 .highlight-def {
635 color: #00f;
635 color: #00f;
636 }
636 }
637 .highlight-string-2 {
637 .highlight-string-2 {
638 color: #f50;
638 color: #f50;
639 }
639 }
640 .highlight-qualifier {
640 .highlight-qualifier {
641 color: #555;
641 color: #555;
642 }
642 }
643 .highlight-bracket {
643 .highlight-bracket {
644 color: #997;
644 color: #997;
645 }
645 }
646 .highlight-tag {
646 .highlight-tag {
647 color: #170;
647 color: #170;
648 }
648 }
649 .highlight-attribute {
649 .highlight-attribute {
650 color: #00c;
650 color: #00c;
651 }
651 }
652 .highlight-header {
652 .highlight-header {
653 color: blue;
653 color: blue;
654 }
654 }
655 .highlight-quote {
655 .highlight-quote {
656 color: #090;
656 color: #090;
657 }
657 }
658 .highlight-link {
658 .highlight-link {
659 color: #00c;
659 color: #00c;
660 }
660 }
661 /* apply the same style to codemirror */
661 /* apply the same style to codemirror */
662 .cm-s-ipython span.cm-keyword {
662 .cm-s-ipython span.cm-keyword {
663 color: #008000;
663 color: #008000;
664 font-weight: bold;
664 font-weight: bold;
665 }
665 }
666 .cm-s-ipython span.cm-atom {
666 .cm-s-ipython span.cm-atom {
667 color: #88F;
667 color: #88F;
668 }
668 }
669 .cm-s-ipython span.cm-number {
669 .cm-s-ipython span.cm-number {
670 color: #080;
670 color: #080;
671 }
671 }
672 .cm-s-ipython span.cm-def {
672 .cm-s-ipython span.cm-def {
673 color: #00f;
673 color: #00f;
674 }
674 }
675 .cm-s-ipython span.cm-variable {
675 .cm-s-ipython span.cm-variable {
676 color: #000000;
676 color: #000000;
677 }
677 }
678 .cm-s-ipython span.cm-operator {
678 .cm-s-ipython span.cm-operator {
679 color: #AA22FF;
679 color: #AA22FF;
680 font-weight: bold;
680 font-weight: bold;
681 }
681 }
682 .cm-s-ipython span.cm-variable-2 {
682 .cm-s-ipython span.cm-variable-2 {
683 color: #1a1a1a;
683 color: #1a1a1a;
684 }
684 }
685 .cm-s-ipython span.cm-variable-3 {
685 .cm-s-ipython span.cm-variable-3 {
686 color: #333333;
686 color: #333333;
687 }
687 }
688 .cm-s-ipython span.cm-comment {
688 .cm-s-ipython span.cm-comment {
689 color: #408080;
689 color: #408080;
690 font-style: italic;
690 font-style: italic;
691 }
691 }
692 .cm-s-ipython span.cm-string {
692 .cm-s-ipython span.cm-string {
693 color: #BA2121;
693 color: #BA2121;
694 }
694 }
695 .cm-s-ipython span.cm-string-2 {
695 .cm-s-ipython span.cm-string-2 {
696 color: #f50;
696 color: #f50;
697 }
697 }
698 .cm-s-ipython span.cm-meta {
698 .cm-s-ipython span.cm-meta {
699 color: #AA22FF;
699 color: #AA22FF;
700 }
700 }
701 .cm-s-ipython span.cm-qualifier {
701 .cm-s-ipython span.cm-qualifier {
702 color: #555;
702 color: #555;
703 }
703 }
704 .cm-s-ipython span.cm-builtin {
704 .cm-s-ipython span.cm-builtin {
705 color: #008000;
705 color: #008000;
706 }
706 }
707 .cm-s-ipython span.cm-bracket {
707 .cm-s-ipython span.cm-bracket {
708 color: #997;
708 color: #997;
709 }
709 }
710 .cm-s-ipython span.cm-tag {
710 .cm-s-ipython span.cm-tag {
711 color: #170;
711 color: #170;
712 }
712 }
713 .cm-s-ipython span.cm-attribute {
713 .cm-s-ipython span.cm-attribute {
714 color: #00c;
714 color: #00c;
715 }
715 }
716 .cm-s-ipython span.cm-header {
716 .cm-s-ipython span.cm-header {
717 color: blue;
717 color: blue;
718 }
718 }
719 .cm-s-ipython span.cm-quote {
719 .cm-s-ipython span.cm-quote {
720 color: #090;
720 color: #090;
721 }
721 }
722 .cm-s-ipython span.cm-link {
722 .cm-s-ipython span.cm-link {
723 color: #00c;
723 color: #00c;
724 }
724 }
725 .cm-s-ipython span.cm-error {
725 .cm-s-ipython span.cm-error {
726 color: #f00;
726 color: #f00;
727 }
727 }
728 .cm-s-ipython span.cm-tab {
728 .cm-s-ipython span.cm-tab {
729 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
729 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
730 background-position: right;
730 background-position: right;
731 background-repeat: no-repeat;
731 background-repeat: no-repeat;
732 }
732 }
733 div.output_wrapper {
733 div.output_wrapper {
734 /* this position must be relative to enable descendents to be absolute within it */
734 /* this position must be relative to enable descendents to be absolute within it */
735 position: relative;
735 position: relative;
736 /* Old browsers */
736 /* Old browsers */
737 display: -webkit-box;
737 display: -webkit-box;
738 -webkit-box-orient: vertical;
738 -webkit-box-orient: vertical;
739 -webkit-box-align: stretch;
739 -webkit-box-align: stretch;
740 display: -moz-box;
740 display: -moz-box;
741 -moz-box-orient: vertical;
741 -moz-box-orient: vertical;
742 -moz-box-align: stretch;
742 -moz-box-align: stretch;
743 display: box;
743 display: box;
744 box-orient: vertical;
744 box-orient: vertical;
745 box-align: stretch;
745 box-align: stretch;
746 /* Modern browsers */
746 /* Modern browsers */
747 display: flex;
747 display: flex;
748 flex-direction: column;
748 flex-direction: column;
749 align-items: stretch;
749 align-items: stretch;
750 }
750 }
751 /* class for the output area when it should be height-limited */
751 /* class for the output area when it should be height-limited */
752 div.output_scroll {
752 div.output_scroll {
753 /* ideally, this would be max-height, but FF barfs all over that */
753 /* ideally, this would be max-height, but FF barfs all over that */
754 height: 24em;
754 height: 24em;
755 /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
755 /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
756 width: 100%;
756 width: 100%;
757 overflow: auto;
757 overflow: auto;
758 border-radius: 2px;
758 border-radius: 2px;
759 -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
759 -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
760 box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
760 box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
761 display: block;
761 display: block;
762 }
762 }
763 /* output div while it is collapsed */
763 /* output div while it is collapsed */
764 div.output_collapsed {
764 div.output_collapsed {
765 margin: 0px;
765 margin: 0px;
766 padding: 0px;
766 padding: 0px;
767 /* Old browsers */
767 /* Old browsers */
768 display: -webkit-box;
768 display: -webkit-box;
769 -webkit-box-orient: vertical;
769 -webkit-box-orient: vertical;
770 -webkit-box-align: stretch;
770 -webkit-box-align: stretch;
771 display: -moz-box;
771 display: -moz-box;
772 -moz-box-orient: vertical;
772 -moz-box-orient: vertical;
773 -moz-box-align: stretch;
773 -moz-box-align: stretch;
774 display: box;
774 display: box;
775 box-orient: vertical;
775 box-orient: vertical;
776 box-align: stretch;
776 box-align: stretch;
777 /* Modern browsers */
777 /* Modern browsers */
778 display: flex;
778 display: flex;
779 flex-direction: column;
779 flex-direction: column;
780 align-items: stretch;
780 align-items: stretch;
781 }
781 }
782 div.out_prompt_overlay {
782 div.out_prompt_overlay {
783 height: 100%;
783 height: 100%;
784 padding: 0px 0.4em;
784 padding: 0px 0.4em;
785 position: absolute;
785 position: absolute;
786 border-radius: 2px;
786 border-radius: 2px;
787 }
787 }
788 div.out_prompt_overlay:hover {
788 div.out_prompt_overlay:hover {
789 /* use inner shadow to get border that is computed the same on WebKit/FF */
789 /* use inner shadow to get border that is computed the same on WebKit/FF */
790 -webkit-box-shadow: inset 0 0 1px #000000;
790 -webkit-box-shadow: inset 0 0 1px #000000;
791 box-shadow: inset 0 0 1px #000000;
791 box-shadow: inset 0 0 1px #000000;
792 background: rgba(240, 240, 240, 0.5);
792 background: rgba(240, 240, 240, 0.5);
793 }
793 }
794 div.output_prompt {
794 div.output_prompt {
795 color: darkred;
795 color: darkred;
796 }
796 }
797 /* This class is the outer container of all output sections. */
797 /* This class is the outer container of all output sections. */
798 div.output_area {
798 div.output_area {
799 padding: 0px;
799 padding: 0px;
800 page-break-inside: avoid;
800 page-break-inside: avoid;
801 /* Old browsers */
801 /* Old browsers */
802 display: -webkit-box;
802 display: -webkit-box;
803 -webkit-box-orient: horizontal;
803 -webkit-box-orient: horizontal;
804 -webkit-box-align: stretch;
804 -webkit-box-align: stretch;
805 display: -moz-box;
805 display: -moz-box;
806 -moz-box-orient: horizontal;
806 -moz-box-orient: horizontal;
807 -moz-box-align: stretch;
807 -moz-box-align: stretch;
808 display: box;
808 display: box;
809 box-orient: horizontal;
809 box-orient: horizontal;
810 box-align: stretch;
810 box-align: stretch;
811 /* Modern browsers */
811 /* Modern browsers */
812 display: flex;
812 display: flex;
813 flex-direction: row;
813 flex-direction: row;
814 align-items: stretch;
814 align-items: stretch;
815 }
815 }
816 div.output_area .MathJax_Display {
816 div.output_area .MathJax_Display {
817 text-align: left !important;
817 text-align: left !important;
818 }
818 }
819 div.output_area .rendered_html table {
819 div.output_area .rendered_html table {
820 margin-left: 0;
820 margin-left: 0;
821 margin-right: 0;
821 margin-right: 0;
822 }
822 }
823 div.output_area .rendered_html img {
823 div.output_area .rendered_html img {
824 margin-left: 0;
824 margin-left: 0;
825 margin-right: 0;
825 margin-right: 0;
826 }
826 }
827 /* This is needed to protect the pre formating from global settings such
827 /* This is needed to protect the pre formating from global settings such
828 as that of bootstrap */
828 as that of bootstrap */
829 .output {
829 .output {
830 /* Old browsers */
830 /* Old browsers */
831 display: -webkit-box;
831 display: -webkit-box;
832 -webkit-box-orient: vertical;
832 -webkit-box-orient: vertical;
833 -webkit-box-align: stretch;
833 -webkit-box-align: stretch;
834 display: -moz-box;
834 display: -moz-box;
835 -moz-box-orient: vertical;
835 -moz-box-orient: vertical;
836 -moz-box-align: stretch;
836 -moz-box-align: stretch;
837 display: box;
837 display: box;
838 box-orient: vertical;
838 box-orient: vertical;
839 box-align: stretch;
839 box-align: stretch;
840 /* Modern browsers */
840 /* Modern browsers */
841 display: flex;
841 display: flex;
842 flex-direction: column;
842 flex-direction: column;
843 align-items: stretch;
843 align-items: stretch;
844 }
844 }
845 @media (max-width: 540px) {
845 @media (max-width: 540px) {
846 div.output_area {
846 div.output_area {
847 /* Old browsers */
847 /* Old browsers */
848 display: -webkit-box;
848 display: -webkit-box;
849 -webkit-box-orient: vertical;
849 -webkit-box-orient: vertical;
850 -webkit-box-align: stretch;
850 -webkit-box-align: stretch;
851 display: -moz-box;
851 display: -moz-box;
852 -moz-box-orient: vertical;
852 -moz-box-orient: vertical;
853 -moz-box-align: stretch;
853 -moz-box-align: stretch;
854 display: box;
854 display: box;
855 box-orient: vertical;
855 box-orient: vertical;
856 box-align: stretch;
856 box-align: stretch;
857 /* Modern browsers */
857 /* Modern browsers */
858 display: flex;
858 display: flex;
859 flex-direction: column;
859 flex-direction: column;
860 align-items: stretch;
860 align-items: stretch;
861 }
861 }
862 }
862 }
863 div.output_area pre {
863 div.output_area pre {
864 margin: 0;
864 margin: 0;
865 padding: 0;
865 padding: 0;
866 border: 0;
866 border: 0;
867 vertical-align: baseline;
867 vertical-align: baseline;
868 color: black;
868 color: black;
869 background-color: transparent;
869 background-color: transparent;
870 border-radius: 0;
870 border-radius: 0;
871 }
871 }
872 /* This class is for the output subarea inside the output_area and after
872 /* This class is for the output subarea inside the output_area and after
873 the prompt div. */
873 the prompt div. */
874 div.output_subarea {
874 div.output_subarea {
875 padding: 0.4em;
875 padding: 0.4em;
876 /* Old browsers */
876 /* Old browsers */
877 -webkit-box-flex: 1;
877 -webkit-box-flex: 1;
878 -moz-box-flex: 1;
878 -moz-box-flex: 1;
879 box-flex: 1;
879 box-flex: 1;
880 /* Modern browsers */
880 /* Modern browsers */
881 flex: 1;
881 flex: 1;
882 }
882 }
883 /* The rest of the output_* classes are for special styling of the different
883 /* The rest of the output_* classes are for special styling of the different
884 output types */
884 output types */
885 /* all text output has this class: */
885 /* all text output has this class: */
886 div.output_text {
886 div.output_text {
887 text-align: left;
887 text-align: left;
888 color: #000000;
888 color: #000000;
889 /* This has to match that of the the CodeMirror class line-height below */
889 /* This has to match that of the the CodeMirror class line-height below */
890 line-height: 1.21429em;
890 line-height: 1.21429em;
891 }
891 }
892 /* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
892 /* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
893 div.output_stderr {
893 div.output_stderr {
894 background: #fdd;
894 background: #fdd;
895 /* very light red background for stderr */
895 /* very light red background for stderr */
896 }
896 }
897 div.output_latex {
897 div.output_latex {
898 text-align: left;
898 text-align: left;
899 }
899 }
900 /* Empty output_javascript divs should have no height */
900 /* Empty output_javascript divs should have no height */
901 div.output_javascript:empty {
901 div.output_javascript:empty {
902 padding: 0;
902 padding: 0;
903 }
903 }
904 .js-error {
904 .js-error {
905 color: darkred;
905 color: darkred;
906 }
906 }
907 /* raw_input styles */
907 /* raw_input styles */
908 div.raw_input_container {
908 div.raw_input_container {
909 font-family: monospace;
909 font-family: monospace;
910 padding-top: 5px;
910 padding-top: 5px;
911 }
911 }
912 span.raw_input_prompt {
912 span.raw_input_prompt {
913 /* nothing needed here */
913 /* nothing needed here */
914 }
914 }
915 input.raw_input {
915 input.raw_input {
916 font-family: inherit;
916 font-family: inherit;
917 font-size: inherit;
917 font-size: inherit;
918 color: inherit;
918 color: inherit;
919 width: auto;
919 width: auto;
920 /* make sure input baseline aligns with prompt */
920 /* make sure input baseline aligns with prompt */
921 vertical-align: baseline;
921 vertical-align: baseline;
922 /* padding + margin = 0.5em between prompt and cursor */
922 /* padding + margin = 0.5em between prompt and cursor */
923 padding: 0em 0.25em;
923 padding: 0em 0.25em;
924 margin: 0em 0.25em;
924 margin: 0em 0.25em;
925 }
925 }
926 input.raw_input:focus {
926 input.raw_input:focus {
927 box-shadow: none;
927 box-shadow: none;
928 }
928 }
929 p.p-space {
929 p.p-space {
930 margin-bottom: 10px;
930 margin-bottom: 10px;
931 }
931 }
932 div.output_unrecognized {
932 div.output_unrecognized {
933 padding: 5px;
933 padding: 5px;
934 font-weight: bold;
934 font-weight: bold;
935 color: red;
935 color: red;
936 }
936 }
937 div.output_unrecognized a {
937 div.output_unrecognized a {
938 color: inherit;
938 color: inherit;
939 text-decoration: none;
939 text-decoration: none;
940 }
940 }
941 div.output_unrecognized a:hover {
941 div.output_unrecognized a:hover {
942 color: inherit;
942 color: inherit;
943 text-decoration: none;
943 text-decoration: none;
944 }
944 }
945 .rendered_html {
945 .rendered_html {
946 color: #000000;
946 color: #000000;
947 /* any extras will just be numbers: */
947 /* any extras will just be numbers: */
948 }
948 }
949 .rendered_html em {
949 .rendered_html em {
950 font-style: italic;
950 font-style: italic;
951 }
951 }
952 .rendered_html strong {
952 .rendered_html strong {
953 font-weight: bold;
953 font-weight: bold;
954 }
954 }
955 .rendered_html u {
955 .rendered_html u {
956 text-decoration: underline;
956 text-decoration: underline;
957 }
957 }
958 .rendered_html :link {
958 .rendered_html :link {
959 text-decoration: underline;
959 text-decoration: underline;
960 }
960 }
961 .rendered_html :visited {
961 .rendered_html :visited {
962 text-decoration: underline;
962 text-decoration: underline;
963 }
963 }
964 .rendered_html h1 {
964 .rendered_html h1 {
965 font-size: 185.7%;
965 font-size: 185.7%;
966 margin: 1.08em 0 0 0;
966 margin: 1.08em 0 0 0;
967 font-weight: bold;
967 font-weight: bold;
968 line-height: 1.0;
968 line-height: 1.0;
969 }
969 }
970 .rendered_html h2 {
970 .rendered_html h2 {
971 font-size: 157.1%;
971 font-size: 157.1%;
972 margin: 1.27em 0 0 0;
972 margin: 1.27em 0 0 0;
973 font-weight: bold;
973 font-weight: bold;
974 line-height: 1.0;
974 line-height: 1.0;
975 }
975 }
976 .rendered_html h3 {
976 .rendered_html h3 {
977 font-size: 128.6%;
977 font-size: 128.6%;
978 margin: 1.55em 0 0 0;
978 margin: 1.55em 0 0 0;
979 font-weight: bold;
979 font-weight: bold;
980 line-height: 1.0;
980 line-height: 1.0;
981 }
981 }
982 .rendered_html h4 {
982 .rendered_html h4 {
983 font-size: 100%;
983 font-size: 100%;
984 margin: 2em 0 0 0;
984 margin: 2em 0 0 0;
985 font-weight: bold;
985 font-weight: bold;
986 line-height: 1.0;
986 line-height: 1.0;
987 }
987 }
988 .rendered_html h5 {
988 .rendered_html h5 {
989 font-size: 100%;
989 font-size: 100%;
990 margin: 2em 0 0 0;
990 margin: 2em 0 0 0;
991 font-weight: bold;
991 font-weight: bold;
992 line-height: 1.0;
992 line-height: 1.0;
993 font-style: italic;
993 font-style: italic;
994 }
994 }
995 .rendered_html h6 {
995 .rendered_html h6 {
996 font-size: 100%;
996 font-size: 100%;
997 margin: 2em 0 0 0;
997 margin: 2em 0 0 0;
998 font-weight: bold;
998 font-weight: bold;
999 line-height: 1.0;
999 line-height: 1.0;
1000 font-style: italic;
1000 font-style: italic;
1001 }
1001 }
1002 .rendered_html h1:first-child {
1002 .rendered_html h1:first-child {
1003 margin-top: 0.538em;
1003 margin-top: 0.538em;
1004 }
1004 }
1005 .rendered_html h2:first-child {
1005 .rendered_html h2:first-child {
1006 margin-top: 0.636em;
1006 margin-top: 0.636em;
1007 }
1007 }
1008 .rendered_html h3:first-child {
1008 .rendered_html h3:first-child {
1009 margin-top: 0.777em;
1009 margin-top: 0.777em;
1010 }
1010 }
1011 .rendered_html h4:first-child {
1011 .rendered_html h4:first-child {
1012 margin-top: 1em;
1012 margin-top: 1em;
1013 }
1013 }
1014 .rendered_html h5:first-child {
1014 .rendered_html h5:first-child {
1015 margin-top: 1em;
1015 margin-top: 1em;
1016 }
1016 }
1017 .rendered_html h6:first-child {
1017 .rendered_html h6:first-child {
1018 margin-top: 1em;
1018 margin-top: 1em;
1019 }
1019 }
1020 .rendered_html ul {
1020 .rendered_html ul {
1021 list-style: disc;
1021 list-style: disc;
1022 margin: 0em 2em;
1022 margin: 0em 2em;
1023 padding-left: 0px;
1023 padding-left: 0px;
1024 }
1024 }
1025 .rendered_html ul ul {
1025 .rendered_html ul ul {
1026 list-style: square;
1026 list-style: square;
1027 margin: 0em 2em;
1027 margin: 0em 2em;
1028 }
1028 }
1029 .rendered_html ul ul ul {
1029 .rendered_html ul ul ul {
1030 list-style: circle;
1030 list-style: circle;
1031 margin: 0em 2em;
1031 margin: 0em 2em;
1032 }
1032 }
1033 .rendered_html ol {
1033 .rendered_html ol {
1034 list-style: decimal;
1034 list-style: decimal;
1035 margin: 0em 2em;
1035 margin: 0em 2em;
1036 padding-left: 0px;
1036 padding-left: 0px;
1037 }
1037 }
1038 .rendered_html ol ol {
1038 .rendered_html ol ol {
1039 list-style: upper-alpha;
1039 list-style: upper-alpha;
1040 margin: 0em 2em;
1040 margin: 0em 2em;
1041 }
1041 }
1042 .rendered_html ol ol ol {
1042 .rendered_html ol ol ol {
1043 list-style: lower-alpha;
1043 list-style: lower-alpha;
1044 margin: 0em 2em;
1044 margin: 0em 2em;
1045 }
1045 }
1046 .rendered_html ol ol ol ol {
1046 .rendered_html ol ol ol ol {
1047 list-style: lower-roman;
1047 list-style: lower-roman;
1048 margin: 0em 2em;
1048 margin: 0em 2em;
1049 }
1049 }
1050 .rendered_html ol ol ol ol ol {
1050 .rendered_html ol ol ol ol ol {
1051 list-style: decimal;
1051 list-style: decimal;
1052 margin: 0em 2em;
1052 margin: 0em 2em;
1053 }
1053 }
1054 .rendered_html * + ul {
1054 .rendered_html * + ul {
1055 margin-top: 1em;
1055 margin-top: 1em;
1056 }
1056 }
1057 .rendered_html * + ol {
1057 .rendered_html * + ol {
1058 margin-top: 1em;
1058 margin-top: 1em;
1059 }
1059 }
1060 .rendered_html hr {
1060 .rendered_html hr {
1061 color: black;
1061 color: black;
1062 background-color: black;
1062 background-color: black;
1063 }
1063 }
1064 .rendered_html pre {
1064 .rendered_html pre {
1065 margin: 1em 2em;
1065 margin: 1em 2em;
1066 }
1066 }
1067 .rendered_html pre,
1067 .rendered_html pre,
1068 .rendered_html code {
1068 .rendered_html code {
1069 border: 0;
1069 border: 0;
1070 background-color: #ffffff;
1070 background-color: #ffffff;
1071 color: #000000;
1071 color: #000000;
1072 font-size: 100%;
1072 font-size: 100%;
1073 padding: 0px;
1073 padding: 0px;
1074 }
1074 }
1075 .rendered_html blockquote {
1075 .rendered_html blockquote {
1076 margin: 1em 2em;
1076 margin: 1em 2em;
1077 }
1077 }
1078 .rendered_html table {
1078 .rendered_html table {
1079 margin-left: auto;
1079 margin-left: auto;
1080 margin-right: auto;
1080 margin-right: auto;
1081 border: 1px solid black;
1081 border: 1px solid black;
1082 border-collapse: collapse;
1082 border-collapse: collapse;
1083 }
1083 }
1084 .rendered_html tr,
1084 .rendered_html tr,
1085 .rendered_html th,
1085 .rendered_html th,
1086 .rendered_html td {
1086 .rendered_html td {
1087 border: 1px solid black;
1087 border: 1px solid black;
1088 border-collapse: collapse;
1088 border-collapse: collapse;
1089 margin: 1em 2em;
1089 margin: 1em 2em;
1090 }
1090 }
1091 .rendered_html td,
1091 .rendered_html td,
1092 .rendered_html th {
1092 .rendered_html th {
1093 text-align: left;
1093 text-align: left;
1094 vertical-align: middle;
1094 vertical-align: middle;
1095 padding: 4px;
1095 padding: 4px;
1096 }
1096 }
1097 .rendered_html th {
1097 .rendered_html th {
1098 font-weight: bold;
1098 font-weight: bold;
1099 }
1099 }
1100 .rendered_html * + table {
1100 .rendered_html * + table {
1101 margin-top: 1em;
1101 margin-top: 1em;
1102 }
1102 }
1103 .rendered_html p {
1103 .rendered_html p {
1104 text-align: left;
1104 text-align: left;
1105 }
1105 }
1106 .rendered_html * + p {
1106 .rendered_html * + p {
1107 margin-top: 1em;
1107 margin-top: 1em;
1108 }
1108 }
1109 .rendered_html img {
1109 .rendered_html img {
1110 display: block;
1110 display: block;
1111 margin-left: auto;
1111 margin-left: auto;
1112 margin-right: auto;
1112 margin-right: auto;
1113 }
1113 }
1114 .rendered_html * + img {
1114 .rendered_html * + img {
1115 margin-top: 1em;
1115 margin-top: 1em;
1116 }
1116 }
1117 div.text_cell {
1117 div.text_cell {
1118 /* Old browsers */
1118 /* Old browsers */
1119 display: -webkit-box;
1119 display: -webkit-box;
1120 -webkit-box-orient: horizontal;
1120 -webkit-box-orient: horizontal;
1121 -webkit-box-align: stretch;
1121 -webkit-box-align: stretch;
1122 display: -moz-box;
1122 display: -moz-box;
1123 -moz-box-orient: horizontal;
1123 -moz-box-orient: horizontal;
1124 -moz-box-align: stretch;
1124 -moz-box-align: stretch;
1125 display: box;
1125 display: box;
1126 box-orient: horizontal;
1126 box-orient: horizontal;
1127 box-align: stretch;
1127 box-align: stretch;
1128 /* Modern browsers */
1128 /* Modern browsers */
1129 display: flex;
1129 display: flex;
1130 flex-direction: row;
1130 flex-direction: row;
1131 align-items: stretch;
1131 align-items: stretch;
1132 }
1132 }
1133 @media (max-width: 540px) {
1133 @media (max-width: 540px) {
1134 div.text_cell > div.prompt {
1134 div.text_cell > div.prompt {
1135 display: none;
1135 display: none;
1136 }
1136 }
1137 }
1137 }
1138 div.text_cell_render {
1138 div.text_cell_render {
1139 /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
1139 /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
1140 outline: none;
1140 outline: none;
1141 resize: none;
1141 resize: none;
1142 width: inherit;
1142 width: inherit;
1143 border-style: none;
1143 border-style: none;
1144 padding: 0.5em 0.5em 0.5em 0.4em;
1144 padding: 0.5em 0.5em 0.5em 0.4em;
1145 color: #000000;
1145 color: #000000;
1146 box-sizing: border-box;
1146 box-sizing: border-box;
1147 -moz-box-sizing: border-box;
1147 -moz-box-sizing: border-box;
1148 -webkit-box-sizing: border-box;
1148 -webkit-box-sizing: border-box;
1149 }
1149 }
1150 a.anchor-link:link {
1150 a.anchor-link:link {
1151 text-decoration: none;
1151 text-decoration: none;
1152 padding: 0px 20px;
1152 padding: 0px 20px;
1153 visibility: hidden;
1153 visibility: hidden;
1154 }
1154 }
1155 h1:hover .anchor-link,
1155 h1:hover .anchor-link,
1156 h2:hover .anchor-link,
1156 h2:hover .anchor-link,
1157 h3:hover .anchor-link,
1157 h3:hover .anchor-link,
1158 h4:hover .anchor-link,
1158 h4:hover .anchor-link,
1159 h5:hover .anchor-link,
1159 h5:hover .anchor-link,
1160 h6:hover .anchor-link {
1160 h6:hover .anchor-link {
1161 visibility: visible;
1161 visibility: visible;
1162 }
1162 }
1163 .text_cell.rendered .input_area {
1163 .text_cell.rendered .input_area {
1164 display: none;
1164 display: none;
1165 }
1165 }
1166 .text_cell.unrendered .text_cell_render {
1166 .text_cell.unrendered .text_cell_render {
1167 display: none;
1167 display: none;
1168 }
1168 }
1169 .cm-header-1,
1169 .cm-header-1,
1170 .cm-header-2,
1170 .cm-header-2,
1171 .cm-header-3,
1171 .cm-header-3,
1172 .cm-header-4,
1172 .cm-header-4,
1173 .cm-header-5,
1173 .cm-header-5,
1174 .cm-header-6 {
1174 .cm-header-6 {
1175 font-weight: bold;
1175 font-weight: bold;
1176 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1176 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1177 }
1177 }
1178 .cm-header-1 {
1178 .cm-header-1 {
1179 font-size: 185.7%;
1179 font-size: 185.7%;
1180 }
1180 }
1181 .cm-header-2 {
1181 .cm-header-2 {
1182 font-size: 157.1%;
1182 font-size: 157.1%;
1183 }
1183 }
1184 .cm-header-3 {
1184 .cm-header-3 {
1185 font-size: 128.6%;
1185 font-size: 128.6%;
1186 }
1186 }
1187 .cm-header-4 {
1187 .cm-header-4 {
1188 font-size: 110%;
1188 font-size: 110%;
1189 }
1189 }
1190 .cm-header-5 {
1190 .cm-header-5 {
1191 font-size: 100%;
1191 font-size: 100%;
1192 font-style: italic;
1192 font-style: italic;
1193 }
1193 }
1194 .cm-header-6 {
1194 .cm-header-6 {
1195 font-size: 100%;
1195 font-size: 100%;
1196 font-style: italic;
1196 font-style: italic;
1197 }
1197 }
1198 .widget-interact > div,
1198 .widget-interact > div,
1199 .widget-interact > input {
1199 .widget-interact > input {
1200 padding: 2.5px;
1200 padding: 2.5px;
1201 }
1201 }
1202 .widget-area {
1202 .widget-area {
1203 /*
1203 /*
1204 LESS file that styles IPython notebook widgets and the area they sit in.
1204 LESS file that styles IPython notebook widgets and the area they sit in.
1205
1205
1206 The widget area typically looks something like this:
1206 The widget area typically looks something like this:
1207 +------------------------------------------+
1207 +------------------------------------------+
1208 | widget-area |
1208 | widget-area |
1209 | +--------+---------------------------+ |
1209 | +--------+---------------------------+ |
1210 | | prompt | widget-subarea | |
1210 | | prompt | widget-subarea | |
1211 | | | +--------+ +--------+ | |
1211 | | | +--------+ +--------+ | |
1212 | | | | widget | | widget | | |
1212 | | | | widget | | widget | | |
1213 | | | +--------+ +--------+ | |
1213 | | | +--------+ +--------+ | |
1214 | +--------+---------------------------+ |
1214 | +--------+---------------------------+ |
1215 +------------------------------------------+
1215 +------------------------------------------+
1216 */
1216 */
1217 page-break-inside: avoid;
1217 page-break-inside: avoid;
1218 /* Old browsers */
1218 /* Old browsers */
1219 display: -webkit-box;
1219 display: -webkit-box;
1220 -webkit-box-orient: horizontal;
1220 -webkit-box-orient: horizontal;
1221 -webkit-box-align: stretch;
1221 -webkit-box-align: stretch;
1222 display: -moz-box;
1222 display: -moz-box;
1223 -moz-box-orient: horizontal;
1223 -moz-box-orient: horizontal;
1224 -moz-box-align: stretch;
1224 -moz-box-align: stretch;
1225 display: box;
1225 display: box;
1226 box-orient: horizontal;
1226 box-orient: horizontal;
1227 box-align: stretch;
1227 box-align: stretch;
1228 /* Modern browsers */
1228 /* Modern browsers */
1229 display: flex;
1229 display: flex;
1230 flex-direction: row;
1230 flex-direction: row;
1231 align-items: stretch;
1231 align-items: stretch;
1232 }
1232 }
1233 .widget-area .widget-subarea {
1233 .widget-area .widget-subarea {
1234 padding: 0.44em 0.4em 0.4em 1px;
1234 padding: 0.44em 0.4em 0.4em 1px;
1235 margin-left: 6px;
1235 margin-left: 6px;
1236 box-sizing: border-box;
1236 box-sizing: border-box;
1237 -moz-box-sizing: border-box;
1237 -moz-box-sizing: border-box;
1238 -webkit-box-sizing: border-box;
1238 -webkit-box-sizing: border-box;
1239 /* Old browsers */
1239 /* Old browsers */
1240 display: -webkit-box;
1240 display: -webkit-box;
1241 -webkit-box-orient: vertical;
1241 -webkit-box-orient: vertical;
1242 -webkit-box-align: stretch;
1242 -webkit-box-align: stretch;
1243 display: -moz-box;
1243 display: -moz-box;
1244 -moz-box-orient: vertical;
1244 -moz-box-orient: vertical;
1245 -moz-box-align: stretch;
1245 -moz-box-align: stretch;
1246 display: box;
1246 display: box;
1247 box-orient: vertical;
1247 box-orient: vertical;
1248 box-align: stretch;
1248 box-align: stretch;
1249 /* Modern browsers */
1249 /* Modern browsers */
1250 display: flex;
1250 display: flex;
1251 flex-direction: column;
1251 flex-direction: column;
1252 align-items: stretch;
1252 align-items: stretch;
1253 /* Old browsers */
1253 /* Old browsers */
1254 -webkit-box-flex: 2;
1254 -webkit-box-flex: 2;
1255 -moz-box-flex: 2;
1255 -moz-box-flex: 2;
1256 box-flex: 2;
1256 box-flex: 2;
1257 /* Modern browsers */
1257 /* Modern browsers */
1258 flex: 2;
1258 flex: 2;
1259 /* Old browsers */
1259 /* Old browsers */
1260 -webkit-box-align: start;
1260 -webkit-box-align: start;
1261 -moz-box-align: start;
1261 -moz-box-align: start;
1262 box-align: start;
1262 box-align: start;
1263 /* Modern browsers */
1263 /* Modern browsers */
1264 align-items: flex-start;
1264 align-items: flex-start;
1265 }
1265 }
1266 .widget-area.connection-problems .prompt:after {
1266 .widget-area.connection-problems .prompt:after {
1267 content: "\f127";
1267 content: "\f127";
1268 font-family: 'FontAwesome';
1268 font-family: 'FontAwesome';
1269 color: #d9534f;
1269 color: #d9534f;
1270 font-size: 14px;
1270 font-size: 14px;
1271 top: 3px;
1271 top: 3px;
1272 padding: 3px;
1272 padding: 3px;
1273 }
1273 }
1274 /* THE CLASSES BELOW CAN APPEAR ANYWHERE IN THE DOM (POSSIBLEY OUTSIDE OF
1274 /* THE CLASSES BELOW CAN APPEAR ANYWHERE IN THE DOM (POSSIBLEY OUTSIDE OF
1275 THE WIDGET AREA). */
1275 THE WIDGET AREA). */
1276 .slide-track {
1276 .slide-track {
1277 /* Slider Track */
1277 /* Slider Track */
1278 border: 1px solid #CCCCCC;
1278 border: 1px solid #CCCCCC;
1279 background: #FFFFFF;
1279 background: #FFFFFF;
1280 border-radius: 2px;
1280 border-radius: 2px;
1281 /* Round the corners of the slide track */
1281 /* Round the corners of the slide track */
1282 }
1282 }
1283 .widget-hslider {
1283 .widget-hslider {
1284 /* Horizontal jQuery Slider
1284 /* Horizontal jQuery Slider
1285
1285
1286 Both the horizontal and vertical versions of the slider are characterized
1286 Both the horizontal and vertical versions of the slider are characterized
1287 by a styled div that contains an invisible jQuery slide div which
1287 by a styled div that contains an invisible jQuery slide div which
1288 contains a visible slider handle div. This is requred so we can control
1288 contains a visible slider handle div. This is requred so we can control
1289 how the slider is drawn and 'fix' the issue where the slide handle
1289 how the slider is drawn and 'fix' the issue where the slide handle
1290 doesn't stop at the end of the slide.
1290 doesn't stop at the end of the slide.
1291
1291
1292 Both horizontal and vertical sliders have this div nesting:
1292 Both horizontal and vertical sliders have this div nesting:
1293 +------------------------------------------+
1293 +------------------------------------------+
1294 | widget-(h/v)slider |
1294 | widget-(h/v)slider |
1295 | +--------+---------------------------+ |
1295 | +--------+---------------------------+ |
1296 | | ui-slider | |
1296 | | ui-slider | |
1297 | | +------------------+ | |
1297 | | +------------------+ | |
1298 | | | ui-slider-handle | | |
1298 | | | ui-slider-handle | | |
1299 | | +------------------+ | |
1299 | | +------------------+ | |
1300 | +--------+---------------------------+ |
1300 | +--------+---------------------------+ |
1301 +------------------------------------------+
1301 +------------------------------------------+
1302 */
1302 */
1303 /* Fix the padding of the slide track so the ui-slider is sized
1303 /* Fix the padding of the slide track so the ui-slider is sized
1304 correctly. */
1304 correctly. */
1305 padding-left: 8px;
1305 padding-left: 8px;
1306 padding-right: 2px;
1306 padding-right: 2px;
1307 overflow: visible;
1307 overflow: visible;
1308 /* Default size of the slider */
1308 /* Default size of the slider */
1309 width: 350px;
1309 width: 350px;
1310 height: 5px;
1310 height: 5px;
1311 max-height: 5px;
1311 max-height: 5px;
1312 margin-top: 13px;
1312 margin-top: 13px;
1313 margin-bottom: 10px;
1313 margin-bottom: 10px;
1314 /* Style the slider track */
1314 /* Style the slider track */
1315 /* Slider Track */
1315 /* Slider Track */
1316 border: 1px solid #CCCCCC;
1316 border: 1px solid #CCCCCC;
1317 background: #FFFFFF;
1317 background: #FFFFFF;
1318 border-radius: 2px;
1318 border-radius: 2px;
1319 /* Round the corners of the slide track */
1319 /* Round the corners of the slide track */
1320 /* Make the div a flex box (makes FF behave correctly). */
1320 /* Make the div a flex box (makes FF behave correctly). */
1321 /* Old browsers */
1321 /* Old browsers */
1322 display: -webkit-box;
1322 display: -webkit-box;
1323 -webkit-box-orient: horizontal;
1323 -webkit-box-orient: horizontal;
1324 -webkit-box-align: stretch;
1324 -webkit-box-align: stretch;
1325 display: -moz-box;
1325 display: -moz-box;
1326 -moz-box-orient: horizontal;
1326 -moz-box-orient: horizontal;
1327 -moz-box-align: stretch;
1327 -moz-box-align: stretch;
1328 display: box;
1328 display: box;
1329 box-orient: horizontal;
1329 box-orient: horizontal;
1330 box-align: stretch;
1330 box-align: stretch;
1331 /* Modern browsers */
1331 /* Modern browsers */
1332 display: flex;
1332 display: flex;
1333 flex-direction: row;
1333 flex-direction: row;
1334 align-items: stretch;
1334 align-items: stretch;
1335 }
1335 }
1336 .widget-hslider .ui-slider {
1336 .widget-hslider .ui-slider {
1337 /* Inner, invisible slide div */
1337 /* Inner, invisible slide div */
1338 border: 0px;
1338 border: 0px;
1339 background: none;
1339 background: none;
1340 /* Old browsers */
1340 /* Old browsers */
1341 display: -webkit-box;
1341 display: -webkit-box;
1342 -webkit-box-orient: horizontal;
1342 -webkit-box-orient: horizontal;
1343 -webkit-box-align: stretch;
1343 -webkit-box-align: stretch;
1344 display: -moz-box;
1344 display: -moz-box;
1345 -moz-box-orient: horizontal;
1345 -moz-box-orient: horizontal;
1346 -moz-box-align: stretch;
1346 -moz-box-align: stretch;
1347 display: box;
1347 display: box;
1348 box-orient: horizontal;
1348 box-orient: horizontal;
1349 box-align: stretch;
1349 box-align: stretch;
1350 /* Modern browsers */
1350 /* Modern browsers */
1351 display: flex;
1351 display: flex;
1352 flex-direction: row;
1352 flex-direction: row;
1353 align-items: stretch;
1353 align-items: stretch;
1354 /* Old browsers */
1354 /* Old browsers */
1355 -webkit-box-flex: 1;
1355 -webkit-box-flex: 1;
1356 -moz-box-flex: 1;
1356 -moz-box-flex: 1;
1357 box-flex: 1;
1357 box-flex: 1;
1358 /* Modern browsers */
1358 /* Modern browsers */
1359 flex: 1;
1359 flex: 1;
1360 }
1360 }
1361 .widget-hslider .ui-slider .ui-slider-handle {
1361 .widget-hslider .ui-slider .ui-slider-handle {
1362 width: 12px;
1362 width: 12px;
1363 height: 28px;
1363 height: 28px;
1364 margin-top: -8px;
1364 margin-top: -8px;
1365 border-radius: 2px;
1365 border-radius: 2px;
1366 }
1366 }
1367 .widget-hslider .ui-slider .ui-slider-range {
1367 .widget-hslider .ui-slider .ui-slider-range {
1368 height: 12px;
1368 height: 12px;
1369 margin-top: -4px;
1369 margin-top: -4px;
1370 background: #eeeeee;
1370 background: #eeeeee;
1371 }
1371 }
1372 .widget-vslider {
1372 .widget-vslider {
1373 /* Vertical jQuery Slider */
1373 /* Vertical jQuery Slider */
1374 /* Fix the padding of the slide track so the ui-slider is sized
1374 /* Fix the padding of the slide track so the ui-slider is sized
1375 correctly. */
1375 correctly. */
1376 padding-bottom: 5px;
1376 padding-bottom: 5px;
1377 overflow: visible;
1377 overflow: visible;
1378 /* Default size of the slider */
1378 /* Default size of the slider */
1379 width: 5px;
1379 width: 5px;
1380 max-width: 5px;
1380 max-width: 5px;
1381 height: 250px;
1381 height: 250px;
1382 margin-left: 12px;
1382 margin-left: 12px;
1383 /* Style the slider track */
1383 /* Style the slider track */
1384 /* Slider Track */
1384 /* Slider Track */
1385 border: 1px solid #CCCCCC;
1385 border: 1px solid #CCCCCC;
1386 background: #FFFFFF;
1386 background: #FFFFFF;
1387 border-radius: 2px;
1387 border-radius: 2px;
1388 /* Round the corners of the slide track */
1388 /* Round the corners of the slide track */
1389 /* Make the div a flex box (makes FF behave correctly). */
1389 /* Make the div a flex box (makes FF behave correctly). */
1390 /* Old browsers */
1390 /* Old browsers */
1391 display: -webkit-box;
1391 display: -webkit-box;
1392 -webkit-box-orient: vertical;
1392 -webkit-box-orient: vertical;
1393 -webkit-box-align: stretch;
1393 -webkit-box-align: stretch;
1394 display: -moz-box;
1394 display: -moz-box;
1395 -moz-box-orient: vertical;
1395 -moz-box-orient: vertical;
1396 -moz-box-align: stretch;
1396 -moz-box-align: stretch;
1397 display: box;
1397 display: box;
1398 box-orient: vertical;
1398 box-orient: vertical;
1399 box-align: stretch;
1399 box-align: stretch;
1400 /* Modern browsers */
1400 /* Modern browsers */
1401 display: flex;
1401 display: flex;
1402 flex-direction: column;
1402 flex-direction: column;
1403 align-items: stretch;
1403 align-items: stretch;
1404 }
1404 }
1405 .widget-vslider .ui-slider {
1405 .widget-vslider .ui-slider {
1406 /* Inner, invisible slide div */
1406 /* Inner, invisible slide div */
1407 border: 0px;
1407 border: 0px;
1408 background: none;
1408 background: none;
1409 margin-left: -4px;
1409 margin-left: -4px;
1410 margin-top: 5px;
1410 margin-top: 5px;
1411 /* Old browsers */
1411 /* Old browsers */
1412 display: -webkit-box;
1412 display: -webkit-box;
1413 -webkit-box-orient: vertical;
1413 -webkit-box-orient: vertical;
1414 -webkit-box-align: stretch;
1414 -webkit-box-align: stretch;
1415 display: -moz-box;
1415 display: -moz-box;
1416 -moz-box-orient: vertical;
1416 -moz-box-orient: vertical;
1417 -moz-box-align: stretch;
1417 -moz-box-align: stretch;
1418 display: box;
1418 display: box;
1419 box-orient: vertical;
1419 box-orient: vertical;
1420 box-align: stretch;
1420 box-align: stretch;
1421 /* Modern browsers */
1421 /* Modern browsers */
1422 display: flex;
1422 display: flex;
1423 flex-direction: column;
1423 flex-direction: column;
1424 align-items: stretch;
1424 align-items: stretch;
1425 /* Old browsers */
1425 /* Old browsers */
1426 -webkit-box-flex: 1;
1426 -webkit-box-flex: 1;
1427 -moz-box-flex: 1;
1427 -moz-box-flex: 1;
1428 box-flex: 1;
1428 box-flex: 1;
1429 /* Modern browsers */
1429 /* Modern browsers */
1430 flex: 1;
1430 flex: 1;
1431 }
1431 }
1432 .widget-vslider .ui-slider .ui-slider-handle {
1432 .widget-vslider .ui-slider .ui-slider-handle {
1433 width: 28px;
1433 width: 28px;
1434 height: 12px;
1434 height: 12px;
1435 margin-left: -9px;
1435 margin-left: -9px;
1436 border-radius: 2px;
1436 border-radius: 2px;
1437 }
1437 }
1438 .widget-vslider .ui-slider .ui-slider-range {
1438 .widget-vslider .ui-slider .ui-slider-range {
1439 width: 12px;
1439 width: 12px;
1440 margin-left: -1px;
1440 margin-left: -1px;
1441 background: #eeeeee;
1441 background: #eeeeee;
1442 }
1442 }
1443 .widget-text {
1443 .widget-text {
1444 /* String Textbox - used for TextBoxView and TextAreaView */
1444 /* String Textbox - used for TextBoxView and TextAreaView */
1445 width: 350px;
1445 width: 350px;
1446 margin: 0px;
1446 margin: 0px;
1447 }
1447 }
1448 .widget-listbox {
1448 .widget-listbox {
1449 /* Listbox */
1449 /* Listbox */
1450 width: 350px;
1450 width: 350px;
1451 margin-bottom: 0px;
1451 margin-bottom: 0px;
1452 }
1452 }
1453 .widget-numeric-text {
1453 .widget-numeric-text {
1454 /* Single Line Textbox - used for IntTextView and FloatTextView */
1454 /* Single Line Textbox - used for IntTextView and FloatTextView */
1455 width: 150px;
1455 width: 150px;
1456 margin: 0px;
1456 margin: 0px;
1457 }
1457 }
1458 .widget-progress {
1458 .widget-progress {
1459 /* Progress Bar */
1459 /* Progress Bar */
1460 margin-top: 6px;
1460 margin-top: 6px;
1461 min-width: 350px;
1461 min-width: 350px;
1462 }
1462 }
1463 .widget-progress .progress-bar {
1463 .widget-progress .progress-bar {
1464 /* Disable progress bar animation */
1464 /* Disable progress bar animation */
1465 -webkit-transition: none;
1465 -webkit-transition: none;
1466 -moz-transition: none;
1466 -moz-transition: none;
1467 -ms-transition: none;
1467 -ms-transition: none;
1468 -o-transition: none;
1468 -o-transition: none;
1469 transition: none;
1469 transition: none;
1470 }
1470 }
1471 .widget-combo-btn {
1471 .widget-combo-btn {
1472 /* ComboBox Main Button */
1472 /* ComboBox Main Button */
1473 /* Subtract 25px to account for the drop arrow button */
1473 /* Subtract 25px to account for the drop arrow button */
1474 min-width: 125px;
1474 min-width: 125px;
1475 }
1475 }
1476 .widget_item .dropdown-menu li a {
1476 .widget_item .dropdown-menu li a {
1477 color: inherit;
1477 color: inherit;
1478 }
1478 }
1479 .widget-hbox {
1479 .widget-hbox {
1480 /* Horizontal widgets */
1480 /* Horizontal widgets */
1481 /* Old browsers */
1481 /* Old browsers */
1482 display: -webkit-box;
1482 display: -webkit-box;
1483 -webkit-box-orient: horizontal;
1483 -webkit-box-orient: horizontal;
1484 -webkit-box-align: stretch;
1484 -webkit-box-align: stretch;
1485 display: -moz-box;
1485 display: -moz-box;
1486 -moz-box-orient: horizontal;
1486 -moz-box-orient: horizontal;
1487 -moz-box-align: stretch;
1487 -moz-box-align: stretch;
1488 display: box;
1488 display: box;
1489 box-orient: horizontal;
1489 box-orient: horizontal;
1490 box-align: stretch;
1490 box-align: stretch;
1491 /* Modern browsers */
1491 /* Modern browsers */
1492 display: flex;
1492 display: flex;
1493 flex-direction: row;
1493 flex-direction: row;
1494 align-items: stretch;
1494 align-items: stretch;
1495 }
1495 }
1496 .widget-hbox input[type="checkbox"] {
1496 .widget-hbox input[type="checkbox"] {
1497 margin-top: 9px;
1497 margin-top: 9px;
1498 margin-bottom: 10px;
1498 margin-bottom: 10px;
1499 }
1499 }
1500 .widget-hbox .widget-label {
1500 .widget-hbox .widget-label {
1501 /* Horizontal Label */
1501 /* Horizontal Label */
1502 min-width: 10ex;
1502 min-width: 10ex;
1503 padding-right: 8px;
1503 padding-right: 8px;
1504 padding-top: 5px;
1504 padding-top: 5px;
1505 text-align: right;
1505 text-align: right;
1506 vertical-align: text-top;
1506 vertical-align: text-top;
1507 }
1507 }
1508 .widget-hbox .widget-readout {
1508 .widget-hbox .widget-readout {
1509 padding-left: 8px;
1509 padding-left: 8px;
1510 padding-top: 5px;
1510 padding-top: 5px;
1511 text-align: left;
1511 text-align: left;
1512 vertical-align: text-top;
1512 vertical-align: text-top;
1513 }
1513 }
1514 .widget-vbox {
1514 .widget-vbox {
1515 /* Vertical widgets */
1515 /* Vertical widgets */
1516 /* Old browsers */
1516 /* Old browsers */
1517 display: -webkit-box;
1517 display: -webkit-box;
1518 -webkit-box-orient: vertical;
1518 -webkit-box-orient: vertical;
1519 -webkit-box-align: stretch;
1519 -webkit-box-align: stretch;
1520 display: -moz-box;
1520 display: -moz-box;
1521 -moz-box-orient: vertical;
1521 -moz-box-orient: vertical;
1522 -moz-box-align: stretch;
1522 -moz-box-align: stretch;
1523 display: box;
1523 display: box;
1524 box-orient: vertical;
1524 box-orient: vertical;
1525 box-align: stretch;
1525 box-align: stretch;
1526 /* Modern browsers */
1526 /* Modern browsers */
1527 display: flex;
1527 display: flex;
1528 flex-direction: column;
1528 flex-direction: column;
1529 align-items: stretch;
1529 align-items: stretch;
1530 }
1530 }
1531 .widget-vbox .widget-label {
1531 .widget-vbox .widget-label {
1532 /* Vertical Label */
1532 /* Vertical Label */
1533 padding-bottom: 5px;
1533 padding-bottom: 5px;
1534 text-align: center;
1534 text-align: center;
1535 vertical-align: text-bottom;
1535 vertical-align: text-bottom;
1536 }
1536 }
1537 .widget-vbox .widget-readout {
1537 .widget-vbox .widget-readout {
1538 /* Vertical Label */
1538 /* Vertical Label */
1539 padding-top: 5px;
1539 padding-top: 5px;
1540 text-align: center;
1540 text-align: center;
1541 vertical-align: text-top;
1541 vertical-align: text-top;
1542 }
1542 }
1543 .widget-box {
1543 .widget-box {
1544 /* Box */
1544 /* Box */
1545 box-sizing: border-box;
1545 box-sizing: border-box;
1546 -moz-box-sizing: border-box;
1546 -moz-box-sizing: border-box;
1547 -webkit-box-sizing: border-box;
1547 -webkit-box-sizing: border-box;
1548 /* Old browsers */
1548 /* Old browsers */
1549 -webkit-box-align: start;
1549 -webkit-box-align: start;
1550 -moz-box-align: start;
1550 -moz-box-align: start;
1551 box-align: start;
1551 box-align: start;
1552 /* Modern browsers */
1552 /* Modern browsers */
1553 align-items: flex-start;
1553 align-items: flex-start;
1554 }
1554 }
1555 .widget-radio-box {
1555 .widget-radio-box {
1556 /* Contains RadioButtonsWidget */
1556 /* Contains RadioButtonsWidget */
1557 /* Old browsers */
1557 /* Old browsers */
1558 display: -webkit-box;
1558 display: -webkit-box;
1559 -webkit-box-orient: vertical;
1559 -webkit-box-orient: vertical;
1560 -webkit-box-align: stretch;
1560 -webkit-box-align: stretch;
1561 display: -moz-box;
1561 display: -moz-box;
1562 -moz-box-orient: vertical;
1562 -moz-box-orient: vertical;
1563 -moz-box-align: stretch;
1563 -moz-box-align: stretch;
1564 display: box;
1564 display: box;
1565 box-orient: vertical;
1565 box-orient: vertical;
1566 box-align: stretch;
1566 box-align: stretch;
1567 /* Modern browsers */
1567 /* Modern browsers */
1568 display: flex;
1568 display: flex;
1569 flex-direction: column;
1569 flex-direction: column;
1570 align-items: stretch;
1570 align-items: stretch;
1571 box-sizing: border-box;
1571 box-sizing: border-box;
1572 -moz-box-sizing: border-box;
1572 -moz-box-sizing: border-box;
1573 -webkit-box-sizing: border-box;
1573 -webkit-box-sizing: border-box;
1574 padding-top: 4px;
1574 padding-top: 4px;
1575 }
1575 }
1576 .widget-radio-box label {
1576 .widget-radio-box label {
1577 margin-top: 0px;
1577 margin-top: 0px;
1578 }
1579 .widget-radio {
1580 margin-left: 20px;
1578 margin-left: 20px;
1581 }
1579 }
1582 /*# sourceMappingURL=ipython.min.css.map */ No newline at end of file
1580 /*# sourceMappingURL=ipython.min.css.map */
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now