##// 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
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,3388 +1,3389 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Main IPython class."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 from __future__ import absolute_import, print_function
14 14
15 15 import __future__
16 16 import abc
17 17 import ast
18 18 import atexit
19 19 import functools
20 20 import os
21 21 import re
22 22 import runpy
23 23 import sys
24 24 import tempfile
25 25 import traceback
26 26 import types
27 27 import subprocess
28 28 from io import open as io_open
29 29
30 30 from IPython.config.configurable import SingletonConfigurable
31 31 from IPython.core import debugger, oinspect
32 32 from IPython.core import magic
33 33 from IPython.core import page
34 34 from IPython.core import prefilter
35 35 from IPython.core import shadowns
36 36 from IPython.core import ultratb
37 from IPython.core.alias import AliasManager, AliasError
37 from IPython.core.alias import Alias, AliasManager
38 38 from IPython.core.autocall import ExitAutocall
39 39 from IPython.core.builtin_trap import BuiltinTrap
40 40 from IPython.core.events import EventManager, available_events
41 41 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
42 42 from IPython.core.display_trap import DisplayTrap
43 43 from IPython.core.displayhook import DisplayHook
44 44 from IPython.core.displaypub import DisplayPublisher
45 45 from IPython.core.error import InputRejected, UsageError
46 46 from IPython.core.extensions import ExtensionManager
47 47 from IPython.core.formatters import DisplayFormatter
48 48 from IPython.core.history import HistoryManager
49 49 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
50 50 from IPython.core.logger import Logger
51 51 from IPython.core.macro import Macro
52 52 from IPython.core.payload import PayloadManager
53 53 from IPython.core.prefilter import PrefilterManager
54 54 from IPython.core.profiledir import ProfileDir
55 55 from IPython.core.prompts import PromptManager
56 56 from IPython.core.usage import default_banner
57 57 from IPython.testing.skipdoctest import skip_doctest
58 58 from IPython.utils import PyColorize
59 59 from IPython.utils import io
60 60 from IPython.utils import py3compat
61 61 from IPython.utils import openpy
62 62 from IPython.utils.decorators import undoc
63 63 from IPython.utils.io import ask_yes_no
64 64 from IPython.utils.ipstruct import Struct
65 65 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename, ensure_dir_exists
66 66 from IPython.utils.pickleshare import PickleShareDB
67 67 from IPython.utils.process import system, getoutput
68 68 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
69 69 with_metaclass, iteritems)
70 70 from IPython.utils.strdispatch import StrDispatch
71 71 from IPython.utils.syspathcontext import prepended_to_syspath
72 72 from IPython.utils.text import (format_screen, LSString, SList,
73 73 DollarFormatter)
74 74 from IPython.utils.traitlets import (Integer, Bool, CBool, CaselessStrEnum, Enum,
75 75 List, Unicode, Instance, Type)
76 76 from IPython.utils.warn import warn, error
77 77 import IPython.core.hooks
78 78
79 79 #-----------------------------------------------------------------------------
80 80 # Globals
81 81 #-----------------------------------------------------------------------------
82 82
83 83 # compiled regexps for autoindent management
84 84 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
85 85
86 86 #-----------------------------------------------------------------------------
87 87 # Utilities
88 88 #-----------------------------------------------------------------------------
89 89
90 90 @undoc
91 91 def softspace(file, newvalue):
92 92 """Copied from code.py, to remove the dependency"""
93 93
94 94 oldvalue = 0
95 95 try:
96 96 oldvalue = file.softspace
97 97 except AttributeError:
98 98 pass
99 99 try:
100 100 file.softspace = newvalue
101 101 except (AttributeError, TypeError):
102 102 # "attribute-less object" or "read-only attributes"
103 103 pass
104 104 return oldvalue
105 105
106 106 @undoc
107 107 def no_op(*a, **kw): pass
108 108
109 109 @undoc
110 110 class NoOpContext(object):
111 111 def __enter__(self): pass
112 112 def __exit__(self, type, value, traceback): pass
113 113 no_op_context = NoOpContext()
114 114
115 115 class SpaceInInput(Exception): pass
116 116
117 117 @undoc
118 118 class Bunch: pass
119 119
120 120
121 121 def get_default_colors():
122 122 if sys.platform=='darwin':
123 123 return "LightBG"
124 124 elif os.name=='nt':
125 125 return 'Linux'
126 126 else:
127 127 return 'Linux'
128 128
129 129
130 130 class SeparateUnicode(Unicode):
131 131 r"""A Unicode subclass to validate separate_in, separate_out, etc.
132 132
133 133 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
134 134 """
135 135
136 136 def validate(self, obj, value):
137 137 if value == '0': value = ''
138 138 value = value.replace('\\n','\n')
139 139 return super(SeparateUnicode, self).validate(obj, value)
140 140
141 141
142 142 class ReadlineNoRecord(object):
143 143 """Context manager to execute some code, then reload readline history
144 144 so that interactive input to the code doesn't appear when pressing up."""
145 145 def __init__(self, shell):
146 146 self.shell = shell
147 147 self._nested_level = 0
148 148
149 149 def __enter__(self):
150 150 if self._nested_level == 0:
151 151 try:
152 152 self.orig_length = self.current_length()
153 153 self.readline_tail = self.get_readline_tail()
154 154 except (AttributeError, IndexError): # Can fail with pyreadline
155 155 self.orig_length, self.readline_tail = 999999, []
156 156 self._nested_level += 1
157 157
158 158 def __exit__(self, type, value, traceback):
159 159 self._nested_level -= 1
160 160 if self._nested_level == 0:
161 161 # Try clipping the end if it's got longer
162 162 try:
163 163 e = self.current_length() - self.orig_length
164 164 if e > 0:
165 165 for _ in range(e):
166 166 self.shell.readline.remove_history_item(self.orig_length)
167 167
168 168 # If it still doesn't match, just reload readline history.
169 169 if self.current_length() != self.orig_length \
170 170 or self.get_readline_tail() != self.readline_tail:
171 171 self.shell.refill_readline_hist()
172 172 except (AttributeError, IndexError):
173 173 pass
174 174 # Returning False will cause exceptions to propagate
175 175 return False
176 176
177 177 def current_length(self):
178 178 return self.shell.readline.get_current_history_length()
179 179
180 180 def get_readline_tail(self, n=10):
181 181 """Get the last n items in readline history."""
182 182 end = self.shell.readline.get_current_history_length() + 1
183 183 start = max(end-n, 1)
184 184 ghi = self.shell.readline.get_history_item
185 185 return [ghi(x) for x in range(start, end)]
186 186
187 187
188 188 @undoc
189 189 class DummyMod(object):
190 190 """A dummy module used for IPython's interactive module when
191 191 a namespace must be assigned to the module's __dict__."""
192 192 pass
193 193
194 194
195 195 class ExecutionResult(object):
196 196 """The result of a call to :meth:`InteractiveShell.run_cell`
197 197
198 198 Stores information about what took place.
199 199 """
200 200 execution_count = None
201 201 error_before_exec = None
202 202 error_in_exec = None
203 203 result = None
204 204
205 205 @property
206 206 def success(self):
207 207 return (self.error_before_exec is None) and (self.error_in_exec is None)
208 208
209 209
210 210 class InteractiveShell(SingletonConfigurable):
211 211 """An enhanced, interactive shell for Python."""
212 212
213 213 _instance = None
214 214
215 215 ast_transformers = List([], config=True, help=
216 216 """
217 217 A list of ast.NodeTransformer subclass instances, which will be applied
218 218 to user input before code is run.
219 219 """
220 220 )
221 221
222 222 autocall = Enum((0,1,2), default_value=0, config=True, help=
223 223 """
224 224 Make IPython automatically call any callable object even if you didn't
225 225 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
226 226 automatically. The value can be '0' to disable the feature, '1' for
227 227 'smart' autocall, where it is not applied if there are no more
228 228 arguments on the line, and '2' for 'full' autocall, where all callable
229 229 objects are automatically called (even if no arguments are present).
230 230 """
231 231 )
232 232 # TODO: remove all autoindent logic and put into frontends.
233 233 # We can't do this yet because even runlines uses the autoindent.
234 234 autoindent = CBool(True, config=True, help=
235 235 """
236 236 Autoindent IPython code entered interactively.
237 237 """
238 238 )
239 239 automagic = CBool(True, config=True, help=
240 240 """
241 241 Enable magic commands to be called without the leading %.
242 242 """
243 243 )
244 244
245 245 banner1 = Unicode(default_banner, config=True,
246 246 help="""The part of the banner to be printed before the profile"""
247 247 )
248 248 banner2 = Unicode('', config=True,
249 249 help="""The part of the banner to be printed after the profile"""
250 250 )
251 251
252 252 cache_size = Integer(1000, config=True, help=
253 253 """
254 254 Set the size of the output cache. The default is 1000, you can
255 255 change it permanently in your config file. Setting it to 0 completely
256 256 disables the caching system, and the minimum value accepted is 20 (if
257 257 you provide a value less than 20, it is reset to 0 and a warning is
258 258 issued). This limit is defined because otherwise you'll spend more
259 259 time re-flushing a too small cache than working
260 260 """
261 261 )
262 262 color_info = CBool(True, config=True, help=
263 263 """
264 264 Use colors for displaying information about objects. Because this
265 265 information is passed through a pager (like 'less'), and some pagers
266 266 get confused with color codes, this capability can be turned off.
267 267 """
268 268 )
269 269 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
270 270 default_value=get_default_colors(), config=True,
271 271 help="Set the color scheme (NoColor, Linux, or LightBG)."
272 272 )
273 273 colors_force = CBool(False, help=
274 274 """
275 275 Force use of ANSI color codes, regardless of OS and readline
276 276 availability.
277 277 """
278 278 # FIXME: This is essentially a hack to allow ZMQShell to show colors
279 279 # without readline on Win32. When the ZMQ formatting system is
280 280 # refactored, this should be removed.
281 281 )
282 282 debug = CBool(False, config=True)
283 283 deep_reload = CBool(False, config=True, help=
284 284 """
285 285 Enable deep (recursive) reloading by default. IPython can use the
286 286 deep_reload module which reloads changes in modules recursively (it
287 287 replaces the reload() function, so you don't need to change anything to
288 288 use it). deep_reload() forces a full reload of modules whose code may
289 289 have changed, which the default reload() function does not. When
290 290 deep_reload is off, IPython will use the normal reload(), but
291 291 deep_reload will still be available as dreload().
292 292 """
293 293 )
294 294 disable_failing_post_execute = CBool(False, config=True,
295 295 help="Don't call post-execute functions that have failed in the past."
296 296 )
297 297 display_formatter = Instance(DisplayFormatter)
298 298 displayhook_class = Type(DisplayHook)
299 299 display_pub_class = Type(DisplayPublisher)
300 300 data_pub_class = None
301 301
302 302 exit_now = CBool(False)
303 303 exiter = Instance(ExitAutocall)
304 304 def _exiter_default(self):
305 305 return ExitAutocall(self)
306 306 # Monotonically increasing execution counter
307 307 execution_count = Integer(1)
308 308 filename = Unicode("<ipython console>")
309 309 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
310 310
311 311 # Input splitter, to transform input line by line and detect when a block
312 312 # is ready to be executed.
313 313 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
314 314 (), {'line_input_checker': True})
315 315
316 316 # This InputSplitter instance is used to transform completed cells before
317 317 # running them. It allows cell magics to contain blank lines.
318 318 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
319 319 (), {'line_input_checker': False})
320 320
321 321 logstart = CBool(False, config=True, help=
322 322 """
323 323 Start logging to the default log file.
324 324 """
325 325 )
326 326 logfile = Unicode('', config=True, help=
327 327 """
328 328 The name of the logfile to use.
329 329 """
330 330 )
331 331 logappend = Unicode('', config=True, help=
332 332 """
333 333 Start logging to the given file in append mode.
334 334 """
335 335 )
336 336 object_info_string_level = Enum((0,1,2), default_value=0,
337 337 config=True)
338 338 pdb = CBool(False, config=True, help=
339 339 """
340 340 Automatically call the pdb debugger after every exception.
341 341 """
342 342 )
343 343 multiline_history = CBool(sys.platform != 'win32', config=True,
344 344 help="Save multi-line entries as one entry in readline history"
345 345 )
346 346 display_page = Bool(False, config=True,
347 347 help="""If True, anything that would be passed to the pager
348 348 will be displayed as regular output instead."""
349 349 )
350 350
351 351 # deprecated prompt traits:
352 352
353 353 prompt_in1 = Unicode('In [\\#]: ', config=True,
354 354 help="Deprecated, use PromptManager.in_template")
355 355 prompt_in2 = Unicode(' .\\D.: ', config=True,
356 356 help="Deprecated, use PromptManager.in2_template")
357 357 prompt_out = Unicode('Out[\\#]: ', config=True,
358 358 help="Deprecated, use PromptManager.out_template")
359 359 prompts_pad_left = CBool(True, config=True,
360 360 help="Deprecated, use PromptManager.justify")
361 361
362 362 def _prompt_trait_changed(self, name, old, new):
363 363 table = {
364 364 'prompt_in1' : 'in_template',
365 365 'prompt_in2' : 'in2_template',
366 366 'prompt_out' : 'out_template',
367 367 'prompts_pad_left' : 'justify',
368 368 }
369 369 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
370 370 name=name, newname=table[name])
371 371 )
372 372 # protect against weird cases where self.config may not exist:
373 373 if self.config is not None:
374 374 # propagate to corresponding PromptManager trait
375 375 setattr(self.config.PromptManager, table[name], new)
376 376
377 377 _prompt_in1_changed = _prompt_trait_changed
378 378 _prompt_in2_changed = _prompt_trait_changed
379 379 _prompt_out_changed = _prompt_trait_changed
380 380 _prompt_pad_left_changed = _prompt_trait_changed
381 381
382 382 show_rewritten_input = CBool(True, config=True,
383 383 help="Show rewritten input, e.g. for autocall."
384 384 )
385 385
386 386 quiet = CBool(False, config=True)
387 387
388 388 history_length = Integer(10000, config=True)
389 389
390 390 # The readline stuff will eventually be moved to the terminal subclass
391 391 # but for now, we can't do that as readline is welded in everywhere.
392 392 readline_use = CBool(True, config=True)
393 393 readline_remove_delims = Unicode('-/~', config=True)
394 394 readline_delims = Unicode() # set by init_readline()
395 395 # don't use \M- bindings by default, because they
396 396 # conflict with 8-bit encodings. See gh-58,gh-88
397 397 readline_parse_and_bind = List([
398 398 'tab: complete',
399 399 '"\C-l": clear-screen',
400 400 'set show-all-if-ambiguous on',
401 401 '"\C-o": tab-insert',
402 402 '"\C-r": reverse-search-history',
403 403 '"\C-s": forward-search-history',
404 404 '"\C-p": history-search-backward',
405 405 '"\C-n": history-search-forward',
406 406 '"\e[A": history-search-backward',
407 407 '"\e[B": history-search-forward',
408 408 '"\C-k": kill-line',
409 409 '"\C-u": unix-line-discard',
410 410 ], config=True)
411 411
412 412 _custom_readline_config = False
413 413
414 414 def _readline_parse_and_bind_changed(self, name, old, new):
415 415 # notice that readline config is customized
416 416 # indicates that it should have higher priority than inputrc
417 417 self._custom_readline_config = True
418 418
419 419 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
420 420 default_value='last_expr', config=True,
421 421 help="""
422 422 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
423 423 run interactively (displaying output from expressions).""")
424 424
425 425 # TODO: this part of prompt management should be moved to the frontends.
426 426 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
427 427 separate_in = SeparateUnicode('\n', config=True)
428 428 separate_out = SeparateUnicode('', config=True)
429 429 separate_out2 = SeparateUnicode('', config=True)
430 430 wildcards_case_sensitive = CBool(True, config=True)
431 431 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
432 432 default_value='Context', config=True)
433 433
434 434 # Subcomponents of InteractiveShell
435 435 alias_manager = Instance('IPython.core.alias.AliasManager')
436 436 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
437 437 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
438 438 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
439 439 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
440 440 payload_manager = Instance('IPython.core.payload.PayloadManager')
441 441 history_manager = Instance('IPython.core.history.HistoryAccessorBase')
442 442 magics_manager = Instance('IPython.core.magic.MagicsManager')
443 443
444 444 profile_dir = Instance('IPython.core.application.ProfileDir')
445 445 @property
446 446 def profile(self):
447 447 if self.profile_dir is not None:
448 448 name = os.path.basename(self.profile_dir.location)
449 449 return name.replace('profile_','')
450 450
451 451
452 452 # Private interface
453 453 _post_execute = Instance(dict)
454 454
455 455 # Tracks any GUI loop loaded for pylab
456 456 pylab_gui_select = None
457 457
458 458 def __init__(self, ipython_dir=None, profile_dir=None,
459 459 user_module=None, user_ns=None,
460 460 custom_exceptions=((), None), **kwargs):
461 461
462 462 # This is where traits with a config_key argument are updated
463 463 # from the values on config.
464 464 super(InteractiveShell, self).__init__(**kwargs)
465 465 self.configurables = [self]
466 466
467 467 # These are relatively independent and stateless
468 468 self.init_ipython_dir(ipython_dir)
469 469 self.init_profile_dir(profile_dir)
470 470 self.init_instance_attrs()
471 471 self.init_environment()
472 472
473 473 # Check if we're in a virtualenv, and set up sys.path.
474 474 self.init_virtualenv()
475 475
476 476 # Create namespaces (user_ns, user_global_ns, etc.)
477 477 self.init_create_namespaces(user_module, user_ns)
478 478 # This has to be done after init_create_namespaces because it uses
479 479 # something in self.user_ns, but before init_sys_modules, which
480 480 # is the first thing to modify sys.
481 481 # TODO: When we override sys.stdout and sys.stderr before this class
482 482 # is created, we are saving the overridden ones here. Not sure if this
483 483 # is what we want to do.
484 484 self.save_sys_module_state()
485 485 self.init_sys_modules()
486 486
487 487 # While we're trying to have each part of the code directly access what
488 488 # it needs without keeping redundant references to objects, we have too
489 489 # much legacy code that expects ip.db to exist.
490 490 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
491 491
492 492 self.init_history()
493 493 self.init_encoding()
494 494 self.init_prefilter()
495 495
496 496 self.init_syntax_highlighting()
497 497 self.init_hooks()
498 498 self.init_events()
499 499 self.init_pushd_popd_magic()
500 500 # self.init_traceback_handlers use to be here, but we moved it below
501 501 # because it and init_io have to come after init_readline.
502 502 self.init_user_ns()
503 503 self.init_logger()
504 504 self.init_builtins()
505 505
506 506 # The following was in post_config_initialization
507 507 self.init_inspector()
508 508 # init_readline() must come before init_io(), because init_io uses
509 509 # readline related things.
510 510 self.init_readline()
511 511 # We save this here in case user code replaces raw_input, but it needs
512 512 # to be after init_readline(), because PyPy's readline works by replacing
513 513 # raw_input.
514 514 if py3compat.PY3:
515 515 self.raw_input_original = input
516 516 else:
517 517 self.raw_input_original = raw_input
518 518 # init_completer must come after init_readline, because it needs to
519 519 # know whether readline is present or not system-wide to configure the
520 520 # completers, since the completion machinery can now operate
521 521 # independently of readline (e.g. over the network)
522 522 self.init_completer()
523 523 # TODO: init_io() needs to happen before init_traceback handlers
524 524 # because the traceback handlers hardcode the stdout/stderr streams.
525 525 # This logic in in debugger.Pdb and should eventually be changed.
526 526 self.init_io()
527 527 self.init_traceback_handlers(custom_exceptions)
528 528 self.init_prompts()
529 529 self.init_display_formatter()
530 530 self.init_display_pub()
531 531 self.init_data_pub()
532 532 self.init_displayhook()
533 533 self.init_magics()
534 534 self.init_alias()
535 535 self.init_logstart()
536 536 self.init_pdb()
537 537 self.init_extension_manager()
538 538 self.init_payload()
539 539 self.hooks.late_startup_hook()
540 540 self.events.trigger('shell_initialized', self)
541 541 atexit.register(self.atexit_operations)
542 542
543 543 def get_ipython(self):
544 544 """Return the currently running IPython instance."""
545 545 return self
546 546
547 547 #-------------------------------------------------------------------------
548 548 # Trait changed handlers
549 549 #-------------------------------------------------------------------------
550 550
551 551 def _ipython_dir_changed(self, name, new):
552 552 ensure_dir_exists(new)
553 553
554 554 def set_autoindent(self,value=None):
555 555 """Set the autoindent flag, checking for readline support.
556 556
557 557 If called with no arguments, it acts as a toggle."""
558 558
559 559 if value != 0 and not self.has_readline:
560 560 if os.name == 'posix':
561 561 warn("The auto-indent feature requires the readline library")
562 562 self.autoindent = 0
563 563 return
564 564 if value is None:
565 565 self.autoindent = not self.autoindent
566 566 else:
567 567 self.autoindent = value
568 568
569 569 #-------------------------------------------------------------------------
570 570 # init_* methods called by __init__
571 571 #-------------------------------------------------------------------------
572 572
573 573 def init_ipython_dir(self, ipython_dir):
574 574 if ipython_dir is not None:
575 575 self.ipython_dir = ipython_dir
576 576 return
577 577
578 578 self.ipython_dir = get_ipython_dir()
579 579
580 580 def init_profile_dir(self, profile_dir):
581 581 if profile_dir is not None:
582 582 self.profile_dir = profile_dir
583 583 return
584 584 self.profile_dir =\
585 585 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
586 586
587 587 def init_instance_attrs(self):
588 588 self.more = False
589 589
590 590 # command compiler
591 591 self.compile = CachingCompiler()
592 592
593 593 # Make an empty namespace, which extension writers can rely on both
594 594 # existing and NEVER being used by ipython itself. This gives them a
595 595 # convenient location for storing additional information and state
596 596 # their extensions may require, without fear of collisions with other
597 597 # ipython names that may develop later.
598 598 self.meta = Struct()
599 599
600 600 # Temporary files used for various purposes. Deleted at exit.
601 601 self.tempfiles = []
602 602 self.tempdirs = []
603 603
604 604 # Keep track of readline usage (later set by init_readline)
605 605 self.has_readline = False
606 606
607 607 # keep track of where we started running (mainly for crash post-mortem)
608 608 # This is not being used anywhere currently.
609 609 self.starting_dir = py3compat.getcwd()
610 610
611 611 # Indentation management
612 612 self.indent_current_nsp = 0
613 613
614 614 # Dict to track post-execution functions that have been registered
615 615 self._post_execute = {}
616 616
617 617 def init_environment(self):
618 618 """Any changes we need to make to the user's environment."""
619 619 pass
620 620
621 621 def init_encoding(self):
622 622 # Get system encoding at startup time. Certain terminals (like Emacs
623 623 # under Win32 have it set to None, and we need to have a known valid
624 624 # encoding to use in the raw_input() method
625 625 try:
626 626 self.stdin_encoding = sys.stdin.encoding or 'ascii'
627 627 except AttributeError:
628 628 self.stdin_encoding = 'ascii'
629 629
630 630 def init_syntax_highlighting(self):
631 631 # Python source parser/formatter for syntax highlighting
632 632 pyformat = PyColorize.Parser().format
633 633 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
634 634
635 635 def init_pushd_popd_magic(self):
636 636 # for pushd/popd management
637 637 self.home_dir = get_home_dir()
638 638
639 639 self.dir_stack = []
640 640
641 641 def init_logger(self):
642 642 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
643 643 logmode='rotate')
644 644
645 645 def init_logstart(self):
646 646 """Initialize logging in case it was requested at the command line.
647 647 """
648 648 if self.logappend:
649 649 self.magic('logstart %s append' % self.logappend)
650 650 elif self.logfile:
651 651 self.magic('logstart %s' % self.logfile)
652 652 elif self.logstart:
653 653 self.magic('logstart')
654 654
655 655 def init_builtins(self):
656 656 # A single, static flag that we set to True. Its presence indicates
657 657 # that an IPython shell has been created, and we make no attempts at
658 658 # removing on exit or representing the existence of more than one
659 659 # IPython at a time.
660 660 builtin_mod.__dict__['__IPYTHON__'] = True
661 661
662 662 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
663 663 # manage on enter/exit, but with all our shells it's virtually
664 664 # impossible to get all the cases right. We're leaving the name in for
665 665 # those who adapted their codes to check for this flag, but will
666 666 # eventually remove it after a few more releases.
667 667 builtin_mod.__dict__['__IPYTHON__active'] = \
668 668 'Deprecated, check for __IPYTHON__'
669 669
670 670 self.builtin_trap = BuiltinTrap(shell=self)
671 671
672 672 def init_inspector(self):
673 673 # Object inspector
674 674 self.inspector = oinspect.Inspector(oinspect.InspectColors,
675 675 PyColorize.ANSICodeColors,
676 676 'NoColor',
677 677 self.object_info_string_level)
678 678
679 679 def init_io(self):
680 680 # This will just use sys.stdout and sys.stderr. If you want to
681 681 # override sys.stdout and sys.stderr themselves, you need to do that
682 682 # *before* instantiating this class, because io holds onto
683 683 # references to the underlying streams.
684 684 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
685 685 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
686 686 else:
687 687 io.stdout = io.IOStream(sys.stdout)
688 688 io.stderr = io.IOStream(sys.stderr)
689 689
690 690 def init_prompts(self):
691 691 self.prompt_manager = PromptManager(shell=self, parent=self)
692 692 self.configurables.append(self.prompt_manager)
693 693 # Set system prompts, so that scripts can decide if they are running
694 694 # interactively.
695 695 sys.ps1 = 'In : '
696 696 sys.ps2 = '...: '
697 697 sys.ps3 = 'Out: '
698 698
699 699 def init_display_formatter(self):
700 700 self.display_formatter = DisplayFormatter(parent=self)
701 701 self.configurables.append(self.display_formatter)
702 702
703 703 def init_display_pub(self):
704 704 self.display_pub = self.display_pub_class(parent=self)
705 705 self.configurables.append(self.display_pub)
706 706
707 707 def init_data_pub(self):
708 708 if not self.data_pub_class:
709 709 self.data_pub = None
710 710 return
711 711 self.data_pub = self.data_pub_class(parent=self)
712 712 self.configurables.append(self.data_pub)
713 713
714 714 def init_displayhook(self):
715 715 # Initialize displayhook, set in/out prompts and printing system
716 716 self.displayhook = self.displayhook_class(
717 717 parent=self,
718 718 shell=self,
719 719 cache_size=self.cache_size,
720 720 )
721 721 self.configurables.append(self.displayhook)
722 722 # This is a context manager that installs/revmoes the displayhook at
723 723 # the appropriate time.
724 724 self.display_trap = DisplayTrap(hook=self.displayhook)
725 725
726 726 def init_virtualenv(self):
727 727 """Add a virtualenv to sys.path so the user can import modules from it.
728 728 This isn't perfect: it doesn't use the Python interpreter with which the
729 729 virtualenv was built, and it ignores the --no-site-packages option. A
730 730 warning will appear suggesting the user installs IPython in the
731 731 virtualenv, but for many cases, it probably works well enough.
732 732
733 733 Adapted from code snippets online.
734 734
735 735 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
736 736 """
737 737 if 'VIRTUAL_ENV' not in os.environ:
738 738 # Not in a virtualenv
739 739 return
740 740
741 741 # venv detection:
742 742 # stdlib venv may symlink sys.executable, so we can't use realpath.
743 743 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
744 744 # So we just check every item in the symlink tree (generally <= 3)
745 745 p = os.path.normcase(sys.executable)
746 746 paths = [p]
747 747 while os.path.islink(p):
748 748 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
749 749 paths.append(p)
750 750 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
751 751 if any(p.startswith(p_venv) for p in paths):
752 752 # Running properly in the virtualenv, don't need to do anything
753 753 return
754 754
755 755 warn("Attempting to work in a virtualenv. If you encounter problems, please "
756 756 "install IPython inside the virtualenv.")
757 757 if sys.platform == "win32":
758 758 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
759 759 else:
760 760 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
761 761 'python%d.%d' % sys.version_info[:2], 'site-packages')
762 762
763 763 import site
764 764 sys.path.insert(0, virtual_env)
765 765 site.addsitedir(virtual_env)
766 766
767 767 #-------------------------------------------------------------------------
768 768 # Things related to injections into the sys module
769 769 #-------------------------------------------------------------------------
770 770
771 771 def save_sys_module_state(self):
772 772 """Save the state of hooks in the sys module.
773 773
774 774 This has to be called after self.user_module is created.
775 775 """
776 776 self._orig_sys_module_state = {}
777 777 self._orig_sys_module_state['stdin'] = sys.stdin
778 778 self._orig_sys_module_state['stdout'] = sys.stdout
779 779 self._orig_sys_module_state['stderr'] = sys.stderr
780 780 self._orig_sys_module_state['excepthook'] = sys.excepthook
781 781 self._orig_sys_modules_main_name = self.user_module.__name__
782 782 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
783 783
784 784 def restore_sys_module_state(self):
785 785 """Restore the state of the sys module."""
786 786 try:
787 787 for k, v in iteritems(self._orig_sys_module_state):
788 788 setattr(sys, k, v)
789 789 except AttributeError:
790 790 pass
791 791 # Reset what what done in self.init_sys_modules
792 792 if self._orig_sys_modules_main_mod is not None:
793 793 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
794 794
795 795 #-------------------------------------------------------------------------
796 796 # Things related to the banner
797 797 #-------------------------------------------------------------------------
798 798
799 799 @property
800 800 def banner(self):
801 801 banner = self.banner1
802 802 if self.profile and self.profile != 'default':
803 803 banner += '\nIPython profile: %s\n' % self.profile
804 804 if self.banner2:
805 805 banner += '\n' + self.banner2
806 806 return banner
807 807
808 808 def show_banner(self, banner=None):
809 809 if banner is None:
810 810 banner = self.banner
811 811 self.write(banner)
812 812
813 813 #-------------------------------------------------------------------------
814 814 # Things related to hooks
815 815 #-------------------------------------------------------------------------
816 816
817 817 def init_hooks(self):
818 818 # hooks holds pointers used for user-side customizations
819 819 self.hooks = Struct()
820 820
821 821 self.strdispatchers = {}
822 822
823 823 # Set all default hooks, defined in the IPython.hooks module.
824 824 hooks = IPython.core.hooks
825 825 for hook_name in hooks.__all__:
826 826 # default hooks have priority 100, i.e. low; user hooks should have
827 827 # 0-100 priority
828 828 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
829 829
830 830 if self.display_page:
831 831 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
832 832
833 833 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
834 834 _warn_deprecated=True):
835 835 """set_hook(name,hook) -> sets an internal IPython hook.
836 836
837 837 IPython exposes some of its internal API as user-modifiable hooks. By
838 838 adding your function to one of these hooks, you can modify IPython's
839 839 behavior to call at runtime your own routines."""
840 840
841 841 # At some point in the future, this should validate the hook before it
842 842 # accepts it. Probably at least check that the hook takes the number
843 843 # of args it's supposed to.
844 844
845 845 f = types.MethodType(hook,self)
846 846
847 847 # check if the hook is for strdispatcher first
848 848 if str_key is not None:
849 849 sdp = self.strdispatchers.get(name, StrDispatch())
850 850 sdp.add_s(str_key, f, priority )
851 851 self.strdispatchers[name] = sdp
852 852 return
853 853 if re_key is not None:
854 854 sdp = self.strdispatchers.get(name, StrDispatch())
855 855 sdp.add_re(re.compile(re_key), f, priority )
856 856 self.strdispatchers[name] = sdp
857 857 return
858 858
859 859 dp = getattr(self.hooks, name, None)
860 860 if name not in IPython.core.hooks.__all__:
861 861 print("Warning! Hook '%s' is not one of %s" % \
862 862 (name, IPython.core.hooks.__all__ ))
863 863
864 864 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
865 865 alternative = IPython.core.hooks.deprecated[name]
866 866 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative))
867 867
868 868 if not dp:
869 869 dp = IPython.core.hooks.CommandChainDispatcher()
870 870
871 871 try:
872 872 dp.add(f,priority)
873 873 except AttributeError:
874 874 # it was not commandchain, plain old func - replace
875 875 dp = f
876 876
877 877 setattr(self.hooks,name, dp)
878 878
879 879 #-------------------------------------------------------------------------
880 880 # Things related to events
881 881 #-------------------------------------------------------------------------
882 882
883 883 def init_events(self):
884 884 self.events = EventManager(self, available_events)
885 885
886 886 self.events.register("pre_execute", self._clear_warning_registry)
887 887
888 888 def register_post_execute(self, func):
889 889 """DEPRECATED: Use ip.events.register('post_run_cell', func)
890 890
891 891 Register a function for calling after code execution.
892 892 """
893 893 warn("ip.register_post_execute is deprecated, use "
894 894 "ip.events.register('post_run_cell', func) instead.")
895 895 self.events.register('post_run_cell', func)
896 896
897 897 def _clear_warning_registry(self):
898 898 # clear the warning registry, so that different code blocks with
899 899 # overlapping line number ranges don't cause spurious suppression of
900 900 # warnings (see gh-6611 for details)
901 901 if "__warningregistry__" in self.user_global_ns:
902 902 del self.user_global_ns["__warningregistry__"]
903 903
904 904 #-------------------------------------------------------------------------
905 905 # Things related to the "main" module
906 906 #-------------------------------------------------------------------------
907 907
908 908 def new_main_mod(self, filename, modname):
909 909 """Return a new 'main' module object for user code execution.
910 910
911 911 ``filename`` should be the path of the script which will be run in the
912 912 module. Requests with the same filename will get the same module, with
913 913 its namespace cleared.
914 914
915 915 ``modname`` should be the module name - normally either '__main__' or
916 916 the basename of the file without the extension.
917 917
918 918 When scripts are executed via %run, we must keep a reference to their
919 919 __main__ module around so that Python doesn't
920 920 clear it, rendering references to module globals useless.
921 921
922 922 This method keeps said reference in a private dict, keyed by the
923 923 absolute path of the script. This way, for multiple executions of the
924 924 same script we only keep one copy of the namespace (the last one),
925 925 thus preventing memory leaks from old references while allowing the
926 926 objects from the last execution to be accessible.
927 927 """
928 928 filename = os.path.abspath(filename)
929 929 try:
930 930 main_mod = self._main_mod_cache[filename]
931 931 except KeyError:
932 932 main_mod = self._main_mod_cache[filename] = types.ModuleType(
933 933 py3compat.cast_bytes_py2(modname),
934 934 doc="Module created for script run in IPython")
935 935 else:
936 936 main_mod.__dict__.clear()
937 937 main_mod.__name__ = modname
938 938
939 939 main_mod.__file__ = filename
940 940 # It seems pydoc (and perhaps others) needs any module instance to
941 941 # implement a __nonzero__ method
942 942 main_mod.__nonzero__ = lambda : True
943 943
944 944 return main_mod
945 945
946 946 def clear_main_mod_cache(self):
947 947 """Clear the cache of main modules.
948 948
949 949 Mainly for use by utilities like %reset.
950 950
951 951 Examples
952 952 --------
953 953
954 954 In [15]: import IPython
955 955
956 956 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
957 957
958 958 In [17]: len(_ip._main_mod_cache) > 0
959 959 Out[17]: True
960 960
961 961 In [18]: _ip.clear_main_mod_cache()
962 962
963 963 In [19]: len(_ip._main_mod_cache) == 0
964 964 Out[19]: True
965 965 """
966 966 self._main_mod_cache.clear()
967 967
968 968 #-------------------------------------------------------------------------
969 969 # Things related to debugging
970 970 #-------------------------------------------------------------------------
971 971
972 972 def init_pdb(self):
973 973 # Set calling of pdb on exceptions
974 974 # self.call_pdb is a property
975 975 self.call_pdb = self.pdb
976 976
977 977 def _get_call_pdb(self):
978 978 return self._call_pdb
979 979
980 980 def _set_call_pdb(self,val):
981 981
982 982 if val not in (0,1,False,True):
983 983 raise ValueError('new call_pdb value must be boolean')
984 984
985 985 # store value in instance
986 986 self._call_pdb = val
987 987
988 988 # notify the actual exception handlers
989 989 self.InteractiveTB.call_pdb = val
990 990
991 991 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
992 992 'Control auto-activation of pdb at exceptions')
993 993
994 994 def debugger(self,force=False):
995 995 """Call the pydb/pdb debugger.
996 996
997 997 Keywords:
998 998
999 999 - force(False): by default, this routine checks the instance call_pdb
1000 1000 flag and does not actually invoke the debugger if the flag is false.
1001 1001 The 'force' option forces the debugger to activate even if the flag
1002 1002 is false.
1003 1003 """
1004 1004
1005 1005 if not (force or self.call_pdb):
1006 1006 return
1007 1007
1008 1008 if not hasattr(sys,'last_traceback'):
1009 1009 error('No traceback has been produced, nothing to debug.')
1010 1010 return
1011 1011
1012 1012 # use pydb if available
1013 1013 if debugger.has_pydb:
1014 1014 from pydb import pm
1015 1015 else:
1016 1016 # fallback to our internal debugger
1017 1017 pm = lambda : self.InteractiveTB.debugger(force=True)
1018 1018
1019 1019 with self.readline_no_record:
1020 1020 pm()
1021 1021
1022 1022 #-------------------------------------------------------------------------
1023 1023 # Things related to IPython's various namespaces
1024 1024 #-------------------------------------------------------------------------
1025 1025 default_user_namespaces = True
1026 1026
1027 1027 def init_create_namespaces(self, user_module=None, user_ns=None):
1028 1028 # Create the namespace where the user will operate. user_ns is
1029 1029 # normally the only one used, and it is passed to the exec calls as
1030 1030 # the locals argument. But we do carry a user_global_ns namespace
1031 1031 # given as the exec 'globals' argument, This is useful in embedding
1032 1032 # situations where the ipython shell opens in a context where the
1033 1033 # distinction between locals and globals is meaningful. For
1034 1034 # non-embedded contexts, it is just the same object as the user_ns dict.
1035 1035
1036 1036 # FIXME. For some strange reason, __builtins__ is showing up at user
1037 1037 # level as a dict instead of a module. This is a manual fix, but I
1038 1038 # should really track down where the problem is coming from. Alex
1039 1039 # Schmolck reported this problem first.
1040 1040
1041 1041 # A useful post by Alex Martelli on this topic:
1042 1042 # Re: inconsistent value from __builtins__
1043 1043 # Von: Alex Martelli <aleaxit@yahoo.com>
1044 1044 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1045 1045 # Gruppen: comp.lang.python
1046 1046
1047 1047 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1048 1048 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1049 1049 # > <type 'dict'>
1050 1050 # > >>> print type(__builtins__)
1051 1051 # > <type 'module'>
1052 1052 # > Is this difference in return value intentional?
1053 1053
1054 1054 # Well, it's documented that '__builtins__' can be either a dictionary
1055 1055 # or a module, and it's been that way for a long time. Whether it's
1056 1056 # intentional (or sensible), I don't know. In any case, the idea is
1057 1057 # that if you need to access the built-in namespace directly, you
1058 1058 # should start with "import __builtin__" (note, no 's') which will
1059 1059 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1060 1060
1061 1061 # These routines return a properly built module and dict as needed by
1062 1062 # the rest of the code, and can also be used by extension writers to
1063 1063 # generate properly initialized namespaces.
1064 1064 if (user_ns is not None) or (user_module is not None):
1065 1065 self.default_user_namespaces = False
1066 1066 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1067 1067
1068 1068 # A record of hidden variables we have added to the user namespace, so
1069 1069 # we can list later only variables defined in actual interactive use.
1070 1070 self.user_ns_hidden = {}
1071 1071
1072 1072 # Now that FakeModule produces a real module, we've run into a nasty
1073 1073 # problem: after script execution (via %run), the module where the user
1074 1074 # code ran is deleted. Now that this object is a true module (needed
1075 1075 # so docetst and other tools work correctly), the Python module
1076 1076 # teardown mechanism runs over it, and sets to None every variable
1077 1077 # present in that module. Top-level references to objects from the
1078 1078 # script survive, because the user_ns is updated with them. However,
1079 1079 # calling functions defined in the script that use other things from
1080 1080 # the script will fail, because the function's closure had references
1081 1081 # to the original objects, which are now all None. So we must protect
1082 1082 # these modules from deletion by keeping a cache.
1083 1083 #
1084 1084 # To avoid keeping stale modules around (we only need the one from the
1085 1085 # last run), we use a dict keyed with the full path to the script, so
1086 1086 # only the last version of the module is held in the cache. Note,
1087 1087 # however, that we must cache the module *namespace contents* (their
1088 1088 # __dict__). Because if we try to cache the actual modules, old ones
1089 1089 # (uncached) could be destroyed while still holding references (such as
1090 1090 # those held by GUI objects that tend to be long-lived)>
1091 1091 #
1092 1092 # The %reset command will flush this cache. See the cache_main_mod()
1093 1093 # and clear_main_mod_cache() methods for details on use.
1094 1094
1095 1095 # This is the cache used for 'main' namespaces
1096 1096 self._main_mod_cache = {}
1097 1097
1098 1098 # A table holding all the namespaces IPython deals with, so that
1099 1099 # introspection facilities can search easily.
1100 1100 self.ns_table = {'user_global':self.user_module.__dict__,
1101 1101 'user_local':self.user_ns,
1102 1102 'builtin':builtin_mod.__dict__
1103 1103 }
1104 1104
1105 1105 @property
1106 1106 def user_global_ns(self):
1107 1107 return self.user_module.__dict__
1108 1108
1109 1109 def prepare_user_module(self, user_module=None, user_ns=None):
1110 1110 """Prepare the module and namespace in which user code will be run.
1111 1111
1112 1112 When IPython is started normally, both parameters are None: a new module
1113 1113 is created automatically, and its __dict__ used as the namespace.
1114 1114
1115 1115 If only user_module is provided, its __dict__ is used as the namespace.
1116 1116 If only user_ns is provided, a dummy module is created, and user_ns
1117 1117 becomes the global namespace. If both are provided (as they may be
1118 1118 when embedding), user_ns is the local namespace, and user_module
1119 1119 provides the global namespace.
1120 1120
1121 1121 Parameters
1122 1122 ----------
1123 1123 user_module : module, optional
1124 1124 The current user module in which IPython is being run. If None,
1125 1125 a clean module will be created.
1126 1126 user_ns : dict, optional
1127 1127 A namespace in which to run interactive commands.
1128 1128
1129 1129 Returns
1130 1130 -------
1131 1131 A tuple of user_module and user_ns, each properly initialised.
1132 1132 """
1133 1133 if user_module is None and user_ns is not None:
1134 1134 user_ns.setdefault("__name__", "__main__")
1135 1135 user_module = DummyMod()
1136 1136 user_module.__dict__ = user_ns
1137 1137
1138 1138 if user_module is None:
1139 1139 user_module = types.ModuleType("__main__",
1140 1140 doc="Automatically created module for IPython interactive environment")
1141 1141
1142 1142 # We must ensure that __builtin__ (without the final 's') is always
1143 1143 # available and pointing to the __builtin__ *module*. For more details:
1144 1144 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1145 1145 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1146 1146 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1147 1147
1148 1148 if user_ns is None:
1149 1149 user_ns = user_module.__dict__
1150 1150
1151 1151 return user_module, user_ns
1152 1152
1153 1153 def init_sys_modules(self):
1154 1154 # We need to insert into sys.modules something that looks like a
1155 1155 # module but which accesses the IPython namespace, for shelve and
1156 1156 # pickle to work interactively. Normally they rely on getting
1157 1157 # everything out of __main__, but for embedding purposes each IPython
1158 1158 # instance has its own private namespace, so we can't go shoving
1159 1159 # everything into __main__.
1160 1160
1161 1161 # note, however, that we should only do this for non-embedded
1162 1162 # ipythons, which really mimic the __main__.__dict__ with their own
1163 1163 # namespace. Embedded instances, on the other hand, should not do
1164 1164 # this because they need to manage the user local/global namespaces
1165 1165 # only, but they live within a 'normal' __main__ (meaning, they
1166 1166 # shouldn't overtake the execution environment of the script they're
1167 1167 # embedded in).
1168 1168
1169 1169 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1170 1170 main_name = self.user_module.__name__
1171 1171 sys.modules[main_name] = self.user_module
1172 1172
1173 1173 def init_user_ns(self):
1174 1174 """Initialize all user-visible namespaces to their minimum defaults.
1175 1175
1176 1176 Certain history lists are also initialized here, as they effectively
1177 1177 act as user namespaces.
1178 1178
1179 1179 Notes
1180 1180 -----
1181 1181 All data structures here are only filled in, they are NOT reset by this
1182 1182 method. If they were not empty before, data will simply be added to
1183 1183 therm.
1184 1184 """
1185 1185 # This function works in two parts: first we put a few things in
1186 1186 # user_ns, and we sync that contents into user_ns_hidden so that these
1187 1187 # initial variables aren't shown by %who. After the sync, we add the
1188 1188 # rest of what we *do* want the user to see with %who even on a new
1189 1189 # session (probably nothing, so theye really only see their own stuff)
1190 1190
1191 1191 # The user dict must *always* have a __builtin__ reference to the
1192 1192 # Python standard __builtin__ namespace, which must be imported.
1193 1193 # This is so that certain operations in prompt evaluation can be
1194 1194 # reliably executed with builtins. Note that we can NOT use
1195 1195 # __builtins__ (note the 's'), because that can either be a dict or a
1196 1196 # module, and can even mutate at runtime, depending on the context
1197 1197 # (Python makes no guarantees on it). In contrast, __builtin__ is
1198 1198 # always a module object, though it must be explicitly imported.
1199 1199
1200 1200 # For more details:
1201 1201 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1202 1202 ns = dict()
1203 1203
1204 1204 # make global variables for user access to the histories
1205 1205 ns['_ih'] = self.history_manager.input_hist_parsed
1206 1206 ns['_oh'] = self.history_manager.output_hist
1207 1207 ns['_dh'] = self.history_manager.dir_hist
1208 1208
1209 1209 ns['_sh'] = shadowns
1210 1210
1211 1211 # user aliases to input and output histories. These shouldn't show up
1212 1212 # in %who, as they can have very large reprs.
1213 1213 ns['In'] = self.history_manager.input_hist_parsed
1214 1214 ns['Out'] = self.history_manager.output_hist
1215 1215
1216 1216 # Store myself as the public api!!!
1217 1217 ns['get_ipython'] = self.get_ipython
1218 1218
1219 1219 ns['exit'] = self.exiter
1220 1220 ns['quit'] = self.exiter
1221 1221
1222 1222 # Sync what we've added so far to user_ns_hidden so these aren't seen
1223 1223 # by %who
1224 1224 self.user_ns_hidden.update(ns)
1225 1225
1226 1226 # Anything put into ns now would show up in %who. Think twice before
1227 1227 # putting anything here, as we really want %who to show the user their
1228 1228 # stuff, not our variables.
1229 1229
1230 1230 # Finally, update the real user's namespace
1231 1231 self.user_ns.update(ns)
1232 1232
1233 1233 @property
1234 1234 def all_ns_refs(self):
1235 1235 """Get a list of references to all the namespace dictionaries in which
1236 1236 IPython might store a user-created object.
1237 1237
1238 1238 Note that this does not include the displayhook, which also caches
1239 1239 objects from the output."""
1240 1240 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1241 1241 [m.__dict__ for m in self._main_mod_cache.values()]
1242 1242
1243 1243 def reset(self, new_session=True):
1244 1244 """Clear all internal namespaces, and attempt to release references to
1245 1245 user objects.
1246 1246
1247 1247 If new_session is True, a new history session will be opened.
1248 1248 """
1249 1249 # Clear histories
1250 1250 self.history_manager.reset(new_session)
1251 1251 # Reset counter used to index all histories
1252 1252 if new_session:
1253 1253 self.execution_count = 1
1254 1254
1255 1255 # Flush cached output items
1256 1256 if self.displayhook.do_full_cache:
1257 1257 self.displayhook.flush()
1258 1258
1259 1259 # The main execution namespaces must be cleared very carefully,
1260 1260 # skipping the deletion of the builtin-related keys, because doing so
1261 1261 # would cause errors in many object's __del__ methods.
1262 1262 if self.user_ns is not self.user_global_ns:
1263 1263 self.user_ns.clear()
1264 1264 ns = self.user_global_ns
1265 1265 drop_keys = set(ns.keys())
1266 1266 drop_keys.discard('__builtin__')
1267 1267 drop_keys.discard('__builtins__')
1268 1268 drop_keys.discard('__name__')
1269 1269 for k in drop_keys:
1270 1270 del ns[k]
1271 1271
1272 1272 self.user_ns_hidden.clear()
1273 1273
1274 1274 # Restore the user namespaces to minimal usability
1275 1275 self.init_user_ns()
1276 1276
1277 1277 # Restore the default and user aliases
1278 1278 self.alias_manager.clear_aliases()
1279 1279 self.alias_manager.init_aliases()
1280 1280
1281 1281 # Flush the private list of module references kept for script
1282 1282 # execution protection
1283 1283 self.clear_main_mod_cache()
1284 1284
1285 1285 def del_var(self, varname, by_name=False):
1286 1286 """Delete a variable from the various namespaces, so that, as
1287 1287 far as possible, we're not keeping any hidden references to it.
1288 1288
1289 1289 Parameters
1290 1290 ----------
1291 1291 varname : str
1292 1292 The name of the variable to delete.
1293 1293 by_name : bool
1294 1294 If True, delete variables with the given name in each
1295 1295 namespace. If False (default), find the variable in the user
1296 1296 namespace, and delete references to it.
1297 1297 """
1298 1298 if varname in ('__builtin__', '__builtins__'):
1299 1299 raise ValueError("Refusing to delete %s" % varname)
1300 1300
1301 1301 ns_refs = self.all_ns_refs
1302 1302
1303 1303 if by_name: # Delete by name
1304 1304 for ns in ns_refs:
1305 1305 try:
1306 1306 del ns[varname]
1307 1307 except KeyError:
1308 1308 pass
1309 1309 else: # Delete by object
1310 1310 try:
1311 1311 obj = self.user_ns[varname]
1312 1312 except KeyError:
1313 1313 raise NameError("name '%s' is not defined" % varname)
1314 1314 # Also check in output history
1315 1315 ns_refs.append(self.history_manager.output_hist)
1316 1316 for ns in ns_refs:
1317 1317 to_delete = [n for n, o in iteritems(ns) if o is obj]
1318 1318 for name in to_delete:
1319 1319 del ns[name]
1320 1320
1321 1321 # displayhook keeps extra references, but not in a dictionary
1322 1322 for name in ('_', '__', '___'):
1323 1323 if getattr(self.displayhook, name) is obj:
1324 1324 setattr(self.displayhook, name, None)
1325 1325
1326 1326 def reset_selective(self, regex=None):
1327 1327 """Clear selective variables from internal namespaces based on a
1328 1328 specified regular expression.
1329 1329
1330 1330 Parameters
1331 1331 ----------
1332 1332 regex : string or compiled pattern, optional
1333 1333 A regular expression pattern that will be used in searching
1334 1334 variable names in the users namespaces.
1335 1335 """
1336 1336 if regex is not None:
1337 1337 try:
1338 1338 m = re.compile(regex)
1339 1339 except TypeError:
1340 1340 raise TypeError('regex must be a string or compiled pattern')
1341 1341 # Search for keys in each namespace that match the given regex
1342 1342 # If a match is found, delete the key/value pair.
1343 1343 for ns in self.all_ns_refs:
1344 1344 for var in ns:
1345 1345 if m.search(var):
1346 1346 del ns[var]
1347 1347
1348 1348 def push(self, variables, interactive=True):
1349 1349 """Inject a group of variables into the IPython user namespace.
1350 1350
1351 1351 Parameters
1352 1352 ----------
1353 1353 variables : dict, str or list/tuple of str
1354 1354 The variables to inject into the user's namespace. If a dict, a
1355 1355 simple update is done. If a str, the string is assumed to have
1356 1356 variable names separated by spaces. A list/tuple of str can also
1357 1357 be used to give the variable names. If just the variable names are
1358 1358 give (list/tuple/str) then the variable values looked up in the
1359 1359 callers frame.
1360 1360 interactive : bool
1361 1361 If True (default), the variables will be listed with the ``who``
1362 1362 magic.
1363 1363 """
1364 1364 vdict = None
1365 1365
1366 1366 # We need a dict of name/value pairs to do namespace updates.
1367 1367 if isinstance(variables, dict):
1368 1368 vdict = variables
1369 1369 elif isinstance(variables, string_types+(list, tuple)):
1370 1370 if isinstance(variables, string_types):
1371 1371 vlist = variables.split()
1372 1372 else:
1373 1373 vlist = variables
1374 1374 vdict = {}
1375 1375 cf = sys._getframe(1)
1376 1376 for name in vlist:
1377 1377 try:
1378 1378 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1379 1379 except:
1380 1380 print('Could not get variable %s from %s' %
1381 1381 (name,cf.f_code.co_name))
1382 1382 else:
1383 1383 raise ValueError('variables must be a dict/str/list/tuple')
1384 1384
1385 1385 # Propagate variables to user namespace
1386 1386 self.user_ns.update(vdict)
1387 1387
1388 1388 # And configure interactive visibility
1389 1389 user_ns_hidden = self.user_ns_hidden
1390 1390 if interactive:
1391 1391 for name in vdict:
1392 1392 user_ns_hidden.pop(name, None)
1393 1393 else:
1394 1394 user_ns_hidden.update(vdict)
1395 1395
1396 1396 def drop_by_id(self, variables):
1397 1397 """Remove a dict of variables from the user namespace, if they are the
1398 1398 same as the values in the dictionary.
1399 1399
1400 1400 This is intended for use by extensions: variables that they've added can
1401 1401 be taken back out if they are unloaded, without removing any that the
1402 1402 user has overwritten.
1403 1403
1404 1404 Parameters
1405 1405 ----------
1406 1406 variables : dict
1407 1407 A dictionary mapping object names (as strings) to the objects.
1408 1408 """
1409 1409 for name, obj in iteritems(variables):
1410 1410 if name in self.user_ns and self.user_ns[name] is obj:
1411 1411 del self.user_ns[name]
1412 1412 self.user_ns_hidden.pop(name, None)
1413 1413
1414 1414 #-------------------------------------------------------------------------
1415 1415 # Things related to object introspection
1416 1416 #-------------------------------------------------------------------------
1417 1417
1418 1418 def _ofind(self, oname, namespaces=None):
1419 1419 """Find an object in the available namespaces.
1420 1420
1421 1421 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1422 1422
1423 1423 Has special code to detect magic functions.
1424 1424 """
1425 1425 oname = oname.strip()
1426 1426 #print '1- oname: <%r>' % oname # dbg
1427 1427 if not oname.startswith(ESC_MAGIC) and \
1428 1428 not oname.startswith(ESC_MAGIC2) and \
1429 1429 not py3compat.isidentifier(oname, dotted=True):
1430 1430 return dict(found=False)
1431 1431
1432 1432 alias_ns = None
1433 1433 if namespaces is None:
1434 1434 # Namespaces to search in:
1435 1435 # Put them in a list. The order is important so that we
1436 1436 # find things in the same order that Python finds them.
1437 1437 namespaces = [ ('Interactive', self.user_ns),
1438 1438 ('Interactive (global)', self.user_global_ns),
1439 1439 ('Python builtin', builtin_mod.__dict__),
1440 1440 ]
1441 1441
1442 1442 # initialize results to 'null'
1443 1443 found = False; obj = None; ospace = None; ds = None;
1444 1444 ismagic = False; isalias = False; parent = None
1445 1445
1446 1446 # We need to special-case 'print', which as of python2.6 registers as a
1447 1447 # function but should only be treated as one if print_function was
1448 1448 # loaded with a future import. In this case, just bail.
1449 1449 if (oname == 'print' and not py3compat.PY3 and not \
1450 1450 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1451 1451 return {'found':found, 'obj':obj, 'namespace':ospace,
1452 1452 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1453 1453
1454 1454 # Look for the given name by splitting it in parts. If the head is
1455 1455 # found, then we look for all the remaining parts as members, and only
1456 1456 # declare success if we can find them all.
1457 1457 oname_parts = oname.split('.')
1458 1458 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1459 1459 for nsname,ns in namespaces:
1460 1460 try:
1461 1461 obj = ns[oname_head]
1462 1462 except KeyError:
1463 1463 continue
1464 1464 else:
1465 1465 #print 'oname_rest:', oname_rest # dbg
1466 1466 for idx, part in enumerate(oname_rest):
1467 1467 try:
1468 1468 parent = obj
1469 1469 # The last part is looked up in a special way to avoid
1470 1470 # descriptor invocation as it may raise or have side
1471 1471 # effects.
1472 1472 if idx == len(oname_rest) - 1:
1473 1473 obj = self._getattr_property(obj, part)
1474 1474 else:
1475 1475 obj = getattr(obj, part)
1476 1476 except:
1477 1477 # Blanket except b/c some badly implemented objects
1478 1478 # allow __getattr__ to raise exceptions other than
1479 1479 # AttributeError, which then crashes IPython.
1480 1480 break
1481 1481 else:
1482 1482 # If we finish the for loop (no break), we got all members
1483 1483 found = True
1484 1484 ospace = nsname
1485 1485 break # namespace loop
1486 1486
1487 1487 # Try to see if it's magic
1488 1488 if not found:
1489 1489 obj = None
1490 1490 if oname.startswith(ESC_MAGIC2):
1491 1491 oname = oname.lstrip(ESC_MAGIC2)
1492 1492 obj = self.find_cell_magic(oname)
1493 1493 elif oname.startswith(ESC_MAGIC):
1494 1494 oname = oname.lstrip(ESC_MAGIC)
1495 1495 obj = self.find_line_magic(oname)
1496 1496 else:
1497 1497 # search without prefix, so run? will find %run?
1498 1498 obj = self.find_line_magic(oname)
1499 1499 if obj is None:
1500 1500 obj = self.find_cell_magic(oname)
1501 1501 if obj is not None:
1502 1502 found = True
1503 1503 ospace = 'IPython internal'
1504 1504 ismagic = True
1505 isalias = isinstance(obj, Alias)
1505 1506
1506 1507 # Last try: special-case some literals like '', [], {}, etc:
1507 1508 if not found and oname_head in ["''",'""','[]','{}','()']:
1508 1509 obj = eval(oname_head)
1509 1510 found = True
1510 1511 ospace = 'Interactive'
1511 1512
1512 1513 return {'found':found, 'obj':obj, 'namespace':ospace,
1513 1514 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1514 1515
1515 1516 @staticmethod
1516 1517 def _getattr_property(obj, attrname):
1517 1518 """Property-aware getattr to use in object finding.
1518 1519
1519 1520 If attrname represents a property, return it unevaluated (in case it has
1520 1521 side effects or raises an error.
1521 1522
1522 1523 """
1523 1524 if not isinstance(obj, type):
1524 1525 try:
1525 1526 # `getattr(type(obj), attrname)` is not guaranteed to return
1526 1527 # `obj`, but does so for property:
1527 1528 #
1528 1529 # property.__get__(self, None, cls) -> self
1529 1530 #
1530 1531 # The universal alternative is to traverse the mro manually
1531 1532 # searching for attrname in class dicts.
1532 1533 attr = getattr(type(obj), attrname)
1533 1534 except AttributeError:
1534 1535 pass
1535 1536 else:
1536 1537 # This relies on the fact that data descriptors (with both
1537 1538 # __get__ & __set__ magic methods) take precedence over
1538 1539 # instance-level attributes:
1539 1540 #
1540 1541 # class A(object):
1541 1542 # @property
1542 1543 # def foobar(self): return 123
1543 1544 # a = A()
1544 1545 # a.__dict__['foobar'] = 345
1545 1546 # a.foobar # == 123
1546 1547 #
1547 1548 # So, a property may be returned right away.
1548 1549 if isinstance(attr, property):
1549 1550 return attr
1550 1551
1551 1552 # Nothing helped, fall back.
1552 1553 return getattr(obj, attrname)
1553 1554
1554 1555 def _object_find(self, oname, namespaces=None):
1555 1556 """Find an object and return a struct with info about it."""
1556 1557 return Struct(self._ofind(oname, namespaces))
1557 1558
1558 1559 def _inspect(self, meth, oname, namespaces=None, **kw):
1559 1560 """Generic interface to the inspector system.
1560 1561
1561 1562 This function is meant to be called by pdef, pdoc & friends."""
1562 1563 info = self._object_find(oname, namespaces)
1563 1564 if info.found:
1564 1565 pmethod = getattr(self.inspector, meth)
1565 1566 formatter = format_screen if info.ismagic else None
1566 1567 if meth == 'pdoc':
1567 1568 pmethod(info.obj, oname, formatter)
1568 1569 elif meth == 'pinfo':
1569 1570 pmethod(info.obj, oname, formatter, info, **kw)
1570 1571 else:
1571 1572 pmethod(info.obj, oname)
1572 1573 else:
1573 1574 print('Object `%s` not found.' % oname)
1574 1575 return 'not found' # so callers can take other action
1575 1576
1576 1577 def object_inspect(self, oname, detail_level=0):
1577 1578 """Get object info about oname"""
1578 1579 with self.builtin_trap:
1579 1580 info = self._object_find(oname)
1580 1581 if info.found:
1581 1582 return self.inspector.info(info.obj, oname, info=info,
1582 1583 detail_level=detail_level
1583 1584 )
1584 1585 else:
1585 1586 return oinspect.object_info(name=oname, found=False)
1586 1587
1587 1588 def object_inspect_text(self, oname, detail_level=0):
1588 1589 """Get object info as formatted text"""
1589 1590 with self.builtin_trap:
1590 1591 info = self._object_find(oname)
1591 1592 if info.found:
1592 1593 return self.inspector._format_info(info.obj, oname, info=info,
1593 1594 detail_level=detail_level
1594 1595 )
1595 1596 else:
1596 1597 raise KeyError(oname)
1597 1598
1598 1599 #-------------------------------------------------------------------------
1599 1600 # Things related to history management
1600 1601 #-------------------------------------------------------------------------
1601 1602
1602 1603 def init_history(self):
1603 1604 """Sets up the command history, and starts regular autosaves."""
1604 1605 self.history_manager = HistoryManager(shell=self, parent=self)
1605 1606 self.configurables.append(self.history_manager)
1606 1607
1607 1608 #-------------------------------------------------------------------------
1608 1609 # Things related to exception handling and tracebacks (not debugging)
1609 1610 #-------------------------------------------------------------------------
1610 1611
1611 1612 def init_traceback_handlers(self, custom_exceptions):
1612 1613 # Syntax error handler.
1613 1614 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1614 1615
1615 1616 # The interactive one is initialized with an offset, meaning we always
1616 1617 # want to remove the topmost item in the traceback, which is our own
1617 1618 # internal code. Valid modes: ['Plain','Context','Verbose']
1618 1619 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1619 1620 color_scheme='NoColor',
1620 1621 tb_offset = 1,
1621 1622 check_cache=check_linecache_ipython)
1622 1623
1623 1624 # The instance will store a pointer to the system-wide exception hook,
1624 1625 # so that runtime code (such as magics) can access it. This is because
1625 1626 # during the read-eval loop, it may get temporarily overwritten.
1626 1627 self.sys_excepthook = sys.excepthook
1627 1628
1628 1629 # and add any custom exception handlers the user may have specified
1629 1630 self.set_custom_exc(*custom_exceptions)
1630 1631
1631 1632 # Set the exception mode
1632 1633 self.InteractiveTB.set_mode(mode=self.xmode)
1633 1634
1634 1635 def set_custom_exc(self, exc_tuple, handler):
1635 1636 """set_custom_exc(exc_tuple,handler)
1636 1637
1637 1638 Set a custom exception handler, which will be called if any of the
1638 1639 exceptions in exc_tuple occur in the mainloop (specifically, in the
1639 1640 run_code() method).
1640 1641
1641 1642 Parameters
1642 1643 ----------
1643 1644
1644 1645 exc_tuple : tuple of exception classes
1645 1646 A *tuple* of exception classes, for which to call the defined
1646 1647 handler. It is very important that you use a tuple, and NOT A
1647 1648 LIST here, because of the way Python's except statement works. If
1648 1649 you only want to trap a single exception, use a singleton tuple::
1649 1650
1650 1651 exc_tuple == (MyCustomException,)
1651 1652
1652 1653 handler : callable
1653 1654 handler must have the following signature::
1654 1655
1655 1656 def my_handler(self, etype, value, tb, tb_offset=None):
1656 1657 ...
1657 1658 return structured_traceback
1658 1659
1659 1660 Your handler must return a structured traceback (a list of strings),
1660 1661 or None.
1661 1662
1662 1663 This will be made into an instance method (via types.MethodType)
1663 1664 of IPython itself, and it will be called if any of the exceptions
1664 1665 listed in the exc_tuple are caught. If the handler is None, an
1665 1666 internal basic one is used, which just prints basic info.
1666 1667
1667 1668 To protect IPython from crashes, if your handler ever raises an
1668 1669 exception or returns an invalid result, it will be immediately
1669 1670 disabled.
1670 1671
1671 1672 WARNING: by putting in your own exception handler into IPython's main
1672 1673 execution loop, you run a very good chance of nasty crashes. This
1673 1674 facility should only be used if you really know what you are doing."""
1674 1675
1675 1676 assert type(exc_tuple)==type(()) , \
1676 1677 "The custom exceptions must be given AS A TUPLE."
1677 1678
1678 1679 def dummy_handler(self,etype,value,tb,tb_offset=None):
1679 1680 print('*** Simple custom exception handler ***')
1680 1681 print('Exception type :',etype)
1681 1682 print('Exception value:',value)
1682 1683 print('Traceback :',tb)
1683 1684 #print 'Source code :','\n'.join(self.buffer)
1684 1685
1685 1686 def validate_stb(stb):
1686 1687 """validate structured traceback return type
1687 1688
1688 1689 return type of CustomTB *should* be a list of strings, but allow
1689 1690 single strings or None, which are harmless.
1690 1691
1691 1692 This function will *always* return a list of strings,
1692 1693 and will raise a TypeError if stb is inappropriate.
1693 1694 """
1694 1695 msg = "CustomTB must return list of strings, not %r" % stb
1695 1696 if stb is None:
1696 1697 return []
1697 1698 elif isinstance(stb, string_types):
1698 1699 return [stb]
1699 1700 elif not isinstance(stb, list):
1700 1701 raise TypeError(msg)
1701 1702 # it's a list
1702 1703 for line in stb:
1703 1704 # check every element
1704 1705 if not isinstance(line, string_types):
1705 1706 raise TypeError(msg)
1706 1707 return stb
1707 1708
1708 1709 if handler is None:
1709 1710 wrapped = dummy_handler
1710 1711 else:
1711 1712 def wrapped(self,etype,value,tb,tb_offset=None):
1712 1713 """wrap CustomTB handler, to protect IPython from user code
1713 1714
1714 1715 This makes it harder (but not impossible) for custom exception
1715 1716 handlers to crash IPython.
1716 1717 """
1717 1718 try:
1718 1719 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1719 1720 return validate_stb(stb)
1720 1721 except:
1721 1722 # clear custom handler immediately
1722 1723 self.set_custom_exc((), None)
1723 1724 print("Custom TB Handler failed, unregistering", file=io.stderr)
1724 1725 # show the exception in handler first
1725 1726 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1726 1727 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1727 1728 print("The original exception:", file=io.stdout)
1728 1729 stb = self.InteractiveTB.structured_traceback(
1729 1730 (etype,value,tb), tb_offset=tb_offset
1730 1731 )
1731 1732 return stb
1732 1733
1733 1734 self.CustomTB = types.MethodType(wrapped,self)
1734 1735 self.custom_exceptions = exc_tuple
1735 1736
1736 1737 def excepthook(self, etype, value, tb):
1737 1738 """One more defense for GUI apps that call sys.excepthook.
1738 1739
1739 1740 GUI frameworks like wxPython trap exceptions and call
1740 1741 sys.excepthook themselves. I guess this is a feature that
1741 1742 enables them to keep running after exceptions that would
1742 1743 otherwise kill their mainloop. This is a bother for IPython
1743 1744 which excepts to catch all of the program exceptions with a try:
1744 1745 except: statement.
1745 1746
1746 1747 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1747 1748 any app directly invokes sys.excepthook, it will look to the user like
1748 1749 IPython crashed. In order to work around this, we can disable the
1749 1750 CrashHandler and replace it with this excepthook instead, which prints a
1750 1751 regular traceback using our InteractiveTB. In this fashion, apps which
1751 1752 call sys.excepthook will generate a regular-looking exception from
1752 1753 IPython, and the CrashHandler will only be triggered by real IPython
1753 1754 crashes.
1754 1755
1755 1756 This hook should be used sparingly, only in places which are not likely
1756 1757 to be true IPython errors.
1757 1758 """
1758 1759 self.showtraceback((etype, value, tb), tb_offset=0)
1759 1760
1760 1761 def _get_exc_info(self, exc_tuple=None):
1761 1762 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1762 1763
1763 1764 Ensures sys.last_type,value,traceback hold the exc_info we found,
1764 1765 from whichever source.
1765 1766
1766 1767 raises ValueError if none of these contain any information
1767 1768 """
1768 1769 if exc_tuple is None:
1769 1770 etype, value, tb = sys.exc_info()
1770 1771 else:
1771 1772 etype, value, tb = exc_tuple
1772 1773
1773 1774 if etype is None:
1774 1775 if hasattr(sys, 'last_type'):
1775 1776 etype, value, tb = sys.last_type, sys.last_value, \
1776 1777 sys.last_traceback
1777 1778
1778 1779 if etype is None:
1779 1780 raise ValueError("No exception to find")
1780 1781
1781 1782 # Now store the exception info in sys.last_type etc.
1782 1783 # WARNING: these variables are somewhat deprecated and not
1783 1784 # necessarily safe to use in a threaded environment, but tools
1784 1785 # like pdb depend on their existence, so let's set them. If we
1785 1786 # find problems in the field, we'll need to revisit their use.
1786 1787 sys.last_type = etype
1787 1788 sys.last_value = value
1788 1789 sys.last_traceback = tb
1789 1790
1790 1791 return etype, value, tb
1791 1792
1792 1793 def show_usage_error(self, exc):
1793 1794 """Show a short message for UsageErrors
1794 1795
1795 1796 These are special exceptions that shouldn't show a traceback.
1796 1797 """
1797 1798 self.write_err("UsageError: %s" % exc)
1798 1799
1799 1800 def get_exception_only(self, exc_tuple=None):
1800 1801 """
1801 1802 Return as a string (ending with a newline) the exception that
1802 1803 just occurred, without any traceback.
1803 1804 """
1804 1805 etype, value, tb = self._get_exc_info(exc_tuple)
1805 1806 msg = traceback.format_exception_only(etype, value)
1806 1807 return ''.join(msg)
1807 1808
1808 1809 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1809 1810 exception_only=False):
1810 1811 """Display the exception that just occurred.
1811 1812
1812 1813 If nothing is known about the exception, this is the method which
1813 1814 should be used throughout the code for presenting user tracebacks,
1814 1815 rather than directly invoking the InteractiveTB object.
1815 1816
1816 1817 A specific showsyntaxerror() also exists, but this method can take
1817 1818 care of calling it if needed, so unless you are explicitly catching a
1818 1819 SyntaxError exception, don't try to analyze the stack manually and
1819 1820 simply call this method."""
1820 1821
1821 1822 try:
1822 1823 try:
1823 1824 etype, value, tb = self._get_exc_info(exc_tuple)
1824 1825 except ValueError:
1825 1826 self.write_err('No traceback available to show.\n')
1826 1827 return
1827 1828
1828 1829 if issubclass(etype, SyntaxError):
1829 1830 # Though this won't be called by syntax errors in the input
1830 1831 # line, there may be SyntaxError cases with imported code.
1831 1832 self.showsyntaxerror(filename)
1832 1833 elif etype is UsageError:
1833 1834 self.show_usage_error(value)
1834 1835 else:
1835 1836 if exception_only:
1836 1837 stb = ['An exception has occurred, use %tb to see '
1837 1838 'the full traceback.\n']
1838 1839 stb.extend(self.InteractiveTB.get_exception_only(etype,
1839 1840 value))
1840 1841 else:
1841 1842 try:
1842 1843 # Exception classes can customise their traceback - we
1843 1844 # use this in IPython.parallel for exceptions occurring
1844 1845 # in the engines. This should return a list of strings.
1845 1846 stb = value._render_traceback_()
1846 1847 except Exception:
1847 1848 stb = self.InteractiveTB.structured_traceback(etype,
1848 1849 value, tb, tb_offset=tb_offset)
1849 1850
1850 1851 self._showtraceback(etype, value, stb)
1851 1852 if self.call_pdb:
1852 1853 # drop into debugger
1853 1854 self.debugger(force=True)
1854 1855 return
1855 1856
1856 1857 # Actually show the traceback
1857 1858 self._showtraceback(etype, value, stb)
1858 1859
1859 1860 except KeyboardInterrupt:
1860 1861 self.write_err('\n' + self.get_exception_only())
1861 1862
1862 1863 def _showtraceback(self, etype, evalue, stb):
1863 1864 """Actually show a traceback.
1864 1865
1865 1866 Subclasses may override this method to put the traceback on a different
1866 1867 place, like a side channel.
1867 1868 """
1868 1869 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1869 1870
1870 1871 def showsyntaxerror(self, filename=None):
1871 1872 """Display the syntax error that just occurred.
1872 1873
1873 1874 This doesn't display a stack trace because there isn't one.
1874 1875
1875 1876 If a filename is given, it is stuffed in the exception instead
1876 1877 of what was there before (because Python's parser always uses
1877 1878 "<string>" when reading from a string).
1878 1879 """
1879 1880 etype, value, last_traceback = self._get_exc_info()
1880 1881
1881 1882 if filename and issubclass(etype, SyntaxError):
1882 1883 try:
1883 1884 value.filename = filename
1884 1885 except:
1885 1886 # Not the format we expect; leave it alone
1886 1887 pass
1887 1888
1888 1889 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1889 1890 self._showtraceback(etype, value, stb)
1890 1891
1891 1892 # This is overridden in TerminalInteractiveShell to show a message about
1892 1893 # the %paste magic.
1893 1894 def showindentationerror(self):
1894 1895 """Called by run_cell when there's an IndentationError in code entered
1895 1896 at the prompt.
1896 1897
1897 1898 This is overridden in TerminalInteractiveShell to show a message about
1898 1899 the %paste magic."""
1899 1900 self.showsyntaxerror()
1900 1901
1901 1902 #-------------------------------------------------------------------------
1902 1903 # Things related to readline
1903 1904 #-------------------------------------------------------------------------
1904 1905
1905 1906 def init_readline(self):
1906 1907 """Command history completion/saving/reloading."""
1907 1908
1908 1909 if self.readline_use:
1909 1910 import IPython.utils.rlineimpl as readline
1910 1911
1911 1912 self.rl_next_input = None
1912 1913 self.rl_do_indent = False
1913 1914
1914 1915 if not self.readline_use or not readline.have_readline:
1915 1916 self.has_readline = False
1916 1917 self.readline = None
1917 1918 # Set a number of methods that depend on readline to be no-op
1918 1919 self.readline_no_record = no_op_context
1919 1920 self.set_readline_completer = no_op
1920 1921 self.set_custom_completer = no_op
1921 1922 if self.readline_use:
1922 1923 warn('Readline services not available or not loaded.')
1923 1924 else:
1924 1925 self.has_readline = True
1925 1926 self.readline = readline
1926 1927 sys.modules['readline'] = readline
1927 1928
1928 1929 # Platform-specific configuration
1929 1930 if os.name == 'nt':
1930 1931 # FIXME - check with Frederick to see if we can harmonize
1931 1932 # naming conventions with pyreadline to avoid this
1932 1933 # platform-dependent check
1933 1934 self.readline_startup_hook = readline.set_pre_input_hook
1934 1935 else:
1935 1936 self.readline_startup_hook = readline.set_startup_hook
1936 1937
1937 1938 # Readline config order:
1938 1939 # - IPython config (default value)
1939 1940 # - custom inputrc
1940 1941 # - IPython config (user customized)
1941 1942
1942 1943 # load IPython config before inputrc if default
1943 1944 # skip if libedit because parse_and_bind syntax is different
1944 1945 if not self._custom_readline_config and not readline.uses_libedit:
1945 1946 for rlcommand in self.readline_parse_and_bind:
1946 1947 readline.parse_and_bind(rlcommand)
1947 1948
1948 1949 # Load user's initrc file (readline config)
1949 1950 # Or if libedit is used, load editrc.
1950 1951 inputrc_name = os.environ.get('INPUTRC')
1951 1952 if inputrc_name is None:
1952 1953 inputrc_name = '.inputrc'
1953 1954 if readline.uses_libedit:
1954 1955 inputrc_name = '.editrc'
1955 1956 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1956 1957 if os.path.isfile(inputrc_name):
1957 1958 try:
1958 1959 readline.read_init_file(inputrc_name)
1959 1960 except:
1960 1961 warn('Problems reading readline initialization file <%s>'
1961 1962 % inputrc_name)
1962 1963
1963 1964 # load IPython config after inputrc if user has customized
1964 1965 if self._custom_readline_config:
1965 1966 for rlcommand in self.readline_parse_and_bind:
1966 1967 readline.parse_and_bind(rlcommand)
1967 1968
1968 1969 # Remove some chars from the delimiters list. If we encounter
1969 1970 # unicode chars, discard them.
1970 1971 delims = readline.get_completer_delims()
1971 1972 if not py3compat.PY3:
1972 1973 delims = delims.encode("ascii", "ignore")
1973 1974 for d in self.readline_remove_delims:
1974 1975 delims = delims.replace(d, "")
1975 1976 delims = delims.replace(ESC_MAGIC, '')
1976 1977 readline.set_completer_delims(delims)
1977 1978 # Store these so we can restore them if something like rpy2 modifies
1978 1979 # them.
1979 1980 self.readline_delims = delims
1980 1981 # otherwise we end up with a monster history after a while:
1981 1982 readline.set_history_length(self.history_length)
1982 1983
1983 1984 self.refill_readline_hist()
1984 1985 self.readline_no_record = ReadlineNoRecord(self)
1985 1986
1986 1987 # Configure auto-indent for all platforms
1987 1988 self.set_autoindent(self.autoindent)
1988 1989
1989 1990 def refill_readline_hist(self):
1990 1991 # Load the last 1000 lines from history
1991 1992 self.readline.clear_history()
1992 1993 stdin_encoding = sys.stdin.encoding or "utf-8"
1993 1994 last_cell = u""
1994 1995 for _, _, cell in self.history_manager.get_tail(1000,
1995 1996 include_latest=True):
1996 1997 # Ignore blank lines and consecutive duplicates
1997 1998 cell = cell.rstrip()
1998 1999 if cell and (cell != last_cell):
1999 2000 try:
2000 2001 if self.multiline_history:
2001 2002 self.readline.add_history(py3compat.unicode_to_str(cell,
2002 2003 stdin_encoding))
2003 2004 else:
2004 2005 for line in cell.splitlines():
2005 2006 self.readline.add_history(py3compat.unicode_to_str(line,
2006 2007 stdin_encoding))
2007 2008 last_cell = cell
2008 2009
2009 2010 except TypeError:
2010 2011 # The history DB can get corrupted so it returns strings
2011 2012 # containing null bytes, which readline objects to.
2012 2013 continue
2013 2014
2014 2015 @skip_doctest
2015 2016 def set_next_input(self, s, replace=False):
2016 2017 """ Sets the 'default' input string for the next command line.
2017 2018
2018 2019 Requires readline.
2019 2020
2020 2021 Example::
2021 2022
2022 2023 In [1]: _ip.set_next_input("Hello Word")
2023 2024 In [2]: Hello Word_ # cursor is here
2024 2025 """
2025 2026 self.rl_next_input = py3compat.cast_bytes_py2(s)
2026 2027
2027 2028 # Maybe move this to the terminal subclass?
2028 2029 def pre_readline(self):
2029 2030 """readline hook to be used at the start of each line.
2030 2031
2031 2032 Currently it handles auto-indent only."""
2032 2033
2033 2034 if self.rl_do_indent:
2034 2035 self.readline.insert_text(self._indent_current_str())
2035 2036 if self.rl_next_input is not None:
2036 2037 self.readline.insert_text(self.rl_next_input)
2037 2038 self.rl_next_input = None
2038 2039
2039 2040 def _indent_current_str(self):
2040 2041 """return the current level of indentation as a string"""
2041 2042 return self.input_splitter.indent_spaces * ' '
2042 2043
2043 2044 #-------------------------------------------------------------------------
2044 2045 # Things related to text completion
2045 2046 #-------------------------------------------------------------------------
2046 2047
2047 2048 def init_completer(self):
2048 2049 """Initialize the completion machinery.
2049 2050
2050 2051 This creates completion machinery that can be used by client code,
2051 2052 either interactively in-process (typically triggered by the readline
2052 2053 library), programatically (such as in test suites) or out-of-prcess
2053 2054 (typically over the network by remote frontends).
2054 2055 """
2055 2056 from IPython.core.completer import IPCompleter
2056 2057 from IPython.core.completerlib import (module_completer,
2057 2058 magic_run_completer, cd_completer, reset_completer)
2058 2059
2059 2060 self.Completer = IPCompleter(shell=self,
2060 2061 namespace=self.user_ns,
2061 2062 global_namespace=self.user_global_ns,
2062 2063 use_readline=self.has_readline,
2063 2064 parent=self,
2064 2065 )
2065 2066 self.configurables.append(self.Completer)
2066 2067
2067 2068 # Add custom completers to the basic ones built into IPCompleter
2068 2069 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2069 2070 self.strdispatchers['complete_command'] = sdisp
2070 2071 self.Completer.custom_completers = sdisp
2071 2072
2072 2073 self.set_hook('complete_command', module_completer, str_key = 'import')
2073 2074 self.set_hook('complete_command', module_completer, str_key = 'from')
2074 2075 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2075 2076 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2076 2077 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2077 2078
2078 2079 # Only configure readline if we truly are using readline. IPython can
2079 2080 # do tab-completion over the network, in GUIs, etc, where readline
2080 2081 # itself may be absent
2081 2082 if self.has_readline:
2082 2083 self.set_readline_completer()
2083 2084
2084 2085 def complete(self, text, line=None, cursor_pos=None):
2085 2086 """Return the completed text and a list of completions.
2086 2087
2087 2088 Parameters
2088 2089 ----------
2089 2090
2090 2091 text : string
2091 2092 A string of text to be completed on. It can be given as empty and
2092 2093 instead a line/position pair are given. In this case, the
2093 2094 completer itself will split the line like readline does.
2094 2095
2095 2096 line : string, optional
2096 2097 The complete line that text is part of.
2097 2098
2098 2099 cursor_pos : int, optional
2099 2100 The position of the cursor on the input line.
2100 2101
2101 2102 Returns
2102 2103 -------
2103 2104 text : string
2104 2105 The actual text that was completed.
2105 2106
2106 2107 matches : list
2107 2108 A sorted list with all possible completions.
2108 2109
2109 2110 The optional arguments allow the completion to take more context into
2110 2111 account, and are part of the low-level completion API.
2111 2112
2112 2113 This is a wrapper around the completion mechanism, similar to what
2113 2114 readline does at the command line when the TAB key is hit. By
2114 2115 exposing it as a method, it can be used by other non-readline
2115 2116 environments (such as GUIs) for text completion.
2116 2117
2117 2118 Simple usage example:
2118 2119
2119 2120 In [1]: x = 'hello'
2120 2121
2121 2122 In [2]: _ip.complete('x.l')
2122 2123 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2123 2124 """
2124 2125
2125 2126 # Inject names into __builtin__ so we can complete on the added names.
2126 2127 with self.builtin_trap:
2127 2128 return self.Completer.complete(text, line, cursor_pos)
2128 2129
2129 2130 def set_custom_completer(self, completer, pos=0):
2130 2131 """Adds a new custom completer function.
2131 2132
2132 2133 The position argument (defaults to 0) is the index in the completers
2133 2134 list where you want the completer to be inserted."""
2134 2135
2135 2136 newcomp = types.MethodType(completer,self.Completer)
2136 2137 self.Completer.matchers.insert(pos,newcomp)
2137 2138
2138 2139 def set_readline_completer(self):
2139 2140 """Reset readline's completer to be our own."""
2140 2141 self.readline.set_completer(self.Completer.rlcomplete)
2141 2142
2142 2143 def set_completer_frame(self, frame=None):
2143 2144 """Set the frame of the completer."""
2144 2145 if frame:
2145 2146 self.Completer.namespace = frame.f_locals
2146 2147 self.Completer.global_namespace = frame.f_globals
2147 2148 else:
2148 2149 self.Completer.namespace = self.user_ns
2149 2150 self.Completer.global_namespace = self.user_global_ns
2150 2151
2151 2152 #-------------------------------------------------------------------------
2152 2153 # Things related to magics
2153 2154 #-------------------------------------------------------------------------
2154 2155
2155 2156 def init_magics(self):
2156 2157 from IPython.core import magics as m
2157 2158 self.magics_manager = magic.MagicsManager(shell=self,
2158 2159 parent=self,
2159 2160 user_magics=m.UserMagics(self))
2160 2161 self.configurables.append(self.magics_manager)
2161 2162
2162 2163 # Expose as public API from the magics manager
2163 2164 self.register_magics = self.magics_manager.register
2164 2165 self.define_magic = self.magics_manager.define_magic
2165 2166
2166 2167 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2167 2168 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2168 2169 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2169 2170 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2170 2171 )
2171 2172
2172 2173 # Register Magic Aliases
2173 2174 mman = self.magics_manager
2174 2175 # FIXME: magic aliases should be defined by the Magics classes
2175 2176 # or in MagicsManager, not here
2176 2177 mman.register_alias('ed', 'edit')
2177 2178 mman.register_alias('hist', 'history')
2178 2179 mman.register_alias('rep', 'recall')
2179 2180 mman.register_alias('SVG', 'svg', 'cell')
2180 2181 mman.register_alias('HTML', 'html', 'cell')
2181 2182 mman.register_alias('file', 'writefile', 'cell')
2182 2183
2183 2184 # FIXME: Move the color initialization to the DisplayHook, which
2184 2185 # should be split into a prompt manager and displayhook. We probably
2185 2186 # even need a centralize colors management object.
2186 2187 self.magic('colors %s' % self.colors)
2187 2188
2188 2189 # Defined here so that it's included in the documentation
2189 2190 @functools.wraps(magic.MagicsManager.register_function)
2190 2191 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2191 2192 self.magics_manager.register_function(func,
2192 2193 magic_kind=magic_kind, magic_name=magic_name)
2193 2194
2194 2195 def run_line_magic(self, magic_name, line):
2195 2196 """Execute the given line magic.
2196 2197
2197 2198 Parameters
2198 2199 ----------
2199 2200 magic_name : str
2200 2201 Name of the desired magic function, without '%' prefix.
2201 2202
2202 2203 line : str
2203 2204 The rest of the input line as a single string.
2204 2205 """
2205 2206 fn = self.find_line_magic(magic_name)
2206 2207 if fn is None:
2207 2208 cm = self.find_cell_magic(magic_name)
2208 2209 etpl = "Line magic function `%%%s` not found%s."
2209 2210 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2210 2211 'did you mean that instead?)' % magic_name )
2211 2212 error(etpl % (magic_name, extra))
2212 2213 else:
2213 2214 # Note: this is the distance in the stack to the user's frame.
2214 2215 # This will need to be updated if the internal calling logic gets
2215 2216 # refactored, or else we'll be expanding the wrong variables.
2216 2217 stack_depth = 2
2217 2218 magic_arg_s = self.var_expand(line, stack_depth)
2218 2219 # Put magic args in a list so we can call with f(*a) syntax
2219 2220 args = [magic_arg_s]
2220 2221 kwargs = {}
2221 2222 # Grab local namespace if we need it:
2222 2223 if getattr(fn, "needs_local_scope", False):
2223 2224 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2224 2225 with self.builtin_trap:
2225 2226 result = fn(*args,**kwargs)
2226 2227 return result
2227 2228
2228 2229 def run_cell_magic(self, magic_name, line, cell):
2229 2230 """Execute the given cell magic.
2230 2231
2231 2232 Parameters
2232 2233 ----------
2233 2234 magic_name : str
2234 2235 Name of the desired magic function, without '%' prefix.
2235 2236
2236 2237 line : str
2237 2238 The rest of the first input line as a single string.
2238 2239
2239 2240 cell : str
2240 2241 The body of the cell as a (possibly multiline) string.
2241 2242 """
2242 2243 fn = self.find_cell_magic(magic_name)
2243 2244 if fn is None:
2244 2245 lm = self.find_line_magic(magic_name)
2245 2246 etpl = "Cell magic `%%{0}` not found{1}."
2246 2247 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2247 2248 'did you mean that instead?)'.format(magic_name))
2248 2249 error(etpl.format(magic_name, extra))
2249 2250 elif cell == '':
2250 2251 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2251 2252 if self.find_line_magic(magic_name) is not None:
2252 2253 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2253 2254 raise UsageError(message)
2254 2255 else:
2255 2256 # Note: this is the distance in the stack to the user's frame.
2256 2257 # This will need to be updated if the internal calling logic gets
2257 2258 # refactored, or else we'll be expanding the wrong variables.
2258 2259 stack_depth = 2
2259 2260 magic_arg_s = self.var_expand(line, stack_depth)
2260 2261 with self.builtin_trap:
2261 2262 result = fn(magic_arg_s, cell)
2262 2263 return result
2263 2264
2264 2265 def find_line_magic(self, magic_name):
2265 2266 """Find and return a line magic by name.
2266 2267
2267 2268 Returns None if the magic isn't found."""
2268 2269 return self.magics_manager.magics['line'].get(magic_name)
2269 2270
2270 2271 def find_cell_magic(self, magic_name):
2271 2272 """Find and return a cell magic by name.
2272 2273
2273 2274 Returns None if the magic isn't found."""
2274 2275 return self.magics_manager.magics['cell'].get(magic_name)
2275 2276
2276 2277 def find_magic(self, magic_name, magic_kind='line'):
2277 2278 """Find and return a magic of the given type by name.
2278 2279
2279 2280 Returns None if the magic isn't found."""
2280 2281 return self.magics_manager.magics[magic_kind].get(magic_name)
2281 2282
2282 2283 def magic(self, arg_s):
2283 2284 """DEPRECATED. Use run_line_magic() instead.
2284 2285
2285 2286 Call a magic function by name.
2286 2287
2287 2288 Input: a string containing the name of the magic function to call and
2288 2289 any additional arguments to be passed to the magic.
2289 2290
2290 2291 magic('name -opt foo bar') is equivalent to typing at the ipython
2291 2292 prompt:
2292 2293
2293 2294 In[1]: %name -opt foo bar
2294 2295
2295 2296 To call a magic without arguments, simply use magic('name').
2296 2297
2297 2298 This provides a proper Python function to call IPython's magics in any
2298 2299 valid Python code you can type at the interpreter, including loops and
2299 2300 compound statements.
2300 2301 """
2301 2302 # TODO: should we issue a loud deprecation warning here?
2302 2303 magic_name, _, magic_arg_s = arg_s.partition(' ')
2303 2304 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2304 2305 return self.run_line_magic(magic_name, magic_arg_s)
2305 2306
2306 2307 #-------------------------------------------------------------------------
2307 2308 # Things related to macros
2308 2309 #-------------------------------------------------------------------------
2309 2310
2310 2311 def define_macro(self, name, themacro):
2311 2312 """Define a new macro
2312 2313
2313 2314 Parameters
2314 2315 ----------
2315 2316 name : str
2316 2317 The name of the macro.
2317 2318 themacro : str or Macro
2318 2319 The action to do upon invoking the macro. If a string, a new
2319 2320 Macro object is created by passing the string to it.
2320 2321 """
2321 2322
2322 2323 from IPython.core import macro
2323 2324
2324 2325 if isinstance(themacro, string_types):
2325 2326 themacro = macro.Macro(themacro)
2326 2327 if not isinstance(themacro, macro.Macro):
2327 2328 raise ValueError('A macro must be a string or a Macro instance.')
2328 2329 self.user_ns[name] = themacro
2329 2330
2330 2331 #-------------------------------------------------------------------------
2331 2332 # Things related to the running of system commands
2332 2333 #-------------------------------------------------------------------------
2333 2334
2334 2335 def system_piped(self, cmd):
2335 2336 """Call the given cmd in a subprocess, piping stdout/err
2336 2337
2337 2338 Parameters
2338 2339 ----------
2339 2340 cmd : str
2340 2341 Command to execute (can not end in '&', as background processes are
2341 2342 not supported. Should not be a command that expects input
2342 2343 other than simple text.
2343 2344 """
2344 2345 if cmd.rstrip().endswith('&'):
2345 2346 # this is *far* from a rigorous test
2346 2347 # We do not support backgrounding processes because we either use
2347 2348 # pexpect or pipes to read from. Users can always just call
2348 2349 # os.system() or use ip.system=ip.system_raw
2349 2350 # if they really want a background process.
2350 2351 raise OSError("Background processes not supported.")
2351 2352
2352 2353 # we explicitly do NOT return the subprocess status code, because
2353 2354 # a non-None value would trigger :func:`sys.displayhook` calls.
2354 2355 # Instead, we store the exit_code in user_ns.
2355 2356 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2356 2357
2357 2358 def system_raw(self, cmd):
2358 2359 """Call the given cmd in a subprocess using os.system on Windows or
2359 2360 subprocess.call using the system shell on other platforms.
2360 2361
2361 2362 Parameters
2362 2363 ----------
2363 2364 cmd : str
2364 2365 Command to execute.
2365 2366 """
2366 2367 cmd = self.var_expand(cmd, depth=1)
2367 2368 # protect os.system from UNC paths on Windows, which it can't handle:
2368 2369 if sys.platform == 'win32':
2369 2370 from IPython.utils._process_win32 import AvoidUNCPath
2370 2371 with AvoidUNCPath() as path:
2371 2372 if path is not None:
2372 2373 cmd = '"pushd %s &&"%s' % (path, cmd)
2373 2374 cmd = py3compat.unicode_to_str(cmd)
2374 2375 try:
2375 2376 ec = os.system(cmd)
2376 2377 except KeyboardInterrupt:
2377 2378 self.write_err('\n' + self.get_exception_only())
2378 2379 ec = -2
2379 2380 else:
2380 2381 cmd = py3compat.unicode_to_str(cmd)
2381 2382 # For posix the result of the subprocess.call() below is an exit
2382 2383 # code, which by convention is zero for success, positive for
2383 2384 # program failure. Exit codes above 128 are reserved for signals,
2384 2385 # and the formula for converting a signal to an exit code is usually
2385 2386 # signal_number+128. To more easily differentiate between exit
2386 2387 # codes and signals, ipython uses negative numbers. For instance
2387 2388 # since control-c is signal 2 but exit code 130, ipython's
2388 2389 # _exit_code variable will read -2. Note that some shells like
2389 2390 # csh and fish don't follow sh/bash conventions for exit codes.
2390 2391 executable = os.environ.get('SHELL', None)
2391 2392 try:
2392 2393 # Use env shell instead of default /bin/sh
2393 2394 ec = subprocess.call(cmd, shell=True, executable=executable)
2394 2395 except KeyboardInterrupt:
2395 2396 # intercept control-C; a long traceback is not useful here
2396 2397 self.write_err('\n' + self.get_exception_only())
2397 2398 ec = 130
2398 2399 if ec > 128:
2399 2400 ec = -(ec - 128)
2400 2401
2401 2402 # We explicitly do NOT return the subprocess status code, because
2402 2403 # a non-None value would trigger :func:`sys.displayhook` calls.
2403 2404 # Instead, we store the exit_code in user_ns. Note the semantics
2404 2405 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2405 2406 # but raising SystemExit(_exit_code) will give status 254!
2406 2407 self.user_ns['_exit_code'] = ec
2407 2408
2408 2409 # use piped system by default, because it is better behaved
2409 2410 system = system_piped
2410 2411
2411 2412 def getoutput(self, cmd, split=True, depth=0):
2412 2413 """Get output (possibly including stderr) from a subprocess.
2413 2414
2414 2415 Parameters
2415 2416 ----------
2416 2417 cmd : str
2417 2418 Command to execute (can not end in '&', as background processes are
2418 2419 not supported.
2419 2420 split : bool, optional
2420 2421 If True, split the output into an IPython SList. Otherwise, an
2421 2422 IPython LSString is returned. These are objects similar to normal
2422 2423 lists and strings, with a few convenience attributes for easier
2423 2424 manipulation of line-based output. You can use '?' on them for
2424 2425 details.
2425 2426 depth : int, optional
2426 2427 How many frames above the caller are the local variables which should
2427 2428 be expanded in the command string? The default (0) assumes that the
2428 2429 expansion variables are in the stack frame calling this function.
2429 2430 """
2430 2431 if cmd.rstrip().endswith('&'):
2431 2432 # this is *far* from a rigorous test
2432 2433 raise OSError("Background processes not supported.")
2433 2434 out = getoutput(self.var_expand(cmd, depth=depth+1))
2434 2435 if split:
2435 2436 out = SList(out.splitlines())
2436 2437 else:
2437 2438 out = LSString(out)
2438 2439 return out
2439 2440
2440 2441 #-------------------------------------------------------------------------
2441 2442 # Things related to aliases
2442 2443 #-------------------------------------------------------------------------
2443 2444
2444 2445 def init_alias(self):
2445 2446 self.alias_manager = AliasManager(shell=self, parent=self)
2446 2447 self.configurables.append(self.alias_manager)
2447 2448
2448 2449 #-------------------------------------------------------------------------
2449 2450 # Things related to extensions
2450 2451 #-------------------------------------------------------------------------
2451 2452
2452 2453 def init_extension_manager(self):
2453 2454 self.extension_manager = ExtensionManager(shell=self, parent=self)
2454 2455 self.configurables.append(self.extension_manager)
2455 2456
2456 2457 #-------------------------------------------------------------------------
2457 2458 # Things related to payloads
2458 2459 #-------------------------------------------------------------------------
2459 2460
2460 2461 def init_payload(self):
2461 2462 self.payload_manager = PayloadManager(parent=self)
2462 2463 self.configurables.append(self.payload_manager)
2463 2464
2464 2465 #-------------------------------------------------------------------------
2465 2466 # Things related to the prefilter
2466 2467 #-------------------------------------------------------------------------
2467 2468
2468 2469 def init_prefilter(self):
2469 2470 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2470 2471 self.configurables.append(self.prefilter_manager)
2471 2472 # Ultimately this will be refactored in the new interpreter code, but
2472 2473 # for now, we should expose the main prefilter method (there's legacy
2473 2474 # code out there that may rely on this).
2474 2475 self.prefilter = self.prefilter_manager.prefilter_lines
2475 2476
2476 2477 def auto_rewrite_input(self, cmd):
2477 2478 """Print to the screen the rewritten form of the user's command.
2478 2479
2479 2480 This shows visual feedback by rewriting input lines that cause
2480 2481 automatic calling to kick in, like::
2481 2482
2482 2483 /f x
2483 2484
2484 2485 into::
2485 2486
2486 2487 ------> f(x)
2487 2488
2488 2489 after the user's input prompt. This helps the user understand that the
2489 2490 input line was transformed automatically by IPython.
2490 2491 """
2491 2492 if not self.show_rewritten_input:
2492 2493 return
2493 2494
2494 2495 rw = self.prompt_manager.render('rewrite') + cmd
2495 2496
2496 2497 try:
2497 2498 # plain ascii works better w/ pyreadline, on some machines, so
2498 2499 # we use it and only print uncolored rewrite if we have unicode
2499 2500 rw = str(rw)
2500 2501 print(rw, file=io.stdout)
2501 2502 except UnicodeEncodeError:
2502 2503 print("------> " + cmd)
2503 2504
2504 2505 #-------------------------------------------------------------------------
2505 2506 # Things related to extracting values/expressions from kernel and user_ns
2506 2507 #-------------------------------------------------------------------------
2507 2508
2508 2509 def _user_obj_error(self):
2509 2510 """return simple exception dict
2510 2511
2511 2512 for use in user_expressions
2512 2513 """
2513 2514
2514 2515 etype, evalue, tb = self._get_exc_info()
2515 2516 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2516 2517
2517 2518 exc_info = {
2518 2519 u'status' : 'error',
2519 2520 u'traceback' : stb,
2520 2521 u'ename' : unicode_type(etype.__name__),
2521 2522 u'evalue' : py3compat.safe_unicode(evalue),
2522 2523 }
2523 2524
2524 2525 return exc_info
2525 2526
2526 2527 def _format_user_obj(self, obj):
2527 2528 """format a user object to display dict
2528 2529
2529 2530 for use in user_expressions
2530 2531 """
2531 2532
2532 2533 data, md = self.display_formatter.format(obj)
2533 2534 value = {
2534 2535 'status' : 'ok',
2535 2536 'data' : data,
2536 2537 'metadata' : md,
2537 2538 }
2538 2539 return value
2539 2540
2540 2541 def user_expressions(self, expressions):
2541 2542 """Evaluate a dict of expressions in the user's namespace.
2542 2543
2543 2544 Parameters
2544 2545 ----------
2545 2546 expressions : dict
2546 2547 A dict with string keys and string values. The expression values
2547 2548 should be valid Python expressions, each of which will be evaluated
2548 2549 in the user namespace.
2549 2550
2550 2551 Returns
2551 2552 -------
2552 2553 A dict, keyed like the input expressions dict, with the rich mime-typed
2553 2554 display_data of each value.
2554 2555 """
2555 2556 out = {}
2556 2557 user_ns = self.user_ns
2557 2558 global_ns = self.user_global_ns
2558 2559
2559 2560 for key, expr in iteritems(expressions):
2560 2561 try:
2561 2562 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2562 2563 except:
2563 2564 value = self._user_obj_error()
2564 2565 out[key] = value
2565 2566 return out
2566 2567
2567 2568 #-------------------------------------------------------------------------
2568 2569 # Things related to the running of code
2569 2570 #-------------------------------------------------------------------------
2570 2571
2571 2572 def ex(self, cmd):
2572 2573 """Execute a normal python statement in user namespace."""
2573 2574 with self.builtin_trap:
2574 2575 exec(cmd, self.user_global_ns, self.user_ns)
2575 2576
2576 2577 def ev(self, expr):
2577 2578 """Evaluate python expression expr in user namespace.
2578 2579
2579 2580 Returns the result of evaluation
2580 2581 """
2581 2582 with self.builtin_trap:
2582 2583 return eval(expr, self.user_global_ns, self.user_ns)
2583 2584
2584 2585 def safe_execfile(self, fname, *where, **kw):
2585 2586 """A safe version of the builtin execfile().
2586 2587
2587 2588 This version will never throw an exception, but instead print
2588 2589 helpful error messages to the screen. This only works on pure
2589 2590 Python files with the .py extension.
2590 2591
2591 2592 Parameters
2592 2593 ----------
2593 2594 fname : string
2594 2595 The name of the file to be executed.
2595 2596 where : tuple
2596 2597 One or two namespaces, passed to execfile() as (globals,locals).
2597 2598 If only one is given, it is passed as both.
2598 2599 exit_ignore : bool (False)
2599 2600 If True, then silence SystemExit for non-zero status (it is always
2600 2601 silenced for zero status, as it is so common).
2601 2602 raise_exceptions : bool (False)
2602 2603 If True raise exceptions everywhere. Meant for testing.
2603 2604 shell_futures : bool (False)
2604 2605 If True, the code will share future statements with the interactive
2605 2606 shell. It will both be affected by previous __future__ imports, and
2606 2607 any __future__ imports in the code will affect the shell. If False,
2607 2608 __future__ imports are not shared in either direction.
2608 2609
2609 2610 """
2610 2611 kw.setdefault('exit_ignore', False)
2611 2612 kw.setdefault('raise_exceptions', False)
2612 2613 kw.setdefault('shell_futures', False)
2613 2614
2614 2615 fname = os.path.abspath(os.path.expanduser(fname))
2615 2616
2616 2617 # Make sure we can open the file
2617 2618 try:
2618 2619 with open(fname) as thefile:
2619 2620 pass
2620 2621 except:
2621 2622 warn('Could not open file <%s> for safe execution.' % fname)
2622 2623 return
2623 2624
2624 2625 # Find things also in current directory. This is needed to mimic the
2625 2626 # behavior of running a script from the system command line, where
2626 2627 # Python inserts the script's directory into sys.path
2627 2628 dname = os.path.dirname(fname)
2628 2629
2629 2630 with prepended_to_syspath(dname):
2630 2631 try:
2631 2632 glob, loc = (where + (None, ))[:2]
2632 2633 py3compat.execfile(
2633 2634 fname, glob, loc,
2634 2635 self.compile if kw['shell_futures'] else None)
2635 2636 except SystemExit as status:
2636 2637 # If the call was made with 0 or None exit status (sys.exit(0)
2637 2638 # or sys.exit() ), don't bother showing a traceback, as both of
2638 2639 # these are considered normal by the OS:
2639 2640 # > python -c'import sys;sys.exit(0)'; echo $?
2640 2641 # 0
2641 2642 # > python -c'import sys;sys.exit()'; echo $?
2642 2643 # 0
2643 2644 # For other exit status, we show the exception unless
2644 2645 # explicitly silenced, but only in short form.
2645 2646 if kw['raise_exceptions']:
2646 2647 raise
2647 2648 if status.code and not kw['exit_ignore']:
2648 2649 self.showtraceback(exception_only=True)
2649 2650 except:
2650 2651 if kw['raise_exceptions']:
2651 2652 raise
2652 2653 # tb offset is 2 because we wrap execfile
2653 2654 self.showtraceback(tb_offset=2)
2654 2655
2655 2656 def safe_execfile_ipy(self, fname, shell_futures=False):
2656 2657 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2657 2658
2658 2659 Parameters
2659 2660 ----------
2660 2661 fname : str
2661 2662 The name of the file to execute. The filename must have a
2662 2663 .ipy or .ipynb extension.
2663 2664 shell_futures : bool (False)
2664 2665 If True, the code will share future statements with the interactive
2665 2666 shell. It will both be affected by previous __future__ imports, and
2666 2667 any __future__ imports in the code will affect the shell. If False,
2667 2668 __future__ imports are not shared in either direction.
2668 2669 """
2669 2670 fname = os.path.abspath(os.path.expanduser(fname))
2670 2671
2671 2672 # Make sure we can open the file
2672 2673 try:
2673 2674 with open(fname) as thefile:
2674 2675 pass
2675 2676 except:
2676 2677 warn('Could not open file <%s> for safe execution.' % fname)
2677 2678 return
2678 2679
2679 2680 # Find things also in current directory. This is needed to mimic the
2680 2681 # behavior of running a script from the system command line, where
2681 2682 # Python inserts the script's directory into sys.path
2682 2683 dname = os.path.dirname(fname)
2683 2684
2684 2685 def get_cells():
2685 2686 """generator for sequence of code blocks to run"""
2686 2687 if fname.endswith('.ipynb'):
2687 2688 from IPython.nbformat import read
2688 2689 with io_open(fname) as f:
2689 2690 nb = read(f, as_version=4)
2690 2691 if not nb.cells:
2691 2692 return
2692 2693 for cell in nb.cells:
2693 2694 if cell.cell_type == 'code':
2694 2695 yield cell.source
2695 2696 else:
2696 2697 with open(fname) as f:
2697 2698 yield f.read()
2698 2699
2699 2700 with prepended_to_syspath(dname):
2700 2701 try:
2701 2702 for cell in get_cells():
2702 2703 # self.run_cell currently captures all exceptions
2703 2704 # raised in user code. It would be nice if there were
2704 2705 # versions of run_cell that did raise, so
2705 2706 # we could catch the errors.
2706 2707 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2707 2708 if not result.success:
2708 2709 break
2709 2710 except:
2710 2711 self.showtraceback()
2711 2712 warn('Unknown failure executing file: <%s>' % fname)
2712 2713
2713 2714 def safe_run_module(self, mod_name, where):
2714 2715 """A safe version of runpy.run_module().
2715 2716
2716 2717 This version will never throw an exception, but instead print
2717 2718 helpful error messages to the screen.
2718 2719
2719 2720 `SystemExit` exceptions with status code 0 or None are ignored.
2720 2721
2721 2722 Parameters
2722 2723 ----------
2723 2724 mod_name : string
2724 2725 The name of the module to be executed.
2725 2726 where : dict
2726 2727 The globals namespace.
2727 2728 """
2728 2729 try:
2729 2730 try:
2730 2731 where.update(
2731 2732 runpy.run_module(str(mod_name), run_name="__main__",
2732 2733 alter_sys=True)
2733 2734 )
2734 2735 except SystemExit as status:
2735 2736 if status.code:
2736 2737 raise
2737 2738 except:
2738 2739 self.showtraceback()
2739 2740 warn('Unknown failure executing module: <%s>' % mod_name)
2740 2741
2741 2742 def _run_cached_cell_magic(self, magic_name, line):
2742 2743 """Special method to call a cell magic with the data stored in self.
2743 2744 """
2744 2745 cell = self._current_cell_magic_body
2745 2746 self._current_cell_magic_body = None
2746 2747 return self.run_cell_magic(magic_name, line, cell)
2747 2748
2748 2749 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2749 2750 """Run a complete IPython cell.
2750 2751
2751 2752 Parameters
2752 2753 ----------
2753 2754 raw_cell : str
2754 2755 The code (including IPython code such as %magic functions) to run.
2755 2756 store_history : bool
2756 2757 If True, the raw and translated cell will be stored in IPython's
2757 2758 history. For user code calling back into IPython's machinery, this
2758 2759 should be set to False.
2759 2760 silent : bool
2760 2761 If True, avoid side-effects, such as implicit displayhooks and
2761 2762 and logging. silent=True forces store_history=False.
2762 2763 shell_futures : bool
2763 2764 If True, the code will share future statements with the interactive
2764 2765 shell. It will both be affected by previous __future__ imports, and
2765 2766 any __future__ imports in the code will affect the shell. If False,
2766 2767 __future__ imports are not shared in either direction.
2767 2768
2768 2769 Returns
2769 2770 -------
2770 2771 result : :class:`ExecutionResult`
2771 2772 """
2772 2773 result = ExecutionResult()
2773 2774
2774 2775 if (not raw_cell) or raw_cell.isspace():
2775 2776 return result
2776 2777
2777 2778 if silent:
2778 2779 store_history = False
2779 2780
2780 2781 if store_history:
2781 2782 result.execution_count = self.execution_count
2782 2783
2783 2784 def error_before_exec(value):
2784 2785 result.error_before_exec = value
2785 2786 return result
2786 2787
2787 2788 self.events.trigger('pre_execute')
2788 2789 if not silent:
2789 2790 self.events.trigger('pre_run_cell')
2790 2791
2791 2792 # If any of our input transformation (input_transformer_manager or
2792 2793 # prefilter_manager) raises an exception, we store it in this variable
2793 2794 # so that we can display the error after logging the input and storing
2794 2795 # it in the history.
2795 2796 preprocessing_exc_tuple = None
2796 2797 try:
2797 2798 # Static input transformations
2798 2799 cell = self.input_transformer_manager.transform_cell(raw_cell)
2799 2800 except SyntaxError:
2800 2801 preprocessing_exc_tuple = sys.exc_info()
2801 2802 cell = raw_cell # cell has to exist so it can be stored/logged
2802 2803 else:
2803 2804 if len(cell.splitlines()) == 1:
2804 2805 # Dynamic transformations - only applied for single line commands
2805 2806 with self.builtin_trap:
2806 2807 try:
2807 2808 # use prefilter_lines to handle trailing newlines
2808 2809 # restore trailing newline for ast.parse
2809 2810 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2810 2811 except Exception:
2811 2812 # don't allow prefilter errors to crash IPython
2812 2813 preprocessing_exc_tuple = sys.exc_info()
2813 2814
2814 2815 # Store raw and processed history
2815 2816 if store_history:
2816 2817 self.history_manager.store_inputs(self.execution_count,
2817 2818 cell, raw_cell)
2818 2819 if not silent:
2819 2820 self.logger.log(cell, raw_cell)
2820 2821
2821 2822 # Display the exception if input processing failed.
2822 2823 if preprocessing_exc_tuple is not None:
2823 2824 self.showtraceback(preprocessing_exc_tuple)
2824 2825 if store_history:
2825 2826 self.execution_count += 1
2826 2827 return error_before_exec(preprocessing_exc_tuple[2])
2827 2828
2828 2829 # Our own compiler remembers the __future__ environment. If we want to
2829 2830 # run code with a separate __future__ environment, use the default
2830 2831 # compiler
2831 2832 compiler = self.compile if shell_futures else CachingCompiler()
2832 2833
2833 2834 with self.builtin_trap:
2834 2835 cell_name = self.compile.cache(cell, self.execution_count)
2835 2836
2836 2837 with self.display_trap:
2837 2838 # Compile to bytecode
2838 2839 try:
2839 2840 code_ast = compiler.ast_parse(cell, filename=cell_name)
2840 2841 except IndentationError as e:
2841 2842 self.showindentationerror()
2842 2843 if store_history:
2843 2844 self.execution_count += 1
2844 2845 return error_before_exec(e)
2845 2846 except (OverflowError, SyntaxError, ValueError, TypeError,
2846 2847 MemoryError) as e:
2847 2848 self.showsyntaxerror()
2848 2849 if store_history:
2849 2850 self.execution_count += 1
2850 2851 return error_before_exec(e)
2851 2852
2852 2853 # Apply AST transformations
2853 2854 try:
2854 2855 code_ast = self.transform_ast(code_ast)
2855 2856 except InputRejected as e:
2856 2857 self.showtraceback()
2857 2858 if store_history:
2858 2859 self.execution_count += 1
2859 2860 return error_before_exec(e)
2860 2861
2861 2862 # Give the displayhook a reference to our ExecutionResult so it
2862 2863 # can fill in the output value.
2863 2864 self.displayhook.exec_result = result
2864 2865
2865 2866 # Execute the user code
2866 2867 interactivity = "none" if silent else self.ast_node_interactivity
2867 2868 self.run_ast_nodes(code_ast.body, cell_name,
2868 2869 interactivity=interactivity, compiler=compiler, result=result)
2869 2870
2870 2871 # Reset this so later displayed values do not modify the
2871 2872 # ExecutionResult
2872 2873 self.displayhook.exec_result = None
2873 2874
2874 2875 self.events.trigger('post_execute')
2875 2876 if not silent:
2876 2877 self.events.trigger('post_run_cell')
2877 2878
2878 2879 if store_history:
2879 2880 # Write output to the database. Does nothing unless
2880 2881 # history output logging is enabled.
2881 2882 self.history_manager.store_output(self.execution_count)
2882 2883 # Each cell is a *single* input, regardless of how many lines it has
2883 2884 self.execution_count += 1
2884 2885
2885 2886 return result
2886 2887
2887 2888 def transform_ast(self, node):
2888 2889 """Apply the AST transformations from self.ast_transformers
2889 2890
2890 2891 Parameters
2891 2892 ----------
2892 2893 node : ast.Node
2893 2894 The root node to be transformed. Typically called with the ast.Module
2894 2895 produced by parsing user input.
2895 2896
2896 2897 Returns
2897 2898 -------
2898 2899 An ast.Node corresponding to the node it was called with. Note that it
2899 2900 may also modify the passed object, so don't rely on references to the
2900 2901 original AST.
2901 2902 """
2902 2903 for transformer in self.ast_transformers:
2903 2904 try:
2904 2905 node = transformer.visit(node)
2905 2906 except InputRejected:
2906 2907 # User-supplied AST transformers can reject an input by raising
2907 2908 # an InputRejected. Short-circuit in this case so that we
2908 2909 # don't unregister the transform.
2909 2910 raise
2910 2911 except Exception:
2911 2912 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2912 2913 self.ast_transformers.remove(transformer)
2913 2914
2914 2915 if self.ast_transformers:
2915 2916 ast.fix_missing_locations(node)
2916 2917 return node
2917 2918
2918 2919
2919 2920 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2920 2921 compiler=compile, result=None):
2921 2922 """Run a sequence of AST nodes. The execution mode depends on the
2922 2923 interactivity parameter.
2923 2924
2924 2925 Parameters
2925 2926 ----------
2926 2927 nodelist : list
2927 2928 A sequence of AST nodes to run.
2928 2929 cell_name : str
2929 2930 Will be passed to the compiler as the filename of the cell. Typically
2930 2931 the value returned by ip.compile.cache(cell).
2931 2932 interactivity : str
2932 2933 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2933 2934 run interactively (displaying output from expressions). 'last_expr'
2934 2935 will run the last node interactively only if it is an expression (i.e.
2935 2936 expressions in loops or other blocks are not displayed. Other values
2936 2937 for this parameter will raise a ValueError.
2937 2938 compiler : callable
2938 2939 A function with the same interface as the built-in compile(), to turn
2939 2940 the AST nodes into code objects. Default is the built-in compile().
2940 2941 result : ExecutionResult, optional
2941 2942 An object to store exceptions that occur during execution.
2942 2943
2943 2944 Returns
2944 2945 -------
2945 2946 True if an exception occurred while running code, False if it finished
2946 2947 running.
2947 2948 """
2948 2949 if not nodelist:
2949 2950 return
2950 2951
2951 2952 if interactivity == 'last_expr':
2952 2953 if isinstance(nodelist[-1], ast.Expr):
2953 2954 interactivity = "last"
2954 2955 else:
2955 2956 interactivity = "none"
2956 2957
2957 2958 if interactivity == 'none':
2958 2959 to_run_exec, to_run_interactive = nodelist, []
2959 2960 elif interactivity == 'last':
2960 2961 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2961 2962 elif interactivity == 'all':
2962 2963 to_run_exec, to_run_interactive = [], nodelist
2963 2964 else:
2964 2965 raise ValueError("Interactivity was %r" % interactivity)
2965 2966
2966 2967 exec_count = self.execution_count
2967 2968
2968 2969 try:
2969 2970 for i, node in enumerate(to_run_exec):
2970 2971 mod = ast.Module([node])
2971 2972 code = compiler(mod, cell_name, "exec")
2972 2973 if self.run_code(code, result):
2973 2974 return True
2974 2975
2975 2976 for i, node in enumerate(to_run_interactive):
2976 2977 mod = ast.Interactive([node])
2977 2978 code = compiler(mod, cell_name, "single")
2978 2979 if self.run_code(code, result):
2979 2980 return True
2980 2981
2981 2982 # Flush softspace
2982 2983 if softspace(sys.stdout, 0):
2983 2984 print()
2984 2985
2985 2986 except:
2986 2987 # It's possible to have exceptions raised here, typically by
2987 2988 # compilation of odd code (such as a naked 'return' outside a
2988 2989 # function) that did parse but isn't valid. Typically the exception
2989 2990 # is a SyntaxError, but it's safest just to catch anything and show
2990 2991 # the user a traceback.
2991 2992
2992 2993 # We do only one try/except outside the loop to minimize the impact
2993 2994 # on runtime, and also because if any node in the node list is
2994 2995 # broken, we should stop execution completely.
2995 2996 if result:
2996 2997 result.error_before_exec = sys.exc_info()[1]
2997 2998 self.showtraceback()
2998 2999 return True
2999 3000
3000 3001 return False
3001 3002
3002 3003 def run_code(self, code_obj, result=None):
3003 3004 """Execute a code object.
3004 3005
3005 3006 When an exception occurs, self.showtraceback() is called to display a
3006 3007 traceback.
3007 3008
3008 3009 Parameters
3009 3010 ----------
3010 3011 code_obj : code object
3011 3012 A compiled code object, to be executed
3012 3013 result : ExecutionResult, optional
3013 3014 An object to store exceptions that occur during execution.
3014 3015
3015 3016 Returns
3016 3017 -------
3017 3018 False : successful execution.
3018 3019 True : an error occurred.
3019 3020 """
3020 3021 # Set our own excepthook in case the user code tries to call it
3021 3022 # directly, so that the IPython crash handler doesn't get triggered
3022 3023 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3023 3024
3024 3025 # we save the original sys.excepthook in the instance, in case config
3025 3026 # code (such as magics) needs access to it.
3026 3027 self.sys_excepthook = old_excepthook
3027 3028 outflag = 1 # happens in more places, so it's easier as default
3028 3029 try:
3029 3030 try:
3030 3031 self.hooks.pre_run_code_hook()
3031 3032 #rprint('Running code', repr(code_obj)) # dbg
3032 3033 exec(code_obj, self.user_global_ns, self.user_ns)
3033 3034 finally:
3034 3035 # Reset our crash handler in place
3035 3036 sys.excepthook = old_excepthook
3036 3037 except SystemExit as e:
3037 3038 if result is not None:
3038 3039 result.error_in_exec = e
3039 3040 self.showtraceback(exception_only=True)
3040 3041 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
3041 3042 except self.custom_exceptions:
3042 3043 etype, value, tb = sys.exc_info()
3043 3044 if result is not None:
3044 3045 result.error_in_exec = value
3045 3046 self.CustomTB(etype, value, tb)
3046 3047 except:
3047 3048 if result is not None:
3048 3049 result.error_in_exec = sys.exc_info()[1]
3049 3050 self.showtraceback()
3050 3051 else:
3051 3052 outflag = 0
3052 3053 return outflag
3053 3054
3054 3055 # For backwards compatibility
3055 3056 runcode = run_code
3056 3057
3057 3058 #-------------------------------------------------------------------------
3058 3059 # Things related to GUI support and pylab
3059 3060 #-------------------------------------------------------------------------
3060 3061
3061 3062 def enable_gui(self, gui=None):
3062 3063 raise NotImplementedError('Implement enable_gui in a subclass')
3063 3064
3064 3065 def enable_matplotlib(self, gui=None):
3065 3066 """Enable interactive matplotlib and inline figure support.
3066 3067
3067 3068 This takes the following steps:
3068 3069
3069 3070 1. select the appropriate eventloop and matplotlib backend
3070 3071 2. set up matplotlib for interactive use with that backend
3071 3072 3. configure formatters for inline figure display
3072 3073 4. enable the selected gui eventloop
3073 3074
3074 3075 Parameters
3075 3076 ----------
3076 3077 gui : optional, string
3077 3078 If given, dictates the choice of matplotlib GUI backend to use
3078 3079 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3079 3080 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3080 3081 matplotlib (as dictated by the matplotlib build-time options plus the
3081 3082 user's matplotlibrc configuration file). Note that not all backends
3082 3083 make sense in all contexts, for example a terminal ipython can't
3083 3084 display figures inline.
3084 3085 """
3085 3086 from IPython.core import pylabtools as pt
3086 3087 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3087 3088
3088 3089 if gui != 'inline':
3089 3090 # If we have our first gui selection, store it
3090 3091 if self.pylab_gui_select is None:
3091 3092 self.pylab_gui_select = gui
3092 3093 # Otherwise if they are different
3093 3094 elif gui != self.pylab_gui_select:
3094 3095 print ('Warning: Cannot change to a different GUI toolkit: %s.'
3095 3096 ' Using %s instead.' % (gui, self.pylab_gui_select))
3096 3097 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3097 3098
3098 3099 pt.activate_matplotlib(backend)
3099 3100 pt.configure_inline_support(self, backend)
3100 3101
3101 3102 # Now we must activate the gui pylab wants to use, and fix %run to take
3102 3103 # plot updates into account
3103 3104 self.enable_gui(gui)
3104 3105 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3105 3106 pt.mpl_runner(self.safe_execfile)
3106 3107
3107 3108 return gui, backend
3108 3109
3109 3110 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3110 3111 """Activate pylab support at runtime.
3111 3112
3112 3113 This turns on support for matplotlib, preloads into the interactive
3113 3114 namespace all of numpy and pylab, and configures IPython to correctly
3114 3115 interact with the GUI event loop. The GUI backend to be used can be
3115 3116 optionally selected with the optional ``gui`` argument.
3116 3117
3117 3118 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3118 3119
3119 3120 Parameters
3120 3121 ----------
3121 3122 gui : optional, string
3122 3123 If given, dictates the choice of matplotlib GUI backend to use
3123 3124 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3124 3125 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3125 3126 matplotlib (as dictated by the matplotlib build-time options plus the
3126 3127 user's matplotlibrc configuration file). Note that not all backends
3127 3128 make sense in all contexts, for example a terminal ipython can't
3128 3129 display figures inline.
3129 3130 import_all : optional, bool, default: True
3130 3131 Whether to do `from numpy import *` and `from pylab import *`
3131 3132 in addition to module imports.
3132 3133 welcome_message : deprecated
3133 3134 This argument is ignored, no welcome message will be displayed.
3134 3135 """
3135 3136 from IPython.core.pylabtools import import_pylab
3136 3137
3137 3138 gui, backend = self.enable_matplotlib(gui)
3138 3139
3139 3140 # We want to prevent the loading of pylab to pollute the user's
3140 3141 # namespace as shown by the %who* magics, so we execute the activation
3141 3142 # code in an empty namespace, and we update *both* user_ns and
3142 3143 # user_ns_hidden with this information.
3143 3144 ns = {}
3144 3145 import_pylab(ns, import_all)
3145 3146 # warn about clobbered names
3146 3147 ignored = set(["__builtins__"])
3147 3148 both = set(ns).intersection(self.user_ns).difference(ignored)
3148 3149 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3149 3150 self.user_ns.update(ns)
3150 3151 self.user_ns_hidden.update(ns)
3151 3152 return gui, backend, clobbered
3152 3153
3153 3154 #-------------------------------------------------------------------------
3154 3155 # Utilities
3155 3156 #-------------------------------------------------------------------------
3156 3157
3157 3158 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3158 3159 """Expand python variables in a string.
3159 3160
3160 3161 The depth argument indicates how many frames above the caller should
3161 3162 be walked to look for the local namespace where to expand variables.
3162 3163
3163 3164 The global namespace for expansion is always the user's interactive
3164 3165 namespace.
3165 3166 """
3166 3167 ns = self.user_ns.copy()
3167 3168 try:
3168 3169 frame = sys._getframe(depth+1)
3169 3170 except ValueError:
3170 3171 # This is thrown if there aren't that many frames on the stack,
3171 3172 # e.g. if a script called run_line_magic() directly.
3172 3173 pass
3173 3174 else:
3174 3175 ns.update(frame.f_locals)
3175 3176
3176 3177 try:
3177 3178 # We have to use .vformat() here, because 'self' is a valid and common
3178 3179 # name, and expanding **ns for .format() would make it collide with
3179 3180 # the 'self' argument of the method.
3180 3181 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3181 3182 except Exception:
3182 3183 # if formatter couldn't format, just let it go untransformed
3183 3184 pass
3184 3185 return cmd
3185 3186
3186 3187 def mktempfile(self, data=None, prefix='ipython_edit_'):
3187 3188 """Make a new tempfile and return its filename.
3188 3189
3189 3190 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3190 3191 but it registers the created filename internally so ipython cleans it up
3191 3192 at exit time.
3192 3193
3193 3194 Optional inputs:
3194 3195
3195 3196 - data(None): if data is given, it gets written out to the temp file
3196 3197 immediately, and the file is closed again."""
3197 3198
3198 3199 dirname = tempfile.mkdtemp(prefix=prefix)
3199 3200 self.tempdirs.append(dirname)
3200 3201
3201 3202 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3202 3203 os.close(handle) # On Windows, there can only be one open handle on a file
3203 3204 self.tempfiles.append(filename)
3204 3205
3205 3206 if data:
3206 3207 tmp_file = open(filename,'w')
3207 3208 tmp_file.write(data)
3208 3209 tmp_file.close()
3209 3210 return filename
3210 3211
3211 3212 # TODO: This should be removed when Term is refactored.
3212 3213 def write(self,data):
3213 3214 """Write a string to the default output"""
3214 3215 io.stdout.write(data)
3215 3216
3216 3217 # TODO: This should be removed when Term is refactored.
3217 3218 def write_err(self,data):
3218 3219 """Write a string to the default error output"""
3219 3220 io.stderr.write(data)
3220 3221
3221 3222 def ask_yes_no(self, prompt, default=None):
3222 3223 if self.quiet:
3223 3224 return True
3224 3225 return ask_yes_no(prompt,default)
3225 3226
3226 3227 def show_usage(self):
3227 3228 """Show a usage message"""
3228 3229 page.page(IPython.core.usage.interactive_usage)
3229 3230
3230 3231 def extract_input_lines(self, range_str, raw=False):
3231 3232 """Return as a string a set of input history slices.
3232 3233
3233 3234 Parameters
3234 3235 ----------
3235 3236 range_str : string
3236 3237 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3237 3238 since this function is for use by magic functions which get their
3238 3239 arguments as strings. The number before the / is the session
3239 3240 number: ~n goes n back from the current session.
3240 3241
3241 3242 raw : bool, optional
3242 3243 By default, the processed input is used. If this is true, the raw
3243 3244 input history is used instead.
3244 3245
3245 3246 Notes
3246 3247 -----
3247 3248
3248 3249 Slices can be described with two notations:
3249 3250
3250 3251 * ``N:M`` -> standard python form, means including items N...(M-1).
3251 3252 * ``N-M`` -> include items N..M (closed endpoint).
3252 3253 """
3253 3254 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3254 3255 return "\n".join(x for _, _, x in lines)
3255 3256
3256 3257 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3257 3258 """Get a code string from history, file, url, or a string or macro.
3258 3259
3259 3260 This is mainly used by magic functions.
3260 3261
3261 3262 Parameters
3262 3263 ----------
3263 3264
3264 3265 target : str
3265 3266
3266 3267 A string specifying code to retrieve. This will be tried respectively
3267 3268 as: ranges of input history (see %history for syntax), url,
3268 3269 correspnding .py file, filename, or an expression evaluating to a
3269 3270 string or Macro in the user namespace.
3270 3271
3271 3272 raw : bool
3272 3273 If true (default), retrieve raw history. Has no effect on the other
3273 3274 retrieval mechanisms.
3274 3275
3275 3276 py_only : bool (default False)
3276 3277 Only try to fetch python code, do not try alternative methods to decode file
3277 3278 if unicode fails.
3278 3279
3279 3280 Returns
3280 3281 -------
3281 3282 A string of code.
3282 3283
3283 3284 ValueError is raised if nothing is found, and TypeError if it evaluates
3284 3285 to an object of another type. In each case, .args[0] is a printable
3285 3286 message.
3286 3287 """
3287 3288 code = self.extract_input_lines(target, raw=raw) # Grab history
3288 3289 if code:
3289 3290 return code
3290 3291 utarget = unquote_filename(target)
3291 3292 try:
3292 3293 if utarget.startswith(('http://', 'https://')):
3293 3294 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3294 3295 except UnicodeDecodeError:
3295 3296 if not py_only :
3296 3297 # Deferred import
3297 3298 try:
3298 3299 from urllib.request import urlopen # Py3
3299 3300 except ImportError:
3300 3301 from urllib import urlopen
3301 3302 response = urlopen(target)
3302 3303 return response.read().decode('latin1')
3303 3304 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3304 3305
3305 3306 potential_target = [target]
3306 3307 try :
3307 3308 potential_target.insert(0,get_py_filename(target))
3308 3309 except IOError:
3309 3310 pass
3310 3311
3311 3312 for tgt in potential_target :
3312 3313 if os.path.isfile(tgt): # Read file
3313 3314 try :
3314 3315 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3315 3316 except UnicodeDecodeError :
3316 3317 if not py_only :
3317 3318 with io_open(tgt,'r', encoding='latin1') as f :
3318 3319 return f.read()
3319 3320 raise ValueError(("'%s' seem to be unreadable.") % target)
3320 3321 elif os.path.isdir(os.path.expanduser(tgt)):
3321 3322 raise ValueError("'%s' is a directory, not a regular file." % target)
3322 3323
3323 3324 if search_ns:
3324 3325 # Inspect namespace to load object source
3325 3326 object_info = self.object_inspect(target, detail_level=1)
3326 3327 if object_info['found'] and object_info['source']:
3327 3328 return object_info['source']
3328 3329
3329 3330 try: # User namespace
3330 3331 codeobj = eval(target, self.user_ns)
3331 3332 except Exception:
3332 3333 raise ValueError(("'%s' was not found in history, as a file, url, "
3333 3334 "nor in the user namespace.") % target)
3334 3335
3335 3336 if isinstance(codeobj, string_types):
3336 3337 return codeobj
3337 3338 elif isinstance(codeobj, Macro):
3338 3339 return codeobj.value
3339 3340
3340 3341 raise TypeError("%s is neither a string nor a macro." % target,
3341 3342 codeobj)
3342 3343
3343 3344 #-------------------------------------------------------------------------
3344 3345 # Things related to IPython exiting
3345 3346 #-------------------------------------------------------------------------
3346 3347 def atexit_operations(self):
3347 3348 """This will be executed at the time of exit.
3348 3349
3349 3350 Cleanup operations and saving of persistent data that is done
3350 3351 unconditionally by IPython should be performed here.
3351 3352
3352 3353 For things that may depend on startup flags or platform specifics (such
3353 3354 as having readline or not), register a separate atexit function in the
3354 3355 code that has the appropriate information, rather than trying to
3355 3356 clutter
3356 3357 """
3357 3358 # Close the history session (this stores the end time and line count)
3358 3359 # this must be *before* the tempfile cleanup, in case of temporary
3359 3360 # history db
3360 3361 self.history_manager.end_session()
3361 3362
3362 3363 # Cleanup all tempfiles and folders left around
3363 3364 for tfile in self.tempfiles:
3364 3365 try:
3365 3366 os.unlink(tfile)
3366 3367 except OSError:
3367 3368 pass
3368 3369
3369 3370 for tdir in self.tempdirs:
3370 3371 try:
3371 3372 os.rmdir(tdir)
3372 3373 except OSError:
3373 3374 pass
3374 3375
3375 3376 # Clear all user namespaces to release all references cleanly.
3376 3377 self.reset(new_session=False)
3377 3378
3378 3379 # Run user hooks
3379 3380 self.hooks.shutdown_hook()
3380 3381
3381 3382 def cleanup(self):
3382 3383 self.restore_sys_module_state()
3383 3384
3384 3385
3385 3386 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3386 3387 """An abstract base class for InteractiveShell."""
3387 3388
3388 3389 InteractiveShellABC.register(InteractiveShell)
@@ -1,919 +1,924 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for inspecting Python objects.
3 3
4 4 Uses syntax highlighting for presenting the various information elements.
5 5
6 6 Similar in spirit to the inspect module, but all calls take a name argument to
7 7 reference the name under which an object is being read.
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12
13 13 from __future__ import print_function
14 14
15 15 __all__ = ['Inspector','InspectColors']
16 16
17 17 # stdlib modules
18 18 import inspect
19 19 import linecache
20 20 import os
21 21 from textwrap import dedent
22 22 import types
23 23 import io as stdlib_io
24 24
25 25 try:
26 26 from itertools import izip_longest
27 27 except ImportError:
28 28 from itertools import zip_longest as izip_longest
29 29
30 30 # IPython's own
31 31 from IPython.core import page
32 32 from IPython.lib.pretty import pretty
33 33 from IPython.testing.skipdoctest import skip_doctest_py3
34 34 from IPython.utils import PyColorize
35 35 from IPython.utils import io
36 36 from IPython.utils import openpy
37 37 from IPython.utils import py3compat
38 38 from IPython.utils.dir2 import safe_hasattr
39 from IPython.utils.path import compress_user
39 40 from IPython.utils.text import indent
40 41 from IPython.utils.wildcard import list_namespace
41 42 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
42 43 from IPython.utils.py3compat import cast_unicode, string_types, PY3
43 44 from IPython.utils.signatures import signature
44 45
45 46 # builtin docstrings to ignore
46 47 _func_call_docstring = types.FunctionType.__call__.__doc__
47 48 _object_init_docstring = object.__init__.__doc__
48 49 _builtin_type_docstrings = {
49 50 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
50 51 types.FunctionType, property)
51 52 }
52 53
53 54 _builtin_func_type = type(all)
54 55 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
55 56 #****************************************************************************
56 57 # Builtin color schemes
57 58
58 59 Colors = TermColors # just a shorthand
59 60
60 61 # Build a few color schemes
61 62 NoColor = ColorScheme(
62 63 'NoColor',{
63 64 'header' : Colors.NoColor,
64 65 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
65 66 } )
66 67
67 68 LinuxColors = ColorScheme(
68 69 'Linux',{
69 70 'header' : Colors.LightRed,
70 71 'normal' : Colors.Normal # color off (usu. Colors.Normal)
71 72 } )
72 73
73 74 LightBGColors = ColorScheme(
74 75 'LightBG',{
75 76 'header' : Colors.Red,
76 77 'normal' : Colors.Normal # color off (usu. Colors.Normal)
77 78 } )
78 79
79 80 # Build table of color schemes (needed by the parser)
80 81 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
81 82 'Linux')
82 83
83 84 #****************************************************************************
84 85 # Auxiliary functions and objects
85 86
86 87 # See the messaging spec for the definition of all these fields. This list
87 88 # effectively defines the order of display
88 89 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
89 90 'length', 'file', 'definition', 'docstring', 'source',
90 91 'init_definition', 'class_docstring', 'init_docstring',
91 92 'call_def', 'call_docstring',
92 93 # These won't be printed but will be used to determine how to
93 94 # format the object
94 95 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
95 96 ]
96 97
97 98
98 99 def object_info(**kw):
99 100 """Make an object info dict with all fields present."""
100 101 infodict = dict(izip_longest(info_fields, [None]))
101 102 infodict.update(kw)
102 103 return infodict
103 104
104 105
105 106 def get_encoding(obj):
106 107 """Get encoding for python source file defining obj
107 108
108 109 Returns None if obj is not defined in a sourcefile.
109 110 """
110 111 ofile = find_file(obj)
111 112 # run contents of file through pager starting at line where the object
112 113 # is defined, as long as the file isn't binary and is actually on the
113 114 # filesystem.
114 115 if ofile is None:
115 116 return None
116 117 elif ofile.endswith(('.so', '.dll', '.pyd')):
117 118 return None
118 119 elif not os.path.isfile(ofile):
119 120 return None
120 121 else:
121 122 # Print only text files, not extension binaries. Note that
122 123 # getsourcelines returns lineno with 1-offset and page() uses
123 124 # 0-offset, so we must adjust.
124 125 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
125 126 encoding, lines = openpy.detect_encoding(buffer.readline)
126 127 return encoding
127 128
128 129 def getdoc(obj):
129 130 """Stable wrapper around inspect.getdoc.
130 131
131 132 This can't crash because of attribute problems.
132 133
133 134 It also attempts to call a getdoc() method on the given object. This
134 135 allows objects which provide their docstrings via non-standard mechanisms
135 136 (like Pyro proxies) to still be inspected by ipython's ? system."""
136 137 # Allow objects to offer customized documentation via a getdoc method:
137 138 try:
138 139 ds = obj.getdoc()
139 140 except Exception:
140 141 pass
141 142 else:
142 143 # if we get extra info, we add it to the normal docstring.
143 144 if isinstance(ds, string_types):
144 145 return inspect.cleandoc(ds)
145 146
146 147 try:
147 148 docstr = inspect.getdoc(obj)
148 149 encoding = get_encoding(obj)
149 150 return py3compat.cast_unicode(docstr, encoding=encoding)
150 151 except Exception:
151 152 # Harden against an inspect failure, which can occur with
152 153 # SWIG-wrapped extensions.
153 154 raise
154 155 return None
155 156
156 157
157 158 def getsource(obj, oname=''):
158 159 """Wrapper around inspect.getsource.
159 160
160 161 This can be modified by other projects to provide customized source
161 162 extraction.
162 163
163 164 Parameters
164 165 ----------
165 166 obj : object
166 167 an object whose source code we will attempt to extract
167 168 oname : str
168 169 (optional) a name under which the object is known
169 170
170 171 Returns
171 172 -------
172 173 src : unicode or None
173 174
174 175 """
175 176
176 177 if isinstance(obj, property):
177 178 sources = []
178 179 for attrname in ['fget', 'fset', 'fdel']:
179 180 fn = getattr(obj, attrname)
180 181 if fn is not None:
181 182 encoding = get_encoding(fn)
182 183 oname_prefix = ('%s.' % oname) if oname else ''
183 184 sources.append(cast_unicode(
184 185 ''.join(('# ', oname_prefix, attrname)),
185 186 encoding=encoding))
186 187 if inspect.isfunction(fn):
187 188 sources.append(dedent(getsource(fn)))
188 189 else:
189 190 # Default str/repr only prints function name,
190 191 # pretty.pretty prints module name too.
191 192 sources.append(cast_unicode(
192 193 '%s%s = %s\n' % (
193 194 oname_prefix, attrname, pretty(fn)),
194 195 encoding=encoding))
195 196 if sources:
196 197 return '\n'.join(sources)
197 198 else:
198 199 return None
199 200
200 201 else:
201 202 # Get source for non-property objects.
202 203
203 204 # '__wrapped__' attribute is used by some decorators (e.g. ones defined
204 205 # functools) to provide access to the decorated function.
205 206 if hasattr(obj, "__wrapped__"):
206 207 obj = obj.__wrapped__
207 208
208 209 try:
209 210 src = inspect.getsource(obj)
210 211 except TypeError:
211 212 # The object itself provided no meaningful source, try looking for
212 213 # its class definition instead.
213 214 if hasattr(obj, '__class__'):
214 215 try:
215 216 src = inspect.getsource(obj.__class__)
216 217 except TypeError:
217 218 return None
218 219
219 220 encoding = get_encoding(obj)
220 221 return cast_unicode(src, encoding=encoding)
221 222
222 223
223 224 def is_simple_callable(obj):
224 225 """True if obj is a function ()"""
225 226 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
226 227 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
227 228
228 229
229 230 def getargspec(obj):
230 231 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
231 232 :func:inspect.getargspec` on Python 2.
232 233
233 234 In addition to functions and methods, this can also handle objects with a
234 235 ``__call__`` attribute.
235 236 """
236 237 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
237 238 obj = obj.__call__
238 239
239 240 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
240 241
241 242
242 243 def format_argspec(argspec):
243 244 """Format argspect, convenience wrapper around inspect's.
244 245
245 246 This takes a dict instead of ordered arguments and calls
246 247 inspect.format_argspec with the arguments in the necessary order.
247 248 """
248 249 return inspect.formatargspec(argspec['args'], argspec['varargs'],
249 250 argspec['varkw'], argspec['defaults'])
250 251
251 252
252 253 def call_tip(oinfo, format_call=True):
253 254 """Extract call tip data from an oinfo dict.
254 255
255 256 Parameters
256 257 ----------
257 258 oinfo : dict
258 259
259 260 format_call : bool, optional
260 261 If True, the call line is formatted and returned as a string. If not, a
261 262 tuple of (name, argspec) is returned.
262 263
263 264 Returns
264 265 -------
265 266 call_info : None, str or (str, dict) tuple.
266 267 When format_call is True, the whole call information is formattted as a
267 268 single string. Otherwise, the object's name and its argspec dict are
268 269 returned. If no call information is available, None is returned.
269 270
270 271 docstring : str or None
271 272 The most relevant docstring for calling purposes is returned, if
272 273 available. The priority is: call docstring for callable instances, then
273 274 constructor docstring for classes, then main object's docstring otherwise
274 275 (regular functions).
275 276 """
276 277 # Get call definition
277 278 argspec = oinfo.get('argspec')
278 279 if argspec is None:
279 280 call_line = None
280 281 else:
281 282 # Callable objects will have 'self' as their first argument, prune
282 283 # it out if it's there for clarity (since users do *not* pass an
283 284 # extra first argument explicitly).
284 285 try:
285 286 has_self = argspec['args'][0] == 'self'
286 287 except (KeyError, IndexError):
287 288 pass
288 289 else:
289 290 if has_self:
290 291 argspec['args'] = argspec['args'][1:]
291 292
292 293 call_line = oinfo['name']+format_argspec(argspec)
293 294
294 295 # Now get docstring.
295 296 # The priority is: call docstring, constructor docstring, main one.
296 297 doc = oinfo.get('call_docstring')
297 298 if doc is None:
298 299 doc = oinfo.get('init_docstring')
299 300 if doc is None:
300 301 doc = oinfo.get('docstring','')
301 302
302 303 return call_line, doc
303 304
304 305
305 306 def find_file(obj):
306 307 """Find the absolute path to the file where an object was defined.
307 308
308 309 This is essentially a robust wrapper around `inspect.getabsfile`.
309 310
310 311 Returns None if no file can be found.
311 312
312 313 Parameters
313 314 ----------
314 315 obj : any Python object
315 316
316 317 Returns
317 318 -------
318 319 fname : str
319 320 The absolute path to the file where the object was defined.
320 321 """
321 322 # get source if obj was decorated with @decorator
322 323 if safe_hasattr(obj, '__wrapped__'):
323 324 obj = obj.__wrapped__
324 325
325 326 fname = None
326 327 try:
327 328 fname = inspect.getabsfile(obj)
328 329 except TypeError:
329 330 # For an instance, the file that matters is where its class was
330 331 # declared.
331 332 if hasattr(obj, '__class__'):
332 333 try:
333 334 fname = inspect.getabsfile(obj.__class__)
334 335 except TypeError:
335 336 # Can happen for builtins
336 337 pass
337 338 except:
338 339 pass
339 340 return cast_unicode(fname)
340 341
341 342
342 343 def find_source_lines(obj):
343 344 """Find the line number in a file where an object was defined.
344 345
345 346 This is essentially a robust wrapper around `inspect.getsourcelines`.
346 347
347 348 Returns None if no file can be found.
348 349
349 350 Parameters
350 351 ----------
351 352 obj : any Python object
352 353
353 354 Returns
354 355 -------
355 356 lineno : int
356 357 The line number where the object definition starts.
357 358 """
358 359 # get source if obj was decorated with @decorator
359 360 if safe_hasattr(obj, '__wrapped__'):
360 361 obj = obj.__wrapped__
361 362
362 363 try:
363 364 try:
364 365 lineno = inspect.getsourcelines(obj)[1]
365 366 except TypeError:
366 367 # For instances, try the class object like getsource() does
367 368 if hasattr(obj, '__class__'):
368 369 lineno = inspect.getsourcelines(obj.__class__)[1]
369 370 else:
370 371 lineno = None
371 372 except:
372 373 return None
373 374
374 375 return lineno
375 376
376 377
377 378 class Inspector:
378 379 def __init__(self, color_table=InspectColors,
379 380 code_color_table=PyColorize.ANSICodeColors,
380 381 scheme='NoColor',
381 382 str_detail_level=0):
382 383 self.color_table = color_table
383 384 self.parser = PyColorize.Parser(code_color_table,out='str')
384 385 self.format = self.parser.format
385 386 self.str_detail_level = str_detail_level
386 387 self.set_active_scheme(scheme)
387 388
388 389 def _getdef(self,obj,oname=''):
389 390 """Return the call signature for any callable object.
390 391
391 392 If any exception is generated, None is returned instead and the
392 393 exception is suppressed."""
393 394 try:
394 395 hdef = oname + str(signature(obj))
395 396 return cast_unicode(hdef)
396 397 except:
397 398 return None
398 399
399 400 def __head(self,h):
400 401 """Return a header string with proper colors."""
401 402 return '%s%s%s' % (self.color_table.active_colors.header,h,
402 403 self.color_table.active_colors.normal)
403 404
404 405 def set_active_scheme(self, scheme):
405 406 self.color_table.set_active_scheme(scheme)
406 407 self.parser.color_table.set_active_scheme(scheme)
407 408
408 409 def noinfo(self, msg, oname):
409 410 """Generic message when no information is found."""
410 411 print('No %s found' % msg, end=' ')
411 412 if oname:
412 413 print('for %s' % oname)
413 414 else:
414 415 print()
415 416
416 417 def pdef(self, obj, oname=''):
417 418 """Print the call signature for any callable object.
418 419
419 420 If the object is a class, print the constructor information."""
420 421
421 422 if not callable(obj):
422 423 print('Object is not callable.')
423 424 return
424 425
425 426 header = ''
426 427
427 428 if inspect.isclass(obj):
428 429 header = self.__head('Class constructor information:\n')
429 430 obj = obj.__init__
430 431 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
431 432 obj = obj.__call__
432 433
433 434 output = self._getdef(obj,oname)
434 435 if output is None:
435 436 self.noinfo('definition header',oname)
436 437 else:
437 438 print(header,self.format(output), end=' ', file=io.stdout)
438 439
439 440 # In Python 3, all classes are new-style, so they all have __init__.
440 441 @skip_doctest_py3
441 442 def pdoc(self,obj,oname='',formatter = None):
442 443 """Print the docstring for any object.
443 444
444 445 Optional:
445 446 -formatter: a function to run the docstring through for specially
446 447 formatted docstrings.
447 448
448 449 Examples
449 450 --------
450 451
451 452 In [1]: class NoInit:
452 453 ...: pass
453 454
454 455 In [2]: class NoDoc:
455 456 ...: def __init__(self):
456 457 ...: pass
457 458
458 459 In [3]: %pdoc NoDoc
459 460 No documentation found for NoDoc
460 461
461 462 In [4]: %pdoc NoInit
462 463 No documentation found for NoInit
463 464
464 465 In [5]: obj = NoInit()
465 466
466 467 In [6]: %pdoc obj
467 468 No documentation found for obj
468 469
469 470 In [5]: obj2 = NoDoc()
470 471
471 472 In [6]: %pdoc obj2
472 473 No documentation found for obj2
473 474 """
474 475
475 476 head = self.__head # For convenience
476 477 lines = []
477 478 ds = getdoc(obj)
478 479 if formatter:
479 480 ds = formatter(ds)
480 481 if ds:
481 482 lines.append(head("Class docstring:"))
482 483 lines.append(indent(ds))
483 484 if inspect.isclass(obj) and hasattr(obj, '__init__'):
484 485 init_ds = getdoc(obj.__init__)
485 486 if init_ds is not None:
486 487 lines.append(head("Init docstring:"))
487 488 lines.append(indent(init_ds))
488 489 elif hasattr(obj,'__call__'):
489 490 call_ds = getdoc(obj.__call__)
490 491 if call_ds:
491 492 lines.append(head("Call docstring:"))
492 493 lines.append(indent(call_ds))
493 494
494 495 if not lines:
495 496 self.noinfo('documentation',oname)
496 497 else:
497 498 page.page('\n'.join(lines))
498 499
499 500 def psource(self, obj, oname=''):
500 501 """Print the source code for an object."""
501 502
502 503 # Flush the source cache because inspect can return out-of-date source
503 504 linecache.checkcache()
504 505 try:
505 506 src = getsource(obj, oname=oname)
506 507 except Exception:
507 508 src = None
508 509
509 510 if src is None:
510 511 self.noinfo('source', oname)
511 512 else:
512 513 page.page(self.format(src))
513 514
514 515 def pfile(self, obj, oname=''):
515 516 """Show the whole file where an object was defined."""
516 517
517 518 lineno = find_source_lines(obj)
518 519 if lineno is None:
519 520 self.noinfo('file', oname)
520 521 return
521 522
522 523 ofile = find_file(obj)
523 524 # run contents of file through pager starting at line where the object
524 525 # is defined, as long as the file isn't binary and is actually on the
525 526 # filesystem.
526 527 if ofile.endswith(('.so', '.dll', '.pyd')):
527 528 print('File %r is binary, not printing.' % ofile)
528 529 elif not os.path.isfile(ofile):
529 530 print('File %r does not exist, not printing.' % ofile)
530 531 else:
531 532 # Print only text files, not extension binaries. Note that
532 533 # getsourcelines returns lineno with 1-offset and page() uses
533 534 # 0-offset, so we must adjust.
534 535 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
535 536
536 537 def _format_fields(self, fields, title_width=0):
537 538 """Formats a list of fields for display.
538 539
539 540 Parameters
540 541 ----------
541 542 fields : list
542 543 A list of 2-tuples: (field_title, field_content)
543 544 title_width : int
544 545 How many characters to pad titles to. Default to longest title.
545 546 """
546 547 out = []
547 548 header = self.__head
548 549 if title_width == 0:
549 550 title_width = max(len(title) + 2 for title, _ in fields)
550 551 for title, content in fields:
551 552 if len(content.splitlines()) > 1:
552 553 title = header(title + ":") + "\n"
553 554 else:
554 555 title = header((title+":").ljust(title_width))
555 556 out.append(cast_unicode(title) + cast_unicode(content))
556 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 559 def _format_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
576 560 """Format an info dict as text"""
577 561 info = self.info(obj, oname=oname, formatter=formatter,
578 562 info=info, detail_level=detail_level)
579 563 displayfields = []
580 564 def add_fields(fields):
581 565 for title, key in fields:
582 566 field = info[key]
583 567 if field is not None:
584 568 displayfields.append((title, field.rstrip()))
585
586 add_fields(self.pinfo_fields1)
587
588 # Base class for old-style instances
589 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
590 displayfields.append(("Base Class", info['base_class'].rstrip()))
591
592 add_fields(self.pinfo_fields2)
593
594 # Namespace
595 if info['namespace'] != 'Interactive':
596 displayfields.append(("Namespace", info['namespace'].rstrip()))
597
598 add_fields(self.pinfo_fields3)
599 if info['isclass'] and info['init_definition']:
600 displayfields.append(("Init definition",
601 info['init_definition'].rstrip()))
602
603 # Source or docstring, depending on detail level and whether
604 # source found.
605 if detail_level > 0 and info['source'] is not None:
606 displayfields.append(("Source",
607 self.format(cast_unicode(info['source']))))
608 elif info['docstring'] is not None:
609 displayfields.append(("Docstring", info["docstring"]))
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:
569
570 if info['isalias']:
571 add_fields([('Repr', "string_form")])
572
573 elif info['ismagic']:
574 add_fields([("Docstring", "docstring"),
575 ("File", "file")
576 ])
577
578 elif info['isclass'] or is_simple_callable(obj):
579 # Functions, methods, classes
580 add_fields([("Signature", "definition"),
581 ("Init signature", "init_definition"),
582 ])
583 if detail_level > 0 and info['source'] is not None:
584 add_fields([("Source", "source")])
585 else:
586 add_fields([("Docstring", "docstring"),
587 ("Init docstring", "init_docstring"),
588 ])
589
590 add_fields([('File', 'file'),
591 ('Type', 'type_name'),
592 ])
593
618 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 626 if displayfields:
622 627 return self._format_fields(displayfields)
623 628 else:
624 629 return u''
625 630
626 631 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
627 632 """Show detailed information about an object.
628 633
629 634 Optional arguments:
630 635
631 636 - oname: name of the variable pointing to the object.
632 637
633 638 - formatter: special formatter for docstrings (see pdoc)
634 639
635 640 - info: a structure with some information fields which may have been
636 641 precomputed already.
637 642
638 643 - detail_level: if set to 1, more information is given.
639 644 """
640 645 text = self._format_info(obj, oname, formatter, info, detail_level)
641 646 if text:
642 647 page.page(text)
643 648
644 649 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
645 650 """Compute a dict with detailed information about an object.
646 651
647 652 Optional arguments:
648 653
649 654 - oname: name of the variable pointing to the object.
650 655
651 656 - formatter: special formatter for docstrings (see pdoc)
652 657
653 658 - info: a structure with some information fields which may have been
654 659 precomputed already.
655 660
656 661 - detail_level: if set to 1, more information is given.
657 662 """
658 663
659 664 obj_type = type(obj)
660 665
661 666 if info is None:
662 667 ismagic = 0
663 668 isalias = 0
664 669 ospace = ''
665 670 else:
666 671 ismagic = info.ismagic
667 672 isalias = info.isalias
668 673 ospace = info.namespace
669 674
670 675 # Get docstring, special-casing aliases:
671 676 if isalias:
672 677 if not callable(obj):
673 678 try:
674 679 ds = "Alias to the system command:\n %s" % obj[1]
675 680 except:
676 681 ds = "Alias: " + str(obj)
677 682 else:
678 683 ds = "Alias to " + str(obj)
679 684 if obj.__doc__:
680 685 ds += "\nDocstring:\n" + obj.__doc__
681 686 else:
682 687 ds = getdoc(obj)
683 688 if ds is None:
684 689 ds = '<no docstring>'
685 690 if formatter is not None:
686 691 ds = formatter(ds)
687 692
688 693 # store output in a dict, we initialize it here and fill it as we go
689 694 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
690 695
691 696 string_max = 200 # max size of strings to show (snipped if longer)
692 697 shalf = int((string_max -5)/2)
693 698
694 699 if ismagic:
695 700 obj_type_name = 'Magic function'
696 701 elif isalias:
697 702 obj_type_name = 'System alias'
698 703 else:
699 704 obj_type_name = obj_type.__name__
700 705 out['type_name'] = obj_type_name
701 706
702 707 try:
703 708 bclass = obj.__class__
704 709 out['base_class'] = str(bclass)
705 710 except: pass
706 711
707 712 # String form, but snip if too long in ? form (full in ??)
708 713 if detail_level >= self.str_detail_level:
709 714 try:
710 715 ostr = str(obj)
711 716 str_head = 'string_form'
712 717 if not detail_level and len(ostr)>string_max:
713 718 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
714 719 ostr = ("\n" + " " * len(str_head.expandtabs())).\
715 720 join(q.strip() for q in ostr.split("\n"))
716 721 out[str_head] = ostr
717 722 except:
718 723 pass
719 724
720 725 if ospace:
721 726 out['namespace'] = ospace
722 727
723 728 # Length (for strings and lists)
724 729 try:
725 730 out['length'] = str(len(obj))
726 731 except: pass
727 732
728 733 # Filename where object was defined
729 734 binary_file = False
730 735 fname = find_file(obj)
731 736 if fname is None:
732 737 # if anything goes wrong, we don't want to show source, so it's as
733 738 # if the file was binary
734 739 binary_file = True
735 740 else:
736 741 if fname.endswith(('.so', '.dll', '.pyd')):
737 742 binary_file = True
738 743 elif fname.endswith('<string>'):
739 744 fname = 'Dynamically generated function. No source code available.'
740 out['file'] = fname
745 out['file'] = compress_user(fname)
741 746
742 747 # Original source code for a callable, class or property.
743 748 if detail_level:
744 749 # Flush the source cache because inspect can return out-of-date
745 750 # source
746 751 linecache.checkcache()
747 752 try:
748 753 if isinstance(obj, property) or not binary_file:
749 754 src = getsource(obj, oname)
750 755 if src is not None:
751 756 src = src.rstrip()
752 757 out['source'] = src
753 758
754 759 except Exception:
755 760 pass
756 761
757 762 # Add docstring only if no source is to be shown (avoid repetitions).
758 763 if ds and out.get('source', None) is None:
759 764 out['docstring'] = ds
760 765
761 766 # Constructor docstring for classes
762 767 if inspect.isclass(obj):
763 768 out['isclass'] = True
764 769 # reconstruct the function definition and print it:
765 770 try:
766 771 obj_init = obj.__init__
767 772 except AttributeError:
768 773 init_def = init_ds = None
769 774 else:
770 775 init_def = self._getdef(obj_init,oname)
771 776 init_ds = getdoc(obj_init)
772 777 # Skip Python's auto-generated docstrings
773 778 if init_ds == _object_init_docstring:
774 779 init_ds = None
775 780
776 781 if init_def or init_ds:
777 782 if init_def:
778 783 out['init_definition'] = self.format(init_def)
779 784 if init_ds:
780 785 out['init_docstring'] = init_ds
781 786
782 787 # and class docstring for instances:
783 788 else:
784 789 # reconstruct the function definition and print it:
785 790 defln = self._getdef(obj, oname)
786 791 if defln:
787 792 out['definition'] = self.format(defln)
788 793
789 794 # First, check whether the instance docstring is identical to the
790 795 # class one, and print it separately if they don't coincide. In
791 796 # most cases they will, but it's nice to print all the info for
792 797 # objects which use instance-customized docstrings.
793 798 if ds:
794 799 try:
795 800 cls = getattr(obj,'__class__')
796 801 except:
797 802 class_ds = None
798 803 else:
799 804 class_ds = getdoc(cls)
800 805 # Skip Python's auto-generated docstrings
801 806 if class_ds in _builtin_type_docstrings:
802 807 class_ds = None
803 808 if class_ds and ds != class_ds:
804 809 out['class_docstring'] = class_ds
805 810
806 811 # Next, try to show constructor docstrings
807 812 try:
808 813 init_ds = getdoc(obj.__init__)
809 814 # Skip Python's auto-generated docstrings
810 815 if init_ds == _object_init_docstring:
811 816 init_ds = None
812 817 except AttributeError:
813 818 init_ds = None
814 819 if init_ds:
815 820 out['init_docstring'] = init_ds
816 821
817 822 # Call form docstring for callable instances
818 823 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
819 824 call_def = self._getdef(obj.__call__, oname)
820 825 if call_def:
821 826 call_def = self.format(call_def)
822 827 # it may never be the case that call def and definition differ,
823 828 # but don't include the same signature twice
824 829 if call_def != out.get('definition'):
825 830 out['call_def'] = call_def
826 831 call_ds = getdoc(obj.__call__)
827 832 # Skip Python's auto-generated docstrings
828 833 if call_ds == _func_call_docstring:
829 834 call_ds = None
830 835 if call_ds:
831 836 out['call_docstring'] = call_ds
832 837
833 838 # Compute the object's argspec as a callable. The key is to decide
834 839 # whether to pull it from the object itself, from its __init__ or
835 840 # from its __call__ method.
836 841
837 842 if inspect.isclass(obj):
838 843 # Old-style classes need not have an __init__
839 844 callable_obj = getattr(obj, "__init__", None)
840 845 elif callable(obj):
841 846 callable_obj = obj
842 847 else:
843 848 callable_obj = None
844 849
845 850 if callable_obj:
846 851 try:
847 852 argspec = getargspec(callable_obj)
848 853 except (TypeError, AttributeError):
849 854 # For extensions/builtins we can't retrieve the argspec
850 855 pass
851 856 else:
852 857 # named tuples' _asdict() method returns an OrderedDict, but we
853 858 # we want a normal
854 859 out['argspec'] = argspec_dict = dict(argspec._asdict())
855 860 # We called this varkw before argspec became a named tuple.
856 861 # With getfullargspec it's also called varkw.
857 862 if 'varkw' not in argspec_dict:
858 863 argspec_dict['varkw'] = argspec_dict.pop('keywords')
859 864
860 865 return object_info(**out)
861 866
862 867 def psearch(self,pattern,ns_table,ns_search=[],
863 868 ignore_case=False,show_all=False):
864 869 """Search namespaces with wildcards for objects.
865 870
866 871 Arguments:
867 872
868 873 - pattern: string containing shell-like wildcards to use in namespace
869 874 searches and optionally a type specification to narrow the search to
870 875 objects of that type.
871 876
872 877 - ns_table: dict of name->namespaces for search.
873 878
874 879 Optional arguments:
875 880
876 881 - ns_search: list of namespace names to include in search.
877 882
878 883 - ignore_case(False): make the search case-insensitive.
879 884
880 885 - show_all(False): show all names, including those starting with
881 886 underscores.
882 887 """
883 888 #print 'ps pattern:<%r>' % pattern # dbg
884 889
885 890 # defaults
886 891 type_pattern = 'all'
887 892 filter = ''
888 893
889 894 cmds = pattern.split()
890 895 len_cmds = len(cmds)
891 896 if len_cmds == 1:
892 897 # Only filter pattern given
893 898 filter = cmds[0]
894 899 elif len_cmds == 2:
895 900 # Both filter and type specified
896 901 filter,type_pattern = cmds
897 902 else:
898 903 raise ValueError('invalid argument string for psearch: <%s>' %
899 904 pattern)
900 905
901 906 # filter search namespaces
902 907 for name in ns_search:
903 908 if name not in ns_table:
904 909 raise ValueError('invalid namespace <%s>. Valid names: %s' %
905 910 (name,ns_table.keys()))
906 911
907 912 #print 'type_pattern:',type_pattern # dbg
908 913 search_result, namespaces_seen = set(), set()
909 914 for ns_name in ns_search:
910 915 ns = ns_table[ns_name]
911 916 # Normally, locals and globals are the same, so we just check one.
912 917 if id(ns) in namespaces_seen:
913 918 continue
914 919 namespaces_seen.add(id(ns))
915 920 tmp_res = list_namespace(ns, type_pattern, filter,
916 921 ignore_case=ignore_case, show_all=show_all)
917 922 search_result.update(tmp_res)
918 923
919 924 page.page('\n'.join(sorted(search_result)))
@@ -1,437 +1,422 b''
1 1 # encoding: utf-8
2 2 """
3 3 A mixin for :class:`~IPython.core.application.Application` classes that
4 4 launch InteractiveShell instances, load extensions, etc.
5
6 Authors
7 -------
8
9 * Min Ragan-Kelley
10 5 """
11 6
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
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 #-----------------------------------------------------------------------------
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
22 9
23 10 from __future__ import absolute_import
24 11 from __future__ import print_function
25 12
26 13 import glob
27 14 import os
28 15 import sys
29 16
30 17 from IPython.config.application import boolean_flag
31 18 from IPython.config.configurable import Configurable
32 19 from IPython.config.loader import Config
33 20 from IPython.core import pylabtools
34 21 from IPython.utils import py3compat
35 22 from IPython.utils.contexts import preserve_keys
36 23 from IPython.utils.path import filefind
37 24 from IPython.utils.traitlets import (
38 25 Unicode, Instance, List, Bool, CaselessStrEnum
39 26 )
40 27 from IPython.lib.inputhook import guis
41 28
42 29 #-----------------------------------------------------------------------------
43 30 # Aliases and Flags
44 31 #-----------------------------------------------------------------------------
45 32
46 33 gui_keys = tuple(sorted([ key for key in guis if key is not None ]))
47 34
48 35 backend_keys = sorted(pylabtools.backends.keys())
49 36 backend_keys.insert(0, 'auto')
50 37
51 38 shell_flags = {}
52 39
53 40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
54 41 addflag('autoindent', 'InteractiveShell.autoindent',
55 42 'Turn on autoindenting.', 'Turn off autoindenting.'
56 43 )
57 44 addflag('automagic', 'InteractiveShell.automagic',
58 45 """Turn on the auto calling of magic commands. Type %%magic at the
59 46 IPython prompt for more information.""",
60 47 'Turn off the auto calling of magic commands.'
61 48 )
62 49 addflag('pdb', 'InteractiveShell.pdb',
63 50 "Enable auto calling the pdb debugger after every exception.",
64 51 "Disable auto calling the pdb debugger after every exception."
65 52 )
66 53 # pydb flag doesn't do any config, as core.debugger switches on import,
67 54 # which is before parsing. This just allows the flag to be passed.
68 55 shell_flags.update(dict(
69 56 pydb = ({},
70 57 """Use the third party 'pydb' package as debugger, instead of pdb.
71 58 Requires that pydb is installed."""
72 59 )
73 60 ))
74 61 addflag('pprint', 'PlainTextFormatter.pprint',
75 62 "Enable auto pretty printing of results.",
76 63 "Disable auto pretty printing of results."
77 64 )
78 65 addflag('color-info', 'InteractiveShell.color_info',
79 66 """IPython can display information about objects via a set of functions,
80 67 and optionally can use colors for this, syntax highlighting
81 68 source code and various other elements. This is on by default, but can cause
82 69 problems with some pagers. If you see such problems, you can disable the
83 70 colours.""",
84 71 "Disable using colors for info related things."
85 72 )
86 73 addflag('deep-reload', 'InteractiveShell.deep_reload',
87 74 """Enable deep (recursive) reloading by default. IPython can use the
88 75 deep_reload module which reloads changes in modules recursively (it
89 76 replaces the reload() function, so you don't need to change anything to
90 77 use it). deep_reload() forces a full reload of modules whose code may
91 78 have changed, which the default reload() function does not. When
92 79 deep_reload is off, IPython will use the normal reload(), but
93 80 deep_reload will still be available as dreload(). This feature is off
94 81 by default [which means that you have both normal reload() and
95 82 dreload()].""",
96 83 "Disable deep (recursive) reloading by default."
97 84 )
98 85 nosep_config = Config()
99 86 nosep_config.InteractiveShell.separate_in = ''
100 87 nosep_config.InteractiveShell.separate_out = ''
101 88 nosep_config.InteractiveShell.separate_out2 = ''
102 89
103 90 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
104 91 shell_flags['pylab'] = (
105 92 {'InteractiveShellApp' : {'pylab' : 'auto'}},
106 93 """Pre-load matplotlib and numpy for interactive use with
107 94 the default matplotlib backend."""
108 95 )
109 96 shell_flags['matplotlib'] = (
110 97 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
111 98 """Configure matplotlib for interactive use with
112 99 the default matplotlib backend."""
113 100 )
114 101
115 102 # it's possible we don't want short aliases for *all* of these:
116 103 shell_aliases = dict(
117 104 autocall='InteractiveShell.autocall',
118 105 colors='InteractiveShell.colors',
119 106 logfile='InteractiveShell.logfile',
120 107 logappend='InteractiveShell.logappend',
121 108 c='InteractiveShellApp.code_to_run',
122 109 m='InteractiveShellApp.module_to_run',
123 110 ext='InteractiveShellApp.extra_extension',
124 111 gui='InteractiveShellApp.gui',
125 112 pylab='InteractiveShellApp.pylab',
126 113 matplotlib='InteractiveShellApp.matplotlib',
127 114 )
128 115 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
129 116
130 117 #-----------------------------------------------------------------------------
131 118 # Main classes and functions
132 119 #-----------------------------------------------------------------------------
133 120
134 121 class InteractiveShellApp(Configurable):
135 122 """A Mixin for applications that start InteractiveShell instances.
136 123
137 124 Provides configurables for loading extensions and executing files
138 125 as part of configuring a Shell environment.
139 126
140 127 The following methods should be called by the :meth:`initialize` method
141 128 of the subclass:
142 129
143 130 - :meth:`init_path`
144 131 - :meth:`init_shell` (to be implemented by the subclass)
145 132 - :meth:`init_gui_pylab`
146 133 - :meth:`init_extensions`
147 134 - :meth:`init_code`
148 135 """
149 136 extensions = List(Unicode, config=True,
150 137 help="A list of dotted module names of IPython extensions to load."
151 138 )
152 139 extra_extension = Unicode('', config=True,
153 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 143 # Extensions that are always loaded (not configurable)
161 144 default_extensions = List(Unicode, [u'storemagic'], config=False)
162 145
163 146 hide_initial_ns = Bool(True, config=True,
164 147 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
165 148 be hidden from tools like %who?"""
166 149 )
167 150
168 151 exec_files = List(Unicode, config=True,
169 152 help="""List of files to run at IPython startup."""
170 153 )
171 154 exec_PYTHONSTARTUP = Bool(True, config=True,
172 155 help="""Run the file referenced by the PYTHONSTARTUP environment
173 156 variable at IPython startup."""
174 157 )
175 158 file_to_run = Unicode('', config=True,
176 159 help="""A file to be run""")
177 160
178 161 exec_lines = List(Unicode, config=True,
179 162 help="""lines of code to run at IPython startup."""
180 163 )
181 164 code_to_run = Unicode('', config=True,
182 165 help="Execute the given command string."
183 166 )
184 167 module_to_run = Unicode('', config=True,
185 168 help="Run the module as a script."
186 169 )
187 170 gui = CaselessStrEnum(gui_keys, config=True,
188 171 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
189 172 )
190 173 matplotlib = CaselessStrEnum(backend_keys,
191 174 config=True,
192 175 help="""Configure matplotlib for interactive use with
193 176 the default matplotlib backend."""
194 177 )
195 178 pylab = CaselessStrEnum(backend_keys,
196 179 config=True,
197 180 help="""Pre-load matplotlib and numpy for interactive use,
198 181 selecting a particular matplotlib backend and loop integration.
199 182 """
200 183 )
201 184 pylab_import_all = Bool(True, config=True,
202 185 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
203 186 and an ``import *`` is done from numpy and pylab, when using pylab mode.
204 187
205 188 When False, pylab mode should not import any names into the user namespace.
206 189 """
207 190 )
208 191 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
209 192
210 193 user_ns = Instance(dict, args=None, allow_none=True)
211 194 def _user_ns_changed(self, name, old, new):
212 195 if self.shell is not None:
213 196 self.shell.user_ns = new
214 197 self.shell.init_user_ns()
215 198
216 199 def init_path(self):
217 200 """Add current working directory, '', to sys.path"""
218 201 if sys.path[0] != '':
219 202 sys.path.insert(0, '')
220 203
221 204 def init_shell(self):
222 205 raise NotImplementedError("Override in subclasses")
223 206
224 207 def init_gui_pylab(self):
225 208 """Enable GUI event loop integration, taking pylab into account."""
226 209 enable = False
227 210 shell = self.shell
228 211 if self.pylab:
229 212 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
230 213 key = self.pylab
231 214 elif self.matplotlib:
232 215 enable = shell.enable_matplotlib
233 216 key = self.matplotlib
234 217 elif self.gui:
235 218 enable = shell.enable_gui
236 219 key = self.gui
237 220
238 221 if not enable:
239 222 return
240 223
241 224 try:
242 225 r = enable(key)
243 226 except ImportError:
244 227 self.log.warn("Eventloop or matplotlib integration failed. Is matplotlib installed?")
245 228 self.shell.showtraceback()
246 229 return
247 230 except Exception:
248 231 self.log.warn("GUI event loop or pylab initialization failed")
249 232 self.shell.showtraceback()
250 233 return
251 234
252 235 if isinstance(r, tuple):
253 236 gui, backend = r[:2]
254 237 self.log.info("Enabling GUI event loop integration, "
255 238 "eventloop=%s, matplotlib=%s", gui, backend)
256 239 if key == "auto":
257 240 print("Using matplotlib backend: %s" % backend)
258 241 else:
259 242 gui = r
260 243 self.log.info("Enabling GUI event loop integration, "
261 244 "eventloop=%s", gui)
262 245
263 246 def init_extensions(self):
264 247 """Load all IPython extensions in IPythonApp.extensions.
265 248
266 249 This uses the :meth:`ExtensionManager.load_extensions` to load all
267 250 the extensions listed in ``self.extensions``.
268 251 """
269 252 try:
270 253 self.log.debug("Loading IPython extensions...")
271 254 extensions = self.default_extensions + self.extensions
255 if self.extra_extension:
256 extensions.append(self.extra_extension)
272 257 for ext in extensions:
273 258 try:
274 259 self.log.info("Loading IPython extension: %s" % ext)
275 260 self.shell.extension_manager.load_extension(ext)
276 261 except:
277 262 msg = ("Error in loading extension: {ext}\n"
278 263 "Check your config files in {location}".format(
279 264 ext=ext,
280 265 location=self.profile_dir.location
281 266 ))
282 267 self.log.warn(msg, exc_info=True)
283 268 except:
284 269 self.log.warn("Unknown error in loading extensions:", exc_info=True)
285 270
286 271 def init_code(self):
287 272 """run the pre-flight code, specified via exec_lines"""
288 273 self._run_startup_files()
289 274 self._run_exec_lines()
290 275 self._run_exec_files()
291 276
292 277 # Hide variables defined here from %who etc.
293 278 if self.hide_initial_ns:
294 279 self.shell.user_ns_hidden.update(self.shell.user_ns)
295 280
296 281 # command-line execution (ipython -i script.py, ipython -m module)
297 282 # should *not* be excluded from %whos
298 283 self._run_cmd_line_code()
299 284 self._run_module()
300 285
301 286 # flush output, so itwon't be attached to the first cell
302 287 sys.stdout.flush()
303 288 sys.stderr.flush()
304 289
305 290 def _run_exec_lines(self):
306 291 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
307 292 if not self.exec_lines:
308 293 return
309 294 try:
310 295 self.log.debug("Running code from IPythonApp.exec_lines...")
311 296 for line in self.exec_lines:
312 297 try:
313 298 self.log.info("Running code in user namespace: %s" %
314 299 line)
315 300 self.shell.run_cell(line, store_history=False)
316 301 except:
317 302 self.log.warn("Error in executing line in user "
318 303 "namespace: %s" % line)
319 304 self.shell.showtraceback()
320 305 except:
321 306 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
322 307 self.shell.showtraceback()
323 308
324 309 def _exec_file(self, fname, shell_futures=False):
325 310 try:
326 311 full_filename = filefind(fname, [u'.', self.ipython_dir])
327 312 except IOError as e:
328 313 self.log.warn("File not found: %r"%fname)
329 314 return
330 315 # Make sure that the running script gets a proper sys.argv as if it
331 316 # were run from a system shell.
332 317 save_argv = sys.argv
333 318 sys.argv = [full_filename] + self.extra_args[1:]
334 319 # protect sys.argv from potential unicode strings on Python 2:
335 320 if not py3compat.PY3:
336 321 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
337 322 try:
338 323 if os.path.isfile(full_filename):
339 324 self.log.info("Running file in user namespace: %s" %
340 325 full_filename)
341 326 # Ensure that __file__ is always defined to match Python
342 327 # behavior.
343 328 with preserve_keys(self.shell.user_ns, '__file__'):
344 329 self.shell.user_ns['__file__'] = fname
345 330 if full_filename.endswith('.ipy'):
346 331 self.shell.safe_execfile_ipy(full_filename,
347 332 shell_futures=shell_futures)
348 333 else:
349 334 # default to python, even without extension
350 335 self.shell.safe_execfile(full_filename,
351 336 self.shell.user_ns,
352 337 shell_futures=shell_futures)
353 338 finally:
354 339 sys.argv = save_argv
355 340
356 341 def _run_startup_files(self):
357 342 """Run files from profile startup directory"""
358 343 startup_dir = self.profile_dir.startup_dir
359 344 startup_files = []
360 345
361 346 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
362 347 not (self.file_to_run or self.code_to_run or self.module_to_run):
363 348 python_startup = os.environ['PYTHONSTARTUP']
364 349 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
365 350 try:
366 351 self._exec_file(python_startup)
367 352 except:
368 353 self.log.warn("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
369 354 self.shell.showtraceback()
370 355 finally:
371 356 # Many PYTHONSTARTUP files set up the readline completions,
372 357 # but this is often at odds with IPython's own completions.
373 358 # Do not allow PYTHONSTARTUP to set up readline.
374 359 if self.shell.has_readline:
375 360 self.shell.set_readline_completer()
376 361
377 362 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
378 363 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
379 364 if not startup_files:
380 365 return
381 366
382 367 self.log.debug("Running startup files from %s...", startup_dir)
383 368 try:
384 369 for fname in sorted(startup_files):
385 370 self._exec_file(fname)
386 371 except:
387 372 self.log.warn("Unknown error in handling startup files:")
388 373 self.shell.showtraceback()
389 374
390 375 def _run_exec_files(self):
391 376 """Run files from IPythonApp.exec_files"""
392 377 if not self.exec_files:
393 378 return
394 379
395 380 self.log.debug("Running files in IPythonApp.exec_files...")
396 381 try:
397 382 for fname in self.exec_files:
398 383 self._exec_file(fname)
399 384 except:
400 385 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
401 386 self.shell.showtraceback()
402 387
403 388 def _run_cmd_line_code(self):
404 389 """Run code or file specified at the command-line"""
405 390 if self.code_to_run:
406 391 line = self.code_to_run
407 392 try:
408 393 self.log.info("Running code given at command line (c=): %s" %
409 394 line)
410 395 self.shell.run_cell(line, store_history=False)
411 396 except:
412 397 self.log.warn("Error in executing line in user namespace: %s" %
413 398 line)
414 399 self.shell.showtraceback()
415 400
416 401 # Like Python itself, ignore the second if the first of these is present
417 402 elif self.file_to_run:
418 403 fname = self.file_to_run
419 404 try:
420 405 self._exec_file(fname, shell_futures=True)
421 406 except:
422 407 self.log.warn("Error in executing file in user namespace: %s" %
423 408 fname)
424 409 self.shell.showtraceback()
425 410
426 411 def _run_module(self):
427 412 """Run module specified at the command-line."""
428 413 if self.module_to_run:
429 414 # Make sure that the module gets a proper sys.argv as if it were
430 415 # run using `python -m`.
431 416 save_argv = sys.argv
432 417 sys.argv = [sys.executable] + self.extra_args
433 418 try:
434 419 self.shell.safe_run_module(self.module_to_run,
435 420 self.shell.user_ns)
436 421 finally:
437 422 sys.argv = save_argv
@@ -1,373 +1,374 b''
1 1 """Tests for the object inspection functionality.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2010-2011 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14 from __future__ import print_function
15 15
16 16 # Stdlib imports
17 17 import os
18 18 import re
19 19
20 20 # Third-party imports
21 21 import nose.tools as nt
22 22
23 23 # Our own imports
24 24 from .. import oinspect
25 25 from IPython.core.magic import (Magics, magics_class, line_magic,
26 26 cell_magic, line_cell_magic,
27 27 register_line_magic, register_cell_magic,
28 28 register_line_cell_magic)
29 29 from IPython.external.decorator import decorator
30 30 from IPython.testing.decorators import skipif
31 from IPython.utils.path import compress_user
31 32 from IPython.utils import py3compat
32 33
33 34
34 35 #-----------------------------------------------------------------------------
35 36 # Globals and constants
36 37 #-----------------------------------------------------------------------------
37 38
38 39 inspector = oinspect.Inspector()
39 40 ip = get_ipython()
40 41
41 42 #-----------------------------------------------------------------------------
42 43 # Local utilities
43 44 #-----------------------------------------------------------------------------
44 45
45 46 # WARNING: since this test checks the line number where a function is
46 47 # defined, if any code is inserted above, the following line will need to be
47 48 # updated. Do NOT insert any whitespace between the next line and the function
48 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 51 def test_find_source_lines():
51 52 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
52 53 THIS_LINE_NUMBER+1)
53 54
54 55
55 56 # A couple of utilities to ensure these tests work the same from a source or a
56 57 # binary install
57 58 def pyfile(fname):
58 59 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
59 60
60 61
61 62 def match_pyfiles(f1, f2):
62 63 nt.assert_equal(pyfile(f1), pyfile(f2))
63 64
64 65
65 66 def test_find_file():
66 67 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
67 68
68 69
69 70 def test_find_file_decorated1():
70 71
71 72 @decorator
72 73 def noop1(f):
73 74 def wrapper():
74 75 return f(*a, **kw)
75 76 return wrapper
76 77
77 78 @noop1
78 79 def f(x):
79 80 "My docstring"
80 81
81 82 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
82 83 nt.assert_equal(f.__doc__, "My docstring")
83 84
84 85
85 86 def test_find_file_decorated2():
86 87
87 88 @decorator
88 89 def noop2(f, *a, **kw):
89 90 return f(*a, **kw)
90 91
91 92 @noop2
92 93 def f(x):
93 94 "My docstring 2"
94 95
95 96 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
96 97 nt.assert_equal(f.__doc__, "My docstring 2")
97 98
98 99
99 100 def test_find_file_magic():
100 101 run = ip.find_line_magic('run')
101 102 nt.assert_not_equal(oinspect.find_file(run), None)
102 103
103 104
104 105 # A few generic objects we can then inspect in the tests below
105 106
106 107 class Call(object):
107 108 """This is the class docstring."""
108 109
109 110 def __init__(self, x, y=1):
110 111 """This is the constructor docstring."""
111 112
112 113 def __call__(self, *a, **kw):
113 114 """This is the call docstring."""
114 115
115 116 def method(self, x, z=2):
116 117 """Some method's docstring"""
117 118
118 119 class SimpleClass(object):
119 120 def method(self, x, z=2):
120 121 """Some method's docstring"""
121 122
122 123
123 124 class OldStyle:
124 125 """An old-style class for testing."""
125 126 pass
126 127
127 128
128 129 def f(x, y=2, *a, **kw):
129 130 """A simple function."""
130 131
131 132
132 133 def g(y, z=3, *a, **kw):
133 134 pass # no docstring
134 135
135 136
136 137 @register_line_magic
137 138 def lmagic(line):
138 139 "A line magic"
139 140
140 141
141 142 @register_cell_magic
142 143 def cmagic(line, cell):
143 144 "A cell magic"
144 145
145 146
146 147 @register_line_cell_magic
147 148 def lcmagic(line, cell=None):
148 149 "A line/cell magic"
149 150
150 151
151 152 @magics_class
152 153 class SimpleMagics(Magics):
153 154 @line_magic
154 155 def Clmagic(self, cline):
155 156 "A class-based line magic"
156 157
157 158 @cell_magic
158 159 def Ccmagic(self, cline, ccell):
159 160 "A class-based cell magic"
160 161
161 162 @line_cell_magic
162 163 def Clcmagic(self, cline, ccell=None):
163 164 "A class-based line/cell magic"
164 165
165 166
166 167 class Awkward(object):
167 168 def __getattr__(self, name):
168 169 raise Exception(name)
169 170
170 171
171 172 def check_calltip(obj, name, call, docstring):
172 173 """Generic check pattern all calltip tests will use"""
173 174 info = inspector.info(obj, name)
174 175 call_line, ds = oinspect.call_tip(info)
175 176 nt.assert_equal(call_line, call)
176 177 nt.assert_equal(ds, docstring)
177 178
178 179 #-----------------------------------------------------------------------------
179 180 # Tests
180 181 #-----------------------------------------------------------------------------
181 182
182 183 def test_calltip_class():
183 184 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
184 185
185 186
186 187 def test_calltip_instance():
187 188 c = Call(1)
188 189 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
189 190
190 191
191 192 def test_calltip_method():
192 193 c = Call(1)
193 194 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
194 195
195 196
196 197 def test_calltip_function():
197 198 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
198 199
199 200
200 201 def test_calltip_function2():
201 202 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
202 203
203 204
204 205 def test_calltip_builtin():
205 206 check_calltip(sum, 'sum', None, sum.__doc__)
206 207
207 208
208 209 def test_calltip_line_magic():
209 210 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
210 211
211 212
212 213 def test_calltip_cell_magic():
213 214 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
214 215
215 216
216 217 def test_calltip_line_cell_magic():
217 218 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
218 219 "A line/cell magic")
219 220
220 221
221 222 def test_class_magics():
222 223 cm = SimpleMagics(ip)
223 224 ip.register_magics(cm)
224 225 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
225 226 "A class-based line magic")
226 227 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
227 228 "A class-based cell magic")
228 229 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
229 230 "A class-based line/cell magic")
230 231
231 232
232 233 def test_info():
233 234 "Check that Inspector.info fills out various fields as expected."
234 235 i = inspector.info(Call, oname='Call')
235 236 nt.assert_equal(i['type_name'], 'type')
236 237 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
237 238 nt.assert_equal(i['base_class'], expted_class)
238 239 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
239 240 fname = __file__
240 241 if fname.endswith(".pyc"):
241 242 fname = fname[:-1]
242 243 # case-insensitive comparison needed on some filesystems
243 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 246 nt.assert_equal(i['definition'], None)
246 247 nt.assert_equal(i['docstring'], Call.__doc__)
247 248 nt.assert_equal(i['source'], None)
248 249 nt.assert_true(i['isclass'])
249 250 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
250 251 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
251 252
252 253 i = inspector.info(Call, detail_level=1)
253 254 nt.assert_not_equal(i['source'], None)
254 255 nt.assert_equal(i['docstring'], None)
255 256
256 257 c = Call(1)
257 258 c.__doc__ = "Modified instance docstring"
258 259 i = inspector.info(c)
259 260 nt.assert_equal(i['type_name'], 'Call')
260 261 nt.assert_equal(i['docstring'], "Modified instance docstring")
261 262 nt.assert_equal(i['class_docstring'], Call.__doc__)
262 263 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
263 264 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
264 265
265 266 # Test old-style classes, which for example may not have an __init__ method.
266 267 if not py3compat.PY3:
267 268 i = inspector.info(OldStyle)
268 269 nt.assert_equal(i['type_name'], 'classobj')
269 270
270 271 i = inspector.info(OldStyle())
271 272 nt.assert_equal(i['type_name'], 'instance')
272 273 nt.assert_equal(i['docstring'], OldStyle.__doc__)
273 274
274 275 def test_info_awkward():
275 276 # Just test that this doesn't throw an error.
276 277 i = inspector.info(Awkward())
277 278
278 279 def test_calldef_none():
279 280 # We should ignore __call__ for all of these.
280 281 for obj in [f, SimpleClass().method, any, str.upper]:
281 282 print(obj)
282 283 i = inspector.info(obj)
283 284 nt.assert_is(i['call_def'], None)
284 285
285 286 if py3compat.PY3:
286 287 exec("def f_kwarg(pos, *, kwonly): pass")
287 288
288 289 @skipif(not py3compat.PY3)
289 290 def test_definition_kwonlyargs():
290 291 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
291 292 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n")
292 293
293 294 def test_getdoc():
294 295 class A(object):
295 296 """standard docstring"""
296 297 pass
297 298
298 299 class B(object):
299 300 """standard docstring"""
300 301 def getdoc(self):
301 302 return "custom docstring"
302 303
303 304 class C(object):
304 305 """standard docstring"""
305 306 def getdoc(self):
306 307 return None
307 308
308 309 a = A()
309 310 b = B()
310 311 c = C()
311 312
312 313 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
313 314 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
314 315 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
315 316
316 317
317 318 def test_empty_property_has_no_source():
318 319 i = inspector.info(property(), detail_level=1)
319 320 nt.assert_is(i['source'], None)
320 321
321 322
322 323 def test_property_sources():
323 324 import zlib
324 325
325 326 class A(object):
326 327 @property
327 328 def foo(self):
328 329 return 'bar'
329 330
330 331 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
331 332
332 333 id = property(id)
333 334 compress = property(zlib.compress)
334 335
335 336 i = inspector.info(A.foo, detail_level=1)
336 337 nt.assert_in('def foo(self):', i['source'])
337 338 nt.assert_in('lambda self, v:', i['source'])
338 339
339 340 i = inspector.info(A.id, detail_level=1)
340 341 nt.assert_in('fget = <function id>', i['source'])
341 342
342 343 i = inspector.info(A.compress, detail_level=1)
343 344 nt.assert_in('fget = <function zlib.compress>', i['source'])
344 345
345 346
346 347 def test_property_docstring_is_in_info_for_detail_level_0():
347 348 class A(object):
348 349 @property
349 350 def foobar():
350 351 """This is `foobar` property."""
351 352 pass
352 353
353 354 ip.user_ns['a_obj'] = A()
354 355 nt.assert_equals(
355 356 'This is `foobar` property.',
356 357 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
357 358
358 359 ip.user_ns['a_cls'] = A
359 360 nt.assert_equals(
360 361 'This is `foobar` property.',
361 362 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
362 363
363 364
364 365 def test_pdef():
365 366 # See gh-1914
366 367 def foo(): pass
367 368 inspector.pdef(foo, 'foo')
368 369
369 370 def test_pinfo_nonascii():
370 371 # See gh-1177
371 372 from . import nonascii2
372 373 ip.user_ns['nonascii2'] = nonascii2
373 374 ip._inspect('pinfo', 'nonascii2', detail_level=1)
@@ -1,217 +1,219 b''
1 1 // Copyright (c) IPython Development Team.
2 2 // Distributed under the terms of the Modified BSD License.
3 3
4 4 define([
5 5 'base/js/namespace',
6 6 'jquery',
7 7 'base/js/utils',
8 8 ], function(IPython, $, utils) {
9 9 "use strict";
10 10
11 11 //-----------------------------------------------------------------------
12 12 // CommManager class
13 13 //-----------------------------------------------------------------------
14 14
15 15 var CommManager = function (kernel) {
16 16 this.comms = {};
17 17 this.targets = {};
18 18 if (kernel !== undefined) {
19 19 this.init_kernel(kernel);
20 20 }
21 21 };
22 22
23 23 CommManager.prototype.init_kernel = function (kernel) {
24 24 /**
25 25 * connect the kernel, and register message handlers
26 26 */
27 27 this.kernel = kernel;
28 28 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
29 29 for (var i = 0; i < msg_types.length; i++) {
30 30 var msg_type = msg_types[i];
31 31 kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
32 32 }
33 33 };
34 34
35 35 CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata) {
36 36 /**
37 37 * Create a new Comm, register it, and open its Kernel-side counterpart
38 38 * Mimics the auto-registration in `Comm.__init__` in the IPython Comm
39 39 */
40 40 var comm = new Comm(target_name);
41 41 this.register_comm(comm);
42 42 comm.open(data, callbacks, metadata);
43 43 return comm;
44 44 };
45 45
46 46 CommManager.prototype.register_target = function (target_name, f) {
47 47 /**
48 48 * Register a target function for a given target name
49 49 */
50 50 this.targets[target_name] = f;
51 51 };
52 52
53 53 CommManager.prototype.unregister_target = function (target_name, f) {
54 54 /**
55 55 * Unregister a target function for a given target name
56 56 */
57 57 delete this.targets[target_name];
58 58 };
59 59
60 60 CommManager.prototype.register_comm = function (comm) {
61 61 /**
62 62 * Register a comm in the mapping
63 63 */
64 64 this.comms[comm.comm_id] = Promise.resolve(comm);
65 65 comm.kernel = this.kernel;
66 66 return comm.comm_id;
67 67 };
68 68
69 69 CommManager.prototype.unregister_comm = function (comm) {
70 70 /**
71 71 * Remove a comm from the mapping
72 72 */
73 73 delete this.comms[comm.comm_id];
74 74 };
75 75
76 76 // comm message handlers
77 77
78 78 CommManager.prototype.comm_open = function (msg) {
79 79 var content = msg.content;
80 80 var that = this;
81 81 var comm_id = content.comm_id;
82 82
83 83 this.comms[comm_id] = utils.load_class(content.target_name, content.target_module,
84 84 this.targets).then(function(target) {
85 85 var comm = new Comm(content.target_name, comm_id);
86 86 comm.kernel = that.kernel;
87 87 try {
88 88 var response = target(comm, msg);
89 89 } catch (e) {
90 90 comm.close();
91 91 that.unregister_comm(comm);
92 92 var wrapped_error = new utils.WrappedError("Exception opening new comm", e);
93 93 console.error(wrapped_error);
94 94 return Promise.reject(wrapped_error);
95 95 }
96 96 // Regardless of the target return value, we need to
97 97 // then return the comm
98 98 return Promise.resolve(response).then(function() {return comm;});
99 99 }, utils.reject('Could not open comm', true));
100 100 return this.comms[comm_id];
101 101 };
102 102
103 103 CommManager.prototype.comm_close = function(msg) {
104 104 var content = msg.content;
105 105 if (this.comms[content.comm_id] === undefined) {
106 106 console.error('Comm promise not found for comm id ' + content.comm_id);
107 107 return;
108 108 }
109 109 var that = this;
110 110 this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
111 111 that.unregister_comm(comm);
112 112 try {
113 113 comm.handle_close(msg);
114 114 } catch (e) {
115 115 console.log("Exception closing comm: ", e, e.stack, msg);
116 116 }
117 117 // don't return a comm, so that further .then() functions
118 118 // get an undefined comm input
119 119 });
120 return this.comms[content.comm_id];
120 121 };
121 122
122 123 CommManager.prototype.comm_msg = function(msg) {
123 124 var content = msg.content;
124 125 if (this.comms[content.comm_id] === undefined) {
125 126 console.error('Comm promise not found for comm id ' + content.comm_id);
126 127 return;
127 128 }
128 129
129 130 this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
130 131 try {
131 132 comm.handle_msg(msg);
132 133 } catch (e) {
133 134 console.log("Exception handling comm msg: ", e, e.stack, msg);
134 135 }
135 136 return comm;
136 137 });
138 return this.comms[content.comm_id];
137 139 };
138 140
139 141 //-----------------------------------------------------------------------
140 142 // Comm base class
141 143 //-----------------------------------------------------------------------
142 144
143 145 var Comm = function (target_name, comm_id) {
144 146 this.target_name = target_name;
145 147 this.comm_id = comm_id || utils.uuid();
146 148 this._msg_callback = this._close_callback = null;
147 149 };
148 150
149 151 // methods for sending messages
150 152 Comm.prototype.open = function (data, callbacks, metadata) {
151 153 var content = {
152 154 comm_id : this.comm_id,
153 155 target_name : this.target_name,
154 156 data : data || {},
155 157 };
156 158 return this.kernel.send_shell_message("comm_open", content, callbacks, metadata);
157 159 };
158 160
159 161 Comm.prototype.send = function (data, callbacks, metadata, buffers) {
160 162 var content = {
161 163 comm_id : this.comm_id,
162 164 data : data || {},
163 165 };
164 166 return this.kernel.send_shell_message("comm_msg", content, callbacks, metadata, buffers);
165 167 };
166 168
167 169 Comm.prototype.close = function (data, callbacks, metadata) {
168 170 var content = {
169 171 comm_id : this.comm_id,
170 172 data : data || {},
171 173 };
172 174 return this.kernel.send_shell_message("comm_close", content, callbacks, metadata);
173 175 };
174 176
175 177 // methods for registering callbacks for incoming messages
176 178 Comm.prototype._register_callback = function (key, callback) {
177 179 this['_' + key + '_callback'] = callback;
178 180 };
179 181
180 182 Comm.prototype.on_msg = function (callback) {
181 183 this._register_callback('msg', callback);
182 184 };
183 185
184 186 Comm.prototype.on_close = function (callback) {
185 187 this._register_callback('close', callback);
186 188 };
187 189
188 190 // methods for handling incoming messages
189 191
190 192 Comm.prototype._callback = function (key, msg) {
191 193 var callback = this['_' + key + '_callback'];
192 194 if (callback) {
193 195 try {
194 196 callback(msg);
195 197 } catch (e) {
196 198 console.log("Exception in Comm callback", e, e.stack, msg);
197 199 }
198 200 }
199 201 };
200 202
201 203 Comm.prototype.handle_msg = function (msg) {
202 204 this._callback('msg', msg);
203 205 };
204 206
205 207 Comm.prototype.handle_close = function (msg) {
206 208 this._callback('close', msg);
207 209 };
208 210
209 211 // For backwards compatability.
210 212 IPython.CommManager = CommManager;
211 213 IPython.Comm = Comm;
212 214
213 215 return {
214 216 'CommManager': CommManager,
215 217 'Comm': Comm
216 218 };
217 219 });
@@ -1,1052 +1,1064 b''
1 1 // Copyright (c) IPython Development Team.
2 2 // Distributed under the terms of the Modified BSD License.
3 3
4 4 define([
5 5 'base/js/namespace',
6 6 'jquery',
7 7 'base/js/utils',
8 8 './comm',
9 9 './serialize',
10 10 'widgets/js/init'
11 11 ], function(IPython, $, utils, comm, serialize, widgetmanager) {
12 12 "use strict";
13 13
14 14 /**
15 15 * A Kernel class to communicate with the Python kernel. This
16 16 * should generally not be constructed directly, but be created
17 17 * by. the `Session` object. Once created, this object should be
18 18 * used to communicate with the kernel.
19 19 *
20 20 * @class Kernel
21 21 * @param {string} kernel_service_url - the URL to access the kernel REST api
22 22 * @param {string} ws_url - the websockets URL
23 23 * @param {Notebook} notebook - notebook object
24 24 * @param {string} name - the kernel type (e.g. python3)
25 25 */
26 26 var Kernel = function (kernel_service_url, ws_url, notebook, name) {
27 27 this.events = notebook.events;
28 28
29 29 this.id = null;
30 30 this.name = name;
31 31 this.ws = null;
32 32
33 33 this.kernel_service_url = kernel_service_url;
34 34 this.kernel_url = null;
35 35 this.ws_url = ws_url || IPython.utils.get_body_data("wsUrl");
36 36 if (!this.ws_url) {
37 37 // trailing 's' in https will become wss for secure web sockets
38 38 this.ws_url = location.protocol.replace('http', 'ws') + "//" + location.host;
39 39 }
40 40
41 41 this.username = "username";
42 42 this.session_id = utils.uuid();
43 43 this._msg_callbacks = {};
44 this._msg_queue = Promise.resolve();
44 45 this.info_reply = {}; // kernel_info_reply stored here after starting
45 46
46 47 if (typeof(WebSocket) !== 'undefined') {
47 48 this.WebSocket = WebSocket;
48 49 } else if (typeof(MozWebSocket) !== 'undefined') {
49 50 this.WebSocket = MozWebSocket;
50 51 } else {
51 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 55 this.bind_events();
55 56 this.init_iopub_handlers();
56 57 this.comm_manager = new comm.CommManager(this);
57 58 this.widget_manager = new widgetmanager.WidgetManager(this.comm_manager, notebook);
58 59
59 60 this.last_msg_id = null;
60 61 this.last_msg_callbacks = {};
61 62
62 63 this._autorestart_attempt = 0;
63 64 this._reconnect_attempt = 0;
64 65 this.reconnect_limit = 7;
65 66 };
66 67
67 68 /**
68 69 * @function _get_msg
69 70 */
70 71 Kernel.prototype._get_msg = function (msg_type, content, metadata, buffers) {
71 72 var msg = {
72 73 header : {
73 74 msg_id : utils.uuid(),
74 75 username : this.username,
75 76 session : this.session_id,
76 77 msg_type : msg_type,
77 78 version : "5.0"
78 79 },
79 80 metadata : metadata || {},
80 81 content : content,
81 82 buffers : buffers || [],
82 83 parent_header : {}
83 84 };
84 85 return msg;
85 86 };
86 87
87 88 /**
88 89 * @function bind_events
89 90 */
90 91 Kernel.prototype.bind_events = function () {
91 92 var that = this;
92 93 this.events.on('send_input_reply.Kernel', function(evt, data) {
93 94 that.send_input_reply(data);
94 95 });
95 96
96 97 var record_status = function (evt, info) {
97 98 console.log('Kernel: ' + evt.type + ' (' + info.kernel.id + ')');
98 99 };
99 100
100 101 this.events.on('kernel_created.Kernel', record_status);
101 102 this.events.on('kernel_reconnecting.Kernel', record_status);
102 103 this.events.on('kernel_connected.Kernel', record_status);
103 104 this.events.on('kernel_starting.Kernel', record_status);
104 105 this.events.on('kernel_restarting.Kernel', record_status);
105 106 this.events.on('kernel_autorestarting.Kernel', record_status);
106 107 this.events.on('kernel_interrupting.Kernel', record_status);
107 108 this.events.on('kernel_disconnected.Kernel', record_status);
108 109 // these are commented out because they are triggered a lot, but can
109 110 // be uncommented for debugging purposes
110 111 //this.events.on('kernel_idle.Kernel', record_status);
111 112 //this.events.on('kernel_busy.Kernel', record_status);
112 113 this.events.on('kernel_ready.Kernel', record_status);
113 114 this.events.on('kernel_killed.Kernel', record_status);
114 115 this.events.on('kernel_dead.Kernel', record_status);
115 116
116 117 this.events.on('kernel_ready.Kernel', function () {
117 118 that._autorestart_attempt = 0;
118 119 });
119 120 this.events.on('kernel_connected.Kernel', function () {
120 121 that._reconnect_attempt = 0;
121 122 });
122 123 };
123 124
124 125 /**
125 126 * Initialize the iopub handlers.
126 127 *
127 128 * @function init_iopub_handlers
128 129 */
129 130 Kernel.prototype.init_iopub_handlers = function () {
130 131 var output_msg_types = ['stream', 'display_data', 'execute_result', 'error'];
131 132 this._iopub_handlers = {};
132 133 this.register_iopub_handler('status', $.proxy(this._handle_status_message, this));
133 134 this.register_iopub_handler('clear_output', $.proxy(this._handle_clear_output, this));
134 135 this.register_iopub_handler('execute_input', $.proxy(this._handle_input_message, this));
135 136
136 137 for (var i=0; i < output_msg_types.length; i++) {
137 138 this.register_iopub_handler(output_msg_types[i], $.proxy(this._handle_output_message, this));
138 139 }
139 140 };
140 141
141 142 /**
142 143 * GET /api/kernels
143 144 *
144 145 * Get the list of running kernels.
145 146 *
146 147 * @function list
147 148 * @param {function} [success] - function executed on ajax success
148 149 * @param {function} [error] - functon executed on ajax error
149 150 */
150 151 Kernel.prototype.list = function (success, error) {
151 152 $.ajax(this.kernel_service_url, {
152 153 processData: false,
153 154 cache: false,
154 155 type: "GET",
155 156 dataType: "json",
156 157 success: success,
157 158 error: this._on_error(error)
158 159 });
159 160 };
160 161
161 162 /**
162 163 * POST /api/kernels
163 164 *
164 165 * Start a new kernel.
165 166 *
166 167 * In general this shouldn't be used -- the kernel should be
167 168 * started through the session API. If you use this function and
168 169 * are also using the session API then your session and kernel
169 170 * WILL be out of sync!
170 171 *
171 172 * @function start
172 173 * @param {params} [Object] - parameters to include in the query string
173 174 * @param {function} [success] - function executed on ajax success
174 175 * @param {function} [error] - functon executed on ajax error
175 176 */
176 177 Kernel.prototype.start = function (params, success, error) {
177 178 var url = this.kernel_service_url;
178 179 var qs = $.param(params || {}); // query string for sage math stuff
179 180 if (qs !== "") {
180 181 url = url + "?" + qs;
181 182 }
182 183
183 184 this.events.trigger('kernel_starting.Kernel', {kernel: this});
184 185 var that = this;
185 186 var on_success = function (data, status, xhr) {
186 187 that.events.trigger('kernel_created.Kernel', {kernel: that});
187 188 that._kernel_created(data);
188 189 if (success) {
189 190 success(data, status, xhr);
190 191 }
191 192 };
192 193
193 194 $.ajax(url, {
194 195 processData: false,
195 196 cache: false,
196 197 type: "POST",
197 198 data: JSON.stringify({name: this.name}),
198 199 dataType: "json",
199 200 success: this._on_success(on_success),
200 201 error: this._on_error(error)
201 202 });
202 203
203 204 return url;
204 205 };
205 206
206 207 /**
207 208 * GET /api/kernels/[:kernel_id]
208 209 *
209 210 * Get information about the kernel.
210 211 *
211 212 * @function get_info
212 213 * @param {function} [success] - function executed on ajax success
213 214 * @param {function} [error] - functon executed on ajax error
214 215 */
215 216 Kernel.prototype.get_info = function (success, error) {
216 217 $.ajax(this.kernel_url, {
217 218 processData: false,
218 219 cache: false,
219 220 type: "GET",
220 221 dataType: "json",
221 222 success: this._on_success(success),
222 223 error: this._on_error(error)
223 224 });
224 225 };
225 226
226 227 /**
227 228 * DELETE /api/kernels/[:kernel_id]
228 229 *
229 230 * Shutdown the kernel.
230 231 *
231 232 * If you are also using sessions, then this function shoul NOT be
232 233 * used. Instead, use Session.delete. Otherwise, the session and
233 234 * kernel WILL be out of sync.
234 235 *
235 236 * @function kill
236 237 * @param {function} [success] - function executed on ajax success
237 238 * @param {function} [error] - functon executed on ajax error
238 239 */
239 240 Kernel.prototype.kill = function (success, error) {
240 241 this.events.trigger('kernel_killed.Kernel', {kernel: this});
241 242 this._kernel_dead();
242 243 $.ajax(this.kernel_url, {
243 244 processData: false,
244 245 cache: false,
245 246 type: "DELETE",
246 247 dataType: "json",
247 248 success: this._on_success(success),
248 249 error: this._on_error(error)
249 250 });
250 251 };
251 252
252 253 /**
253 254 * POST /api/kernels/[:kernel_id]/interrupt
254 255 *
255 256 * Interrupt the kernel.
256 257 *
257 258 * @function interrupt
258 259 * @param {function} [success] - function executed on ajax success
259 260 * @param {function} [error] - functon executed on ajax error
260 261 */
261 262 Kernel.prototype.interrupt = function (success, error) {
262 263 this.events.trigger('kernel_interrupting.Kernel', {kernel: this});
263 264
264 265 var that = this;
265 266 var on_success = function (data, status, xhr) {
266 267 /**
267 268 * get kernel info so we know what state the kernel is in
268 269 */
269 270 that.kernel_info();
270 271 if (success) {
271 272 success(data, status, xhr);
272 273 }
273 274 };
274 275
275 276 var url = utils.url_join_encode(this.kernel_url, 'interrupt');
276 277 $.ajax(url, {
277 278 processData: false,
278 279 cache: false,
279 280 type: "POST",
280 281 dataType: "json",
281 282 success: this._on_success(on_success),
282 283 error: this._on_error(error)
283 284 });
284 285 };
285 286
286 287 Kernel.prototype.restart = function (success, error) {
287 288 /**
288 289 * POST /api/kernels/[:kernel_id]/restart
289 290 *
290 291 * Restart the kernel.
291 292 *
292 293 * @function interrupt
293 294 * @param {function} [success] - function executed on ajax success
294 295 * @param {function} [error] - functon executed on ajax error
295 296 */
296 297 this.events.trigger('kernel_restarting.Kernel', {kernel: this});
297 298 this.stop_channels();
298 299
299 300 var that = this;
300 301 var on_success = function (data, status, xhr) {
301 302 that.events.trigger('kernel_created.Kernel', {kernel: that});
302 303 that._kernel_created(data);
303 304 if (success) {
304 305 success(data, status, xhr);
305 306 }
306 307 };
307 308
308 309 var on_error = function (xhr, status, err) {
309 310 that.events.trigger('kernel_dead.Kernel', {kernel: that});
310 311 that._kernel_dead();
311 312 if (error) {
312 313 error(xhr, status, err);
313 314 }
314 315 };
315 316
316 317 var url = utils.url_join_encode(this.kernel_url, 'restart');
317 318 $.ajax(url, {
318 319 processData: false,
319 320 cache: false,
320 321 type: "POST",
321 322 dataType: "json",
322 323 success: this._on_success(on_success),
323 324 error: this._on_error(on_error)
324 325 });
325 326 };
326 327
327 328 Kernel.prototype.reconnect = function () {
328 329 /**
329 330 * Reconnect to a disconnected kernel. This is not actually a
330 331 * standard HTTP request, but useful function nonetheless for
331 332 * reconnecting to the kernel if the connection is somehow lost.
332 333 *
333 334 * @function reconnect
334 335 */
335 336 if (this.is_connected()) {
336 337 return;
337 338 }
338 339 this._reconnect_attempt = this._reconnect_attempt + 1;
339 340 this.events.trigger('kernel_reconnecting.Kernel', {
340 341 kernel: this,
341 342 attempt: this._reconnect_attempt,
342 343 });
343 344 this.start_channels();
344 345 };
345 346
346 347 Kernel.prototype._on_success = function (success) {
347 348 /**
348 349 * Handle a successful AJAX request by updating the kernel id and
349 350 * name from the response, and then optionally calling a provided
350 351 * callback.
351 352 *
352 353 * @function _on_success
353 354 * @param {function} success - callback
354 355 */
355 356 var that = this;
356 357 return function (data, status, xhr) {
357 358 if (data) {
358 359 that.id = data.id;
359 360 that.name = data.name;
360 361 }
361 362 that.kernel_url = utils.url_join_encode(that.kernel_service_url, that.id);
362 363 if (success) {
363 364 success(data, status, xhr);
364 365 }
365 366 };
366 367 };
367 368
368 369 Kernel.prototype._on_error = function (error) {
369 370 /**
370 371 * Handle a failed AJAX request by logging the error message, and
371 372 * then optionally calling a provided callback.
372 373 *
373 374 * @function _on_error
374 375 * @param {function} error - callback
375 376 */
376 377 return function (xhr, status, err) {
377 378 utils.log_ajax_error(xhr, status, err);
378 379 if (error) {
379 380 error(xhr, status, err);
380 381 }
381 382 };
382 383 };
383 384
384 385 Kernel.prototype._kernel_created = function (data) {
385 386 /**
386 387 * Perform necessary tasks once the kernel has been started,
387 388 * including actually connecting to the kernel.
388 389 *
389 390 * @function _kernel_created
390 391 * @param {Object} data - information about the kernel including id
391 392 */
392 393 this.id = data.id;
393 394 this.kernel_url = utils.url_join_encode(this.kernel_service_url, this.id);
394 395 this.start_channels();
395 396 };
396 397
397 398 Kernel.prototype._kernel_connected = function () {
398 399 /**
399 400 * Perform necessary tasks once the connection to the kernel has
400 401 * been established. This includes requesting information about
401 402 * the kernel.
402 403 *
403 404 * @function _kernel_connected
404 405 */
405 406 this.events.trigger('kernel_connected.Kernel', {kernel: this});
406 407 // get kernel info so we know what state the kernel is in
407 408 var that = this;
408 409 this.kernel_info(function (reply) {
409 410 that.info_reply = reply.content;
410 411 that.events.trigger('kernel_ready.Kernel', {kernel: that});
411 412 });
412 413 };
413 414
414 415 Kernel.prototype._kernel_dead = function () {
415 416 /**
416 417 * Perform necessary tasks after the kernel has died. This closing
417 418 * communication channels to the kernel if they are still somehow
418 419 * open.
419 420 *
420 421 * @function _kernel_dead
421 422 */
422 423 this.stop_channels();
423 424 };
424 425
425 426 Kernel.prototype.start_channels = function () {
426 427 /**
427 428 * Start the websocket channels.
428 429 * Will stop and restart them if they already exist.
429 430 *
430 431 * @function start_channels
431 432 */
432 433 var that = this;
433 434 this.stop_channels();
434 435 var ws_host_url = this.ws_url + this.kernel_url;
435 436
436 437 console.log("Starting WebSockets:", ws_host_url);
437 438
438 439 this.ws = new this.WebSocket([
439 440 that.ws_url,
440 441 utils.url_join_encode(that.kernel_url, 'channels'),
441 442 "?session_id=" + that.session_id
442 443 ].join('')
443 444 );
444 445
445 446 var already_called_onclose = false; // only alert once
446 447 var ws_closed_early = function(evt){
447 448 if (already_called_onclose){
448 449 return;
449 450 }
450 451 already_called_onclose = true;
451 452 if ( ! evt.wasClean ){
452 453 // If the websocket was closed early, that could mean
453 454 // that the kernel is actually dead. Try getting
454 455 // information about the kernel from the API call --
455 456 // if that fails, then assume the kernel is dead,
456 457 // otherwise just follow the typical websocket closed
457 458 // protocol.
458 459 that.get_info(function () {
459 460 that._ws_closed(ws_host_url, false);
460 461 }, function () {
461 462 that.events.trigger('kernel_dead.Kernel', {kernel: that});
462 463 that._kernel_dead();
463 464 });
464 465 }
465 466 };
466 467 var ws_closed_late = function(evt){
467 468 if (already_called_onclose){
468 469 return;
469 470 }
470 471 already_called_onclose = true;
471 472 if ( ! evt.wasClean ){
472 473 that._ws_closed(ws_host_url, false);
473 474 }
474 475 };
475 476 var ws_error = function(evt){
476 477 if (already_called_onclose){
477 478 return;
478 479 }
479 480 already_called_onclose = true;
480 481 that._ws_closed(ws_host_url, true);
481 482 };
482 483
483 484 this.ws.onopen = $.proxy(this._ws_opened, this);
484 485 this.ws.onclose = ws_closed_early;
485 486 this.ws.onerror = ws_error;
486 487 // switch from early-close to late-close message after 1s
487 488 setTimeout(function() {
488 489 if (that.ws !== null) {
489 490 that.ws.onclose = ws_closed_late;
490 491 }
491 492 }, 1000);
492 493 this.ws.onmessage = $.proxy(this._handle_ws_message, this);
493 494 };
494 495
495 496 Kernel.prototype._ws_opened = function (evt) {
496 497 /**
497 498 * Handle a websocket entering the open state,
498 499 * signaling that the kernel is connected when websocket is open.
499 500 *
500 501 * @function _ws_opened
501 502 */
502 503 if (this.is_connected()) {
503 504 // all events ready, trigger started event.
504 505 this._kernel_connected();
505 506 }
506 507 };
507 508
508 509 Kernel.prototype._ws_closed = function(ws_url, error) {
509 510 /**
510 511 * Handle a websocket entering the closed state. If the websocket
511 512 * was not closed due to an error, try to reconnect to the kernel.
512 513 *
513 514 * @function _ws_closed
514 515 * @param {string} ws_url - the websocket url
515 516 * @param {bool} error - whether the connection was closed due to an error
516 517 */
517 518 this.stop_channels();
518 519
519 520 this.events.trigger('kernel_disconnected.Kernel', {kernel: this});
520 521 if (error) {
521 522 console.log('WebSocket connection failed: ', ws_url);
522 523 this.events.trigger('kernel_connection_failed.Kernel', {kernel: this, ws_url: ws_url, attempt: this._reconnect_attempt});
523 524 }
524 525 this._schedule_reconnect();
525 526 };
526 527
527 528 Kernel.prototype._schedule_reconnect = function () {
528 529 /**
529 530 * function to call when kernel connection is lost
530 531 * schedules reconnect, or fires 'connection_dead' if reconnect limit is hit
531 532 */
532 533 if (this._reconnect_attempt < this.reconnect_limit) {
533 534 var timeout = Math.pow(2, this._reconnect_attempt);
534 535 console.log("Connection lost, reconnecting in " + timeout + " seconds.");
535 536 setTimeout($.proxy(this.reconnect, this), 1e3 * timeout);
536 537 } else {
537 538 this.events.trigger('kernel_connection_dead.Kernel', {
538 539 kernel: this,
539 540 reconnect_attempt: this._reconnect_attempt,
540 541 });
541 542 console.log("Failed to reconnect, giving up.");
542 543 }
543 544 };
544 545
545 546 Kernel.prototype.stop_channels = function () {
546 547 /**
547 548 * Close the websocket. After successful close, the value
548 549 * in `this.ws` will be null.
549 550 *
550 551 * @function stop_channels
551 552 */
552 553 var that = this;
553 554 var close = function () {
554 555 if (that.ws && that.ws.readyState === WebSocket.CLOSED) {
555 556 that.ws = null;
556 557 }
557 558 };
558 559 if (this.ws !== null) {
559 560 if (this.ws.readyState === WebSocket.OPEN) {
560 561 this.ws.onclose = close;
561 562 this.ws.close();
562 563 } else {
563 564 close();
564 565 }
565 566 }
566 567 };
567 568
568 569 Kernel.prototype.is_connected = function () {
569 570 /**
570 571 * Check whether there is a connection to the kernel. This
571 572 * function only returns true if websocket has been
572 573 * created and has a state of WebSocket.OPEN.
573 574 *
574 575 * @function is_connected
575 576 * @returns {bool} - whether there is a connection
576 577 */
577 578 // if any channel is not ready, then we're not connected
578 579 if (this.ws === null) {
579 580 return false;
580 581 }
581 582 if (this.ws.readyState !== WebSocket.OPEN) {
582 583 return false;
583 584 }
584 585 return true;
585 586 };
586 587
587 588 Kernel.prototype.is_fully_disconnected = function () {
588 589 /**
589 590 * Check whether the connection to the kernel has been completely
590 591 * severed. This function only returns true if all channel objects
591 592 * are null.
592 593 *
593 594 * @function is_fully_disconnected
594 595 * @returns {bool} - whether the kernel is fully disconnected
595 596 */
596 597 return (this.ws === null);
597 598 };
598 599
599 600 Kernel.prototype.send_shell_message = function (msg_type, content, callbacks, metadata, buffers) {
600 601 /**
601 602 * Send a message on the Kernel's shell channel
602 603 *
603 604 * @function send_shell_message
604 605 */
605 606 if (!this.is_connected()) {
606 607 throw new Error("kernel is not connected");
607 608 }
608 609 var msg = this._get_msg(msg_type, content, metadata, buffers);
609 610 msg.channel = 'shell';
610 611 this.ws.send(serialize.serialize(msg));
611 612 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
612 613 return msg.header.msg_id;
613 614 };
614 615
615 616 Kernel.prototype.kernel_info = function (callback) {
616 617 /**
617 618 * Get kernel info
618 619 *
619 620 * @function kernel_info
620 621 * @param callback {function}
621 622 *
622 623 * When calling this method, pass a callback function that expects one argument.
623 624 * The callback will be passed the complete `kernel_info_reply` message documented
624 625 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#kernel-info)
625 626 */
626 627 var callbacks;
627 628 if (callback) {
628 629 callbacks = { shell : { reply : callback } };
629 630 }
630 631 return this.send_shell_message("kernel_info_request", {}, callbacks);
631 632 };
632 633
633 634 Kernel.prototype.inspect = function (code, cursor_pos, callback) {
634 635 /**
635 636 * Get info on an object
636 637 *
637 638 * When calling this method, pass a callback function that expects one argument.
638 639 * The callback will be passed the complete `inspect_reply` message documented
639 640 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#object-information)
640 641 *
641 642 * @function inspect
642 643 * @param code {string}
643 644 * @param cursor_pos {integer}
644 645 * @param callback {function}
645 646 */
646 647 var callbacks;
647 648 if (callback) {
648 649 callbacks = { shell : { reply : callback } };
649 650 }
650 651
651 652 var content = {
652 653 code : code,
653 654 cursor_pos : cursor_pos,
654 655 detail_level : 0
655 656 };
656 657 return this.send_shell_message("inspect_request", content, callbacks);
657 658 };
658 659
659 660 Kernel.prototype.execute = function (code, callbacks, options) {
660 661 /**
661 662 * Execute given code into kernel, and pass result to callback.
662 663 *
663 664 * @async
664 665 * @function execute
665 666 * @param {string} code
666 667 * @param [callbacks] {Object} With the following keys (all optional)
667 668 * @param callbacks.shell.reply {function}
668 669 * @param callbacks.shell.payload.[payload_name] {function}
669 670 * @param callbacks.iopub.output {function}
670 671 * @param callbacks.iopub.clear_output {function}
671 672 * @param callbacks.input {function}
672 673 * @param {object} [options]
673 674 * @param [options.silent=false] {Boolean}
674 675 * @param [options.user_expressions=empty_dict] {Dict}
675 676 * @param [options.allow_stdin=false] {Boolean} true|false
676 677 *
677 678 * @example
678 679 *
679 680 * The options object should contain the options for the execute
680 681 * call. Its default values are:
681 682 *
682 683 * options = {
683 684 * silent : true,
684 685 * user_expressions : {},
685 686 * allow_stdin : false
686 687 * }
687 688 *
688 689 * When calling this method pass a callbacks structure of the
689 690 * form:
690 691 *
691 692 * callbacks = {
692 693 * shell : {
693 694 * reply : execute_reply_callback,
694 695 * payload : {
695 696 * set_next_input : set_next_input_callback,
696 697 * }
697 698 * },
698 699 * iopub : {
699 700 * output : output_callback,
700 701 * clear_output : clear_output_callback,
701 702 * },
702 703 * input : raw_input_callback
703 704 * }
704 705 *
705 706 * Each callback will be passed the entire message as a single
706 707 * arugment. Payload handlers will be passed the corresponding
707 708 * payload and the execute_reply message.
708 709 */
709 710 var content = {
710 711 code : code,
711 712 silent : true,
712 713 store_history : false,
713 714 user_expressions : {},
714 715 allow_stdin : false
715 716 };
716 717 callbacks = callbacks || {};
717 718 if (callbacks.input !== undefined) {
718 719 content.allow_stdin = true;
719 720 }
720 721 $.extend(true, content, options);
721 722 this.events.trigger('execution_request.Kernel', {kernel: this, content: content});
722 723 return this.send_shell_message("execute_request", content, callbacks);
723 724 };
724 725
725 726 /**
726 727 * When calling this method, pass a function to be called with the
727 728 * `complete_reply` message as its only argument when it arrives.
728 729 *
729 730 * `complete_reply` is documented
730 731 * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#complete)
731 732 *
732 733 * @function complete
733 734 * @param code {string}
734 735 * @param cursor_pos {integer}
735 736 * @param callback {function}
736 737 */
737 738 Kernel.prototype.complete = function (code, cursor_pos, callback) {
738 739 var callbacks;
739 740 if (callback) {
740 741 callbacks = { shell : { reply : callback } };
741 742 }
742 743 var content = {
743 744 code : code,
744 745 cursor_pos : cursor_pos
745 746 };
746 747 return this.send_shell_message("complete_request", content, callbacks);
747 748 };
748 749
749 750 /**
750 751 * @function send_input_reply
751 752 */
752 753 Kernel.prototype.send_input_reply = function (input) {
753 754 if (!this.is_connected()) {
754 755 throw new Error("kernel is not connected");
755 756 }
756 757 var content = {
757 758 value : input
758 759 };
759 760 this.events.trigger('input_reply.Kernel', {kernel: this, content: content});
760 761 var msg = this._get_msg("input_reply", content);
761 762 msg.channel = 'stdin';
762 763 this.ws.send(serialize.serialize(msg));
763 764 return msg.header.msg_id;
764 765 };
765 766
766 767 /**
767 768 * @function register_iopub_handler
768 769 */
769 770 Kernel.prototype.register_iopub_handler = function (msg_type, callback) {
770 771 this._iopub_handlers[msg_type] = callback;
771 772 };
772 773
773 774 /**
774 775 * Get the iopub handler for a specific message type.
775 776 *
776 777 * @function get_iopub_handler
777 778 */
778 779 Kernel.prototype.get_iopub_handler = function (msg_type) {
779 780 return this._iopub_handlers[msg_type];
780 781 };
781 782
782 783 /**
783 784 * Get callbacks for a specific message.
784 785 *
785 786 * @function get_callbacks_for_msg
786 787 */
787 788 Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
788 789 if (msg_id == this.last_msg_id) {
789 790 return this.last_msg_callbacks;
790 791 } else {
791 792 return this._msg_callbacks[msg_id];
792 793 }
793 794 };
794 795
795 796 /**
796 797 * Clear callbacks for a specific message.
797 798 *
798 799 * @function clear_callbacks_for_msg
799 800 */
800 801 Kernel.prototype.clear_callbacks_for_msg = function (msg_id) {
801 802 if (this._msg_callbacks[msg_id] !== undefined ) {
802 803 delete this._msg_callbacks[msg_id];
803 804 }
804 805 };
805 806
806 807 /**
807 808 * @function _finish_shell
808 809 */
809 810 Kernel.prototype._finish_shell = function (msg_id) {
810 811 var callbacks = this._msg_callbacks[msg_id];
811 812 if (callbacks !== undefined) {
812 813 callbacks.shell_done = true;
813 814 if (callbacks.iopub_done) {
814 815 this.clear_callbacks_for_msg(msg_id);
815 816 }
816 817 }
817 818 };
818 819
819 820 /**
820 821 * @function _finish_iopub
821 822 */
822 823 Kernel.prototype._finish_iopub = function (msg_id) {
823 824 var callbacks = this._msg_callbacks[msg_id];
824 825 if (callbacks !== undefined) {
825 826 callbacks.iopub_done = true;
826 827 if (callbacks.shell_done) {
827 828 this.clear_callbacks_for_msg(msg_id);
828 829 }
829 830 }
830 831 };
831 832
832 833 /**
833 834 * Set callbacks for a particular message.
834 835 * Callbacks should be a struct of the following form:
835 836 * shell : {
836 837 *
837 838 * }
838 839 *
839 840 * @function set_callbacks_for_msg
840 841 */
841 842 Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
842 843 this.last_msg_id = msg_id;
843 844 if (callbacks) {
844 845 // shallow-copy mapping, because we will modify it at the top level
845 846 var cbcopy = this._msg_callbacks[msg_id] = this.last_msg_callbacks = {};
846 847 cbcopy.shell = callbacks.shell;
847 848 cbcopy.iopub = callbacks.iopub;
848 849 cbcopy.input = callbacks.input;
849 850 cbcopy.shell_done = (!callbacks.shell);
850 851 cbcopy.iopub_done = (!callbacks.iopub);
851 852 } else {
852 853 this.last_msg_callbacks = {};
853 854 }
854 855 };
855 856
856 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 865 Kernel.prototype._finish_ws_message = function (msg) {
861 866 switch (msg.channel) {
862 867 case 'shell':
863 this._handle_shell_reply(msg);
868 return this._handle_shell_reply(msg);
864 869 break;
865 870 case 'iopub':
866 this._handle_iopub_message(msg);
871 return this._handle_iopub_message(msg);
867 872 break;
868 873 case 'stdin':
869 this._handle_input_request(msg);
874 return this._handle_input_request(msg);
870 875 break;
871 876 default:
872 877 console.error("unrecognized message channel", msg.channel, msg);
873 878 }
874 879 };
875 880
876 881 Kernel.prototype._handle_shell_reply = function (reply) {
877 882 this.events.trigger('shell_reply.Kernel', {kernel: this, reply:reply});
883 var that = this;
878 884 var content = reply.content;
879 885 var metadata = reply.metadata;
880 886 var parent_id = reply.parent_header.msg_id;
881 887 var callbacks = this.get_callbacks_for_msg(parent_id);
888 var promise = Promise.resolve();
882 889 if (!callbacks || !callbacks.shell) {
883 890 return;
884 891 }
885 892 var shell_callbacks = callbacks.shell;
886 893
887 894 // signal that shell callbacks are done
888 895 this._finish_shell(parent_id);
889 896
890 897 if (shell_callbacks.reply !== undefined) {
891 shell_callbacks.reply(reply);
898 promise = promise.then(function() {return shell_callbacks.reply(reply)});
892 899 }
893 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 909 * @function _handle_payloads
900 910 */
901 911 Kernel.prototype._handle_payloads = function (payloads, payload_callbacks, msg) {
912 var promise = [];
902 913 var l = payloads.length;
903 914 // Payloads are handled by triggering events because we don't want the Kernel
904 915 // to depend on the Notebook or Pager classes.
905 916 for (var i=0; i<l; i++) {
906 917 var payload = payloads[i];
907 918 var callback = payload_callbacks[payload.source];
908 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 927 * @function _handle_status_message
916 928 */
917 929 Kernel.prototype._handle_status_message = function (msg) {
918 930 var execution_state = msg.content.execution_state;
919 931 var parent_id = msg.parent_header.msg_id;
920 932
921 933 // dispatch status msg callbacks, if any
922 934 var callbacks = this.get_callbacks_for_msg(parent_id);
923 935 if (callbacks && callbacks.iopub && callbacks.iopub.status) {
924 936 try {
925 937 callbacks.iopub.status(msg);
926 938 } catch (e) {
927 939 console.log("Exception in status msg handler", e, e.stack);
928 940 }
929 941 }
930 942
931 943 if (execution_state === 'busy') {
932 944 this.events.trigger('kernel_busy.Kernel', {kernel: this});
933 945
934 946 } else if (execution_state === 'idle') {
935 947 // signal that iopub callbacks are (probably) done
936 948 // async output may still arrive,
937 949 // but only for the most recent request
938 950 this._finish_iopub(parent_id);
939 951
940 952 // trigger status_idle event
941 953 this.events.trigger('kernel_idle.Kernel', {kernel: this});
942 954
943 955 } else if (execution_state === 'starting') {
944 956 this.events.trigger('kernel_starting.Kernel', {kernel: this});
945 957 var that = this;
946 958 this.kernel_info(function (reply) {
947 959 that.info_reply = reply.content;
948 960 that.events.trigger('kernel_ready.Kernel', {kernel: that});
949 961 });
950 962
951 963 } else if (execution_state === 'restarting') {
952 964 // autorestarting is distinct from restarting,
953 965 // in that it means the kernel died and the server is restarting it.
954 966 // kernel_restarting sets the notification widget,
955 967 // autorestart shows the more prominent dialog.
956 968 this._autorestart_attempt = this._autorestart_attempt + 1;
957 969 this.events.trigger('kernel_restarting.Kernel', {kernel: this});
958 970 this.events.trigger('kernel_autorestarting.Kernel', {kernel: this, attempt: this._autorestart_attempt});
959 971
960 972 } else if (execution_state === 'dead') {
961 973 this.events.trigger('kernel_dead.Kernel', {kernel: this});
962 974 this._kernel_dead();
963 975 }
964 976 };
965 977
966 978 /**
967 979 * Handle clear_output message
968 980 *
969 981 * @function _handle_clear_output
970 982 */
971 983 Kernel.prototype._handle_clear_output = function (msg) {
972 984 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
973 985 if (!callbacks || !callbacks.iopub) {
974 986 return;
975 987 }
976 988 var callback = callbacks.iopub.clear_output;
977 989 if (callback) {
978 990 callback(msg);
979 991 }
980 992 };
981 993
982 994 /**
983 995 * handle an output message (execute_result, display_data, etc.)
984 996 *
985 997 * @function _handle_output_message
986 998 */
987 999 Kernel.prototype._handle_output_message = function (msg) {
988 1000 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
989 1001 if (!callbacks || !callbacks.iopub) {
990 1002 // The message came from another client. Let the UI decide what to
991 1003 // do with it.
992 1004 this.events.trigger('received_unsolicited_message.Kernel', msg);
993 1005 return;
994 1006 }
995 1007 var callback = callbacks.iopub.output;
996 1008 if (callback) {
997 1009 callback(msg);
998 1010 }
999 1011 };
1000 1012
1001 1013 /**
1002 1014 * Handle an input message (execute_input).
1003 1015 *
1004 1016 * @function _handle_input message
1005 1017 */
1006 1018 Kernel.prototype._handle_input_message = function (msg) {
1007 1019 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
1008 1020 if (!callbacks) {
1009 1021 // The message came from another client. Let the UI decide what to
1010 1022 // do with it.
1011 1023 this.events.trigger('received_unsolicited_message.Kernel', msg);
1012 1024 }
1013 1025 };
1014 1026
1015 1027 /**
1016 1028 * Dispatch IOPub messages to respective handlers. Each message
1017 1029 * type should have a handler.
1018 1030 *
1019 1031 * @function _handle_iopub_message
1020 1032 */
1021 1033 Kernel.prototype._handle_iopub_message = function (msg) {
1022 1034 var handler = this.get_iopub_handler(msg.header.msg_type);
1023 1035 if (handler !== undefined) {
1024 handler(msg);
1036 return handler(msg);
1025 1037 }
1026 1038 };
1027 1039
1028 1040 /**
1029 1041 * @function _handle_input_request
1030 1042 */
1031 1043 Kernel.prototype._handle_input_request = function (request) {
1032 1044 var header = request.header;
1033 1045 var content = request.content;
1034 1046 var metadata = request.metadata;
1035 1047 var msg_type = header.msg_type;
1036 1048 if (msg_type !== 'input_request') {
1037 1049 console.log("Invalid input request!", request);
1038 1050 return;
1039 1051 }
1040 1052 var callbacks = this.get_callbacks_for_msg(request.parent_header.msg_id);
1041 1053 if (callbacks) {
1042 1054 if (callbacks.input) {
1043 1055 callbacks.input(request);
1044 1056 }
1045 1057 }
1046 1058 };
1047 1059
1048 1060 // Backwards compatability.
1049 1061 IPython.Kernel = Kernel;
1050 1062
1051 1063 return {'Kernel': Kernel};
1052 1064 });
@@ -1,120 +1,123 b''
1 1 // Copyright (c) IPython Development Team.
2 2 // Distributed under the terms of the Modified BSD License.
3 3
4 4 define([
5 5 'underscore',
6 6 ], function (_) {
7 7 "use strict";
8 8
9 9 var _deserialize_array_buffer = function (buf) {
10 10 var data = new DataView(buf);
11 11 // read the header: 1 + nbufs 32b integers
12 12 var nbufs = data.getUint32(0);
13 13 var offsets = [];
14 14 var i;
15 15 for (i = 1; i <= nbufs; i++) {
16 16 offsets.push(data.getUint32(i * 4));
17 17 }
18 18 var json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1]));
19 19 var msg = JSON.parse(
20 20 (new TextDecoder('utf8')).decode(json_bytes)
21 21 );
22 22 // the remaining chunks are stored as DataViews in msg.buffers
23 23 msg.buffers = [];
24 24 var start, stop;
25 25 for (i = 1; i < nbufs; i++) {
26 26 start = offsets[i];
27 27 stop = offsets[i+1] || buf.byteLength;
28 28 msg.buffers.push(new DataView(buf.slice(start, stop)));
29 29 }
30 30 return msg;
31 31 };
32 32
33 var _deserialize_binary = function(data, callback) {
33 var _deserialize_binary = function(data) {
34 34 /**
35 35 * deserialize the binary message format
36 36 * callback will be called with a message whose buffers attribute
37 37 * will be an array of DataViews.
38 38 */
39 39 if (data instanceof Blob) {
40 40 // data is Blob, have to deserialize from ArrayBuffer in reader callback
41 41 var reader = new FileReader();
42 reader.onload = function () {
43 var msg = _deserialize_array_buffer(this.result);
44 callback(msg);
45 };
42 var promise = new Promise(function(resolve, reject) {
43 reader.onload = function () {
44 var msg = _deserialize_array_buffer(this.result);
45 resolve(msg);
46 };
47 });
46 48 reader.readAsArrayBuffer(data);
49 return promise;
47 50 } else {
48 51 // data is ArrayBuffer, can deserialize directly
49 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 61 if (typeof data === "string") {
59 62 // text JSON message
60 callback(JSON.parse(data));
63 return Promise.resolve(JSON.parse(data));
61 64 } else {
62 65 // binary message
63 _deserialize_binary(data, callback);
66 return Promise.resolve(_deserialize_binary(data));
64 67 }
65 68 };
66 69
67 70 var _serialize_binary = function (msg) {
68 71 /**
69 72 * implement the binary serialization protocol
70 73 * serializes JSON message to ArrayBuffer
71 74 */
72 75 msg = _.clone(msg);
73 76 var offsets = [];
74 77 var buffers = [];
75 78 msg.buffers.map(function (buf) {
76 79 buffers.push(buf);
77 80 });
78 81 delete msg.buffers;
79 82 var json_utf8 = (new TextEncoder('utf8')).encode(JSON.stringify(msg));
80 83 buffers.unshift(json_utf8);
81 84 var nbufs = buffers.length;
82 85 offsets.push(4 * (nbufs + 1));
83 86 var i;
84 87 for (i = 0; i + 1 < buffers.length; i++) {
85 88 offsets.push(offsets[offsets.length-1] + buffers[i].byteLength);
86 89 }
87 90 var msg_buf = new Uint8Array(
88 91 offsets[offsets.length-1] + buffers[buffers.length-1].byteLength
89 92 );
90 93 // use DataView.setUint32 for network byte-order
91 94 var view = new DataView(msg_buf.buffer);
92 95 // write nbufs to first 4 bytes
93 96 view.setUint32(0, nbufs);
94 97 // write offsets to next 4 * nbufs bytes
95 98 for (i = 0; i < offsets.length; i++) {
96 99 view.setUint32(4 * (i+1), offsets[i]);
97 100 }
98 101 // write all the buffers at their respective offsets
99 102 for (i = 0; i < buffers.length; i++) {
100 103 msg_buf.set(new Uint8Array(buffers[i].buffer), offsets[i]);
101 104 }
102 105
103 106 // return raw ArrayBuffer
104 107 return msg_buf.buffer;
105 108 };
106 109
107 110 var serialize = function (msg) {
108 111 if (msg.buffers && msg.buffers.length) {
109 112 return _serialize_binary(msg);
110 113 } else {
111 114 return JSON.stringify(msg);
112 115 }
113 116 };
114 117
115 118 var exports = {
116 119 deserialize : deserialize,
117 120 serialize: serialize
118 121 };
119 122 return exports;
120 }); No newline at end of file
123 });
@@ -1,1582 +1,1580 b''
1 1 /*!
2 2 *
3 3 * IPython base
4 4 *
5 5 */
6 6 .modal.fade .modal-dialog {
7 7 -webkit-transform: translate(0, 0);
8 8 -ms-transform: translate(0, 0);
9 9 -o-transform: translate(0, 0);
10 10 transform: translate(0, 0);
11 11 }
12 12 code {
13 13 color: #000000;
14 14 }
15 15 pre {
16 16 font-size: inherit;
17 17 line-height: inherit;
18 18 }
19 19 label {
20 20 font-weight: normal;
21 21 }
22 22 /* Make the page background atleast 100% the height of the view port */
23 23 /* Make the page itself atleast 70% the height of the view port */
24 24 .border-box-sizing {
25 25 box-sizing: border-box;
26 26 -moz-box-sizing: border-box;
27 27 -webkit-box-sizing: border-box;
28 28 }
29 29 .corner-all {
30 30 border-radius: 2px;
31 31 }
32 32 .no-padding {
33 33 padding: 0px;
34 34 }
35 35 /* Flexible box model classes */
36 36 /* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
37 37 /* This file is a compatability layer. It allows the usage of flexible box
38 38 model layouts accross multiple browsers, including older browsers. The newest,
39 39 universal implementation of the flexible box model is used when available (see
40 40 `Modern browsers` comments below). Browsers that are known to implement this
41 41 new spec completely include:
42 42
43 43 Firefox 28.0+
44 44 Chrome 29.0+
45 45 Internet Explorer 11+
46 46 Opera 17.0+
47 47
48 48 Browsers not listed, including Safari, are supported via the styling under the
49 49 `Old browsers` comments below.
50 50 */
51 51 .hbox {
52 52 /* Old browsers */
53 53 display: -webkit-box;
54 54 -webkit-box-orient: horizontal;
55 55 -webkit-box-align: stretch;
56 56 display: -moz-box;
57 57 -moz-box-orient: horizontal;
58 58 -moz-box-align: stretch;
59 59 display: box;
60 60 box-orient: horizontal;
61 61 box-align: stretch;
62 62 /* Modern browsers */
63 63 display: flex;
64 64 flex-direction: row;
65 65 align-items: stretch;
66 66 }
67 67 .hbox > * {
68 68 /* Old browsers */
69 69 -webkit-box-flex: 0;
70 70 -moz-box-flex: 0;
71 71 box-flex: 0;
72 72 /* Modern browsers */
73 73 flex: none;
74 74 }
75 75 .vbox {
76 76 /* Old browsers */
77 77 display: -webkit-box;
78 78 -webkit-box-orient: vertical;
79 79 -webkit-box-align: stretch;
80 80 display: -moz-box;
81 81 -moz-box-orient: vertical;
82 82 -moz-box-align: stretch;
83 83 display: box;
84 84 box-orient: vertical;
85 85 box-align: stretch;
86 86 /* Modern browsers */
87 87 display: flex;
88 88 flex-direction: column;
89 89 align-items: stretch;
90 90 }
91 91 .vbox > * {
92 92 /* Old browsers */
93 93 -webkit-box-flex: 0;
94 94 -moz-box-flex: 0;
95 95 box-flex: 0;
96 96 /* Modern browsers */
97 97 flex: none;
98 98 }
99 99 .hbox.reverse,
100 100 .vbox.reverse,
101 101 .reverse {
102 102 /* Old browsers */
103 103 -webkit-box-direction: reverse;
104 104 -moz-box-direction: reverse;
105 105 box-direction: reverse;
106 106 /* Modern browsers */
107 107 flex-direction: row-reverse;
108 108 }
109 109 .hbox.box-flex0,
110 110 .vbox.box-flex0,
111 111 .box-flex0 {
112 112 /* Old browsers */
113 113 -webkit-box-flex: 0;
114 114 -moz-box-flex: 0;
115 115 box-flex: 0;
116 116 /* Modern browsers */
117 117 flex: none;
118 118 width: auto;
119 119 }
120 120 .hbox.box-flex1,
121 121 .vbox.box-flex1,
122 122 .box-flex1 {
123 123 /* Old browsers */
124 124 -webkit-box-flex: 1;
125 125 -moz-box-flex: 1;
126 126 box-flex: 1;
127 127 /* Modern browsers */
128 128 flex: 1;
129 129 }
130 130 .hbox.box-flex,
131 131 .vbox.box-flex,
132 132 .box-flex {
133 133 /* Old browsers */
134 134 /* Old browsers */
135 135 -webkit-box-flex: 1;
136 136 -moz-box-flex: 1;
137 137 box-flex: 1;
138 138 /* Modern browsers */
139 139 flex: 1;
140 140 }
141 141 .hbox.box-flex2,
142 142 .vbox.box-flex2,
143 143 .box-flex2 {
144 144 /* Old browsers */
145 145 -webkit-box-flex: 2;
146 146 -moz-box-flex: 2;
147 147 box-flex: 2;
148 148 /* Modern browsers */
149 149 flex: 2;
150 150 }
151 151 .box-group1 {
152 152 /* Deprecated */
153 153 -webkit-box-flex-group: 1;
154 154 -moz-box-flex-group: 1;
155 155 box-flex-group: 1;
156 156 }
157 157 .box-group2 {
158 158 /* Deprecated */
159 159 -webkit-box-flex-group: 2;
160 160 -moz-box-flex-group: 2;
161 161 box-flex-group: 2;
162 162 }
163 163 .hbox.start,
164 164 .vbox.start,
165 165 .start {
166 166 /* Old browsers */
167 167 -webkit-box-pack: start;
168 168 -moz-box-pack: start;
169 169 box-pack: start;
170 170 /* Modern browsers */
171 171 justify-content: flex-start;
172 172 }
173 173 .hbox.end,
174 174 .vbox.end,
175 175 .end {
176 176 /* Old browsers */
177 177 -webkit-box-pack: end;
178 178 -moz-box-pack: end;
179 179 box-pack: end;
180 180 /* Modern browsers */
181 181 justify-content: flex-end;
182 182 }
183 183 .hbox.center,
184 184 .vbox.center,
185 185 .center {
186 186 /* Old browsers */
187 187 -webkit-box-pack: center;
188 188 -moz-box-pack: center;
189 189 box-pack: center;
190 190 /* Modern browsers */
191 191 justify-content: center;
192 192 }
193 193 .hbox.baseline,
194 194 .vbox.baseline,
195 195 .baseline {
196 196 /* Old browsers */
197 197 -webkit-box-pack: baseline;
198 198 -moz-box-pack: baseline;
199 199 box-pack: baseline;
200 200 /* Modern browsers */
201 201 justify-content: baseline;
202 202 }
203 203 .hbox.stretch,
204 204 .vbox.stretch,
205 205 .stretch {
206 206 /* Old browsers */
207 207 -webkit-box-pack: stretch;
208 208 -moz-box-pack: stretch;
209 209 box-pack: stretch;
210 210 /* Modern browsers */
211 211 justify-content: stretch;
212 212 }
213 213 .hbox.align-start,
214 214 .vbox.align-start,
215 215 .align-start {
216 216 /* Old browsers */
217 217 -webkit-box-align: start;
218 218 -moz-box-align: start;
219 219 box-align: start;
220 220 /* Modern browsers */
221 221 align-items: flex-start;
222 222 }
223 223 .hbox.align-end,
224 224 .vbox.align-end,
225 225 .align-end {
226 226 /* Old browsers */
227 227 -webkit-box-align: end;
228 228 -moz-box-align: end;
229 229 box-align: end;
230 230 /* Modern browsers */
231 231 align-items: flex-end;
232 232 }
233 233 .hbox.align-center,
234 234 .vbox.align-center,
235 235 .align-center {
236 236 /* Old browsers */
237 237 -webkit-box-align: center;
238 238 -moz-box-align: center;
239 239 box-align: center;
240 240 /* Modern browsers */
241 241 align-items: center;
242 242 }
243 243 .hbox.align-baseline,
244 244 .vbox.align-baseline,
245 245 .align-baseline {
246 246 /* Old browsers */
247 247 -webkit-box-align: baseline;
248 248 -moz-box-align: baseline;
249 249 box-align: baseline;
250 250 /* Modern browsers */
251 251 align-items: baseline;
252 252 }
253 253 .hbox.align-stretch,
254 254 .vbox.align-stretch,
255 255 .align-stretch {
256 256 /* Old browsers */
257 257 -webkit-box-align: stretch;
258 258 -moz-box-align: stretch;
259 259 box-align: stretch;
260 260 /* Modern browsers */
261 261 align-items: stretch;
262 262 }
263 263 div.error {
264 264 margin: 2em;
265 265 text-align: center;
266 266 }
267 267 div.error > h1 {
268 268 font-size: 500%;
269 269 line-height: normal;
270 270 }
271 271 div.error > p {
272 272 font-size: 200%;
273 273 line-height: normal;
274 274 }
275 275 div.traceback-wrapper {
276 276 text-align: left;
277 277 max-width: 800px;
278 278 margin: auto;
279 279 }
280 280 /*!
281 281 *
282 282 * IPython notebook
283 283 *
284 284 */
285 285 /* CSS font colors for translated ANSI colors. */
286 286 .ansibold {
287 287 font-weight: bold;
288 288 }
289 289 /* use dark versions for foreground, to improve visibility */
290 290 .ansiblack {
291 291 color: black;
292 292 }
293 293 .ansired {
294 294 color: darkred;
295 295 }
296 296 .ansigreen {
297 297 color: darkgreen;
298 298 }
299 299 .ansiyellow {
300 300 color: #c4a000;
301 301 }
302 302 .ansiblue {
303 303 color: darkblue;
304 304 }
305 305 .ansipurple {
306 306 color: darkviolet;
307 307 }
308 308 .ansicyan {
309 309 color: steelblue;
310 310 }
311 311 .ansigray {
312 312 color: gray;
313 313 }
314 314 /* and light for background, for the same reason */
315 315 .ansibgblack {
316 316 background-color: black;
317 317 }
318 318 .ansibgred {
319 319 background-color: red;
320 320 }
321 321 .ansibggreen {
322 322 background-color: green;
323 323 }
324 324 .ansibgyellow {
325 325 background-color: yellow;
326 326 }
327 327 .ansibgblue {
328 328 background-color: blue;
329 329 }
330 330 .ansibgpurple {
331 331 background-color: magenta;
332 332 }
333 333 .ansibgcyan {
334 334 background-color: cyan;
335 335 }
336 336 .ansibggray {
337 337 background-color: gray;
338 338 }
339 339 div.cell {
340 340 border: 1px solid transparent;
341 341 /* Old browsers */
342 342 display: -webkit-box;
343 343 -webkit-box-orient: vertical;
344 344 -webkit-box-align: stretch;
345 345 display: -moz-box;
346 346 -moz-box-orient: vertical;
347 347 -moz-box-align: stretch;
348 348 display: box;
349 349 box-orient: vertical;
350 350 box-align: stretch;
351 351 /* Modern browsers */
352 352 display: flex;
353 353 flex-direction: column;
354 354 align-items: stretch;
355 355 border-radius: 2px;
356 356 box-sizing: border-box;
357 357 -moz-box-sizing: border-box;
358 358 -webkit-box-sizing: border-box;
359 359 border-width: thin;
360 360 border-style: solid;
361 361 width: 100%;
362 362 padding: 5px;
363 363 /* This acts as a spacer between cells, that is outside the border */
364 364 margin: 0px;
365 365 outline: none;
366 366 }
367 367 div.cell.selected {
368 368 border-color: #ababab;
369 369 /* Don't border the cells when printing */
370 370 }
371 371 @media print {
372 372 div.cell.selected {
373 373 border-color: transparent;
374 374 }
375 375 }
376 376 .edit_mode div.cell.selected {
377 377 border-color: green;
378 378 /* Don't border the cells when printing */
379 379 }
380 380 @media print {
381 381 .edit_mode div.cell.selected {
382 382 border-color: transparent;
383 383 }
384 384 }
385 385 .prompt {
386 386 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
387 387 min-width: 14ex;
388 388 /* This padding is tuned to match the padding on the CodeMirror editor. */
389 389 padding: 0.4em;
390 390 margin: 0px;
391 391 font-family: monospace;
392 392 text-align: right;
393 393 /* This has to match that of the the CodeMirror class line-height below */
394 394 line-height: 1.21429em;
395 395 }
396 396 @media (max-width: 540px) {
397 397 .prompt {
398 398 text-align: left;
399 399 }
400 400 }
401 401 div.inner_cell {
402 402 /* Old browsers */
403 403 display: -webkit-box;
404 404 -webkit-box-orient: vertical;
405 405 -webkit-box-align: stretch;
406 406 display: -moz-box;
407 407 -moz-box-orient: vertical;
408 408 -moz-box-align: stretch;
409 409 display: box;
410 410 box-orient: vertical;
411 411 box-align: stretch;
412 412 /* Modern browsers */
413 413 display: flex;
414 414 flex-direction: column;
415 415 align-items: stretch;
416 416 /* Old browsers */
417 417 -webkit-box-flex: 1;
418 418 -moz-box-flex: 1;
419 419 box-flex: 1;
420 420 /* Modern browsers */
421 421 flex: 1;
422 422 }
423 423 @-moz-document url-prefix() {
424 424 div.inner_cell {
425 425 overflow-x: hidden;
426 426 }
427 427 }
428 428 /* input_area and input_prompt must match in top border and margin for alignment */
429 429 div.input_area {
430 430 border: 1px solid #cfcfcf;
431 431 border-radius: 2px;
432 432 background: #f7f7f7;
433 433 line-height: 1.21429em;
434 434 }
435 435 /* This is needed so that empty prompt areas can collapse to zero height when there
436 436 is no content in the output_subarea and the prompt. The main purpose of this is
437 437 to make sure that empty JavaScript output_subareas have no height. */
438 438 div.prompt:empty {
439 439 padding-top: 0;
440 440 padding-bottom: 0;
441 441 }
442 442 div.unrecognized_cell {
443 443 padding: 5px 5px 5px 0px;
444 444 /* Old browsers */
445 445 display: -webkit-box;
446 446 -webkit-box-orient: horizontal;
447 447 -webkit-box-align: stretch;
448 448 display: -moz-box;
449 449 -moz-box-orient: horizontal;
450 450 -moz-box-align: stretch;
451 451 display: box;
452 452 box-orient: horizontal;
453 453 box-align: stretch;
454 454 /* Modern browsers */
455 455 display: flex;
456 456 flex-direction: row;
457 457 align-items: stretch;
458 458 }
459 459 div.unrecognized_cell .inner_cell {
460 460 border-radius: 2px;
461 461 padding: 5px;
462 462 font-weight: bold;
463 463 color: red;
464 464 border: 1px solid #cfcfcf;
465 465 background: #eaeaea;
466 466 }
467 467 div.unrecognized_cell .inner_cell a {
468 468 color: inherit;
469 469 text-decoration: none;
470 470 }
471 471 div.unrecognized_cell .inner_cell a:hover {
472 472 color: inherit;
473 473 text-decoration: none;
474 474 }
475 475 @media (max-width: 540px) {
476 476 div.unrecognized_cell > div.prompt {
477 477 display: none;
478 478 }
479 479 }
480 480 div.code_cell {
481 481 /* avoid page breaking on code cells when printing */
482 482 }
483 483 @media print {
484 484 div.code_cell {
485 485 page-break-inside: avoid;
486 486 }
487 487 }
488 488 /* any special styling for code cells that are currently running goes here */
489 489 div.input {
490 490 page-break-inside: avoid;
491 491 /* Old browsers */
492 492 display: -webkit-box;
493 493 -webkit-box-orient: horizontal;
494 494 -webkit-box-align: stretch;
495 495 display: -moz-box;
496 496 -moz-box-orient: horizontal;
497 497 -moz-box-align: stretch;
498 498 display: box;
499 499 box-orient: horizontal;
500 500 box-align: stretch;
501 501 /* Modern browsers */
502 502 display: flex;
503 503 flex-direction: row;
504 504 align-items: stretch;
505 505 }
506 506 @media (max-width: 540px) {
507 507 div.input {
508 508 /* Old browsers */
509 509 display: -webkit-box;
510 510 -webkit-box-orient: vertical;
511 511 -webkit-box-align: stretch;
512 512 display: -moz-box;
513 513 -moz-box-orient: vertical;
514 514 -moz-box-align: stretch;
515 515 display: box;
516 516 box-orient: vertical;
517 517 box-align: stretch;
518 518 /* Modern browsers */
519 519 display: flex;
520 520 flex-direction: column;
521 521 align-items: stretch;
522 522 }
523 523 }
524 524 /* input_area and input_prompt must match in top border and margin for alignment */
525 525 div.input_prompt {
526 526 color: navy;
527 527 border-top: 1px solid transparent;
528 528 }
529 529 div.input_area > div.highlight {
530 530 margin: 0.4em;
531 531 border: none;
532 532 padding: 0px;
533 533 background-color: transparent;
534 534 }
535 535 div.input_area > div.highlight > pre {
536 536 margin: 0px;
537 537 border: none;
538 538 padding: 0px;
539 539 background-color: transparent;
540 540 }
541 541 /* The following gets added to the <head> if it is detected that the user has a
542 542 * monospace font with inconsistent normal/bold/italic height. See
543 543 * notebookmain.js. Such fonts will have keywords vertically offset with
544 544 * respect to the rest of the text. The user should select a better font.
545 545 * See: https://github.com/ipython/ipython/issues/1503
546 546 *
547 547 * .CodeMirror span {
548 548 * vertical-align: bottom;
549 549 * }
550 550 */
551 551 .CodeMirror {
552 552 line-height: 1.21429em;
553 553 /* Changed from 1em to our global default */
554 554 font-size: 14px;
555 555 height: auto;
556 556 /* Changed to auto to autogrow */
557 557 background: none;
558 558 /* Changed from white to allow our bg to show through */
559 559 }
560 560 .CodeMirror-scroll {
561 561 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
562 562 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
563 563 overflow-y: hidden;
564 564 overflow-x: auto;
565 565 }
566 566 .CodeMirror-lines {
567 567 /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
568 568 /* we have set a different line-height and want this to scale with that. */
569 569 padding: 0.4em;
570 570 }
571 571 .CodeMirror-linenumber {
572 572 padding: 0 8px 0 4px;
573 573 }
574 574 .CodeMirror-gutters {
575 575 border-bottom-left-radius: 2px;
576 576 border-top-left-radius: 2px;
577 577 }
578 578 .CodeMirror pre {
579 579 /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */
580 580 /* .CodeMirror-lines */
581 581 padding: 0;
582 582 border: 0;
583 583 border-radius: 0;
584 584 }
585 585 /*
586 586
587 587 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
588 588 Adapted from GitHub theme
589 589
590 590 */
591 591 .highlight-base {
592 592 color: #000000;
593 593 }
594 594 .highlight-variable {
595 595 color: #000000;
596 596 }
597 597 .highlight-variable-2 {
598 598 color: #1a1a1a;
599 599 }
600 600 .highlight-variable-3 {
601 601 color: #333333;
602 602 }
603 603 .highlight-string {
604 604 color: #BA2121;
605 605 }
606 606 .highlight-comment {
607 607 color: #408080;
608 608 font-style: italic;
609 609 }
610 610 .highlight-number {
611 611 color: #080;
612 612 }
613 613 .highlight-atom {
614 614 color: #88F;
615 615 }
616 616 .highlight-keyword {
617 617 color: #008000;
618 618 font-weight: bold;
619 619 }
620 620 .highlight-builtin {
621 621 color: #008000;
622 622 }
623 623 .highlight-error {
624 624 color: #f00;
625 625 }
626 626 .highlight-operator {
627 627 color: #AA22FF;
628 628 font-weight: bold;
629 629 }
630 630 .highlight-meta {
631 631 color: #AA22FF;
632 632 }
633 633 /* previously not defined, copying from default codemirror */
634 634 .highlight-def {
635 635 color: #00f;
636 636 }
637 637 .highlight-string-2 {
638 638 color: #f50;
639 639 }
640 640 .highlight-qualifier {
641 641 color: #555;
642 642 }
643 643 .highlight-bracket {
644 644 color: #997;
645 645 }
646 646 .highlight-tag {
647 647 color: #170;
648 648 }
649 649 .highlight-attribute {
650 650 color: #00c;
651 651 }
652 652 .highlight-header {
653 653 color: blue;
654 654 }
655 655 .highlight-quote {
656 656 color: #090;
657 657 }
658 658 .highlight-link {
659 659 color: #00c;
660 660 }
661 661 /* apply the same style to codemirror */
662 662 .cm-s-ipython span.cm-keyword {
663 663 color: #008000;
664 664 font-weight: bold;
665 665 }
666 666 .cm-s-ipython span.cm-atom {
667 667 color: #88F;
668 668 }
669 669 .cm-s-ipython span.cm-number {
670 670 color: #080;
671 671 }
672 672 .cm-s-ipython span.cm-def {
673 673 color: #00f;
674 674 }
675 675 .cm-s-ipython span.cm-variable {
676 676 color: #000000;
677 677 }
678 678 .cm-s-ipython span.cm-operator {
679 679 color: #AA22FF;
680 680 font-weight: bold;
681 681 }
682 682 .cm-s-ipython span.cm-variable-2 {
683 683 color: #1a1a1a;
684 684 }
685 685 .cm-s-ipython span.cm-variable-3 {
686 686 color: #333333;
687 687 }
688 688 .cm-s-ipython span.cm-comment {
689 689 color: #408080;
690 690 font-style: italic;
691 691 }
692 692 .cm-s-ipython span.cm-string {
693 693 color: #BA2121;
694 694 }
695 695 .cm-s-ipython span.cm-string-2 {
696 696 color: #f50;
697 697 }
698 698 .cm-s-ipython span.cm-meta {
699 699 color: #AA22FF;
700 700 }
701 701 .cm-s-ipython span.cm-qualifier {
702 702 color: #555;
703 703 }
704 704 .cm-s-ipython span.cm-builtin {
705 705 color: #008000;
706 706 }
707 707 .cm-s-ipython span.cm-bracket {
708 708 color: #997;
709 709 }
710 710 .cm-s-ipython span.cm-tag {
711 711 color: #170;
712 712 }
713 713 .cm-s-ipython span.cm-attribute {
714 714 color: #00c;
715 715 }
716 716 .cm-s-ipython span.cm-header {
717 717 color: blue;
718 718 }
719 719 .cm-s-ipython span.cm-quote {
720 720 color: #090;
721 721 }
722 722 .cm-s-ipython span.cm-link {
723 723 color: #00c;
724 724 }
725 725 .cm-s-ipython span.cm-error {
726 726 color: #f00;
727 727 }
728 728 .cm-s-ipython span.cm-tab {
729 729 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
730 730 background-position: right;
731 731 background-repeat: no-repeat;
732 732 }
733 733 div.output_wrapper {
734 734 /* this position must be relative to enable descendents to be absolute within it */
735 735 position: relative;
736 736 /* Old browsers */
737 737 display: -webkit-box;
738 738 -webkit-box-orient: vertical;
739 739 -webkit-box-align: stretch;
740 740 display: -moz-box;
741 741 -moz-box-orient: vertical;
742 742 -moz-box-align: stretch;
743 743 display: box;
744 744 box-orient: vertical;
745 745 box-align: stretch;
746 746 /* Modern browsers */
747 747 display: flex;
748 748 flex-direction: column;
749 749 align-items: stretch;
750 750 }
751 751 /* class for the output area when it should be height-limited */
752 752 div.output_scroll {
753 753 /* ideally, this would be max-height, but FF barfs all over that */
754 754 height: 24em;
755 755 /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
756 756 width: 100%;
757 757 overflow: auto;
758 758 border-radius: 2px;
759 759 -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
760 760 box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
761 761 display: block;
762 762 }
763 763 /* output div while it is collapsed */
764 764 div.output_collapsed {
765 765 margin: 0px;
766 766 padding: 0px;
767 767 /* Old browsers */
768 768 display: -webkit-box;
769 769 -webkit-box-orient: vertical;
770 770 -webkit-box-align: stretch;
771 771 display: -moz-box;
772 772 -moz-box-orient: vertical;
773 773 -moz-box-align: stretch;
774 774 display: box;
775 775 box-orient: vertical;
776 776 box-align: stretch;
777 777 /* Modern browsers */
778 778 display: flex;
779 779 flex-direction: column;
780 780 align-items: stretch;
781 781 }
782 782 div.out_prompt_overlay {
783 783 height: 100%;
784 784 padding: 0px 0.4em;
785 785 position: absolute;
786 786 border-radius: 2px;
787 787 }
788 788 div.out_prompt_overlay:hover {
789 789 /* use inner shadow to get border that is computed the same on WebKit/FF */
790 790 -webkit-box-shadow: inset 0 0 1px #000000;
791 791 box-shadow: inset 0 0 1px #000000;
792 792 background: rgba(240, 240, 240, 0.5);
793 793 }
794 794 div.output_prompt {
795 795 color: darkred;
796 796 }
797 797 /* This class is the outer container of all output sections. */
798 798 div.output_area {
799 799 padding: 0px;
800 800 page-break-inside: avoid;
801 801 /* Old browsers */
802 802 display: -webkit-box;
803 803 -webkit-box-orient: horizontal;
804 804 -webkit-box-align: stretch;
805 805 display: -moz-box;
806 806 -moz-box-orient: horizontal;
807 807 -moz-box-align: stretch;
808 808 display: box;
809 809 box-orient: horizontal;
810 810 box-align: stretch;
811 811 /* Modern browsers */
812 812 display: flex;
813 813 flex-direction: row;
814 814 align-items: stretch;
815 815 }
816 816 div.output_area .MathJax_Display {
817 817 text-align: left !important;
818 818 }
819 819 div.output_area .rendered_html table {
820 820 margin-left: 0;
821 821 margin-right: 0;
822 822 }
823 823 div.output_area .rendered_html img {
824 824 margin-left: 0;
825 825 margin-right: 0;
826 826 }
827 827 /* This is needed to protect the pre formating from global settings such
828 828 as that of bootstrap */
829 829 .output {
830 830 /* Old browsers */
831 831 display: -webkit-box;
832 832 -webkit-box-orient: vertical;
833 833 -webkit-box-align: stretch;
834 834 display: -moz-box;
835 835 -moz-box-orient: vertical;
836 836 -moz-box-align: stretch;
837 837 display: box;
838 838 box-orient: vertical;
839 839 box-align: stretch;
840 840 /* Modern browsers */
841 841 display: flex;
842 842 flex-direction: column;
843 843 align-items: stretch;
844 844 }
845 845 @media (max-width: 540px) {
846 846 div.output_area {
847 847 /* Old browsers */
848 848 display: -webkit-box;
849 849 -webkit-box-orient: vertical;
850 850 -webkit-box-align: stretch;
851 851 display: -moz-box;
852 852 -moz-box-orient: vertical;
853 853 -moz-box-align: stretch;
854 854 display: box;
855 855 box-orient: vertical;
856 856 box-align: stretch;
857 857 /* Modern browsers */
858 858 display: flex;
859 859 flex-direction: column;
860 860 align-items: stretch;
861 861 }
862 862 }
863 863 div.output_area pre {
864 864 margin: 0;
865 865 padding: 0;
866 866 border: 0;
867 867 vertical-align: baseline;
868 868 color: black;
869 869 background-color: transparent;
870 870 border-radius: 0;
871 871 }
872 872 /* This class is for the output subarea inside the output_area and after
873 873 the prompt div. */
874 874 div.output_subarea {
875 875 padding: 0.4em;
876 876 /* Old browsers */
877 877 -webkit-box-flex: 1;
878 878 -moz-box-flex: 1;
879 879 box-flex: 1;
880 880 /* Modern browsers */
881 881 flex: 1;
882 882 }
883 883 /* The rest of the output_* classes are for special styling of the different
884 884 output types */
885 885 /* all text output has this class: */
886 886 div.output_text {
887 887 text-align: left;
888 888 color: #000000;
889 889 /* This has to match that of the the CodeMirror class line-height below */
890 890 line-height: 1.21429em;
891 891 }
892 892 /* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
893 893 div.output_stderr {
894 894 background: #fdd;
895 895 /* very light red background for stderr */
896 896 }
897 897 div.output_latex {
898 898 text-align: left;
899 899 }
900 900 /* Empty output_javascript divs should have no height */
901 901 div.output_javascript:empty {
902 902 padding: 0;
903 903 }
904 904 .js-error {
905 905 color: darkred;
906 906 }
907 907 /* raw_input styles */
908 908 div.raw_input_container {
909 909 font-family: monospace;
910 910 padding-top: 5px;
911 911 }
912 912 span.raw_input_prompt {
913 913 /* nothing needed here */
914 914 }
915 915 input.raw_input {
916 916 font-family: inherit;
917 917 font-size: inherit;
918 918 color: inherit;
919 919 width: auto;
920 920 /* make sure input baseline aligns with prompt */
921 921 vertical-align: baseline;
922 922 /* padding + margin = 0.5em between prompt and cursor */
923 923 padding: 0em 0.25em;
924 924 margin: 0em 0.25em;
925 925 }
926 926 input.raw_input:focus {
927 927 box-shadow: none;
928 928 }
929 929 p.p-space {
930 930 margin-bottom: 10px;
931 931 }
932 932 div.output_unrecognized {
933 933 padding: 5px;
934 934 font-weight: bold;
935 935 color: red;
936 936 }
937 937 div.output_unrecognized a {
938 938 color: inherit;
939 939 text-decoration: none;
940 940 }
941 941 div.output_unrecognized a:hover {
942 942 color: inherit;
943 943 text-decoration: none;
944 944 }
945 945 .rendered_html {
946 946 color: #000000;
947 947 /* any extras will just be numbers: */
948 948 }
949 949 .rendered_html em {
950 950 font-style: italic;
951 951 }
952 952 .rendered_html strong {
953 953 font-weight: bold;
954 954 }
955 955 .rendered_html u {
956 956 text-decoration: underline;
957 957 }
958 958 .rendered_html :link {
959 959 text-decoration: underline;
960 960 }
961 961 .rendered_html :visited {
962 962 text-decoration: underline;
963 963 }
964 964 .rendered_html h1 {
965 965 font-size: 185.7%;
966 966 margin: 1.08em 0 0 0;
967 967 font-weight: bold;
968 968 line-height: 1.0;
969 969 }
970 970 .rendered_html h2 {
971 971 font-size: 157.1%;
972 972 margin: 1.27em 0 0 0;
973 973 font-weight: bold;
974 974 line-height: 1.0;
975 975 }
976 976 .rendered_html h3 {
977 977 font-size: 128.6%;
978 978 margin: 1.55em 0 0 0;
979 979 font-weight: bold;
980 980 line-height: 1.0;
981 981 }
982 982 .rendered_html h4 {
983 983 font-size: 100%;
984 984 margin: 2em 0 0 0;
985 985 font-weight: bold;
986 986 line-height: 1.0;
987 987 }
988 988 .rendered_html h5 {
989 989 font-size: 100%;
990 990 margin: 2em 0 0 0;
991 991 font-weight: bold;
992 992 line-height: 1.0;
993 993 font-style: italic;
994 994 }
995 995 .rendered_html h6 {
996 996 font-size: 100%;
997 997 margin: 2em 0 0 0;
998 998 font-weight: bold;
999 999 line-height: 1.0;
1000 1000 font-style: italic;
1001 1001 }
1002 1002 .rendered_html h1:first-child {
1003 1003 margin-top: 0.538em;
1004 1004 }
1005 1005 .rendered_html h2:first-child {
1006 1006 margin-top: 0.636em;
1007 1007 }
1008 1008 .rendered_html h3:first-child {
1009 1009 margin-top: 0.777em;
1010 1010 }
1011 1011 .rendered_html h4:first-child {
1012 1012 margin-top: 1em;
1013 1013 }
1014 1014 .rendered_html h5:first-child {
1015 1015 margin-top: 1em;
1016 1016 }
1017 1017 .rendered_html h6:first-child {
1018 1018 margin-top: 1em;
1019 1019 }
1020 1020 .rendered_html ul {
1021 1021 list-style: disc;
1022 1022 margin: 0em 2em;
1023 1023 padding-left: 0px;
1024 1024 }
1025 1025 .rendered_html ul ul {
1026 1026 list-style: square;
1027 1027 margin: 0em 2em;
1028 1028 }
1029 1029 .rendered_html ul ul ul {
1030 1030 list-style: circle;
1031 1031 margin: 0em 2em;
1032 1032 }
1033 1033 .rendered_html ol {
1034 1034 list-style: decimal;
1035 1035 margin: 0em 2em;
1036 1036 padding-left: 0px;
1037 1037 }
1038 1038 .rendered_html ol ol {
1039 1039 list-style: upper-alpha;
1040 1040 margin: 0em 2em;
1041 1041 }
1042 1042 .rendered_html ol ol ol {
1043 1043 list-style: lower-alpha;
1044 1044 margin: 0em 2em;
1045 1045 }
1046 1046 .rendered_html ol ol ol ol {
1047 1047 list-style: lower-roman;
1048 1048 margin: 0em 2em;
1049 1049 }
1050 1050 .rendered_html ol ol ol ol ol {
1051 1051 list-style: decimal;
1052 1052 margin: 0em 2em;
1053 1053 }
1054 1054 .rendered_html * + ul {
1055 1055 margin-top: 1em;
1056 1056 }
1057 1057 .rendered_html * + ol {
1058 1058 margin-top: 1em;
1059 1059 }
1060 1060 .rendered_html hr {
1061 1061 color: black;
1062 1062 background-color: black;
1063 1063 }
1064 1064 .rendered_html pre {
1065 1065 margin: 1em 2em;
1066 1066 }
1067 1067 .rendered_html pre,
1068 1068 .rendered_html code {
1069 1069 border: 0;
1070 1070 background-color: #ffffff;
1071 1071 color: #000000;
1072 1072 font-size: 100%;
1073 1073 padding: 0px;
1074 1074 }
1075 1075 .rendered_html blockquote {
1076 1076 margin: 1em 2em;
1077 1077 }
1078 1078 .rendered_html table {
1079 1079 margin-left: auto;
1080 1080 margin-right: auto;
1081 1081 border: 1px solid black;
1082 1082 border-collapse: collapse;
1083 1083 }
1084 1084 .rendered_html tr,
1085 1085 .rendered_html th,
1086 1086 .rendered_html td {
1087 1087 border: 1px solid black;
1088 1088 border-collapse: collapse;
1089 1089 margin: 1em 2em;
1090 1090 }
1091 1091 .rendered_html td,
1092 1092 .rendered_html th {
1093 1093 text-align: left;
1094 1094 vertical-align: middle;
1095 1095 padding: 4px;
1096 1096 }
1097 1097 .rendered_html th {
1098 1098 font-weight: bold;
1099 1099 }
1100 1100 .rendered_html * + table {
1101 1101 margin-top: 1em;
1102 1102 }
1103 1103 .rendered_html p {
1104 1104 text-align: left;
1105 1105 }
1106 1106 .rendered_html * + p {
1107 1107 margin-top: 1em;
1108 1108 }
1109 1109 .rendered_html img {
1110 1110 display: block;
1111 1111 margin-left: auto;
1112 1112 margin-right: auto;
1113 1113 }
1114 1114 .rendered_html * + img {
1115 1115 margin-top: 1em;
1116 1116 }
1117 1117 div.text_cell {
1118 1118 /* Old browsers */
1119 1119 display: -webkit-box;
1120 1120 -webkit-box-orient: horizontal;
1121 1121 -webkit-box-align: stretch;
1122 1122 display: -moz-box;
1123 1123 -moz-box-orient: horizontal;
1124 1124 -moz-box-align: stretch;
1125 1125 display: box;
1126 1126 box-orient: horizontal;
1127 1127 box-align: stretch;
1128 1128 /* Modern browsers */
1129 1129 display: flex;
1130 1130 flex-direction: row;
1131 1131 align-items: stretch;
1132 1132 }
1133 1133 @media (max-width: 540px) {
1134 1134 div.text_cell > div.prompt {
1135 1135 display: none;
1136 1136 }
1137 1137 }
1138 1138 div.text_cell_render {
1139 1139 /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
1140 1140 outline: none;
1141 1141 resize: none;
1142 1142 width: inherit;
1143 1143 border-style: none;
1144 1144 padding: 0.5em 0.5em 0.5em 0.4em;
1145 1145 color: #000000;
1146 1146 box-sizing: border-box;
1147 1147 -moz-box-sizing: border-box;
1148 1148 -webkit-box-sizing: border-box;
1149 1149 }
1150 1150 a.anchor-link:link {
1151 1151 text-decoration: none;
1152 1152 padding: 0px 20px;
1153 1153 visibility: hidden;
1154 1154 }
1155 1155 h1:hover .anchor-link,
1156 1156 h2:hover .anchor-link,
1157 1157 h3:hover .anchor-link,
1158 1158 h4:hover .anchor-link,
1159 1159 h5:hover .anchor-link,
1160 1160 h6:hover .anchor-link {
1161 1161 visibility: visible;
1162 1162 }
1163 1163 .text_cell.rendered .input_area {
1164 1164 display: none;
1165 1165 }
1166 1166 .text_cell.unrendered .text_cell_render {
1167 1167 display: none;
1168 1168 }
1169 1169 .cm-header-1,
1170 1170 .cm-header-2,
1171 1171 .cm-header-3,
1172 1172 .cm-header-4,
1173 1173 .cm-header-5,
1174 1174 .cm-header-6 {
1175 1175 font-weight: bold;
1176 1176 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1177 1177 }
1178 1178 .cm-header-1 {
1179 1179 font-size: 185.7%;
1180 1180 }
1181 1181 .cm-header-2 {
1182 1182 font-size: 157.1%;
1183 1183 }
1184 1184 .cm-header-3 {
1185 1185 font-size: 128.6%;
1186 1186 }
1187 1187 .cm-header-4 {
1188 1188 font-size: 110%;
1189 1189 }
1190 1190 .cm-header-5 {
1191 1191 font-size: 100%;
1192 1192 font-style: italic;
1193 1193 }
1194 1194 .cm-header-6 {
1195 1195 font-size: 100%;
1196 1196 font-style: italic;
1197 1197 }
1198 1198 .widget-interact > div,
1199 1199 .widget-interact > input {
1200 1200 padding: 2.5px;
1201 1201 }
1202 1202 .widget-area {
1203 1203 /*
1204 1204 LESS file that styles IPython notebook widgets and the area they sit in.
1205 1205
1206 1206 The widget area typically looks something like this:
1207 1207 +------------------------------------------+
1208 1208 | widget-area |
1209 1209 | +--------+---------------------------+ |
1210 1210 | | prompt | widget-subarea | |
1211 1211 | | | +--------+ +--------+ | |
1212 1212 | | | | widget | | widget | | |
1213 1213 | | | +--------+ +--------+ | |
1214 1214 | +--------+---------------------------+ |
1215 1215 +------------------------------------------+
1216 1216 */
1217 1217 page-break-inside: avoid;
1218 1218 /* Old browsers */
1219 1219 display: -webkit-box;
1220 1220 -webkit-box-orient: horizontal;
1221 1221 -webkit-box-align: stretch;
1222 1222 display: -moz-box;
1223 1223 -moz-box-orient: horizontal;
1224 1224 -moz-box-align: stretch;
1225 1225 display: box;
1226 1226 box-orient: horizontal;
1227 1227 box-align: stretch;
1228 1228 /* Modern browsers */
1229 1229 display: flex;
1230 1230 flex-direction: row;
1231 1231 align-items: stretch;
1232 1232 }
1233 1233 .widget-area .widget-subarea {
1234 1234 padding: 0.44em 0.4em 0.4em 1px;
1235 1235 margin-left: 6px;
1236 1236 box-sizing: border-box;
1237 1237 -moz-box-sizing: border-box;
1238 1238 -webkit-box-sizing: border-box;
1239 1239 /* Old browsers */
1240 1240 display: -webkit-box;
1241 1241 -webkit-box-orient: vertical;
1242 1242 -webkit-box-align: stretch;
1243 1243 display: -moz-box;
1244 1244 -moz-box-orient: vertical;
1245 1245 -moz-box-align: stretch;
1246 1246 display: box;
1247 1247 box-orient: vertical;
1248 1248 box-align: stretch;
1249 1249 /* Modern browsers */
1250 1250 display: flex;
1251 1251 flex-direction: column;
1252 1252 align-items: stretch;
1253 1253 /* Old browsers */
1254 1254 -webkit-box-flex: 2;
1255 1255 -moz-box-flex: 2;
1256 1256 box-flex: 2;
1257 1257 /* Modern browsers */
1258 1258 flex: 2;
1259 1259 /* Old browsers */
1260 1260 -webkit-box-align: start;
1261 1261 -moz-box-align: start;
1262 1262 box-align: start;
1263 1263 /* Modern browsers */
1264 1264 align-items: flex-start;
1265 1265 }
1266 1266 .widget-area.connection-problems .prompt:after {
1267 1267 content: "\f127";
1268 1268 font-family: 'FontAwesome';
1269 1269 color: #d9534f;
1270 1270 font-size: 14px;
1271 1271 top: 3px;
1272 1272 padding: 3px;
1273 1273 }
1274 1274 /* THE CLASSES BELOW CAN APPEAR ANYWHERE IN THE DOM (POSSIBLEY OUTSIDE OF
1275 1275 THE WIDGET AREA). */
1276 1276 .slide-track {
1277 1277 /* Slider Track */
1278 1278 border: 1px solid #CCCCCC;
1279 1279 background: #FFFFFF;
1280 1280 border-radius: 2px;
1281 1281 /* Round the corners of the slide track */
1282 1282 }
1283 1283 .widget-hslider {
1284 1284 /* Horizontal jQuery Slider
1285 1285
1286 1286 Both the horizontal and vertical versions of the slider are characterized
1287 1287 by a styled div that contains an invisible jQuery slide div which
1288 1288 contains a visible slider handle div. This is requred so we can control
1289 1289 how the slider is drawn and 'fix' the issue where the slide handle
1290 1290 doesn't stop at the end of the slide.
1291 1291
1292 1292 Both horizontal and vertical sliders have this div nesting:
1293 1293 +------------------------------------------+
1294 1294 | widget-(h/v)slider |
1295 1295 | +--------+---------------------------+ |
1296 1296 | | ui-slider | |
1297 1297 | | +------------------+ | |
1298 1298 | | | ui-slider-handle | | |
1299 1299 | | +------------------+ | |
1300 1300 | +--------+---------------------------+ |
1301 1301 +------------------------------------------+
1302 1302 */
1303 1303 /* Fix the padding of the slide track so the ui-slider is sized
1304 1304 correctly. */
1305 1305 padding-left: 8px;
1306 1306 padding-right: 2px;
1307 1307 overflow: visible;
1308 1308 /* Default size of the slider */
1309 1309 width: 350px;
1310 1310 height: 5px;
1311 1311 max-height: 5px;
1312 1312 margin-top: 13px;
1313 1313 margin-bottom: 10px;
1314 1314 /* Style the slider track */
1315 1315 /* Slider Track */
1316 1316 border: 1px solid #CCCCCC;
1317 1317 background: #FFFFFF;
1318 1318 border-radius: 2px;
1319 1319 /* Round the corners of the slide track */
1320 1320 /* Make the div a flex box (makes FF behave correctly). */
1321 1321 /* Old browsers */
1322 1322 display: -webkit-box;
1323 1323 -webkit-box-orient: horizontal;
1324 1324 -webkit-box-align: stretch;
1325 1325 display: -moz-box;
1326 1326 -moz-box-orient: horizontal;
1327 1327 -moz-box-align: stretch;
1328 1328 display: box;
1329 1329 box-orient: horizontal;
1330 1330 box-align: stretch;
1331 1331 /* Modern browsers */
1332 1332 display: flex;
1333 1333 flex-direction: row;
1334 1334 align-items: stretch;
1335 1335 }
1336 1336 .widget-hslider .ui-slider {
1337 1337 /* Inner, invisible slide div */
1338 1338 border: 0px;
1339 1339 background: none;
1340 1340 /* Old browsers */
1341 1341 display: -webkit-box;
1342 1342 -webkit-box-orient: horizontal;
1343 1343 -webkit-box-align: stretch;
1344 1344 display: -moz-box;
1345 1345 -moz-box-orient: horizontal;
1346 1346 -moz-box-align: stretch;
1347 1347 display: box;
1348 1348 box-orient: horizontal;
1349 1349 box-align: stretch;
1350 1350 /* Modern browsers */
1351 1351 display: flex;
1352 1352 flex-direction: row;
1353 1353 align-items: stretch;
1354 1354 /* Old browsers */
1355 1355 -webkit-box-flex: 1;
1356 1356 -moz-box-flex: 1;
1357 1357 box-flex: 1;
1358 1358 /* Modern browsers */
1359 1359 flex: 1;
1360 1360 }
1361 1361 .widget-hslider .ui-slider .ui-slider-handle {
1362 1362 width: 12px;
1363 1363 height: 28px;
1364 1364 margin-top: -8px;
1365 1365 border-radius: 2px;
1366 1366 }
1367 1367 .widget-hslider .ui-slider .ui-slider-range {
1368 1368 height: 12px;
1369 1369 margin-top: -4px;
1370 1370 background: #eeeeee;
1371 1371 }
1372 1372 .widget-vslider {
1373 1373 /* Vertical jQuery Slider */
1374 1374 /* Fix the padding of the slide track so the ui-slider is sized
1375 1375 correctly. */
1376 1376 padding-bottom: 5px;
1377 1377 overflow: visible;
1378 1378 /* Default size of the slider */
1379 1379 width: 5px;
1380 1380 max-width: 5px;
1381 1381 height: 250px;
1382 1382 margin-left: 12px;
1383 1383 /* Style the slider track */
1384 1384 /* Slider Track */
1385 1385 border: 1px solid #CCCCCC;
1386 1386 background: #FFFFFF;
1387 1387 border-radius: 2px;
1388 1388 /* Round the corners of the slide track */
1389 1389 /* Make the div a flex box (makes FF behave correctly). */
1390 1390 /* Old browsers */
1391 1391 display: -webkit-box;
1392 1392 -webkit-box-orient: vertical;
1393 1393 -webkit-box-align: stretch;
1394 1394 display: -moz-box;
1395 1395 -moz-box-orient: vertical;
1396 1396 -moz-box-align: stretch;
1397 1397 display: box;
1398 1398 box-orient: vertical;
1399 1399 box-align: stretch;
1400 1400 /* Modern browsers */
1401 1401 display: flex;
1402 1402 flex-direction: column;
1403 1403 align-items: stretch;
1404 1404 }
1405 1405 .widget-vslider .ui-slider {
1406 1406 /* Inner, invisible slide div */
1407 1407 border: 0px;
1408 1408 background: none;
1409 1409 margin-left: -4px;
1410 1410 margin-top: 5px;
1411 1411 /* Old browsers */
1412 1412 display: -webkit-box;
1413 1413 -webkit-box-orient: vertical;
1414 1414 -webkit-box-align: stretch;
1415 1415 display: -moz-box;
1416 1416 -moz-box-orient: vertical;
1417 1417 -moz-box-align: stretch;
1418 1418 display: box;
1419 1419 box-orient: vertical;
1420 1420 box-align: stretch;
1421 1421 /* Modern browsers */
1422 1422 display: flex;
1423 1423 flex-direction: column;
1424 1424 align-items: stretch;
1425 1425 /* Old browsers */
1426 1426 -webkit-box-flex: 1;
1427 1427 -moz-box-flex: 1;
1428 1428 box-flex: 1;
1429 1429 /* Modern browsers */
1430 1430 flex: 1;
1431 1431 }
1432 1432 .widget-vslider .ui-slider .ui-slider-handle {
1433 1433 width: 28px;
1434 1434 height: 12px;
1435 1435 margin-left: -9px;
1436 1436 border-radius: 2px;
1437 1437 }
1438 1438 .widget-vslider .ui-slider .ui-slider-range {
1439 1439 width: 12px;
1440 1440 margin-left: -1px;
1441 1441 background: #eeeeee;
1442 1442 }
1443 1443 .widget-text {
1444 1444 /* String Textbox - used for TextBoxView and TextAreaView */
1445 1445 width: 350px;
1446 1446 margin: 0px;
1447 1447 }
1448 1448 .widget-listbox {
1449 1449 /* Listbox */
1450 1450 width: 350px;
1451 1451 margin-bottom: 0px;
1452 1452 }
1453 1453 .widget-numeric-text {
1454 1454 /* Single Line Textbox - used for IntTextView and FloatTextView */
1455 1455 width: 150px;
1456 1456 margin: 0px;
1457 1457 }
1458 1458 .widget-progress {
1459 1459 /* Progress Bar */
1460 1460 margin-top: 6px;
1461 1461 min-width: 350px;
1462 1462 }
1463 1463 .widget-progress .progress-bar {
1464 1464 /* Disable progress bar animation */
1465 1465 -webkit-transition: none;
1466 1466 -moz-transition: none;
1467 1467 -ms-transition: none;
1468 1468 -o-transition: none;
1469 1469 transition: none;
1470 1470 }
1471 1471 .widget-combo-btn {
1472 1472 /* ComboBox Main Button */
1473 1473 /* Subtract 25px to account for the drop arrow button */
1474 1474 min-width: 125px;
1475 1475 }
1476 1476 .widget_item .dropdown-menu li a {
1477 1477 color: inherit;
1478 1478 }
1479 1479 .widget-hbox {
1480 1480 /* Horizontal widgets */
1481 1481 /* Old browsers */
1482 1482 display: -webkit-box;
1483 1483 -webkit-box-orient: horizontal;
1484 1484 -webkit-box-align: stretch;
1485 1485 display: -moz-box;
1486 1486 -moz-box-orient: horizontal;
1487 1487 -moz-box-align: stretch;
1488 1488 display: box;
1489 1489 box-orient: horizontal;
1490 1490 box-align: stretch;
1491 1491 /* Modern browsers */
1492 1492 display: flex;
1493 1493 flex-direction: row;
1494 1494 align-items: stretch;
1495 1495 }
1496 1496 .widget-hbox input[type="checkbox"] {
1497 1497 margin-top: 9px;
1498 1498 margin-bottom: 10px;
1499 1499 }
1500 1500 .widget-hbox .widget-label {
1501 1501 /* Horizontal Label */
1502 1502 min-width: 10ex;
1503 1503 padding-right: 8px;
1504 1504 padding-top: 5px;
1505 1505 text-align: right;
1506 1506 vertical-align: text-top;
1507 1507 }
1508 1508 .widget-hbox .widget-readout {
1509 1509 padding-left: 8px;
1510 1510 padding-top: 5px;
1511 1511 text-align: left;
1512 1512 vertical-align: text-top;
1513 1513 }
1514 1514 .widget-vbox {
1515 1515 /* Vertical widgets */
1516 1516 /* Old browsers */
1517 1517 display: -webkit-box;
1518 1518 -webkit-box-orient: vertical;
1519 1519 -webkit-box-align: stretch;
1520 1520 display: -moz-box;
1521 1521 -moz-box-orient: vertical;
1522 1522 -moz-box-align: stretch;
1523 1523 display: box;
1524 1524 box-orient: vertical;
1525 1525 box-align: stretch;
1526 1526 /* Modern browsers */
1527 1527 display: flex;
1528 1528 flex-direction: column;
1529 1529 align-items: stretch;
1530 1530 }
1531 1531 .widget-vbox .widget-label {
1532 1532 /* Vertical Label */
1533 1533 padding-bottom: 5px;
1534 1534 text-align: center;
1535 1535 vertical-align: text-bottom;
1536 1536 }
1537 1537 .widget-vbox .widget-readout {
1538 1538 /* Vertical Label */
1539 1539 padding-top: 5px;
1540 1540 text-align: center;
1541 1541 vertical-align: text-top;
1542 1542 }
1543 1543 .widget-box {
1544 1544 /* Box */
1545 1545 box-sizing: border-box;
1546 1546 -moz-box-sizing: border-box;
1547 1547 -webkit-box-sizing: border-box;
1548 1548 /* Old browsers */
1549 1549 -webkit-box-align: start;
1550 1550 -moz-box-align: start;
1551 1551 box-align: start;
1552 1552 /* Modern browsers */
1553 1553 align-items: flex-start;
1554 1554 }
1555 1555 .widget-radio-box {
1556 1556 /* Contains RadioButtonsWidget */
1557 1557 /* Old browsers */
1558 1558 display: -webkit-box;
1559 1559 -webkit-box-orient: vertical;
1560 1560 -webkit-box-align: stretch;
1561 1561 display: -moz-box;
1562 1562 -moz-box-orient: vertical;
1563 1563 -moz-box-align: stretch;
1564 1564 display: box;
1565 1565 box-orient: vertical;
1566 1566 box-align: stretch;
1567 1567 /* Modern browsers */
1568 1568 display: flex;
1569 1569 flex-direction: column;
1570 1570 align-items: stretch;
1571 1571 box-sizing: border-box;
1572 1572 -moz-box-sizing: border-box;
1573 1573 -webkit-box-sizing: border-box;
1574 1574 padding-top: 4px;
1575 1575 }
1576 1576 .widget-radio-box label {
1577 1577 margin-top: 0px;
1578 }
1579 .widget-radio {
1580 1578 margin-left: 20px;
1581 1579 }
1582 1580 /*# sourceMappingURL=ipython.min.css.map */ No newline at end of file
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 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