##// END OF EJS Templates
Make comm_manager a property of kernel, not shell
Thomas Kluyver -
Show More
@@ -1,3288 +1,3279 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 types
26 26 import subprocess
27 27 from io import open as io_open
28 28
29 29 from IPython.config.configurable import SingletonConfigurable
30 30 from IPython.core import debugger, oinspect
31 31 from IPython.core import magic
32 32 from IPython.core import page
33 33 from IPython.core import prefilter
34 34 from IPython.core import shadowns
35 35 from IPython.core import ultratb
36 36 from IPython.core.alias import AliasManager, AliasError
37 37 from IPython.core.autocall import ExitAutocall
38 38 from IPython.core.builtin_trap import BuiltinTrap
39 39 from IPython.core.events import EventManager, available_events
40 40 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
41 41 from IPython.core.display_trap import DisplayTrap
42 42 from IPython.core.displayhook import DisplayHook
43 43 from IPython.core.displaypub import DisplayPublisher
44 44 from IPython.core.error import InputRejected, UsageError
45 45 from IPython.core.extensions import ExtensionManager
46 46 from IPython.core.formatters import DisplayFormatter
47 47 from IPython.core.history import HistoryManager
48 48 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
49 49 from IPython.core.logger import Logger
50 50 from IPython.core.macro import Macro
51 51 from IPython.core.payload import PayloadManager
52 52 from IPython.core.prefilter import PrefilterManager
53 53 from IPython.core.profiledir import ProfileDir
54 54 from IPython.core.prompts import PromptManager
55 55 from IPython.core.usage import default_banner
56 56 from IPython.lib.latextools import LaTeXTool
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, 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 # Main IPython class
196 196 #-----------------------------------------------------------------------------
197 197
198 198 class InteractiveShell(SingletonConfigurable):
199 199 """An enhanced, interactive shell for Python."""
200 200
201 201 _instance = None
202 202
203 203 ast_transformers = List([], config=True, help=
204 204 """
205 205 A list of ast.NodeTransformer subclass instances, which will be applied
206 206 to user input before code is run.
207 207 """
208 208 )
209 209
210 210 autocall = Enum((0,1,2), default_value=0, config=True, help=
211 211 """
212 212 Make IPython automatically call any callable object even if you didn't
213 213 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
214 214 automatically. The value can be '0' to disable the feature, '1' for
215 215 'smart' autocall, where it is not applied if there are no more
216 216 arguments on the line, and '2' for 'full' autocall, where all callable
217 217 objects are automatically called (even if no arguments are present).
218 218 """
219 219 )
220 220 # TODO: remove all autoindent logic and put into frontends.
221 221 # We can't do this yet because even runlines uses the autoindent.
222 222 autoindent = CBool(True, config=True, help=
223 223 """
224 224 Autoindent IPython code entered interactively.
225 225 """
226 226 )
227 227 automagic = CBool(True, config=True, help=
228 228 """
229 229 Enable magic commands to be called without the leading %.
230 230 """
231 231 )
232 232
233 233 banner = Unicode('')
234 234
235 235 banner1 = Unicode(default_banner, config=True,
236 236 help="""The part of the banner to be printed before the profile"""
237 237 )
238 238 banner2 = Unicode('', config=True,
239 239 help="""The part of the banner to be printed after the profile"""
240 240 )
241 241
242 242 cache_size = Integer(1000, config=True, help=
243 243 """
244 244 Set the size of the output cache. The default is 1000, you can
245 245 change it permanently in your config file. Setting it to 0 completely
246 246 disables the caching system, and the minimum value accepted is 20 (if
247 247 you provide a value less than 20, it is reset to 0 and a warning is
248 248 issued). This limit is defined because otherwise you'll spend more
249 249 time re-flushing a too small cache than working
250 250 """
251 251 )
252 252 color_info = CBool(True, config=True, help=
253 253 """
254 254 Use colors for displaying information about objects. Because this
255 255 information is passed through a pager (like 'less'), and some pagers
256 256 get confused with color codes, this capability can be turned off.
257 257 """
258 258 )
259 259 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
260 260 default_value=get_default_colors(), config=True,
261 261 help="Set the color scheme (NoColor, Linux, or LightBG)."
262 262 )
263 263 colors_force = CBool(False, help=
264 264 """
265 265 Force use of ANSI color codes, regardless of OS and readline
266 266 availability.
267 267 """
268 268 # FIXME: This is essentially a hack to allow ZMQShell to show colors
269 269 # without readline on Win32. When the ZMQ formatting system is
270 270 # refactored, this should be removed.
271 271 )
272 272 debug = CBool(False, config=True)
273 273 deep_reload = CBool(False, config=True, help=
274 274 """
275 275 Enable deep (recursive) reloading by default. IPython can use the
276 276 deep_reload module which reloads changes in modules recursively (it
277 277 replaces the reload() function, so you don't need to change anything to
278 278 use it). deep_reload() forces a full reload of modules whose code may
279 279 have changed, which the default reload() function does not. When
280 280 deep_reload is off, IPython will use the normal reload(), but
281 281 deep_reload will still be available as dreload().
282 282 """
283 283 )
284 284 disable_failing_post_execute = CBool(False, config=True,
285 285 help="Don't call post-execute functions that have failed in the past."
286 286 )
287 287 display_formatter = Instance(DisplayFormatter)
288 288 displayhook_class = Type(DisplayHook)
289 289 display_pub_class = Type(DisplayPublisher)
290 290 data_pub_class = None
291 291
292 292 exit_now = CBool(False)
293 293 exiter = Instance(ExitAutocall)
294 294 def _exiter_default(self):
295 295 return ExitAutocall(self)
296 296 # Monotonically increasing execution counter
297 297 execution_count = Integer(1)
298 298 filename = Unicode("<ipython console>")
299 299 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
300 300
301 301 # Input splitter, to transform input line by line and detect when a block
302 302 # is ready to be executed.
303 303 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
304 304 (), {'line_input_checker': True})
305 305
306 306 # This InputSplitter instance is used to transform completed cells before
307 307 # running them. It allows cell magics to contain blank lines.
308 308 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
309 309 (), {'line_input_checker': False})
310 310
311 311 logstart = CBool(False, config=True, help=
312 312 """
313 313 Start logging to the default log file.
314 314 """
315 315 )
316 316 logfile = Unicode('', config=True, help=
317 317 """
318 318 The name of the logfile to use.
319 319 """
320 320 )
321 321 logappend = Unicode('', config=True, help=
322 322 """
323 323 Start logging to the given file in append mode.
324 324 """
325 325 )
326 326 object_info_string_level = Enum((0,1,2), default_value=0,
327 327 config=True)
328 328 pdb = CBool(False, config=True, help=
329 329 """
330 330 Automatically call the pdb debugger after every exception.
331 331 """
332 332 )
333 333 multiline_history = CBool(sys.platform != 'win32', config=True,
334 334 help="Save multi-line entries as one entry in readline history"
335 335 )
336 336
337 337 # deprecated prompt traits:
338 338
339 339 prompt_in1 = Unicode('In [\\#]: ', config=True,
340 340 help="Deprecated, use PromptManager.in_template")
341 341 prompt_in2 = Unicode(' .\\D.: ', config=True,
342 342 help="Deprecated, use PromptManager.in2_template")
343 343 prompt_out = Unicode('Out[\\#]: ', config=True,
344 344 help="Deprecated, use PromptManager.out_template")
345 345 prompts_pad_left = CBool(True, config=True,
346 346 help="Deprecated, use PromptManager.justify")
347 347
348 348 def _prompt_trait_changed(self, name, old, new):
349 349 table = {
350 350 'prompt_in1' : 'in_template',
351 351 'prompt_in2' : 'in2_template',
352 352 'prompt_out' : 'out_template',
353 353 'prompts_pad_left' : 'justify',
354 354 }
355 355 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
356 356 name=name, newname=table[name])
357 357 )
358 358 # protect against weird cases where self.config may not exist:
359 359 if self.config is not None:
360 360 # propagate to corresponding PromptManager trait
361 361 setattr(self.config.PromptManager, table[name], new)
362 362
363 363 _prompt_in1_changed = _prompt_trait_changed
364 364 _prompt_in2_changed = _prompt_trait_changed
365 365 _prompt_out_changed = _prompt_trait_changed
366 366 _prompt_pad_left_changed = _prompt_trait_changed
367 367
368 368 show_rewritten_input = CBool(True, config=True,
369 369 help="Show rewritten input, e.g. for autocall."
370 370 )
371 371
372 372 quiet = CBool(False, config=True)
373 373
374 374 history_length = Integer(10000, config=True)
375 375
376 376 # The readline stuff will eventually be moved to the terminal subclass
377 377 # but for now, we can't do that as readline is welded in everywhere.
378 378 readline_use = CBool(True, config=True)
379 379 readline_remove_delims = Unicode('-/~', config=True)
380 380 readline_delims = Unicode() # set by init_readline()
381 381 # don't use \M- bindings by default, because they
382 382 # conflict with 8-bit encodings. See gh-58,gh-88
383 383 readline_parse_and_bind = List([
384 384 'tab: complete',
385 385 '"\C-l": clear-screen',
386 386 'set show-all-if-ambiguous on',
387 387 '"\C-o": tab-insert',
388 388 '"\C-r": reverse-search-history',
389 389 '"\C-s": forward-search-history',
390 390 '"\C-p": history-search-backward',
391 391 '"\C-n": history-search-forward',
392 392 '"\e[A": history-search-backward',
393 393 '"\e[B": history-search-forward',
394 394 '"\C-k": kill-line',
395 395 '"\C-u": unix-line-discard',
396 396 ], config=True)
397 397
398 398 _custom_readline_config = False
399 399
400 400 def _readline_parse_and_bind_changed(self, name, old, new):
401 401 # notice that readline config is customized
402 402 # indicates that it should have higher priority than inputrc
403 403 self._custom_readline_config = True
404 404
405 405 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
406 406 default_value='last_expr', config=True,
407 407 help="""
408 408 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
409 409 run interactively (displaying output from expressions).""")
410 410
411 411 # TODO: this part of prompt management should be moved to the frontends.
412 412 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
413 413 separate_in = SeparateUnicode('\n', config=True)
414 414 separate_out = SeparateUnicode('', config=True)
415 415 separate_out2 = SeparateUnicode('', config=True)
416 416 wildcards_case_sensitive = CBool(True, config=True)
417 417 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
418 418 default_value='Context', config=True)
419 419
420 420 # Subcomponents of InteractiveShell
421 421 alias_manager = Instance('IPython.core.alias.AliasManager')
422 422 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
423 423 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
424 424 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
425 425 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
426 426 payload_manager = Instance('IPython.core.payload.PayloadManager')
427 427 history_manager = Instance('IPython.core.history.HistoryManager')
428 428 magics_manager = Instance('IPython.core.magic.MagicsManager')
429 429
430 430 profile_dir = Instance('IPython.core.application.ProfileDir')
431 431 @property
432 432 def profile(self):
433 433 if self.profile_dir is not None:
434 434 name = os.path.basename(self.profile_dir.location)
435 435 return name.replace('profile_','')
436 436
437 437
438 438 # Private interface
439 439 _post_execute = Instance(dict)
440 440
441 441 # Tracks any GUI loop loaded for pylab
442 442 pylab_gui_select = None
443 443
444 444 def __init__(self, ipython_dir=None, profile_dir=None,
445 445 user_module=None, user_ns=None,
446 446 custom_exceptions=((), None), **kwargs):
447 447
448 448 # This is where traits with a config_key argument are updated
449 449 # from the values on config.
450 450 super(InteractiveShell, self).__init__(**kwargs)
451 451 self.configurables = [self]
452 452
453 453 # These are relatively independent and stateless
454 454 self.init_ipython_dir(ipython_dir)
455 455 self.init_profile_dir(profile_dir)
456 456 self.init_instance_attrs()
457 457 self.init_environment()
458 458
459 459 # Check if we're in a virtualenv, and set up sys.path.
460 460 self.init_virtualenv()
461 461
462 462 # Create namespaces (user_ns, user_global_ns, etc.)
463 463 self.init_create_namespaces(user_module, user_ns)
464 464 # This has to be done after init_create_namespaces because it uses
465 465 # something in self.user_ns, but before init_sys_modules, which
466 466 # is the first thing to modify sys.
467 467 # TODO: When we override sys.stdout and sys.stderr before this class
468 468 # is created, we are saving the overridden ones here. Not sure if this
469 469 # is what we want to do.
470 470 self.save_sys_module_state()
471 471 self.init_sys_modules()
472 472
473 473 # While we're trying to have each part of the code directly access what
474 474 # it needs without keeping redundant references to objects, we have too
475 475 # much legacy code that expects ip.db to exist.
476 476 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
477 477
478 478 self.init_history()
479 479 self.init_encoding()
480 480 self.init_prefilter()
481 481
482 482 self.init_syntax_highlighting()
483 483 self.init_hooks()
484 484 self.init_events()
485 485 self.init_pushd_popd_magic()
486 486 # self.init_traceback_handlers use to be here, but we moved it below
487 487 # because it and init_io have to come after init_readline.
488 488 self.init_user_ns()
489 489 self.init_logger()
490 490 self.init_builtins()
491 491
492 492 # The following was in post_config_initialization
493 493 self.init_inspector()
494 494 # init_readline() must come before init_io(), because init_io uses
495 495 # readline related things.
496 496 self.init_readline()
497 497 # We save this here in case user code replaces raw_input, but it needs
498 498 # to be after init_readline(), because PyPy's readline works by replacing
499 499 # raw_input.
500 500 if py3compat.PY3:
501 501 self.raw_input_original = input
502 502 else:
503 503 self.raw_input_original = raw_input
504 504 # init_completer must come after init_readline, because it needs to
505 505 # know whether readline is present or not system-wide to configure the
506 506 # completers, since the completion machinery can now operate
507 507 # independently of readline (e.g. over the network)
508 508 self.init_completer()
509 509 # TODO: init_io() needs to happen before init_traceback handlers
510 510 # because the traceback handlers hardcode the stdout/stderr streams.
511 511 # This logic in in debugger.Pdb and should eventually be changed.
512 512 self.init_io()
513 513 self.init_traceback_handlers(custom_exceptions)
514 514 self.init_prompts()
515 515 self.init_display_formatter()
516 516 self.init_display_pub()
517 517 self.init_data_pub()
518 518 self.init_displayhook()
519 519 self.init_latextool()
520 520 self.init_magics()
521 521 self.init_alias()
522 522 self.init_logstart()
523 523 self.init_pdb()
524 524 self.init_extension_manager()
525 525 self.init_payload()
526 self.init_comms()
527 526 self.hooks.late_startup_hook()
528 527 self.events.trigger('shell_initialized', self)
529 528 atexit.register(self.atexit_operations)
530 529
531 530 def get_ipython(self):
532 531 """Return the currently running IPython instance."""
533 532 return self
534 533
535 534 #-------------------------------------------------------------------------
536 535 # Trait changed handlers
537 536 #-------------------------------------------------------------------------
538 537
539 538 def _ipython_dir_changed(self, name, new):
540 539 ensure_dir_exists(new)
541 540
542 541 def set_autoindent(self,value=None):
543 542 """Set the autoindent flag, checking for readline support.
544 543
545 544 If called with no arguments, it acts as a toggle."""
546 545
547 546 if value != 0 and not self.has_readline:
548 547 if os.name == 'posix':
549 548 warn("The auto-indent feature requires the readline library")
550 549 self.autoindent = 0
551 550 return
552 551 if value is None:
553 552 self.autoindent = not self.autoindent
554 553 else:
555 554 self.autoindent = value
556 555
557 556 #-------------------------------------------------------------------------
558 557 # init_* methods called by __init__
559 558 #-------------------------------------------------------------------------
560 559
561 560 def init_ipython_dir(self, ipython_dir):
562 561 if ipython_dir is not None:
563 562 self.ipython_dir = ipython_dir
564 563 return
565 564
566 565 self.ipython_dir = get_ipython_dir()
567 566
568 567 def init_profile_dir(self, profile_dir):
569 568 if profile_dir is not None:
570 569 self.profile_dir = profile_dir
571 570 return
572 571 self.profile_dir =\
573 572 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
574 573
575 574 def init_instance_attrs(self):
576 575 self.more = False
577 576
578 577 # command compiler
579 578 self.compile = CachingCompiler()
580 579
581 580 # Make an empty namespace, which extension writers can rely on both
582 581 # existing and NEVER being used by ipython itself. This gives them a
583 582 # convenient location for storing additional information and state
584 583 # their extensions may require, without fear of collisions with other
585 584 # ipython names that may develop later.
586 585 self.meta = Struct()
587 586
588 587 # Temporary files used for various purposes. Deleted at exit.
589 588 self.tempfiles = []
590 589 self.tempdirs = []
591 590
592 591 # Keep track of readline usage (later set by init_readline)
593 592 self.has_readline = False
594 593
595 594 # keep track of where we started running (mainly for crash post-mortem)
596 595 # This is not being used anywhere currently.
597 596 self.starting_dir = py3compat.getcwd()
598 597
599 598 # Indentation management
600 599 self.indent_current_nsp = 0
601 600
602 601 # Dict to track post-execution functions that have been registered
603 602 self._post_execute = {}
604 603
605 604 def init_environment(self):
606 605 """Any changes we need to make to the user's environment."""
607 606 pass
608 607
609 608 def init_encoding(self):
610 609 # Get system encoding at startup time. Certain terminals (like Emacs
611 610 # under Win32 have it set to None, and we need to have a known valid
612 611 # encoding to use in the raw_input() method
613 612 try:
614 613 self.stdin_encoding = sys.stdin.encoding or 'ascii'
615 614 except AttributeError:
616 615 self.stdin_encoding = 'ascii'
617 616
618 617 def init_syntax_highlighting(self):
619 618 # Python source parser/formatter for syntax highlighting
620 619 pyformat = PyColorize.Parser().format
621 620 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
622 621
623 622 def init_pushd_popd_magic(self):
624 623 # for pushd/popd management
625 624 self.home_dir = get_home_dir()
626 625
627 626 self.dir_stack = []
628 627
629 628 def init_logger(self):
630 629 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
631 630 logmode='rotate')
632 631
633 632 def init_logstart(self):
634 633 """Initialize logging in case it was requested at the command line.
635 634 """
636 635 if self.logappend:
637 636 self.magic('logstart %s append' % self.logappend)
638 637 elif self.logfile:
639 638 self.magic('logstart %s' % self.logfile)
640 639 elif self.logstart:
641 640 self.magic('logstart')
642 641
643 642 def init_builtins(self):
644 643 # A single, static flag that we set to True. Its presence indicates
645 644 # that an IPython shell has been created, and we make no attempts at
646 645 # removing on exit or representing the existence of more than one
647 646 # IPython at a time.
648 647 builtin_mod.__dict__['__IPYTHON__'] = True
649 648
650 649 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
651 650 # manage on enter/exit, but with all our shells it's virtually
652 651 # impossible to get all the cases right. We're leaving the name in for
653 652 # those who adapted their codes to check for this flag, but will
654 653 # eventually remove it after a few more releases.
655 654 builtin_mod.__dict__['__IPYTHON__active'] = \
656 655 'Deprecated, check for __IPYTHON__'
657 656
658 657 self.builtin_trap = BuiltinTrap(shell=self)
659 658
660 659 def init_inspector(self):
661 660 # Object inspector
662 661 self.inspector = oinspect.Inspector(oinspect.InspectColors,
663 662 PyColorize.ANSICodeColors,
664 663 'NoColor',
665 664 self.object_info_string_level)
666 665
667 666 def init_io(self):
668 667 # This will just use sys.stdout and sys.stderr. If you want to
669 668 # override sys.stdout and sys.stderr themselves, you need to do that
670 669 # *before* instantiating this class, because io holds onto
671 670 # references to the underlying streams.
672 671 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
673 672 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
674 673 else:
675 674 io.stdout = io.IOStream(sys.stdout)
676 675 io.stderr = io.IOStream(sys.stderr)
677 676
678 677 def init_prompts(self):
679 678 self.prompt_manager = PromptManager(shell=self, parent=self)
680 679 self.configurables.append(self.prompt_manager)
681 680 # Set system prompts, so that scripts can decide if they are running
682 681 # interactively.
683 682 sys.ps1 = 'In : '
684 683 sys.ps2 = '...: '
685 684 sys.ps3 = 'Out: '
686 685
687 686 def init_display_formatter(self):
688 687 self.display_formatter = DisplayFormatter(parent=self)
689 688 self.configurables.append(self.display_formatter)
690 689
691 690 def init_display_pub(self):
692 691 self.display_pub = self.display_pub_class(parent=self)
693 692 self.configurables.append(self.display_pub)
694 693
695 694 def init_data_pub(self):
696 695 if not self.data_pub_class:
697 696 self.data_pub = None
698 697 return
699 698 self.data_pub = self.data_pub_class(parent=self)
700 699 self.configurables.append(self.data_pub)
701 700
702 701 def init_displayhook(self):
703 702 # Initialize displayhook, set in/out prompts and printing system
704 703 self.displayhook = self.displayhook_class(
705 704 parent=self,
706 705 shell=self,
707 706 cache_size=self.cache_size,
708 707 )
709 708 self.configurables.append(self.displayhook)
710 709 # This is a context manager that installs/revmoes the displayhook at
711 710 # the appropriate time.
712 711 self.display_trap = DisplayTrap(hook=self.displayhook)
713 712
714 713 def init_latextool(self):
715 714 """Configure LaTeXTool."""
716 715 cfg = LaTeXTool.instance(parent=self)
717 716 if cfg not in self.configurables:
718 717 self.configurables.append(cfg)
719 718
720 719 def init_virtualenv(self):
721 720 """Add a virtualenv to sys.path so the user can import modules from it.
722 721 This isn't perfect: it doesn't use the Python interpreter with which the
723 722 virtualenv was built, and it ignores the --no-site-packages option. A
724 723 warning will appear suggesting the user installs IPython in the
725 724 virtualenv, but for many cases, it probably works well enough.
726 725
727 726 Adapted from code snippets online.
728 727
729 728 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
730 729 """
731 730 if 'VIRTUAL_ENV' not in os.environ:
732 731 # Not in a virtualenv
733 732 return
734 733
735 734 # venv detection:
736 735 # stdlib venv may symlink sys.executable, so we can't use realpath.
737 736 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
738 737 # So we just check every item in the symlink tree (generally <= 3)
739 738 p = os.path.normcase(sys.executable)
740 739 paths = [p]
741 740 while os.path.islink(p):
742 741 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
743 742 paths.append(p)
744 743 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
745 744 if any(p.startswith(p_venv) for p in paths):
746 745 # Running properly in the virtualenv, don't need to do anything
747 746 return
748 747
749 748 warn("Attempting to work in a virtualenv. If you encounter problems, please "
750 749 "install IPython inside the virtualenv.")
751 750 if sys.platform == "win32":
752 751 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
753 752 else:
754 753 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
755 754 'python%d.%d' % sys.version_info[:2], 'site-packages')
756 755
757 756 import site
758 757 sys.path.insert(0, virtual_env)
759 758 site.addsitedir(virtual_env)
760 759
761 760 #-------------------------------------------------------------------------
762 761 # Things related to injections into the sys module
763 762 #-------------------------------------------------------------------------
764 763
765 764 def save_sys_module_state(self):
766 765 """Save the state of hooks in the sys module.
767 766
768 767 This has to be called after self.user_module is created.
769 768 """
770 769 self._orig_sys_module_state = {}
771 770 self._orig_sys_module_state['stdin'] = sys.stdin
772 771 self._orig_sys_module_state['stdout'] = sys.stdout
773 772 self._orig_sys_module_state['stderr'] = sys.stderr
774 773 self._orig_sys_module_state['excepthook'] = sys.excepthook
775 774 self._orig_sys_modules_main_name = self.user_module.__name__
776 775 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
777 776
778 777 def restore_sys_module_state(self):
779 778 """Restore the state of the sys module."""
780 779 try:
781 780 for k, v in iteritems(self._orig_sys_module_state):
782 781 setattr(sys, k, v)
783 782 except AttributeError:
784 783 pass
785 784 # Reset what what done in self.init_sys_modules
786 785 if self._orig_sys_modules_main_mod is not None:
787 786 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
788 787
789 788 #-------------------------------------------------------------------------
790 789 # Things related to the banner
791 790 #-------------------------------------------------------------------------
792 791
793 792 @property
794 793 def banner(self):
795 794 banner = self.banner1
796 795 if self.profile and self.profile != 'default':
797 796 banner += '\nIPython profile: %s\n' % self.profile
798 797 if self.banner2:
799 798 banner += '\n' + self.banner2
800 799 return banner
801 800
802 801 def show_banner(self, banner=None):
803 802 if banner is None:
804 803 banner = self.banner
805 804 self.write(banner)
806 805
807 806 #-------------------------------------------------------------------------
808 807 # Things related to hooks
809 808 #-------------------------------------------------------------------------
810 809
811 810 def init_hooks(self):
812 811 # hooks holds pointers used for user-side customizations
813 812 self.hooks = Struct()
814 813
815 814 self.strdispatchers = {}
816 815
817 816 # Set all default hooks, defined in the IPython.hooks module.
818 817 hooks = IPython.core.hooks
819 818 for hook_name in hooks.__all__:
820 819 # default hooks have priority 100, i.e. low; user hooks should have
821 820 # 0-100 priority
822 821 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
823 822
824 823 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
825 824 _warn_deprecated=True):
826 825 """set_hook(name,hook) -> sets an internal IPython hook.
827 826
828 827 IPython exposes some of its internal API as user-modifiable hooks. By
829 828 adding your function to one of these hooks, you can modify IPython's
830 829 behavior to call at runtime your own routines."""
831 830
832 831 # At some point in the future, this should validate the hook before it
833 832 # accepts it. Probably at least check that the hook takes the number
834 833 # of args it's supposed to.
835 834
836 835 f = types.MethodType(hook,self)
837 836
838 837 # check if the hook is for strdispatcher first
839 838 if str_key is not None:
840 839 sdp = self.strdispatchers.get(name, StrDispatch())
841 840 sdp.add_s(str_key, f, priority )
842 841 self.strdispatchers[name] = sdp
843 842 return
844 843 if re_key is not None:
845 844 sdp = self.strdispatchers.get(name, StrDispatch())
846 845 sdp.add_re(re.compile(re_key), f, priority )
847 846 self.strdispatchers[name] = sdp
848 847 return
849 848
850 849 dp = getattr(self.hooks, name, None)
851 850 if name not in IPython.core.hooks.__all__:
852 851 print("Warning! Hook '%s' is not one of %s" % \
853 852 (name, IPython.core.hooks.__all__ ))
854 853
855 854 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
856 855 alternative = IPython.core.hooks.deprecated[name]
857 856 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative))
858 857
859 858 if not dp:
860 859 dp = IPython.core.hooks.CommandChainDispatcher()
861 860
862 861 try:
863 862 dp.add(f,priority)
864 863 except AttributeError:
865 864 # it was not commandchain, plain old func - replace
866 865 dp = f
867 866
868 867 setattr(self.hooks,name, dp)
869 868
870 869 #-------------------------------------------------------------------------
871 870 # Things related to events
872 871 #-------------------------------------------------------------------------
873 872
874 873 def init_events(self):
875 874 self.events = EventManager(self, available_events)
876 875
877 876 def register_post_execute(self, func):
878 877 """DEPRECATED: Use ip.events.register('post_run_cell', func)
879 878
880 879 Register a function for calling after code execution.
881 880 """
882 881 warn("ip.register_post_execute is deprecated, use "
883 882 "ip.events.register('post_run_cell', func) instead.")
884 883 self.events.register('post_run_cell', func)
885 884
886 885 #-------------------------------------------------------------------------
887 886 # Things related to the "main" module
888 887 #-------------------------------------------------------------------------
889 888
890 889 def new_main_mod(self, filename, modname):
891 890 """Return a new 'main' module object for user code execution.
892 891
893 892 ``filename`` should be the path of the script which will be run in the
894 893 module. Requests with the same filename will get the same module, with
895 894 its namespace cleared.
896 895
897 896 ``modname`` should be the module name - normally either '__main__' or
898 897 the basename of the file without the extension.
899 898
900 899 When scripts are executed via %run, we must keep a reference to their
901 900 __main__ module around so that Python doesn't
902 901 clear it, rendering references to module globals useless.
903 902
904 903 This method keeps said reference in a private dict, keyed by the
905 904 absolute path of the script. This way, for multiple executions of the
906 905 same script we only keep one copy of the namespace (the last one),
907 906 thus preventing memory leaks from old references while allowing the
908 907 objects from the last execution to be accessible.
909 908 """
910 909 filename = os.path.abspath(filename)
911 910 try:
912 911 main_mod = self._main_mod_cache[filename]
913 912 except KeyError:
914 913 main_mod = self._main_mod_cache[filename] = types.ModuleType(
915 914 py3compat.cast_bytes_py2(modname),
916 915 doc="Module created for script run in IPython")
917 916 else:
918 917 main_mod.__dict__.clear()
919 918 main_mod.__name__ = modname
920 919
921 920 main_mod.__file__ = filename
922 921 # It seems pydoc (and perhaps others) needs any module instance to
923 922 # implement a __nonzero__ method
924 923 main_mod.__nonzero__ = lambda : True
925 924
926 925 return main_mod
927 926
928 927 def clear_main_mod_cache(self):
929 928 """Clear the cache of main modules.
930 929
931 930 Mainly for use by utilities like %reset.
932 931
933 932 Examples
934 933 --------
935 934
936 935 In [15]: import IPython
937 936
938 937 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
939 938
940 939 In [17]: len(_ip._main_mod_cache) > 0
941 940 Out[17]: True
942 941
943 942 In [18]: _ip.clear_main_mod_cache()
944 943
945 944 In [19]: len(_ip._main_mod_cache) == 0
946 945 Out[19]: True
947 946 """
948 947 self._main_mod_cache.clear()
949 948
950 949 #-------------------------------------------------------------------------
951 950 # Things related to debugging
952 951 #-------------------------------------------------------------------------
953 952
954 953 def init_pdb(self):
955 954 # Set calling of pdb on exceptions
956 955 # self.call_pdb is a property
957 956 self.call_pdb = self.pdb
958 957
959 958 def _get_call_pdb(self):
960 959 return self._call_pdb
961 960
962 961 def _set_call_pdb(self,val):
963 962
964 963 if val not in (0,1,False,True):
965 964 raise ValueError('new call_pdb value must be boolean')
966 965
967 966 # store value in instance
968 967 self._call_pdb = val
969 968
970 969 # notify the actual exception handlers
971 970 self.InteractiveTB.call_pdb = val
972 971
973 972 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
974 973 'Control auto-activation of pdb at exceptions')
975 974
976 975 def debugger(self,force=False):
977 976 """Call the pydb/pdb debugger.
978 977
979 978 Keywords:
980 979
981 980 - force(False): by default, this routine checks the instance call_pdb
982 981 flag and does not actually invoke the debugger if the flag is false.
983 982 The 'force' option forces the debugger to activate even if the flag
984 983 is false.
985 984 """
986 985
987 986 if not (force or self.call_pdb):
988 987 return
989 988
990 989 if not hasattr(sys,'last_traceback'):
991 990 error('No traceback has been produced, nothing to debug.')
992 991 return
993 992
994 993 # use pydb if available
995 994 if debugger.has_pydb:
996 995 from pydb import pm
997 996 else:
998 997 # fallback to our internal debugger
999 998 pm = lambda : self.InteractiveTB.debugger(force=True)
1000 999
1001 1000 with self.readline_no_record:
1002 1001 pm()
1003 1002
1004 1003 #-------------------------------------------------------------------------
1005 1004 # Things related to IPython's various namespaces
1006 1005 #-------------------------------------------------------------------------
1007 1006 default_user_namespaces = True
1008 1007
1009 1008 def init_create_namespaces(self, user_module=None, user_ns=None):
1010 1009 # Create the namespace where the user will operate. user_ns is
1011 1010 # normally the only one used, and it is passed to the exec calls as
1012 1011 # the locals argument. But we do carry a user_global_ns namespace
1013 1012 # given as the exec 'globals' argument, This is useful in embedding
1014 1013 # situations where the ipython shell opens in a context where the
1015 1014 # distinction between locals and globals is meaningful. For
1016 1015 # non-embedded contexts, it is just the same object as the user_ns dict.
1017 1016
1018 1017 # FIXME. For some strange reason, __builtins__ is showing up at user
1019 1018 # level as a dict instead of a module. This is a manual fix, but I
1020 1019 # should really track down where the problem is coming from. Alex
1021 1020 # Schmolck reported this problem first.
1022 1021
1023 1022 # A useful post by Alex Martelli on this topic:
1024 1023 # Re: inconsistent value from __builtins__
1025 1024 # Von: Alex Martelli <aleaxit@yahoo.com>
1026 1025 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1027 1026 # Gruppen: comp.lang.python
1028 1027
1029 1028 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1030 1029 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1031 1030 # > <type 'dict'>
1032 1031 # > >>> print type(__builtins__)
1033 1032 # > <type 'module'>
1034 1033 # > Is this difference in return value intentional?
1035 1034
1036 1035 # Well, it's documented that '__builtins__' can be either a dictionary
1037 1036 # or a module, and it's been that way for a long time. Whether it's
1038 1037 # intentional (or sensible), I don't know. In any case, the idea is
1039 1038 # that if you need to access the built-in namespace directly, you
1040 1039 # should start with "import __builtin__" (note, no 's') which will
1041 1040 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1042 1041
1043 1042 # These routines return a properly built module and dict as needed by
1044 1043 # the rest of the code, and can also be used by extension writers to
1045 1044 # generate properly initialized namespaces.
1046 1045 if (user_ns is not None) or (user_module is not None):
1047 1046 self.default_user_namespaces = False
1048 1047 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1049 1048
1050 1049 # A record of hidden variables we have added to the user namespace, so
1051 1050 # we can list later only variables defined in actual interactive use.
1052 1051 self.user_ns_hidden = {}
1053 1052
1054 1053 # Now that FakeModule produces a real module, we've run into a nasty
1055 1054 # problem: after script execution (via %run), the module where the user
1056 1055 # code ran is deleted. Now that this object is a true module (needed
1057 1056 # so docetst and other tools work correctly), the Python module
1058 1057 # teardown mechanism runs over it, and sets to None every variable
1059 1058 # present in that module. Top-level references to objects from the
1060 1059 # script survive, because the user_ns is updated with them. However,
1061 1060 # calling functions defined in the script that use other things from
1062 1061 # the script will fail, because the function's closure had references
1063 1062 # to the original objects, which are now all None. So we must protect
1064 1063 # these modules from deletion by keeping a cache.
1065 1064 #
1066 1065 # To avoid keeping stale modules around (we only need the one from the
1067 1066 # last run), we use a dict keyed with the full path to the script, so
1068 1067 # only the last version of the module is held in the cache. Note,
1069 1068 # however, that we must cache the module *namespace contents* (their
1070 1069 # __dict__). Because if we try to cache the actual modules, old ones
1071 1070 # (uncached) could be destroyed while still holding references (such as
1072 1071 # those held by GUI objects that tend to be long-lived)>
1073 1072 #
1074 1073 # The %reset command will flush this cache. See the cache_main_mod()
1075 1074 # and clear_main_mod_cache() methods for details on use.
1076 1075
1077 1076 # This is the cache used for 'main' namespaces
1078 1077 self._main_mod_cache = {}
1079 1078
1080 1079 # A table holding all the namespaces IPython deals with, so that
1081 1080 # introspection facilities can search easily.
1082 1081 self.ns_table = {'user_global':self.user_module.__dict__,
1083 1082 'user_local':self.user_ns,
1084 1083 'builtin':builtin_mod.__dict__
1085 1084 }
1086 1085
1087 1086 @property
1088 1087 def user_global_ns(self):
1089 1088 return self.user_module.__dict__
1090 1089
1091 1090 def prepare_user_module(self, user_module=None, user_ns=None):
1092 1091 """Prepare the module and namespace in which user code will be run.
1093 1092
1094 1093 When IPython is started normally, both parameters are None: a new module
1095 1094 is created automatically, and its __dict__ used as the namespace.
1096 1095
1097 1096 If only user_module is provided, its __dict__ is used as the namespace.
1098 1097 If only user_ns is provided, a dummy module is created, and user_ns
1099 1098 becomes the global namespace. If both are provided (as they may be
1100 1099 when embedding), user_ns is the local namespace, and user_module
1101 1100 provides the global namespace.
1102 1101
1103 1102 Parameters
1104 1103 ----------
1105 1104 user_module : module, optional
1106 1105 The current user module in which IPython is being run. If None,
1107 1106 a clean module will be created.
1108 1107 user_ns : dict, optional
1109 1108 A namespace in which to run interactive commands.
1110 1109
1111 1110 Returns
1112 1111 -------
1113 1112 A tuple of user_module and user_ns, each properly initialised.
1114 1113 """
1115 1114 if user_module is None and user_ns is not None:
1116 1115 user_ns.setdefault("__name__", "__main__")
1117 1116 user_module = DummyMod()
1118 1117 user_module.__dict__ = user_ns
1119 1118
1120 1119 if user_module is None:
1121 1120 user_module = types.ModuleType("__main__",
1122 1121 doc="Automatically created module for IPython interactive environment")
1123 1122
1124 1123 # We must ensure that __builtin__ (without the final 's') is always
1125 1124 # available and pointing to the __builtin__ *module*. For more details:
1126 1125 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1127 1126 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1128 1127 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1129 1128
1130 1129 if user_ns is None:
1131 1130 user_ns = user_module.__dict__
1132 1131
1133 1132 return user_module, user_ns
1134 1133
1135 1134 def init_sys_modules(self):
1136 1135 # We need to insert into sys.modules something that looks like a
1137 1136 # module but which accesses the IPython namespace, for shelve and
1138 1137 # pickle to work interactively. Normally they rely on getting
1139 1138 # everything out of __main__, but for embedding purposes each IPython
1140 1139 # instance has its own private namespace, so we can't go shoving
1141 1140 # everything into __main__.
1142 1141
1143 1142 # note, however, that we should only do this for non-embedded
1144 1143 # ipythons, which really mimic the __main__.__dict__ with their own
1145 1144 # namespace. Embedded instances, on the other hand, should not do
1146 1145 # this because they need to manage the user local/global namespaces
1147 1146 # only, but they live within a 'normal' __main__ (meaning, they
1148 1147 # shouldn't overtake the execution environment of the script they're
1149 1148 # embedded in).
1150 1149
1151 1150 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1152 1151 main_name = self.user_module.__name__
1153 1152 sys.modules[main_name] = self.user_module
1154 1153
1155 1154 def init_user_ns(self):
1156 1155 """Initialize all user-visible namespaces to their minimum defaults.
1157 1156
1158 1157 Certain history lists are also initialized here, as they effectively
1159 1158 act as user namespaces.
1160 1159
1161 1160 Notes
1162 1161 -----
1163 1162 All data structures here are only filled in, they are NOT reset by this
1164 1163 method. If they were not empty before, data will simply be added to
1165 1164 therm.
1166 1165 """
1167 1166 # This function works in two parts: first we put a few things in
1168 1167 # user_ns, and we sync that contents into user_ns_hidden so that these
1169 1168 # initial variables aren't shown by %who. After the sync, we add the
1170 1169 # rest of what we *do* want the user to see with %who even on a new
1171 1170 # session (probably nothing, so theye really only see their own stuff)
1172 1171
1173 1172 # The user dict must *always* have a __builtin__ reference to the
1174 1173 # Python standard __builtin__ namespace, which must be imported.
1175 1174 # This is so that certain operations in prompt evaluation can be
1176 1175 # reliably executed with builtins. Note that we can NOT use
1177 1176 # __builtins__ (note the 's'), because that can either be a dict or a
1178 1177 # module, and can even mutate at runtime, depending on the context
1179 1178 # (Python makes no guarantees on it). In contrast, __builtin__ is
1180 1179 # always a module object, though it must be explicitly imported.
1181 1180
1182 1181 # For more details:
1183 1182 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1184 1183 ns = dict()
1185 1184
1186 1185 # make global variables for user access to the histories
1187 1186 ns['_ih'] = self.history_manager.input_hist_parsed
1188 1187 ns['_oh'] = self.history_manager.output_hist
1189 1188 ns['_dh'] = self.history_manager.dir_hist
1190 1189
1191 1190 ns['_sh'] = shadowns
1192 1191
1193 1192 # user aliases to input and output histories. These shouldn't show up
1194 1193 # in %who, as they can have very large reprs.
1195 1194 ns['In'] = self.history_manager.input_hist_parsed
1196 1195 ns['Out'] = self.history_manager.output_hist
1197 1196
1198 1197 # Store myself as the public api!!!
1199 1198 ns['get_ipython'] = self.get_ipython
1200 1199
1201 1200 ns['exit'] = self.exiter
1202 1201 ns['quit'] = self.exiter
1203 1202
1204 1203 # Sync what we've added so far to user_ns_hidden so these aren't seen
1205 1204 # by %who
1206 1205 self.user_ns_hidden.update(ns)
1207 1206
1208 1207 # Anything put into ns now would show up in %who. Think twice before
1209 1208 # putting anything here, as we really want %who to show the user their
1210 1209 # stuff, not our variables.
1211 1210
1212 1211 # Finally, update the real user's namespace
1213 1212 self.user_ns.update(ns)
1214 1213
1215 1214 @property
1216 1215 def all_ns_refs(self):
1217 1216 """Get a list of references to all the namespace dictionaries in which
1218 1217 IPython might store a user-created object.
1219 1218
1220 1219 Note that this does not include the displayhook, which also caches
1221 1220 objects from the output."""
1222 1221 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1223 1222 [m.__dict__ for m in self._main_mod_cache.values()]
1224 1223
1225 1224 def reset(self, new_session=True):
1226 1225 """Clear all internal namespaces, and attempt to release references to
1227 1226 user objects.
1228 1227
1229 1228 If new_session is True, a new history session will be opened.
1230 1229 """
1231 1230 # Clear histories
1232 1231 self.history_manager.reset(new_session)
1233 1232 # Reset counter used to index all histories
1234 1233 if new_session:
1235 1234 self.execution_count = 1
1236 1235
1237 1236 # Flush cached output items
1238 1237 if self.displayhook.do_full_cache:
1239 1238 self.displayhook.flush()
1240 1239
1241 1240 # The main execution namespaces must be cleared very carefully,
1242 1241 # skipping the deletion of the builtin-related keys, because doing so
1243 1242 # would cause errors in many object's __del__ methods.
1244 1243 if self.user_ns is not self.user_global_ns:
1245 1244 self.user_ns.clear()
1246 1245 ns = self.user_global_ns
1247 1246 drop_keys = set(ns.keys())
1248 1247 drop_keys.discard('__builtin__')
1249 1248 drop_keys.discard('__builtins__')
1250 1249 drop_keys.discard('__name__')
1251 1250 for k in drop_keys:
1252 1251 del ns[k]
1253 1252
1254 1253 self.user_ns_hidden.clear()
1255 1254
1256 1255 # Restore the user namespaces to minimal usability
1257 1256 self.init_user_ns()
1258 1257
1259 1258 # Restore the default and user aliases
1260 1259 self.alias_manager.clear_aliases()
1261 1260 self.alias_manager.init_aliases()
1262 1261
1263 1262 # Flush the private list of module references kept for script
1264 1263 # execution protection
1265 1264 self.clear_main_mod_cache()
1266 1265
1267 1266 def del_var(self, varname, by_name=False):
1268 1267 """Delete a variable from the various namespaces, so that, as
1269 1268 far as possible, we're not keeping any hidden references to it.
1270 1269
1271 1270 Parameters
1272 1271 ----------
1273 1272 varname : str
1274 1273 The name of the variable to delete.
1275 1274 by_name : bool
1276 1275 If True, delete variables with the given name in each
1277 1276 namespace. If False (default), find the variable in the user
1278 1277 namespace, and delete references to it.
1279 1278 """
1280 1279 if varname in ('__builtin__', '__builtins__'):
1281 1280 raise ValueError("Refusing to delete %s" % varname)
1282 1281
1283 1282 ns_refs = self.all_ns_refs
1284 1283
1285 1284 if by_name: # Delete by name
1286 1285 for ns in ns_refs:
1287 1286 try:
1288 1287 del ns[varname]
1289 1288 except KeyError:
1290 1289 pass
1291 1290 else: # Delete by object
1292 1291 try:
1293 1292 obj = self.user_ns[varname]
1294 1293 except KeyError:
1295 1294 raise NameError("name '%s' is not defined" % varname)
1296 1295 # Also check in output history
1297 1296 ns_refs.append(self.history_manager.output_hist)
1298 1297 for ns in ns_refs:
1299 1298 to_delete = [n for n, o in iteritems(ns) if o is obj]
1300 1299 for name in to_delete:
1301 1300 del ns[name]
1302 1301
1303 1302 # displayhook keeps extra references, but not in a dictionary
1304 1303 for name in ('_', '__', '___'):
1305 1304 if getattr(self.displayhook, name) is obj:
1306 1305 setattr(self.displayhook, name, None)
1307 1306
1308 1307 def reset_selective(self, regex=None):
1309 1308 """Clear selective variables from internal namespaces based on a
1310 1309 specified regular expression.
1311 1310
1312 1311 Parameters
1313 1312 ----------
1314 1313 regex : string or compiled pattern, optional
1315 1314 A regular expression pattern that will be used in searching
1316 1315 variable names in the users namespaces.
1317 1316 """
1318 1317 if regex is not None:
1319 1318 try:
1320 1319 m = re.compile(regex)
1321 1320 except TypeError:
1322 1321 raise TypeError('regex must be a string or compiled pattern')
1323 1322 # Search for keys in each namespace that match the given regex
1324 1323 # If a match is found, delete the key/value pair.
1325 1324 for ns in self.all_ns_refs:
1326 1325 for var in ns:
1327 1326 if m.search(var):
1328 1327 del ns[var]
1329 1328
1330 1329 def push(self, variables, interactive=True):
1331 1330 """Inject a group of variables into the IPython user namespace.
1332 1331
1333 1332 Parameters
1334 1333 ----------
1335 1334 variables : dict, str or list/tuple of str
1336 1335 The variables to inject into the user's namespace. If a dict, a
1337 1336 simple update is done. If a str, the string is assumed to have
1338 1337 variable names separated by spaces. A list/tuple of str can also
1339 1338 be used to give the variable names. If just the variable names are
1340 1339 give (list/tuple/str) then the variable values looked up in the
1341 1340 callers frame.
1342 1341 interactive : bool
1343 1342 If True (default), the variables will be listed with the ``who``
1344 1343 magic.
1345 1344 """
1346 1345 vdict = None
1347 1346
1348 1347 # We need a dict of name/value pairs to do namespace updates.
1349 1348 if isinstance(variables, dict):
1350 1349 vdict = variables
1351 1350 elif isinstance(variables, string_types+(list, tuple)):
1352 1351 if isinstance(variables, string_types):
1353 1352 vlist = variables.split()
1354 1353 else:
1355 1354 vlist = variables
1356 1355 vdict = {}
1357 1356 cf = sys._getframe(1)
1358 1357 for name in vlist:
1359 1358 try:
1360 1359 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1361 1360 except:
1362 1361 print('Could not get variable %s from %s' %
1363 1362 (name,cf.f_code.co_name))
1364 1363 else:
1365 1364 raise ValueError('variables must be a dict/str/list/tuple')
1366 1365
1367 1366 # Propagate variables to user namespace
1368 1367 self.user_ns.update(vdict)
1369 1368
1370 1369 # And configure interactive visibility
1371 1370 user_ns_hidden = self.user_ns_hidden
1372 1371 if interactive:
1373 1372 for name in vdict:
1374 1373 user_ns_hidden.pop(name, None)
1375 1374 else:
1376 1375 user_ns_hidden.update(vdict)
1377 1376
1378 1377 def drop_by_id(self, variables):
1379 1378 """Remove a dict of variables from the user namespace, if they are the
1380 1379 same as the values in the dictionary.
1381 1380
1382 1381 This is intended for use by extensions: variables that they've added can
1383 1382 be taken back out if they are unloaded, without removing any that the
1384 1383 user has overwritten.
1385 1384
1386 1385 Parameters
1387 1386 ----------
1388 1387 variables : dict
1389 1388 A dictionary mapping object names (as strings) to the objects.
1390 1389 """
1391 1390 for name, obj in iteritems(variables):
1392 1391 if name in self.user_ns and self.user_ns[name] is obj:
1393 1392 del self.user_ns[name]
1394 1393 self.user_ns_hidden.pop(name, None)
1395 1394
1396 1395 #-------------------------------------------------------------------------
1397 1396 # Things related to object introspection
1398 1397 #-------------------------------------------------------------------------
1399 1398
1400 1399 def _ofind(self, oname, namespaces=None):
1401 1400 """Find an object in the available namespaces.
1402 1401
1403 1402 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1404 1403
1405 1404 Has special code to detect magic functions.
1406 1405 """
1407 1406 oname = oname.strip()
1408 1407 #print '1- oname: <%r>' % oname # dbg
1409 1408 if not oname.startswith(ESC_MAGIC) and \
1410 1409 not oname.startswith(ESC_MAGIC2) and \
1411 1410 not py3compat.isidentifier(oname, dotted=True):
1412 1411 return dict(found=False)
1413 1412
1414 1413 alias_ns = None
1415 1414 if namespaces is None:
1416 1415 # Namespaces to search in:
1417 1416 # Put them in a list. The order is important so that we
1418 1417 # find things in the same order that Python finds them.
1419 1418 namespaces = [ ('Interactive', self.user_ns),
1420 1419 ('Interactive (global)', self.user_global_ns),
1421 1420 ('Python builtin', builtin_mod.__dict__),
1422 1421 ]
1423 1422
1424 1423 # initialize results to 'null'
1425 1424 found = False; obj = None; ospace = None; ds = None;
1426 1425 ismagic = False; isalias = False; parent = None
1427 1426
1428 1427 # We need to special-case 'print', which as of python2.6 registers as a
1429 1428 # function but should only be treated as one if print_function was
1430 1429 # loaded with a future import. In this case, just bail.
1431 1430 if (oname == 'print' and not py3compat.PY3 and not \
1432 1431 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1433 1432 return {'found':found, 'obj':obj, 'namespace':ospace,
1434 1433 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1435 1434
1436 1435 # Look for the given name by splitting it in parts. If the head is
1437 1436 # found, then we look for all the remaining parts as members, and only
1438 1437 # declare success if we can find them all.
1439 1438 oname_parts = oname.split('.')
1440 1439 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1441 1440 for nsname,ns in namespaces:
1442 1441 try:
1443 1442 obj = ns[oname_head]
1444 1443 except KeyError:
1445 1444 continue
1446 1445 else:
1447 1446 #print 'oname_rest:', oname_rest # dbg
1448 1447 for idx, part in enumerate(oname_rest):
1449 1448 try:
1450 1449 parent = obj
1451 1450 # The last part is looked up in a special way to avoid
1452 1451 # descriptor invocation as it may raise or have side
1453 1452 # effects.
1454 1453 if idx == len(oname_rest) - 1:
1455 1454 obj = self._getattr_property(obj, part)
1456 1455 else:
1457 1456 obj = getattr(obj, part)
1458 1457 except:
1459 1458 # Blanket except b/c some badly implemented objects
1460 1459 # allow __getattr__ to raise exceptions other than
1461 1460 # AttributeError, which then crashes IPython.
1462 1461 break
1463 1462 else:
1464 1463 # If we finish the for loop (no break), we got all members
1465 1464 found = True
1466 1465 ospace = nsname
1467 1466 break # namespace loop
1468 1467
1469 1468 # Try to see if it's magic
1470 1469 if not found:
1471 1470 obj = None
1472 1471 if oname.startswith(ESC_MAGIC2):
1473 1472 oname = oname.lstrip(ESC_MAGIC2)
1474 1473 obj = self.find_cell_magic(oname)
1475 1474 elif oname.startswith(ESC_MAGIC):
1476 1475 oname = oname.lstrip(ESC_MAGIC)
1477 1476 obj = self.find_line_magic(oname)
1478 1477 else:
1479 1478 # search without prefix, so run? will find %run?
1480 1479 obj = self.find_line_magic(oname)
1481 1480 if obj is None:
1482 1481 obj = self.find_cell_magic(oname)
1483 1482 if obj is not None:
1484 1483 found = True
1485 1484 ospace = 'IPython internal'
1486 1485 ismagic = True
1487 1486
1488 1487 # Last try: special-case some literals like '', [], {}, etc:
1489 1488 if not found and oname_head in ["''",'""','[]','{}','()']:
1490 1489 obj = eval(oname_head)
1491 1490 found = True
1492 1491 ospace = 'Interactive'
1493 1492
1494 1493 return {'found':found, 'obj':obj, 'namespace':ospace,
1495 1494 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1496 1495
1497 1496 @staticmethod
1498 1497 def _getattr_property(obj, attrname):
1499 1498 """Property-aware getattr to use in object finding.
1500 1499
1501 1500 If attrname represents a property, return it unevaluated (in case it has
1502 1501 side effects or raises an error.
1503 1502
1504 1503 """
1505 1504 if not isinstance(obj, type):
1506 1505 try:
1507 1506 # `getattr(type(obj), attrname)` is not guaranteed to return
1508 1507 # `obj`, but does so for property:
1509 1508 #
1510 1509 # property.__get__(self, None, cls) -> self
1511 1510 #
1512 1511 # The universal alternative is to traverse the mro manually
1513 1512 # searching for attrname in class dicts.
1514 1513 attr = getattr(type(obj), attrname)
1515 1514 except AttributeError:
1516 1515 pass
1517 1516 else:
1518 1517 # This relies on the fact that data descriptors (with both
1519 1518 # __get__ & __set__ magic methods) take precedence over
1520 1519 # instance-level attributes:
1521 1520 #
1522 1521 # class A(object):
1523 1522 # @property
1524 1523 # def foobar(self): return 123
1525 1524 # a = A()
1526 1525 # a.__dict__['foobar'] = 345
1527 1526 # a.foobar # == 123
1528 1527 #
1529 1528 # So, a property may be returned right away.
1530 1529 if isinstance(attr, property):
1531 1530 return attr
1532 1531
1533 1532 # Nothing helped, fall back.
1534 1533 return getattr(obj, attrname)
1535 1534
1536 1535 def _object_find(self, oname, namespaces=None):
1537 1536 """Find an object and return a struct with info about it."""
1538 1537 return Struct(self._ofind(oname, namespaces))
1539 1538
1540 1539 def _inspect(self, meth, oname, namespaces=None, **kw):
1541 1540 """Generic interface to the inspector system.
1542 1541
1543 1542 This function is meant to be called by pdef, pdoc & friends."""
1544 1543 info = self._object_find(oname, namespaces)
1545 1544 if info.found:
1546 1545 pmethod = getattr(self.inspector, meth)
1547 1546 formatter = format_screen if info.ismagic else None
1548 1547 if meth == 'pdoc':
1549 1548 pmethod(info.obj, oname, formatter)
1550 1549 elif meth == 'pinfo':
1551 1550 pmethod(info.obj, oname, formatter, info, **kw)
1552 1551 else:
1553 1552 pmethod(info.obj, oname)
1554 1553 else:
1555 1554 print('Object `%s` not found.' % oname)
1556 1555 return 'not found' # so callers can take other action
1557 1556
1558 1557 def object_inspect(self, oname, detail_level=0):
1559 1558 """Get object info about oname"""
1560 1559 with self.builtin_trap:
1561 1560 info = self._object_find(oname)
1562 1561 if info.found:
1563 1562 return self.inspector.info(info.obj, oname, info=info,
1564 1563 detail_level=detail_level
1565 1564 )
1566 1565 else:
1567 1566 return oinspect.object_info(name=oname, found=False)
1568 1567
1569 1568 def object_inspect_text(self, oname, detail_level=0):
1570 1569 """Get object info as formatted text"""
1571 1570 with self.builtin_trap:
1572 1571 info = self._object_find(oname)
1573 1572 if info.found:
1574 1573 return self.inspector._format_info(info.obj, oname, info=info,
1575 1574 detail_level=detail_level
1576 1575 )
1577 1576 else:
1578 1577 raise KeyError(oname)
1579 1578
1580 1579 #-------------------------------------------------------------------------
1581 1580 # Things related to history management
1582 1581 #-------------------------------------------------------------------------
1583 1582
1584 1583 def init_history(self):
1585 1584 """Sets up the command history, and starts regular autosaves."""
1586 1585 self.history_manager = HistoryManager(shell=self, parent=self)
1587 1586 self.configurables.append(self.history_manager)
1588 1587
1589 1588 #-------------------------------------------------------------------------
1590 1589 # Things related to exception handling and tracebacks (not debugging)
1591 1590 #-------------------------------------------------------------------------
1592 1591
1593 1592 def init_traceback_handlers(self, custom_exceptions):
1594 1593 # Syntax error handler.
1595 1594 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1596 1595
1597 1596 # The interactive one is initialized with an offset, meaning we always
1598 1597 # want to remove the topmost item in the traceback, which is our own
1599 1598 # internal code. Valid modes: ['Plain','Context','Verbose']
1600 1599 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1601 1600 color_scheme='NoColor',
1602 1601 tb_offset = 1,
1603 1602 check_cache=check_linecache_ipython)
1604 1603
1605 1604 # The instance will store a pointer to the system-wide exception hook,
1606 1605 # so that runtime code (such as magics) can access it. This is because
1607 1606 # during the read-eval loop, it may get temporarily overwritten.
1608 1607 self.sys_excepthook = sys.excepthook
1609 1608
1610 1609 # and add any custom exception handlers the user may have specified
1611 1610 self.set_custom_exc(*custom_exceptions)
1612 1611
1613 1612 # Set the exception mode
1614 1613 self.InteractiveTB.set_mode(mode=self.xmode)
1615 1614
1616 1615 def set_custom_exc(self, exc_tuple, handler):
1617 1616 """set_custom_exc(exc_tuple,handler)
1618 1617
1619 1618 Set a custom exception handler, which will be called if any of the
1620 1619 exceptions in exc_tuple occur in the mainloop (specifically, in the
1621 1620 run_code() method).
1622 1621
1623 1622 Parameters
1624 1623 ----------
1625 1624
1626 1625 exc_tuple : tuple of exception classes
1627 1626 A *tuple* of exception classes, for which to call the defined
1628 1627 handler. It is very important that you use a tuple, and NOT A
1629 1628 LIST here, because of the way Python's except statement works. If
1630 1629 you only want to trap a single exception, use a singleton tuple::
1631 1630
1632 1631 exc_tuple == (MyCustomException,)
1633 1632
1634 1633 handler : callable
1635 1634 handler must have the following signature::
1636 1635
1637 1636 def my_handler(self, etype, value, tb, tb_offset=None):
1638 1637 ...
1639 1638 return structured_traceback
1640 1639
1641 1640 Your handler must return a structured traceback (a list of strings),
1642 1641 or None.
1643 1642
1644 1643 This will be made into an instance method (via types.MethodType)
1645 1644 of IPython itself, and it will be called if any of the exceptions
1646 1645 listed in the exc_tuple are caught. If the handler is None, an
1647 1646 internal basic one is used, which just prints basic info.
1648 1647
1649 1648 To protect IPython from crashes, if your handler ever raises an
1650 1649 exception or returns an invalid result, it will be immediately
1651 1650 disabled.
1652 1651
1653 1652 WARNING: by putting in your own exception handler into IPython's main
1654 1653 execution loop, you run a very good chance of nasty crashes. This
1655 1654 facility should only be used if you really know what you are doing."""
1656 1655
1657 1656 assert type(exc_tuple)==type(()) , \
1658 1657 "The custom exceptions must be given AS A TUPLE."
1659 1658
1660 1659 def dummy_handler(self,etype,value,tb,tb_offset=None):
1661 1660 print('*** Simple custom exception handler ***')
1662 1661 print('Exception type :',etype)
1663 1662 print('Exception value:',value)
1664 1663 print('Traceback :',tb)
1665 1664 #print 'Source code :','\n'.join(self.buffer)
1666 1665
1667 1666 def validate_stb(stb):
1668 1667 """validate structured traceback return type
1669 1668
1670 1669 return type of CustomTB *should* be a list of strings, but allow
1671 1670 single strings or None, which are harmless.
1672 1671
1673 1672 This function will *always* return a list of strings,
1674 1673 and will raise a TypeError if stb is inappropriate.
1675 1674 """
1676 1675 msg = "CustomTB must return list of strings, not %r" % stb
1677 1676 if stb is None:
1678 1677 return []
1679 1678 elif isinstance(stb, string_types):
1680 1679 return [stb]
1681 1680 elif not isinstance(stb, list):
1682 1681 raise TypeError(msg)
1683 1682 # it's a list
1684 1683 for line in stb:
1685 1684 # check every element
1686 1685 if not isinstance(line, string_types):
1687 1686 raise TypeError(msg)
1688 1687 return stb
1689 1688
1690 1689 if handler is None:
1691 1690 wrapped = dummy_handler
1692 1691 else:
1693 1692 def wrapped(self,etype,value,tb,tb_offset=None):
1694 1693 """wrap CustomTB handler, to protect IPython from user code
1695 1694
1696 1695 This makes it harder (but not impossible) for custom exception
1697 1696 handlers to crash IPython.
1698 1697 """
1699 1698 try:
1700 1699 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1701 1700 return validate_stb(stb)
1702 1701 except:
1703 1702 # clear custom handler immediately
1704 1703 self.set_custom_exc((), None)
1705 1704 print("Custom TB Handler failed, unregistering", file=io.stderr)
1706 1705 # show the exception in handler first
1707 1706 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1708 1707 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1709 1708 print("The original exception:", file=io.stdout)
1710 1709 stb = self.InteractiveTB.structured_traceback(
1711 1710 (etype,value,tb), tb_offset=tb_offset
1712 1711 )
1713 1712 return stb
1714 1713
1715 1714 self.CustomTB = types.MethodType(wrapped,self)
1716 1715 self.custom_exceptions = exc_tuple
1717 1716
1718 1717 def excepthook(self, etype, value, tb):
1719 1718 """One more defense for GUI apps that call sys.excepthook.
1720 1719
1721 1720 GUI frameworks like wxPython trap exceptions and call
1722 1721 sys.excepthook themselves. I guess this is a feature that
1723 1722 enables them to keep running after exceptions that would
1724 1723 otherwise kill their mainloop. This is a bother for IPython
1725 1724 which excepts to catch all of the program exceptions with a try:
1726 1725 except: statement.
1727 1726
1728 1727 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1729 1728 any app directly invokes sys.excepthook, it will look to the user like
1730 1729 IPython crashed. In order to work around this, we can disable the
1731 1730 CrashHandler and replace it with this excepthook instead, which prints a
1732 1731 regular traceback using our InteractiveTB. In this fashion, apps which
1733 1732 call sys.excepthook will generate a regular-looking exception from
1734 1733 IPython, and the CrashHandler will only be triggered by real IPython
1735 1734 crashes.
1736 1735
1737 1736 This hook should be used sparingly, only in places which are not likely
1738 1737 to be true IPython errors.
1739 1738 """
1740 1739 self.showtraceback((etype, value, tb), tb_offset=0)
1741 1740
1742 1741 def _get_exc_info(self, exc_tuple=None):
1743 1742 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1744 1743
1745 1744 Ensures sys.last_type,value,traceback hold the exc_info we found,
1746 1745 from whichever source.
1747 1746
1748 1747 raises ValueError if none of these contain any information
1749 1748 """
1750 1749 if exc_tuple is None:
1751 1750 etype, value, tb = sys.exc_info()
1752 1751 else:
1753 1752 etype, value, tb = exc_tuple
1754 1753
1755 1754 if etype is None:
1756 1755 if hasattr(sys, 'last_type'):
1757 1756 etype, value, tb = sys.last_type, sys.last_value, \
1758 1757 sys.last_traceback
1759 1758
1760 1759 if etype is None:
1761 1760 raise ValueError("No exception to find")
1762 1761
1763 1762 # Now store the exception info in sys.last_type etc.
1764 1763 # WARNING: these variables are somewhat deprecated and not
1765 1764 # necessarily safe to use in a threaded environment, but tools
1766 1765 # like pdb depend on their existence, so let's set them. If we
1767 1766 # find problems in the field, we'll need to revisit their use.
1768 1767 sys.last_type = etype
1769 1768 sys.last_value = value
1770 1769 sys.last_traceback = tb
1771 1770
1772 1771 return etype, value, tb
1773 1772
1774 1773 def show_usage_error(self, exc):
1775 1774 """Show a short message for UsageErrors
1776 1775
1777 1776 These are special exceptions that shouldn't show a traceback.
1778 1777 """
1779 1778 self.write_err("UsageError: %s" % exc)
1780 1779
1781 1780 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1782 1781 exception_only=False):
1783 1782 """Display the exception that just occurred.
1784 1783
1785 1784 If nothing is known about the exception, this is the method which
1786 1785 should be used throughout the code for presenting user tracebacks,
1787 1786 rather than directly invoking the InteractiveTB object.
1788 1787
1789 1788 A specific showsyntaxerror() also exists, but this method can take
1790 1789 care of calling it if needed, so unless you are explicitly catching a
1791 1790 SyntaxError exception, don't try to analyze the stack manually and
1792 1791 simply call this method."""
1793 1792
1794 1793 try:
1795 1794 try:
1796 1795 etype, value, tb = self._get_exc_info(exc_tuple)
1797 1796 except ValueError:
1798 1797 self.write_err('No traceback available to show.\n')
1799 1798 return
1800 1799
1801 1800 if issubclass(etype, SyntaxError):
1802 1801 # Though this won't be called by syntax errors in the input
1803 1802 # line, there may be SyntaxError cases with imported code.
1804 1803 self.showsyntaxerror(filename)
1805 1804 elif etype is UsageError:
1806 1805 self.show_usage_error(value)
1807 1806 else:
1808 1807 if exception_only:
1809 1808 stb = ['An exception has occurred, use %tb to see '
1810 1809 'the full traceback.\n']
1811 1810 stb.extend(self.InteractiveTB.get_exception_only(etype,
1812 1811 value))
1813 1812 else:
1814 1813 try:
1815 1814 # Exception classes can customise their traceback - we
1816 1815 # use this in IPython.parallel for exceptions occurring
1817 1816 # in the engines. This should return a list of strings.
1818 1817 stb = value._render_traceback_()
1819 1818 except Exception:
1820 1819 stb = self.InteractiveTB.structured_traceback(etype,
1821 1820 value, tb, tb_offset=tb_offset)
1822 1821
1823 1822 self._showtraceback(etype, value, stb)
1824 1823 if self.call_pdb:
1825 1824 # drop into debugger
1826 1825 self.debugger(force=True)
1827 1826 return
1828 1827
1829 1828 # Actually show the traceback
1830 1829 self._showtraceback(etype, value, stb)
1831 1830
1832 1831 except KeyboardInterrupt:
1833 1832 self.write_err("\nKeyboardInterrupt\n")
1834 1833
1835 1834 def _showtraceback(self, etype, evalue, stb):
1836 1835 """Actually show a traceback.
1837 1836
1838 1837 Subclasses may override this method to put the traceback on a different
1839 1838 place, like a side channel.
1840 1839 """
1841 1840 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1842 1841
1843 1842 def showsyntaxerror(self, filename=None):
1844 1843 """Display the syntax error that just occurred.
1845 1844
1846 1845 This doesn't display a stack trace because there isn't one.
1847 1846
1848 1847 If a filename is given, it is stuffed in the exception instead
1849 1848 of what was there before (because Python's parser always uses
1850 1849 "<string>" when reading from a string).
1851 1850 """
1852 1851 etype, value, last_traceback = self._get_exc_info()
1853 1852
1854 1853 if filename and issubclass(etype, SyntaxError):
1855 1854 try:
1856 1855 value.filename = filename
1857 1856 except:
1858 1857 # Not the format we expect; leave it alone
1859 1858 pass
1860 1859
1861 1860 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1862 1861 self._showtraceback(etype, value, stb)
1863 1862
1864 1863 # This is overridden in TerminalInteractiveShell to show a message about
1865 1864 # the %paste magic.
1866 1865 def showindentationerror(self):
1867 1866 """Called by run_cell when there's an IndentationError in code entered
1868 1867 at the prompt.
1869 1868
1870 1869 This is overridden in TerminalInteractiveShell to show a message about
1871 1870 the %paste magic."""
1872 1871 self.showsyntaxerror()
1873 1872
1874 1873 #-------------------------------------------------------------------------
1875 1874 # Things related to readline
1876 1875 #-------------------------------------------------------------------------
1877 1876
1878 1877 def init_readline(self):
1879 1878 """Command history completion/saving/reloading."""
1880 1879
1881 1880 if self.readline_use:
1882 1881 import IPython.utils.rlineimpl as readline
1883 1882
1884 1883 self.rl_next_input = None
1885 1884 self.rl_do_indent = False
1886 1885
1887 1886 if not self.readline_use or not readline.have_readline:
1888 1887 self.has_readline = False
1889 1888 self.readline = None
1890 1889 # Set a number of methods that depend on readline to be no-op
1891 1890 self.readline_no_record = no_op_context
1892 1891 self.set_readline_completer = no_op
1893 1892 self.set_custom_completer = no_op
1894 1893 if self.readline_use:
1895 1894 warn('Readline services not available or not loaded.')
1896 1895 else:
1897 1896 self.has_readline = True
1898 1897 self.readline = readline
1899 1898 sys.modules['readline'] = readline
1900 1899
1901 1900 # Platform-specific configuration
1902 1901 if os.name == 'nt':
1903 1902 # FIXME - check with Frederick to see if we can harmonize
1904 1903 # naming conventions with pyreadline to avoid this
1905 1904 # platform-dependent check
1906 1905 self.readline_startup_hook = readline.set_pre_input_hook
1907 1906 else:
1908 1907 self.readline_startup_hook = readline.set_startup_hook
1909 1908
1910 1909 # Readline config order:
1911 1910 # - IPython config (default value)
1912 1911 # - custom inputrc
1913 1912 # - IPython config (user customized)
1914 1913
1915 1914 # load IPython config before inputrc if default
1916 1915 # skip if libedit because parse_and_bind syntax is different
1917 1916 if not self._custom_readline_config and not readline.uses_libedit:
1918 1917 for rlcommand in self.readline_parse_and_bind:
1919 1918 readline.parse_and_bind(rlcommand)
1920 1919
1921 1920 # Load user's initrc file (readline config)
1922 1921 # Or if libedit is used, load editrc.
1923 1922 inputrc_name = os.environ.get('INPUTRC')
1924 1923 if inputrc_name is None:
1925 1924 inputrc_name = '.inputrc'
1926 1925 if readline.uses_libedit:
1927 1926 inputrc_name = '.editrc'
1928 1927 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1929 1928 if os.path.isfile(inputrc_name):
1930 1929 try:
1931 1930 readline.read_init_file(inputrc_name)
1932 1931 except:
1933 1932 warn('Problems reading readline initialization file <%s>'
1934 1933 % inputrc_name)
1935 1934
1936 1935 # load IPython config after inputrc if user has customized
1937 1936 if self._custom_readline_config:
1938 1937 for rlcommand in self.readline_parse_and_bind:
1939 1938 readline.parse_and_bind(rlcommand)
1940 1939
1941 1940 # Remove some chars from the delimiters list. If we encounter
1942 1941 # unicode chars, discard them.
1943 1942 delims = readline.get_completer_delims()
1944 1943 if not py3compat.PY3:
1945 1944 delims = delims.encode("ascii", "ignore")
1946 1945 for d in self.readline_remove_delims:
1947 1946 delims = delims.replace(d, "")
1948 1947 delims = delims.replace(ESC_MAGIC, '')
1949 1948 readline.set_completer_delims(delims)
1950 1949 # Store these so we can restore them if something like rpy2 modifies
1951 1950 # them.
1952 1951 self.readline_delims = delims
1953 1952 # otherwise we end up with a monster history after a while:
1954 1953 readline.set_history_length(self.history_length)
1955 1954
1956 1955 self.refill_readline_hist()
1957 1956 self.readline_no_record = ReadlineNoRecord(self)
1958 1957
1959 1958 # Configure auto-indent for all platforms
1960 1959 self.set_autoindent(self.autoindent)
1961 1960
1962 1961 def refill_readline_hist(self):
1963 1962 # Load the last 1000 lines from history
1964 1963 self.readline.clear_history()
1965 1964 stdin_encoding = sys.stdin.encoding or "utf-8"
1966 1965 last_cell = u""
1967 1966 for _, _, cell in self.history_manager.get_tail(1000,
1968 1967 include_latest=True):
1969 1968 # Ignore blank lines and consecutive duplicates
1970 1969 cell = cell.rstrip()
1971 1970 if cell and (cell != last_cell):
1972 1971 try:
1973 1972 if self.multiline_history:
1974 1973 self.readline.add_history(py3compat.unicode_to_str(cell,
1975 1974 stdin_encoding))
1976 1975 else:
1977 1976 for line in cell.splitlines():
1978 1977 self.readline.add_history(py3compat.unicode_to_str(line,
1979 1978 stdin_encoding))
1980 1979 last_cell = cell
1981 1980
1982 1981 except TypeError:
1983 1982 # The history DB can get corrupted so it returns strings
1984 1983 # containing null bytes, which readline objects to.
1985 1984 continue
1986 1985
1987 1986 @skip_doctest
1988 1987 def set_next_input(self, s):
1989 1988 """ Sets the 'default' input string for the next command line.
1990 1989
1991 1990 Requires readline.
1992 1991
1993 1992 Example::
1994 1993
1995 1994 In [1]: _ip.set_next_input("Hello Word")
1996 1995 In [2]: Hello Word_ # cursor is here
1997 1996 """
1998 1997 self.rl_next_input = py3compat.cast_bytes_py2(s)
1999 1998
2000 1999 # Maybe move this to the terminal subclass?
2001 2000 def pre_readline(self):
2002 2001 """readline hook to be used at the start of each line.
2003 2002
2004 2003 Currently it handles auto-indent only."""
2005 2004
2006 2005 if self.rl_do_indent:
2007 2006 self.readline.insert_text(self._indent_current_str())
2008 2007 if self.rl_next_input is not None:
2009 2008 self.readline.insert_text(self.rl_next_input)
2010 2009 self.rl_next_input = None
2011 2010
2012 2011 def _indent_current_str(self):
2013 2012 """return the current level of indentation as a string"""
2014 2013 return self.input_splitter.indent_spaces * ' '
2015 2014
2016 2015 #-------------------------------------------------------------------------
2017 2016 # Things related to text completion
2018 2017 #-------------------------------------------------------------------------
2019 2018
2020 2019 def init_completer(self):
2021 2020 """Initialize the completion machinery.
2022 2021
2023 2022 This creates completion machinery that can be used by client code,
2024 2023 either interactively in-process (typically triggered by the readline
2025 2024 library), programatically (such as in test suites) or out-of-prcess
2026 2025 (typically over the network by remote frontends).
2027 2026 """
2028 2027 from IPython.core.completer import IPCompleter
2029 2028 from IPython.core.completerlib import (module_completer,
2030 2029 magic_run_completer, cd_completer, reset_completer)
2031 2030
2032 2031 self.Completer = IPCompleter(shell=self,
2033 2032 namespace=self.user_ns,
2034 2033 global_namespace=self.user_global_ns,
2035 2034 use_readline=self.has_readline,
2036 2035 parent=self,
2037 2036 )
2038 2037 self.configurables.append(self.Completer)
2039 2038
2040 2039 # Add custom completers to the basic ones built into IPCompleter
2041 2040 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2042 2041 self.strdispatchers['complete_command'] = sdisp
2043 2042 self.Completer.custom_completers = sdisp
2044 2043
2045 2044 self.set_hook('complete_command', module_completer, str_key = 'import')
2046 2045 self.set_hook('complete_command', module_completer, str_key = 'from')
2047 2046 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2048 2047 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2049 2048 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2050 2049
2051 2050 # Only configure readline if we truly are using readline. IPython can
2052 2051 # do tab-completion over the network, in GUIs, etc, where readline
2053 2052 # itself may be absent
2054 2053 if self.has_readline:
2055 2054 self.set_readline_completer()
2056 2055
2057 2056 def complete(self, text, line=None, cursor_pos=None):
2058 2057 """Return the completed text and a list of completions.
2059 2058
2060 2059 Parameters
2061 2060 ----------
2062 2061
2063 2062 text : string
2064 2063 A string of text to be completed on. It can be given as empty and
2065 2064 instead a line/position pair are given. In this case, the
2066 2065 completer itself will split the line like readline does.
2067 2066
2068 2067 line : string, optional
2069 2068 The complete line that text is part of.
2070 2069
2071 2070 cursor_pos : int, optional
2072 2071 The position of the cursor on the input line.
2073 2072
2074 2073 Returns
2075 2074 -------
2076 2075 text : string
2077 2076 The actual text that was completed.
2078 2077
2079 2078 matches : list
2080 2079 A sorted list with all possible completions.
2081 2080
2082 2081 The optional arguments allow the completion to take more context into
2083 2082 account, and are part of the low-level completion API.
2084 2083
2085 2084 This is a wrapper around the completion mechanism, similar to what
2086 2085 readline does at the command line when the TAB key is hit. By
2087 2086 exposing it as a method, it can be used by other non-readline
2088 2087 environments (such as GUIs) for text completion.
2089 2088
2090 2089 Simple usage example:
2091 2090
2092 2091 In [1]: x = 'hello'
2093 2092
2094 2093 In [2]: _ip.complete('x.l')
2095 2094 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2096 2095 """
2097 2096
2098 2097 # Inject names into __builtin__ so we can complete on the added names.
2099 2098 with self.builtin_trap:
2100 2099 return self.Completer.complete(text, line, cursor_pos)
2101 2100
2102 2101 def set_custom_completer(self, completer, pos=0):
2103 2102 """Adds a new custom completer function.
2104 2103
2105 2104 The position argument (defaults to 0) is the index in the completers
2106 2105 list where you want the completer to be inserted."""
2107 2106
2108 2107 newcomp = types.MethodType(completer,self.Completer)
2109 2108 self.Completer.matchers.insert(pos,newcomp)
2110 2109
2111 2110 def set_readline_completer(self):
2112 2111 """Reset readline's completer to be our own."""
2113 2112 self.readline.set_completer(self.Completer.rlcomplete)
2114 2113
2115 2114 def set_completer_frame(self, frame=None):
2116 2115 """Set the frame of the completer."""
2117 2116 if frame:
2118 2117 self.Completer.namespace = frame.f_locals
2119 2118 self.Completer.global_namespace = frame.f_globals
2120 2119 else:
2121 2120 self.Completer.namespace = self.user_ns
2122 2121 self.Completer.global_namespace = self.user_global_ns
2123 2122
2124 2123 #-------------------------------------------------------------------------
2125 2124 # Things related to magics
2126 2125 #-------------------------------------------------------------------------
2127 2126
2128 2127 def init_magics(self):
2129 2128 from IPython.core import magics as m
2130 2129 self.magics_manager = magic.MagicsManager(shell=self,
2131 2130 parent=self,
2132 2131 user_magics=m.UserMagics(self))
2133 2132 self.configurables.append(self.magics_manager)
2134 2133
2135 2134 # Expose as public API from the magics manager
2136 2135 self.register_magics = self.magics_manager.register
2137 2136 self.define_magic = self.magics_manager.define_magic
2138 2137
2139 2138 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2140 2139 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2141 2140 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2142 2141 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2143 2142 )
2144 2143
2145 2144 # Register Magic Aliases
2146 2145 mman = self.magics_manager
2147 2146 # FIXME: magic aliases should be defined by the Magics classes
2148 2147 # or in MagicsManager, not here
2149 2148 mman.register_alias('ed', 'edit')
2150 2149 mman.register_alias('hist', 'history')
2151 2150 mman.register_alias('rep', 'recall')
2152 2151 mman.register_alias('SVG', 'svg', 'cell')
2153 2152 mman.register_alias('HTML', 'html', 'cell')
2154 2153 mman.register_alias('file', 'writefile', 'cell')
2155 2154
2156 2155 # FIXME: Move the color initialization to the DisplayHook, which
2157 2156 # should be split into a prompt manager and displayhook. We probably
2158 2157 # even need a centralize colors management object.
2159 2158 self.magic('colors %s' % self.colors)
2160 2159
2161 2160 # Defined here so that it's included in the documentation
2162 2161 @functools.wraps(magic.MagicsManager.register_function)
2163 2162 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2164 2163 self.magics_manager.register_function(func,
2165 2164 magic_kind=magic_kind, magic_name=magic_name)
2166 2165
2167 2166 def run_line_magic(self, magic_name, line):
2168 2167 """Execute the given line magic.
2169 2168
2170 2169 Parameters
2171 2170 ----------
2172 2171 magic_name : str
2173 2172 Name of the desired magic function, without '%' prefix.
2174 2173
2175 2174 line : str
2176 2175 The rest of the input line as a single string.
2177 2176 """
2178 2177 fn = self.find_line_magic(magic_name)
2179 2178 if fn is None:
2180 2179 cm = self.find_cell_magic(magic_name)
2181 2180 etpl = "Line magic function `%%%s` not found%s."
2182 2181 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2183 2182 'did you mean that instead?)' % magic_name )
2184 2183 error(etpl % (magic_name, extra))
2185 2184 else:
2186 2185 # Note: this is the distance in the stack to the user's frame.
2187 2186 # This will need to be updated if the internal calling logic gets
2188 2187 # refactored, or else we'll be expanding the wrong variables.
2189 2188 stack_depth = 2
2190 2189 magic_arg_s = self.var_expand(line, stack_depth)
2191 2190 # Put magic args in a list so we can call with f(*a) syntax
2192 2191 args = [magic_arg_s]
2193 2192 kwargs = {}
2194 2193 # Grab local namespace if we need it:
2195 2194 if getattr(fn, "needs_local_scope", False):
2196 2195 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2197 2196 with self.builtin_trap:
2198 2197 result = fn(*args,**kwargs)
2199 2198 return result
2200 2199
2201 2200 def run_cell_magic(self, magic_name, line, cell):
2202 2201 """Execute the given cell magic.
2203 2202
2204 2203 Parameters
2205 2204 ----------
2206 2205 magic_name : str
2207 2206 Name of the desired magic function, without '%' prefix.
2208 2207
2209 2208 line : str
2210 2209 The rest of the first input line as a single string.
2211 2210
2212 2211 cell : str
2213 2212 The body of the cell as a (possibly multiline) string.
2214 2213 """
2215 2214 fn = self.find_cell_magic(magic_name)
2216 2215 if fn is None:
2217 2216 lm = self.find_line_magic(magic_name)
2218 2217 etpl = "Cell magic `%%{0}` not found{1}."
2219 2218 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2220 2219 'did you mean that instead?)'.format(magic_name))
2221 2220 error(etpl.format(magic_name, extra))
2222 2221 elif cell == '':
2223 2222 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2224 2223 if self.find_line_magic(magic_name) is not None:
2225 2224 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2226 2225 raise UsageError(message)
2227 2226 else:
2228 2227 # Note: this is the distance in the stack to the user's frame.
2229 2228 # This will need to be updated if the internal calling logic gets
2230 2229 # refactored, or else we'll be expanding the wrong variables.
2231 2230 stack_depth = 2
2232 2231 magic_arg_s = self.var_expand(line, stack_depth)
2233 2232 with self.builtin_trap:
2234 2233 result = fn(magic_arg_s, cell)
2235 2234 return result
2236 2235
2237 2236 def find_line_magic(self, magic_name):
2238 2237 """Find and return a line magic by name.
2239 2238
2240 2239 Returns None if the magic isn't found."""
2241 2240 return self.magics_manager.magics['line'].get(magic_name)
2242 2241
2243 2242 def find_cell_magic(self, magic_name):
2244 2243 """Find and return a cell magic by name.
2245 2244
2246 2245 Returns None if the magic isn't found."""
2247 2246 return self.magics_manager.magics['cell'].get(magic_name)
2248 2247
2249 2248 def find_magic(self, magic_name, magic_kind='line'):
2250 2249 """Find and return a magic of the given type by name.
2251 2250
2252 2251 Returns None if the magic isn't found."""
2253 2252 return self.magics_manager.magics[magic_kind].get(magic_name)
2254 2253
2255 2254 def magic(self, arg_s):
2256 2255 """DEPRECATED. Use run_line_magic() instead.
2257 2256
2258 2257 Call a magic function by name.
2259 2258
2260 2259 Input: a string containing the name of the magic function to call and
2261 2260 any additional arguments to be passed to the magic.
2262 2261
2263 2262 magic('name -opt foo bar') is equivalent to typing at the ipython
2264 2263 prompt:
2265 2264
2266 2265 In[1]: %name -opt foo bar
2267 2266
2268 2267 To call a magic without arguments, simply use magic('name').
2269 2268
2270 2269 This provides a proper Python function to call IPython's magics in any
2271 2270 valid Python code you can type at the interpreter, including loops and
2272 2271 compound statements.
2273 2272 """
2274 2273 # TODO: should we issue a loud deprecation warning here?
2275 2274 magic_name, _, magic_arg_s = arg_s.partition(' ')
2276 2275 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2277 2276 return self.run_line_magic(magic_name, magic_arg_s)
2278 2277
2279 2278 #-------------------------------------------------------------------------
2280 2279 # Things related to macros
2281 2280 #-------------------------------------------------------------------------
2282 2281
2283 2282 def define_macro(self, name, themacro):
2284 2283 """Define a new macro
2285 2284
2286 2285 Parameters
2287 2286 ----------
2288 2287 name : str
2289 2288 The name of the macro.
2290 2289 themacro : str or Macro
2291 2290 The action to do upon invoking the macro. If a string, a new
2292 2291 Macro object is created by passing the string to it.
2293 2292 """
2294 2293
2295 2294 from IPython.core import macro
2296 2295
2297 2296 if isinstance(themacro, string_types):
2298 2297 themacro = macro.Macro(themacro)
2299 2298 if not isinstance(themacro, macro.Macro):
2300 2299 raise ValueError('A macro must be a string or a Macro instance.')
2301 2300 self.user_ns[name] = themacro
2302 2301
2303 2302 #-------------------------------------------------------------------------
2304 2303 # Things related to the running of system commands
2305 2304 #-------------------------------------------------------------------------
2306 2305
2307 2306 def system_piped(self, cmd):
2308 2307 """Call the given cmd in a subprocess, piping stdout/err
2309 2308
2310 2309 Parameters
2311 2310 ----------
2312 2311 cmd : str
2313 2312 Command to execute (can not end in '&', as background processes are
2314 2313 not supported. Should not be a command that expects input
2315 2314 other than simple text.
2316 2315 """
2317 2316 if cmd.rstrip().endswith('&'):
2318 2317 # this is *far* from a rigorous test
2319 2318 # We do not support backgrounding processes because we either use
2320 2319 # pexpect or pipes to read from. Users can always just call
2321 2320 # os.system() or use ip.system=ip.system_raw
2322 2321 # if they really want a background process.
2323 2322 raise OSError("Background processes not supported.")
2324 2323
2325 2324 # we explicitly do NOT return the subprocess status code, because
2326 2325 # a non-None value would trigger :func:`sys.displayhook` calls.
2327 2326 # Instead, we store the exit_code in user_ns.
2328 2327 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2329 2328
2330 2329 def system_raw(self, cmd):
2331 2330 """Call the given cmd in a subprocess using os.system on Windows or
2332 2331 subprocess.call using the system shell on other platforms.
2333 2332
2334 2333 Parameters
2335 2334 ----------
2336 2335 cmd : str
2337 2336 Command to execute.
2338 2337 """
2339 2338 cmd = self.var_expand(cmd, depth=1)
2340 2339 # protect os.system from UNC paths on Windows, which it can't handle:
2341 2340 if sys.platform == 'win32':
2342 2341 from IPython.utils._process_win32 import AvoidUNCPath
2343 2342 with AvoidUNCPath() as path:
2344 2343 if path is not None:
2345 2344 cmd = '"pushd %s &&"%s' % (path, cmd)
2346 2345 cmd = py3compat.unicode_to_str(cmd)
2347 2346 ec = os.system(cmd)
2348 2347 else:
2349 2348 cmd = py3compat.unicode_to_str(cmd)
2350 2349 # Call the cmd using the OS shell, instead of the default /bin/sh, if set.
2351 2350 ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None))
2352 2351 # exit code is positive for program failure, or negative for
2353 2352 # terminating signal number.
2354 2353
2355 2354 # Interpret ec > 128 as signal
2356 2355 # Some shells (csh, fish) don't follow sh/bash conventions for exit codes
2357 2356 if ec > 128:
2358 2357 ec = -(ec - 128)
2359 2358
2360 2359 # We explicitly do NOT return the subprocess status code, because
2361 2360 # a non-None value would trigger :func:`sys.displayhook` calls.
2362 2361 # Instead, we store the exit_code in user_ns.
2363 2362 self.user_ns['_exit_code'] = ec
2364 2363
2365 2364 # use piped system by default, because it is better behaved
2366 2365 system = system_piped
2367 2366
2368 2367 def getoutput(self, cmd, split=True, depth=0):
2369 2368 """Get output (possibly including stderr) from a subprocess.
2370 2369
2371 2370 Parameters
2372 2371 ----------
2373 2372 cmd : str
2374 2373 Command to execute (can not end in '&', as background processes are
2375 2374 not supported.
2376 2375 split : bool, optional
2377 2376 If True, split the output into an IPython SList. Otherwise, an
2378 2377 IPython LSString is returned. These are objects similar to normal
2379 2378 lists and strings, with a few convenience attributes for easier
2380 2379 manipulation of line-based output. You can use '?' on them for
2381 2380 details.
2382 2381 depth : int, optional
2383 2382 How many frames above the caller are the local variables which should
2384 2383 be expanded in the command string? The default (0) assumes that the
2385 2384 expansion variables are in the stack frame calling this function.
2386 2385 """
2387 2386 if cmd.rstrip().endswith('&'):
2388 2387 # this is *far* from a rigorous test
2389 2388 raise OSError("Background processes not supported.")
2390 2389 out = getoutput(self.var_expand(cmd, depth=depth+1))
2391 2390 if split:
2392 2391 out = SList(out.splitlines())
2393 2392 else:
2394 2393 out = LSString(out)
2395 2394 return out
2396 2395
2397 2396 #-------------------------------------------------------------------------
2398 2397 # Things related to aliases
2399 2398 #-------------------------------------------------------------------------
2400 2399
2401 2400 def init_alias(self):
2402 2401 self.alias_manager = AliasManager(shell=self, parent=self)
2403 2402 self.configurables.append(self.alias_manager)
2404 2403
2405 2404 #-------------------------------------------------------------------------
2406 2405 # Things related to extensions
2407 2406 #-------------------------------------------------------------------------
2408 2407
2409 2408 def init_extension_manager(self):
2410 2409 self.extension_manager = ExtensionManager(shell=self, parent=self)
2411 2410 self.configurables.append(self.extension_manager)
2412 2411
2413 2412 #-------------------------------------------------------------------------
2414 2413 # Things related to payloads
2415 2414 #-------------------------------------------------------------------------
2416 2415
2417 2416 def init_payload(self):
2418 2417 self.payload_manager = PayloadManager(parent=self)
2419 2418 self.configurables.append(self.payload_manager)
2420 2419
2421 2420 #-------------------------------------------------------------------------
2422 # Things related to widgets
2423 #-------------------------------------------------------------------------
2424
2425 def init_comms(self):
2426 # not implemented in the base class
2427 pass
2428
2429 #-------------------------------------------------------------------------
2430 2421 # Things related to the prefilter
2431 2422 #-------------------------------------------------------------------------
2432 2423
2433 2424 def init_prefilter(self):
2434 2425 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2435 2426 self.configurables.append(self.prefilter_manager)
2436 2427 # Ultimately this will be refactored in the new interpreter code, but
2437 2428 # for now, we should expose the main prefilter method (there's legacy
2438 2429 # code out there that may rely on this).
2439 2430 self.prefilter = self.prefilter_manager.prefilter_lines
2440 2431
2441 2432 def auto_rewrite_input(self, cmd):
2442 2433 """Print to the screen the rewritten form of the user's command.
2443 2434
2444 2435 This shows visual feedback by rewriting input lines that cause
2445 2436 automatic calling to kick in, like::
2446 2437
2447 2438 /f x
2448 2439
2449 2440 into::
2450 2441
2451 2442 ------> f(x)
2452 2443
2453 2444 after the user's input prompt. This helps the user understand that the
2454 2445 input line was transformed automatically by IPython.
2455 2446 """
2456 2447 if not self.show_rewritten_input:
2457 2448 return
2458 2449
2459 2450 rw = self.prompt_manager.render('rewrite') + cmd
2460 2451
2461 2452 try:
2462 2453 # plain ascii works better w/ pyreadline, on some machines, so
2463 2454 # we use it and only print uncolored rewrite if we have unicode
2464 2455 rw = str(rw)
2465 2456 print(rw, file=io.stdout)
2466 2457 except UnicodeEncodeError:
2467 2458 print("------> " + cmd)
2468 2459
2469 2460 #-------------------------------------------------------------------------
2470 2461 # Things related to extracting values/expressions from kernel and user_ns
2471 2462 #-------------------------------------------------------------------------
2472 2463
2473 2464 def _user_obj_error(self):
2474 2465 """return simple exception dict
2475 2466
2476 2467 for use in user_expressions
2477 2468 """
2478 2469
2479 2470 etype, evalue, tb = self._get_exc_info()
2480 2471 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2481 2472
2482 2473 exc_info = {
2483 2474 u'status' : 'error',
2484 2475 u'traceback' : stb,
2485 2476 u'ename' : unicode_type(etype.__name__),
2486 2477 u'evalue' : py3compat.safe_unicode(evalue),
2487 2478 }
2488 2479
2489 2480 return exc_info
2490 2481
2491 2482 def _format_user_obj(self, obj):
2492 2483 """format a user object to display dict
2493 2484
2494 2485 for use in user_expressions
2495 2486 """
2496 2487
2497 2488 data, md = self.display_formatter.format(obj)
2498 2489 value = {
2499 2490 'status' : 'ok',
2500 2491 'data' : data,
2501 2492 'metadata' : md,
2502 2493 }
2503 2494 return value
2504 2495
2505 2496 def user_expressions(self, expressions):
2506 2497 """Evaluate a dict of expressions in the user's namespace.
2507 2498
2508 2499 Parameters
2509 2500 ----------
2510 2501 expressions : dict
2511 2502 A dict with string keys and string values. The expression values
2512 2503 should be valid Python expressions, each of which will be evaluated
2513 2504 in the user namespace.
2514 2505
2515 2506 Returns
2516 2507 -------
2517 2508 A dict, keyed like the input expressions dict, with the rich mime-typed
2518 2509 display_data of each value.
2519 2510 """
2520 2511 out = {}
2521 2512 user_ns = self.user_ns
2522 2513 global_ns = self.user_global_ns
2523 2514
2524 2515 for key, expr in iteritems(expressions):
2525 2516 try:
2526 2517 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2527 2518 except:
2528 2519 value = self._user_obj_error()
2529 2520 out[key] = value
2530 2521 return out
2531 2522
2532 2523 #-------------------------------------------------------------------------
2533 2524 # Things related to the running of code
2534 2525 #-------------------------------------------------------------------------
2535 2526
2536 2527 def ex(self, cmd):
2537 2528 """Execute a normal python statement in user namespace."""
2538 2529 with self.builtin_trap:
2539 2530 exec(cmd, self.user_global_ns, self.user_ns)
2540 2531
2541 2532 def ev(self, expr):
2542 2533 """Evaluate python expression expr in user namespace.
2543 2534
2544 2535 Returns the result of evaluation
2545 2536 """
2546 2537 with self.builtin_trap:
2547 2538 return eval(expr, self.user_global_ns, self.user_ns)
2548 2539
2549 2540 def safe_execfile(self, fname, *where, **kw):
2550 2541 """A safe version of the builtin execfile().
2551 2542
2552 2543 This version will never throw an exception, but instead print
2553 2544 helpful error messages to the screen. This only works on pure
2554 2545 Python files with the .py extension.
2555 2546
2556 2547 Parameters
2557 2548 ----------
2558 2549 fname : string
2559 2550 The name of the file to be executed.
2560 2551 where : tuple
2561 2552 One or two namespaces, passed to execfile() as (globals,locals).
2562 2553 If only one is given, it is passed as both.
2563 2554 exit_ignore : bool (False)
2564 2555 If True, then silence SystemExit for non-zero status (it is always
2565 2556 silenced for zero status, as it is so common).
2566 2557 raise_exceptions : bool (False)
2567 2558 If True raise exceptions everywhere. Meant for testing.
2568 2559
2569 2560 """
2570 2561 kw.setdefault('exit_ignore', False)
2571 2562 kw.setdefault('raise_exceptions', False)
2572 2563
2573 2564 fname = os.path.abspath(os.path.expanduser(fname))
2574 2565
2575 2566 # Make sure we can open the file
2576 2567 try:
2577 2568 with open(fname) as thefile:
2578 2569 pass
2579 2570 except:
2580 2571 warn('Could not open file <%s> for safe execution.' % fname)
2581 2572 return
2582 2573
2583 2574 # Find things also in current directory. This is needed to mimic the
2584 2575 # behavior of running a script from the system command line, where
2585 2576 # Python inserts the script's directory into sys.path
2586 2577 dname = os.path.dirname(fname)
2587 2578
2588 2579 with prepended_to_syspath(dname):
2589 2580 try:
2590 2581 py3compat.execfile(fname,*where)
2591 2582 except SystemExit as status:
2592 2583 # If the call was made with 0 or None exit status (sys.exit(0)
2593 2584 # or sys.exit() ), don't bother showing a traceback, as both of
2594 2585 # these are considered normal by the OS:
2595 2586 # > python -c'import sys;sys.exit(0)'; echo $?
2596 2587 # 0
2597 2588 # > python -c'import sys;sys.exit()'; echo $?
2598 2589 # 0
2599 2590 # For other exit status, we show the exception unless
2600 2591 # explicitly silenced, but only in short form.
2601 2592 if kw['raise_exceptions']:
2602 2593 raise
2603 2594 if status.code and not kw['exit_ignore']:
2604 2595 self.showtraceback(exception_only=True)
2605 2596 except:
2606 2597 if kw['raise_exceptions']:
2607 2598 raise
2608 2599 # tb offset is 2 because we wrap execfile
2609 2600 self.showtraceback(tb_offset=2)
2610 2601
2611 2602 def safe_execfile_ipy(self, fname):
2612 2603 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2613 2604
2614 2605 Parameters
2615 2606 ----------
2616 2607 fname : str
2617 2608 The name of the file to execute. The filename must have a
2618 2609 .ipy or .ipynb extension.
2619 2610 """
2620 2611 fname = os.path.abspath(os.path.expanduser(fname))
2621 2612
2622 2613 # Make sure we can open the file
2623 2614 try:
2624 2615 with open(fname) as thefile:
2625 2616 pass
2626 2617 except:
2627 2618 warn('Could not open file <%s> for safe execution.' % fname)
2628 2619 return
2629 2620
2630 2621 # Find things also in current directory. This is needed to mimic the
2631 2622 # behavior of running a script from the system command line, where
2632 2623 # Python inserts the script's directory into sys.path
2633 2624 dname = os.path.dirname(fname)
2634 2625
2635 2626 def get_cells():
2636 2627 """generator for sequence of code blocks to run"""
2637 2628 if fname.endswith('.ipynb'):
2638 2629 from IPython.nbformat import current
2639 2630 with open(fname) as f:
2640 2631 nb = current.read(f, 'json')
2641 2632 if not nb.worksheets:
2642 2633 return
2643 2634 for cell in nb.worksheets[0].cells:
2644 2635 if cell.cell_type == 'code':
2645 2636 yield cell.input
2646 2637 else:
2647 2638 with open(fname) as f:
2648 2639 yield f.read()
2649 2640
2650 2641 with prepended_to_syspath(dname):
2651 2642 try:
2652 2643 for cell in get_cells():
2653 2644 # self.run_cell currently captures all exceptions
2654 2645 # raised in user code. It would be nice if there were
2655 2646 # versions of run_cell that did raise, so
2656 2647 # we could catch the errors.
2657 2648 self.run_cell(cell, silent=True, shell_futures=False)
2658 2649 except:
2659 2650 self.showtraceback()
2660 2651 warn('Unknown failure executing file: <%s>' % fname)
2661 2652
2662 2653 def safe_run_module(self, mod_name, where):
2663 2654 """A safe version of runpy.run_module().
2664 2655
2665 2656 This version will never throw an exception, but instead print
2666 2657 helpful error messages to the screen.
2667 2658
2668 2659 `SystemExit` exceptions with status code 0 or None are ignored.
2669 2660
2670 2661 Parameters
2671 2662 ----------
2672 2663 mod_name : string
2673 2664 The name of the module to be executed.
2674 2665 where : dict
2675 2666 The globals namespace.
2676 2667 """
2677 2668 try:
2678 2669 try:
2679 2670 where.update(
2680 2671 runpy.run_module(str(mod_name), run_name="__main__",
2681 2672 alter_sys=True)
2682 2673 )
2683 2674 except SystemExit as status:
2684 2675 if status.code:
2685 2676 raise
2686 2677 except:
2687 2678 self.showtraceback()
2688 2679 warn('Unknown failure executing module: <%s>' % mod_name)
2689 2680
2690 2681 def _run_cached_cell_magic(self, magic_name, line):
2691 2682 """Special method to call a cell magic with the data stored in self.
2692 2683 """
2693 2684 cell = self._current_cell_magic_body
2694 2685 self._current_cell_magic_body = None
2695 2686 return self.run_cell_magic(magic_name, line, cell)
2696 2687
2697 2688 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2698 2689 """Run a complete IPython cell.
2699 2690
2700 2691 Parameters
2701 2692 ----------
2702 2693 raw_cell : str
2703 2694 The code (including IPython code such as %magic functions) to run.
2704 2695 store_history : bool
2705 2696 If True, the raw and translated cell will be stored in IPython's
2706 2697 history. For user code calling back into IPython's machinery, this
2707 2698 should be set to False.
2708 2699 silent : bool
2709 2700 If True, avoid side-effects, such as implicit displayhooks and
2710 2701 and logging. silent=True forces store_history=False.
2711 2702 shell_futures : bool
2712 2703 If True, the code will share future statements with the interactive
2713 2704 shell. It will both be affected by previous __future__ imports, and
2714 2705 any __future__ imports in the code will affect the shell. If False,
2715 2706 __future__ imports are not shared in either direction.
2716 2707 """
2717 2708 if (not raw_cell) or raw_cell.isspace():
2718 2709 return
2719 2710
2720 2711 if silent:
2721 2712 store_history = False
2722 2713
2723 2714 self.events.trigger('pre_execute')
2724 2715 if not silent:
2725 2716 self.events.trigger('pre_run_cell')
2726 2717
2727 2718 # If any of our input transformation (input_transformer_manager or
2728 2719 # prefilter_manager) raises an exception, we store it in this variable
2729 2720 # so that we can display the error after logging the input and storing
2730 2721 # it in the history.
2731 2722 preprocessing_exc_tuple = None
2732 2723 try:
2733 2724 # Static input transformations
2734 2725 cell = self.input_transformer_manager.transform_cell(raw_cell)
2735 2726 except SyntaxError:
2736 2727 preprocessing_exc_tuple = sys.exc_info()
2737 2728 cell = raw_cell # cell has to exist so it can be stored/logged
2738 2729 else:
2739 2730 if len(cell.splitlines()) == 1:
2740 2731 # Dynamic transformations - only applied for single line commands
2741 2732 with self.builtin_trap:
2742 2733 try:
2743 2734 # use prefilter_lines to handle trailing newlines
2744 2735 # restore trailing newline for ast.parse
2745 2736 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2746 2737 except Exception:
2747 2738 # don't allow prefilter errors to crash IPython
2748 2739 preprocessing_exc_tuple = sys.exc_info()
2749 2740
2750 2741 # Store raw and processed history
2751 2742 if store_history:
2752 2743 self.history_manager.store_inputs(self.execution_count,
2753 2744 cell, raw_cell)
2754 2745 if not silent:
2755 2746 self.logger.log(cell, raw_cell)
2756 2747
2757 2748 # Display the exception if input processing failed.
2758 2749 if preprocessing_exc_tuple is not None:
2759 2750 self.showtraceback(preprocessing_exc_tuple)
2760 2751 if store_history:
2761 2752 self.execution_count += 1
2762 2753 return
2763 2754
2764 2755 # Our own compiler remembers the __future__ environment. If we want to
2765 2756 # run code with a separate __future__ environment, use the default
2766 2757 # compiler
2767 2758 compiler = self.compile if shell_futures else CachingCompiler()
2768 2759
2769 2760 with self.builtin_trap:
2770 2761 cell_name = self.compile.cache(cell, self.execution_count)
2771 2762
2772 2763 with self.display_trap:
2773 2764 # Compile to bytecode
2774 2765 try:
2775 2766 code_ast = compiler.ast_parse(cell, filename=cell_name)
2776 2767 except IndentationError:
2777 2768 self.showindentationerror()
2778 2769 if store_history:
2779 2770 self.execution_count += 1
2780 2771 return None
2781 2772 except (OverflowError, SyntaxError, ValueError, TypeError,
2782 2773 MemoryError):
2783 2774 self.showsyntaxerror()
2784 2775 if store_history:
2785 2776 self.execution_count += 1
2786 2777 return None
2787 2778
2788 2779 # Apply AST transformations
2789 2780 try:
2790 2781 code_ast = self.transform_ast(code_ast)
2791 2782 except InputRejected:
2792 2783 self.showtraceback()
2793 2784 if store_history:
2794 2785 self.execution_count += 1
2795 2786 return None
2796 2787
2797 2788 # Execute the user code
2798 2789 interactivity = "none" if silent else self.ast_node_interactivity
2799 2790 self.run_ast_nodes(code_ast.body, cell_name,
2800 2791 interactivity=interactivity, compiler=compiler)
2801 2792
2802 2793 self.events.trigger('post_execute')
2803 2794 if not silent:
2804 2795 self.events.trigger('post_run_cell')
2805 2796
2806 2797 if store_history:
2807 2798 # Write output to the database. Does nothing unless
2808 2799 # history output logging is enabled.
2809 2800 self.history_manager.store_output(self.execution_count)
2810 2801 # Each cell is a *single* input, regardless of how many lines it has
2811 2802 self.execution_count += 1
2812 2803
2813 2804 def transform_ast(self, node):
2814 2805 """Apply the AST transformations from self.ast_transformers
2815 2806
2816 2807 Parameters
2817 2808 ----------
2818 2809 node : ast.Node
2819 2810 The root node to be transformed. Typically called with the ast.Module
2820 2811 produced by parsing user input.
2821 2812
2822 2813 Returns
2823 2814 -------
2824 2815 An ast.Node corresponding to the node it was called with. Note that it
2825 2816 may also modify the passed object, so don't rely on references to the
2826 2817 original AST.
2827 2818 """
2828 2819 for transformer in self.ast_transformers:
2829 2820 try:
2830 2821 node = transformer.visit(node)
2831 2822 except InputRejected:
2832 2823 # User-supplied AST transformers can reject an input by raising
2833 2824 # an InputRejected. Short-circuit in this case so that we
2834 2825 # don't unregister the transform.
2835 2826 raise
2836 2827 except Exception:
2837 2828 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2838 2829 self.ast_transformers.remove(transformer)
2839 2830
2840 2831 if self.ast_transformers:
2841 2832 ast.fix_missing_locations(node)
2842 2833 return node
2843 2834
2844 2835
2845 2836 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2846 2837 compiler=compile):
2847 2838 """Run a sequence of AST nodes. The execution mode depends on the
2848 2839 interactivity parameter.
2849 2840
2850 2841 Parameters
2851 2842 ----------
2852 2843 nodelist : list
2853 2844 A sequence of AST nodes to run.
2854 2845 cell_name : str
2855 2846 Will be passed to the compiler as the filename of the cell. Typically
2856 2847 the value returned by ip.compile.cache(cell).
2857 2848 interactivity : str
2858 2849 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2859 2850 run interactively (displaying output from expressions). 'last_expr'
2860 2851 will run the last node interactively only if it is an expression (i.e.
2861 2852 expressions in loops or other blocks are not displayed. Other values
2862 2853 for this parameter will raise a ValueError.
2863 2854 compiler : callable
2864 2855 A function with the same interface as the built-in compile(), to turn
2865 2856 the AST nodes into code objects. Default is the built-in compile().
2866 2857 """
2867 2858 if not nodelist:
2868 2859 return
2869 2860
2870 2861 if interactivity == 'last_expr':
2871 2862 if isinstance(nodelist[-1], ast.Expr):
2872 2863 interactivity = "last"
2873 2864 else:
2874 2865 interactivity = "none"
2875 2866
2876 2867 if interactivity == 'none':
2877 2868 to_run_exec, to_run_interactive = nodelist, []
2878 2869 elif interactivity == 'last':
2879 2870 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2880 2871 elif interactivity == 'all':
2881 2872 to_run_exec, to_run_interactive = [], nodelist
2882 2873 else:
2883 2874 raise ValueError("Interactivity was %r" % interactivity)
2884 2875
2885 2876 exec_count = self.execution_count
2886 2877
2887 2878 try:
2888 2879 for i, node in enumerate(to_run_exec):
2889 2880 mod = ast.Module([node])
2890 2881 code = compiler(mod, cell_name, "exec")
2891 2882 if self.run_code(code):
2892 2883 return True
2893 2884
2894 2885 for i, node in enumerate(to_run_interactive):
2895 2886 mod = ast.Interactive([node])
2896 2887 code = compiler(mod, cell_name, "single")
2897 2888 if self.run_code(code):
2898 2889 return True
2899 2890
2900 2891 # Flush softspace
2901 2892 if softspace(sys.stdout, 0):
2902 2893 print()
2903 2894
2904 2895 except:
2905 2896 # It's possible to have exceptions raised here, typically by
2906 2897 # compilation of odd code (such as a naked 'return' outside a
2907 2898 # function) that did parse but isn't valid. Typically the exception
2908 2899 # is a SyntaxError, but it's safest just to catch anything and show
2909 2900 # the user a traceback.
2910 2901
2911 2902 # We do only one try/except outside the loop to minimize the impact
2912 2903 # on runtime, and also because if any node in the node list is
2913 2904 # broken, we should stop execution completely.
2914 2905 self.showtraceback()
2915 2906
2916 2907 return False
2917 2908
2918 2909 def run_code(self, code_obj):
2919 2910 """Execute a code object.
2920 2911
2921 2912 When an exception occurs, self.showtraceback() is called to display a
2922 2913 traceback.
2923 2914
2924 2915 Parameters
2925 2916 ----------
2926 2917 code_obj : code object
2927 2918 A compiled code object, to be executed
2928 2919
2929 2920 Returns
2930 2921 -------
2931 2922 False : successful execution.
2932 2923 True : an error occurred.
2933 2924 """
2934 2925 # Set our own excepthook in case the user code tries to call it
2935 2926 # directly, so that the IPython crash handler doesn't get triggered
2936 2927 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
2937 2928
2938 2929 # we save the original sys.excepthook in the instance, in case config
2939 2930 # code (such as magics) needs access to it.
2940 2931 self.sys_excepthook = old_excepthook
2941 2932 outflag = 1 # happens in more places, so it's easier as default
2942 2933 try:
2943 2934 try:
2944 2935 self.hooks.pre_run_code_hook()
2945 2936 #rprint('Running code', repr(code_obj)) # dbg
2946 2937 exec(code_obj, self.user_global_ns, self.user_ns)
2947 2938 finally:
2948 2939 # Reset our crash handler in place
2949 2940 sys.excepthook = old_excepthook
2950 2941 except SystemExit:
2951 2942 self.showtraceback(exception_only=True)
2952 2943 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2953 2944 except self.custom_exceptions:
2954 2945 etype, value, tb = sys.exc_info()
2955 2946 self.CustomTB(etype, value, tb)
2956 2947 except:
2957 2948 self.showtraceback()
2958 2949 else:
2959 2950 outflag = 0
2960 2951 return outflag
2961 2952
2962 2953 # For backwards compatibility
2963 2954 runcode = run_code
2964 2955
2965 2956 #-------------------------------------------------------------------------
2966 2957 # Things related to GUI support and pylab
2967 2958 #-------------------------------------------------------------------------
2968 2959
2969 2960 def enable_gui(self, gui=None):
2970 2961 raise NotImplementedError('Implement enable_gui in a subclass')
2971 2962
2972 2963 def enable_matplotlib(self, gui=None):
2973 2964 """Enable interactive matplotlib and inline figure support.
2974 2965
2975 2966 This takes the following steps:
2976 2967
2977 2968 1. select the appropriate eventloop and matplotlib backend
2978 2969 2. set up matplotlib for interactive use with that backend
2979 2970 3. configure formatters for inline figure display
2980 2971 4. enable the selected gui eventloop
2981 2972
2982 2973 Parameters
2983 2974 ----------
2984 2975 gui : optional, string
2985 2976 If given, dictates the choice of matplotlib GUI backend to use
2986 2977 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2987 2978 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2988 2979 matplotlib (as dictated by the matplotlib build-time options plus the
2989 2980 user's matplotlibrc configuration file). Note that not all backends
2990 2981 make sense in all contexts, for example a terminal ipython can't
2991 2982 display figures inline.
2992 2983 """
2993 2984 from IPython.core import pylabtools as pt
2994 2985 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2995 2986
2996 2987 if gui != 'inline':
2997 2988 # If we have our first gui selection, store it
2998 2989 if self.pylab_gui_select is None:
2999 2990 self.pylab_gui_select = gui
3000 2991 # Otherwise if they are different
3001 2992 elif gui != self.pylab_gui_select:
3002 2993 print ('Warning: Cannot change to a different GUI toolkit: %s.'
3003 2994 ' Using %s instead.' % (gui, self.pylab_gui_select))
3004 2995 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3005 2996
3006 2997 pt.activate_matplotlib(backend)
3007 2998 pt.configure_inline_support(self, backend)
3008 2999
3009 3000 # Now we must activate the gui pylab wants to use, and fix %run to take
3010 3001 # plot updates into account
3011 3002 self.enable_gui(gui)
3012 3003 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3013 3004 pt.mpl_runner(self.safe_execfile)
3014 3005
3015 3006 return gui, backend
3016 3007
3017 3008 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3018 3009 """Activate pylab support at runtime.
3019 3010
3020 3011 This turns on support for matplotlib, preloads into the interactive
3021 3012 namespace all of numpy and pylab, and configures IPython to correctly
3022 3013 interact with the GUI event loop. The GUI backend to be used can be
3023 3014 optionally selected with the optional ``gui`` argument.
3024 3015
3025 3016 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3026 3017
3027 3018 Parameters
3028 3019 ----------
3029 3020 gui : optional, string
3030 3021 If given, dictates the choice of matplotlib GUI backend to use
3031 3022 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3032 3023 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3033 3024 matplotlib (as dictated by the matplotlib build-time options plus the
3034 3025 user's matplotlibrc configuration file). Note that not all backends
3035 3026 make sense in all contexts, for example a terminal ipython can't
3036 3027 display figures inline.
3037 3028 import_all : optional, bool, default: True
3038 3029 Whether to do `from numpy import *` and `from pylab import *`
3039 3030 in addition to module imports.
3040 3031 welcome_message : deprecated
3041 3032 This argument is ignored, no welcome message will be displayed.
3042 3033 """
3043 3034 from IPython.core.pylabtools import import_pylab
3044 3035
3045 3036 gui, backend = self.enable_matplotlib(gui)
3046 3037
3047 3038 # We want to prevent the loading of pylab to pollute the user's
3048 3039 # namespace as shown by the %who* magics, so we execute the activation
3049 3040 # code in an empty namespace, and we update *both* user_ns and
3050 3041 # user_ns_hidden with this information.
3051 3042 ns = {}
3052 3043 import_pylab(ns, import_all)
3053 3044 # warn about clobbered names
3054 3045 ignored = set(["__builtins__"])
3055 3046 both = set(ns).intersection(self.user_ns).difference(ignored)
3056 3047 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3057 3048 self.user_ns.update(ns)
3058 3049 self.user_ns_hidden.update(ns)
3059 3050 return gui, backend, clobbered
3060 3051
3061 3052 #-------------------------------------------------------------------------
3062 3053 # Utilities
3063 3054 #-------------------------------------------------------------------------
3064 3055
3065 3056 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3066 3057 """Expand python variables in a string.
3067 3058
3068 3059 The depth argument indicates how many frames above the caller should
3069 3060 be walked to look for the local namespace where to expand variables.
3070 3061
3071 3062 The global namespace for expansion is always the user's interactive
3072 3063 namespace.
3073 3064 """
3074 3065 ns = self.user_ns.copy()
3075 3066 ns.update(sys._getframe(depth+1).f_locals)
3076 3067 try:
3077 3068 # We have to use .vformat() here, because 'self' is a valid and common
3078 3069 # name, and expanding **ns for .format() would make it collide with
3079 3070 # the 'self' argument of the method.
3080 3071 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3081 3072 except Exception:
3082 3073 # if formatter couldn't format, just let it go untransformed
3083 3074 pass
3084 3075 return cmd
3085 3076
3086 3077 def mktempfile(self, data=None, prefix='ipython_edit_'):
3087 3078 """Make a new tempfile and return its filename.
3088 3079
3089 3080 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3090 3081 but it registers the created filename internally so ipython cleans it up
3091 3082 at exit time.
3092 3083
3093 3084 Optional inputs:
3094 3085
3095 3086 - data(None): if data is given, it gets written out to the temp file
3096 3087 immediately, and the file is closed again."""
3097 3088
3098 3089 dirname = tempfile.mkdtemp(prefix=prefix)
3099 3090 self.tempdirs.append(dirname)
3100 3091
3101 3092 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3102 3093 os.close(handle) # On Windows, there can only be one open handle on a file
3103 3094 self.tempfiles.append(filename)
3104 3095
3105 3096 if data:
3106 3097 tmp_file = open(filename,'w')
3107 3098 tmp_file.write(data)
3108 3099 tmp_file.close()
3109 3100 return filename
3110 3101
3111 3102 # TODO: This should be removed when Term is refactored.
3112 3103 def write(self,data):
3113 3104 """Write a string to the default output"""
3114 3105 io.stdout.write(data)
3115 3106
3116 3107 # TODO: This should be removed when Term is refactored.
3117 3108 def write_err(self,data):
3118 3109 """Write a string to the default error output"""
3119 3110 io.stderr.write(data)
3120 3111
3121 3112 def ask_yes_no(self, prompt, default=None):
3122 3113 if self.quiet:
3123 3114 return True
3124 3115 return ask_yes_no(prompt,default)
3125 3116
3126 3117 def show_usage(self):
3127 3118 """Show a usage message"""
3128 3119 page.page(IPython.core.usage.interactive_usage)
3129 3120
3130 3121 def extract_input_lines(self, range_str, raw=False):
3131 3122 """Return as a string a set of input history slices.
3132 3123
3133 3124 Parameters
3134 3125 ----------
3135 3126 range_str : string
3136 3127 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3137 3128 since this function is for use by magic functions which get their
3138 3129 arguments as strings. The number before the / is the session
3139 3130 number: ~n goes n back from the current session.
3140 3131
3141 3132 raw : bool, optional
3142 3133 By default, the processed input is used. If this is true, the raw
3143 3134 input history is used instead.
3144 3135
3145 3136 Notes
3146 3137 -----
3147 3138
3148 3139 Slices can be described with two notations:
3149 3140
3150 3141 * ``N:M`` -> standard python form, means including items N...(M-1).
3151 3142 * ``N-M`` -> include items N..M (closed endpoint).
3152 3143 """
3153 3144 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3154 3145 return "\n".join(x for _, _, x in lines)
3155 3146
3156 3147 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3157 3148 """Get a code string from history, file, url, or a string or macro.
3158 3149
3159 3150 This is mainly used by magic functions.
3160 3151
3161 3152 Parameters
3162 3153 ----------
3163 3154
3164 3155 target : str
3165 3156
3166 3157 A string specifying code to retrieve. This will be tried respectively
3167 3158 as: ranges of input history (see %history for syntax), url,
3168 3159 correspnding .py file, filename, or an expression evaluating to a
3169 3160 string or Macro in the user namespace.
3170 3161
3171 3162 raw : bool
3172 3163 If true (default), retrieve raw history. Has no effect on the other
3173 3164 retrieval mechanisms.
3174 3165
3175 3166 py_only : bool (default False)
3176 3167 Only try to fetch python code, do not try alternative methods to decode file
3177 3168 if unicode fails.
3178 3169
3179 3170 Returns
3180 3171 -------
3181 3172 A string of code.
3182 3173
3183 3174 ValueError is raised if nothing is found, and TypeError if it evaluates
3184 3175 to an object of another type. In each case, .args[0] is a printable
3185 3176 message.
3186 3177 """
3187 3178 code = self.extract_input_lines(target, raw=raw) # Grab history
3188 3179 if code:
3189 3180 return code
3190 3181 utarget = unquote_filename(target)
3191 3182 try:
3192 3183 if utarget.startswith(('http://', 'https://')):
3193 3184 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3194 3185 except UnicodeDecodeError:
3195 3186 if not py_only :
3196 3187 # Deferred import
3197 3188 try:
3198 3189 from urllib.request import urlopen # Py3
3199 3190 except ImportError:
3200 3191 from urllib import urlopen
3201 3192 response = urlopen(target)
3202 3193 return response.read().decode('latin1')
3203 3194 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3204 3195
3205 3196 potential_target = [target]
3206 3197 try :
3207 3198 potential_target.insert(0,get_py_filename(target))
3208 3199 except IOError:
3209 3200 pass
3210 3201
3211 3202 for tgt in potential_target :
3212 3203 if os.path.isfile(tgt): # Read file
3213 3204 try :
3214 3205 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3215 3206 except UnicodeDecodeError :
3216 3207 if not py_only :
3217 3208 with io_open(tgt,'r', encoding='latin1') as f :
3218 3209 return f.read()
3219 3210 raise ValueError(("'%s' seem to be unreadable.") % target)
3220 3211 elif os.path.isdir(os.path.expanduser(tgt)):
3221 3212 raise ValueError("'%s' is a directory, not a regular file." % target)
3222 3213
3223 3214 if search_ns:
3224 3215 # Inspect namespace to load object source
3225 3216 object_info = self.object_inspect(target, detail_level=1)
3226 3217 if object_info['found'] and object_info['source']:
3227 3218 return object_info['source']
3228 3219
3229 3220 try: # User namespace
3230 3221 codeobj = eval(target, self.user_ns)
3231 3222 except Exception:
3232 3223 raise ValueError(("'%s' was not found in history, as a file, url, "
3233 3224 "nor in the user namespace.") % target)
3234 3225
3235 3226 if isinstance(codeobj, string_types):
3236 3227 return codeobj
3237 3228 elif isinstance(codeobj, Macro):
3238 3229 return codeobj.value
3239 3230
3240 3231 raise TypeError("%s is neither a string nor a macro." % target,
3241 3232 codeobj)
3242 3233
3243 3234 #-------------------------------------------------------------------------
3244 3235 # Things related to IPython exiting
3245 3236 #-------------------------------------------------------------------------
3246 3237 def atexit_operations(self):
3247 3238 """This will be executed at the time of exit.
3248 3239
3249 3240 Cleanup operations and saving of persistent data that is done
3250 3241 unconditionally by IPython should be performed here.
3251 3242
3252 3243 For things that may depend on startup flags or platform specifics (such
3253 3244 as having readline or not), register a separate atexit function in the
3254 3245 code that has the appropriate information, rather than trying to
3255 3246 clutter
3256 3247 """
3257 3248 # Close the history session (this stores the end time and line count)
3258 3249 # this must be *before* the tempfile cleanup, in case of temporary
3259 3250 # history db
3260 3251 self.history_manager.end_session()
3261 3252
3262 3253 # Cleanup all tempfiles and folders left around
3263 3254 for tfile in self.tempfiles:
3264 3255 try:
3265 3256 os.unlink(tfile)
3266 3257 except OSError:
3267 3258 pass
3268 3259
3269 3260 for tdir in self.tempdirs:
3270 3261 try:
3271 3262 os.rmdir(tdir)
3272 3263 except OSError:
3273 3264 pass
3274 3265
3275 3266 # Clear all user namespaces to release all references cleanly.
3276 3267 self.reset(new_session=False)
3277 3268
3278 3269 # Run user hooks
3279 3270 self.hooks.shutdown_hook()
3280 3271
3281 3272 def cleanup(self):
3282 3273 self.restore_sys_module_state()
3283 3274
3284 3275
3285 3276 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3286 3277 """An abstract base class for InteractiveShell."""
3287 3278
3288 3279 InteractiveShellABC.register(InteractiveShell)
@@ -1,609 +1,612 b''
1 1 """Test interact and interactive."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 from __future__ import print_function
7 7
8 8 from collections import OrderedDict
9 9
10 10 import nose.tools as nt
11 11 import IPython.testing.tools as tt
12 12
13 13 from IPython.kernel.comm import Comm
14 14 from IPython.html import widgets
15 15 from IPython.html.widgets import interact, interactive, Widget, interaction
16 16 from IPython.utils.py3compat import annotate
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Utility stuff
20 20 #-----------------------------------------------------------------------------
21 21
22 22 class DummyComm(Comm):
23 23 comm_id = 'a-b-c-d'
24 24
25 def open(self, *args, **kwargs):
26 pass
27
25 28 def send(self, *args, **kwargs):
26 29 pass
27 30
28 31 def close(self, *args, **kwargs):
29 32 pass
30 33
31 34 _widget_attrs = {}
32 35 displayed = []
33 36 undefined = object()
34 37
35 38 def setup():
36 39 _widget_attrs['_comm_default'] = getattr(Widget, '_comm_default', undefined)
37 40 Widget._comm_default = lambda self: DummyComm()
38 41 _widget_attrs['_ipython_display_'] = Widget._ipython_display_
39 42 def raise_not_implemented(*args, **kwargs):
40 43 raise NotImplementedError()
41 44 Widget._ipython_display_ = raise_not_implemented
42 45
43 46 def teardown():
44 47 for attr, value in _widget_attrs.items():
45 48 if value is undefined:
46 49 delattr(Widget, attr)
47 50 else:
48 51 setattr(Widget, attr, value)
49 52
50 53 def f(**kwargs):
51 54 pass
52 55
53 56 def clear_display():
54 57 global displayed
55 58 displayed = []
56 59
57 60 def record_display(*args):
58 61 displayed.extend(args)
59 62
60 63 #-----------------------------------------------------------------------------
61 64 # Actual tests
62 65 #-----------------------------------------------------------------------------
63 66
64 67 def check_widget(w, **d):
65 68 """Check a single widget against a dict"""
66 69 for attr, expected in d.items():
67 70 if attr == 'cls':
68 71 nt.assert_is(w.__class__, expected)
69 72 else:
70 73 value = getattr(w, attr)
71 74 nt.assert_equal(value, expected,
72 75 "%s.%s = %r != %r" % (w.__class__.__name__, attr, value, expected)
73 76 )
74 77
75 78 def check_widgets(container, **to_check):
76 79 """Check that widgets are created as expected"""
77 80 # build a widget dictionary, so it matches
78 81 widgets = {}
79 82 for w in container.children:
80 83 widgets[w.description] = w
81 84
82 85 for key, d in to_check.items():
83 86 nt.assert_in(key, widgets)
84 87 check_widget(widgets[key], **d)
85 88
86 89
87 90 def test_single_value_string():
88 91 a = u'hello'
89 92 c = interactive(f, a=a)
90 93 w = c.children[0]
91 94 check_widget(w,
92 95 cls=widgets.Text,
93 96 description='a',
94 97 value=a,
95 98 )
96 99
97 100 def test_single_value_bool():
98 101 for a in (True, False):
99 102 c = interactive(f, a=a)
100 103 w = c.children[0]
101 104 check_widget(w,
102 105 cls=widgets.Checkbox,
103 106 description='a',
104 107 value=a,
105 108 )
106 109
107 110 def test_single_value_dict():
108 111 for d in [
109 112 dict(a=5),
110 113 dict(a=5, b='b', c=dict),
111 114 ]:
112 115 c = interactive(f, d=d)
113 116 w = c.children[0]
114 117 check_widget(w,
115 118 cls=widgets.Dropdown,
116 119 description='d',
117 120 values=d,
118 121 value=next(iter(d.values())),
119 122 )
120 123
121 124 def test_single_value_float():
122 125 for a in (2.25, 1.0, -3.5):
123 126 c = interactive(f, a=a)
124 127 w = c.children[0]
125 128 check_widget(w,
126 129 cls=widgets.FloatSlider,
127 130 description='a',
128 131 value=a,
129 132 min= -a if a > 0 else 3*a,
130 133 max= 3*a if a > 0 else -a,
131 134 step=0.1,
132 135 readout=True,
133 136 )
134 137
135 138 def test_single_value_int():
136 139 for a in (1, 5, -3):
137 140 c = interactive(f, a=a)
138 141 nt.assert_equal(len(c.children), 1)
139 142 w = c.children[0]
140 143 check_widget(w,
141 144 cls=widgets.IntSlider,
142 145 description='a',
143 146 value=a,
144 147 min= -a if a > 0 else 3*a,
145 148 max= 3*a if a > 0 else -a,
146 149 step=1,
147 150 readout=True,
148 151 )
149 152
150 153 def test_list_tuple_2_int():
151 154 with nt.assert_raises(ValueError):
152 155 c = interactive(f, tup=(1,1))
153 156 with nt.assert_raises(ValueError):
154 157 c = interactive(f, tup=(1,-1))
155 158 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
156 159 c = interactive(f, tup=(min, max), lis=[min, max])
157 160 nt.assert_equal(len(c.children), 2)
158 161 d = dict(
159 162 cls=widgets.IntSlider,
160 163 min=min,
161 164 max=max,
162 165 step=1,
163 166 readout=True,
164 167 )
165 168 check_widgets(c, tup=d, lis=d)
166 169
167 170 def test_list_tuple_3_int():
168 171 with nt.assert_raises(ValueError):
169 172 c = interactive(f, tup=(1,2,0))
170 173 with nt.assert_raises(ValueError):
171 174 c = interactive(f, tup=(1,2,-1))
172 175 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
173 176 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
174 177 nt.assert_equal(len(c.children), 2)
175 178 d = dict(
176 179 cls=widgets.IntSlider,
177 180 min=min,
178 181 max=max,
179 182 step=step,
180 183 readout=True,
181 184 )
182 185 check_widgets(c, tup=d, lis=d)
183 186
184 187 def test_list_tuple_2_float():
185 188 with nt.assert_raises(ValueError):
186 189 c = interactive(f, tup=(1.0,1.0))
187 190 with nt.assert_raises(ValueError):
188 191 c = interactive(f, tup=(0.5,-0.5))
189 192 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
190 193 c = interactive(f, tup=(min, max), lis=[min, max])
191 194 nt.assert_equal(len(c.children), 2)
192 195 d = dict(
193 196 cls=widgets.FloatSlider,
194 197 min=min,
195 198 max=max,
196 199 step=.1,
197 200 readout=True,
198 201 )
199 202 check_widgets(c, tup=d, lis=d)
200 203
201 204 def test_list_tuple_3_float():
202 205 with nt.assert_raises(ValueError):
203 206 c = interactive(f, tup=(1,2,0.0))
204 207 with nt.assert_raises(ValueError):
205 208 c = interactive(f, tup=(-1,-2,1.))
206 209 with nt.assert_raises(ValueError):
207 210 c = interactive(f, tup=(1,2.,-1.))
208 211 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
209 212 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
210 213 nt.assert_equal(len(c.children), 2)
211 214 d = dict(
212 215 cls=widgets.FloatSlider,
213 216 min=min,
214 217 max=max,
215 218 step=step,
216 219 readout=True,
217 220 )
218 221 check_widgets(c, tup=d, lis=d)
219 222
220 223 def test_list_tuple_str():
221 224 values = ['hello', 'there', 'guy']
222 225 first = values[0]
223 226 dvalues = OrderedDict((v,v) for v in values)
224 227 c = interactive(f, tup=tuple(values), lis=list(values))
225 228 nt.assert_equal(len(c.children), 2)
226 229 d = dict(
227 230 cls=widgets.Dropdown,
228 231 value=first,
229 232 values=dvalues
230 233 )
231 234 check_widgets(c, tup=d, lis=d)
232 235
233 236 def test_list_tuple_invalid():
234 237 for bad in [
235 238 (),
236 239 (5, 'hi'),
237 240 ('hi', 5),
238 241 ({},),
239 242 (None,),
240 243 ]:
241 244 with nt.assert_raises(ValueError):
242 245 print(bad) # because there is no custom message in assert_raises
243 246 c = interactive(f, tup=bad)
244 247
245 248 def test_defaults():
246 249 @annotate(n=10)
247 250 def f(n, f=4.5, g=1):
248 251 pass
249 252
250 253 c = interactive(f)
251 254 check_widgets(c,
252 255 n=dict(
253 256 cls=widgets.IntSlider,
254 257 value=10,
255 258 ),
256 259 f=dict(
257 260 cls=widgets.FloatSlider,
258 261 value=4.5,
259 262 ),
260 263 g=dict(
261 264 cls=widgets.IntSlider,
262 265 value=1,
263 266 ),
264 267 )
265 268
266 269 def test_default_values():
267 270 @annotate(n=10, f=(0, 10.), g=5, h={'a': 1, 'b': 2}, j=['hi', 'there'])
268 271 def f(n, f=4.5, g=1, h=2, j='there'):
269 272 pass
270 273
271 274 c = interactive(f)
272 275 check_widgets(c,
273 276 n=dict(
274 277 cls=widgets.IntSlider,
275 278 value=10,
276 279 ),
277 280 f=dict(
278 281 cls=widgets.FloatSlider,
279 282 value=4.5,
280 283 ),
281 284 g=dict(
282 285 cls=widgets.IntSlider,
283 286 value=5,
284 287 ),
285 288 h=dict(
286 289 cls=widgets.Dropdown,
287 290 values={'a': 1, 'b': 2},
288 291 value=2
289 292 ),
290 293 j=dict(
291 294 cls=widgets.Dropdown,
292 295 values={'hi':'hi', 'there':'there'},
293 296 value='there'
294 297 ),
295 298 )
296 299
297 300 def test_default_out_of_bounds():
298 301 @annotate(f=(0, 10.), h={'a': 1}, j=['hi', 'there'])
299 302 def f(f='hi', h=5, j='other'):
300 303 pass
301 304
302 305 c = interactive(f)
303 306 check_widgets(c,
304 307 f=dict(
305 308 cls=widgets.FloatSlider,
306 309 value=5.,
307 310 ),
308 311 h=dict(
309 312 cls=widgets.Dropdown,
310 313 values={'a': 1},
311 314 value=1,
312 315 ),
313 316 j=dict(
314 317 cls=widgets.Dropdown,
315 318 values={'hi':'hi', 'there':'there'},
316 319 value='hi',
317 320 ),
318 321 )
319 322
320 323 def test_annotations():
321 324 @annotate(n=10, f=widgets.FloatText())
322 325 def f(n, f):
323 326 pass
324 327
325 328 c = interactive(f)
326 329 check_widgets(c,
327 330 n=dict(
328 331 cls=widgets.IntSlider,
329 332 value=10,
330 333 ),
331 334 f=dict(
332 335 cls=widgets.FloatText,
333 336 ),
334 337 )
335 338
336 339 def test_priority():
337 340 @annotate(annotate='annotate', kwarg='annotate')
338 341 def f(kwarg='default', annotate='default', default='default'):
339 342 pass
340 343
341 344 c = interactive(f, kwarg='kwarg')
342 345 check_widgets(c,
343 346 kwarg=dict(
344 347 cls=widgets.Text,
345 348 value='kwarg',
346 349 ),
347 350 annotate=dict(
348 351 cls=widgets.Text,
349 352 value='annotate',
350 353 ),
351 354 )
352 355
353 356 @nt.with_setup(clear_display)
354 357 def test_decorator_kwarg():
355 358 with tt.monkeypatch(interaction, 'display', record_display):
356 359 @interact(a=5)
357 360 def foo(a):
358 361 pass
359 362 nt.assert_equal(len(displayed), 1)
360 363 w = displayed[0].children[0]
361 364 check_widget(w,
362 365 cls=widgets.IntSlider,
363 366 value=5,
364 367 )
365 368
366 369 @nt.with_setup(clear_display)
367 370 def test_decorator_no_call():
368 371 with tt.monkeypatch(interaction, 'display', record_display):
369 372 @interact
370 373 def foo(a='default'):
371 374 pass
372 375 nt.assert_equal(len(displayed), 1)
373 376 w = displayed[0].children[0]
374 377 check_widget(w,
375 378 cls=widgets.Text,
376 379 value='default',
377 380 )
378 381
379 382 @nt.with_setup(clear_display)
380 383 def test_call_interact():
381 384 def foo(a='default'):
382 385 pass
383 386 with tt.monkeypatch(interaction, 'display', record_display):
384 387 ifoo = interact(foo)
385 388 nt.assert_equal(len(displayed), 1)
386 389 w = displayed[0].children[0]
387 390 check_widget(w,
388 391 cls=widgets.Text,
389 392 value='default',
390 393 )
391 394
392 395 @nt.with_setup(clear_display)
393 396 def test_call_interact_kwargs():
394 397 def foo(a='default'):
395 398 pass
396 399 with tt.monkeypatch(interaction, 'display', record_display):
397 400 ifoo = interact(foo, a=10)
398 401 nt.assert_equal(len(displayed), 1)
399 402 w = displayed[0].children[0]
400 403 check_widget(w,
401 404 cls=widgets.IntSlider,
402 405 value=10,
403 406 )
404 407
405 408 @nt.with_setup(clear_display)
406 409 def test_call_decorated_on_trait_change():
407 410 """test calling @interact decorated functions"""
408 411 d = {}
409 412 with tt.monkeypatch(interaction, 'display', record_display):
410 413 @interact
411 414 def foo(a='default'):
412 415 d['a'] = a
413 416 return a
414 417 nt.assert_equal(len(displayed), 1)
415 418 w = displayed[0].children[0]
416 419 check_widget(w,
417 420 cls=widgets.Text,
418 421 value='default',
419 422 )
420 423 # test calling the function directly
421 424 a = foo('hello')
422 425 nt.assert_equal(a, 'hello')
423 426 nt.assert_equal(d['a'], 'hello')
424 427
425 428 # test that setting trait values calls the function
426 429 w.value = 'called'
427 430 nt.assert_equal(d['a'], 'called')
428 431
429 432 @nt.with_setup(clear_display)
430 433 def test_call_decorated_kwargs_on_trait_change():
431 434 """test calling @interact(foo=bar) decorated functions"""
432 435 d = {}
433 436 with tt.monkeypatch(interaction, 'display', record_display):
434 437 @interact(a='kwarg')
435 438 def foo(a='default'):
436 439 d['a'] = a
437 440 return a
438 441 nt.assert_equal(len(displayed), 1)
439 442 w = displayed[0].children[0]
440 443 check_widget(w,
441 444 cls=widgets.Text,
442 445 value='kwarg',
443 446 )
444 447 # test calling the function directly
445 448 a = foo('hello')
446 449 nt.assert_equal(a, 'hello')
447 450 nt.assert_equal(d['a'], 'hello')
448 451
449 452 # test that setting trait values calls the function
450 453 w.value = 'called'
451 454 nt.assert_equal(d['a'], 'called')
452 455
453 456 def test_fixed():
454 457 c = interactive(f, a=widgets.fixed(5), b='text')
455 458 nt.assert_equal(len(c.children), 1)
456 459 w = c.children[0]
457 460 check_widget(w,
458 461 cls=widgets.Text,
459 462 value='text',
460 463 description='b',
461 464 )
462 465
463 466 def test_default_description():
464 467 c = interactive(f, b='text')
465 468 w = c.children[0]
466 469 check_widget(w,
467 470 cls=widgets.Text,
468 471 value='text',
469 472 description='b',
470 473 )
471 474
472 475 def test_custom_description():
473 476 c = interactive(f, b=widgets.Text(value='text', description='foo'))
474 477 w = c.children[0]
475 478 check_widget(w,
476 479 cls=widgets.Text,
477 480 value='text',
478 481 description='foo',
479 482 )
480 483
481 484 def test_interact_manual_button():
482 485 c = interactive(f, __manual=True)
483 486 w = c.children[0]
484 487 check_widget(w, cls=widgets.Button)
485 488
486 489 def test_interact_manual_nocall():
487 490 callcount = 0
488 491 def calltest(testarg):
489 492 callcount += 1
490 493 c = interactive(calltest, testarg=5, __manual=True)
491 494 c.children[0].value = 10
492 495 nt.assert_equal(callcount, 0)
493 496
494 497 def test_int_range_logic():
495 498 irsw = widgets.IntRangeSlider
496 499 w = irsw(value=(2, 4), min=0, max=6)
497 500 check_widget(w, cls=irsw, value=(2, 4), min=0, max=6)
498 501 w.value = (4, 2)
499 502 check_widget(w, cls=irsw, value=(2, 4), min=0, max=6)
500 503 w.value = (-1, 7)
501 504 check_widget(w, cls=irsw, value=(0, 6), min=0, max=6)
502 505 w.min = 3
503 506 check_widget(w, cls=irsw, value=(3, 6), min=3, max=6)
504 507 w.max = 3
505 508 check_widget(w, cls=irsw, value=(3, 3), min=3, max=3)
506 509
507 510 w.min = 0
508 511 w.max = 6
509 512 w.lower = 2
510 513 w.upper = 4
511 514 check_widget(w, cls=irsw, value=(2, 4), min=0, max=6)
512 515 w.value = (0, 1) #lower non-overlapping range
513 516 check_widget(w, cls=irsw, value=(0, 1), min=0, max=6)
514 517 w.value = (5, 6) #upper non-overlapping range
515 518 check_widget(w, cls=irsw, value=(5, 6), min=0, max=6)
516 519 w.value = (-1, 4) #semi out-of-range
517 520 check_widget(w, cls=irsw, value=(0, 4), min=0, max=6)
518 521 w.lower = 2
519 522 check_widget(w, cls=irsw, value=(2, 4), min=0, max=6)
520 523 w.value = (-2, -1) #wholly out of range
521 524 check_widget(w, cls=irsw, value=(0, 0), min=0, max=6)
522 525 w.value = (7, 8)
523 526 check_widget(w, cls=irsw, value=(6, 6), min=0, max=6)
524 527
525 528 with nt.assert_raises(ValueError):
526 529 w.min = 7
527 530 with nt.assert_raises(ValueError):
528 531 w.max = -1
529 532 with nt.assert_raises(ValueError):
530 533 w.lower = 5
531 534 with nt.assert_raises(ValueError):
532 535 w.upper = 1
533 536
534 537 w = irsw(min=2, max=3)
535 538 check_widget(w, min=2, max=3)
536 539 w = irsw(min=100, max=200)
537 540 check_widget(w, lower=125, upper=175, value=(125, 175))
538 541
539 542 with nt.assert_raises(ValueError):
540 543 irsw(value=(2, 4), lower=3)
541 544 with nt.assert_raises(ValueError):
542 545 irsw(value=(2, 4), upper=3)
543 546 with nt.assert_raises(ValueError):
544 547 irsw(value=(2, 4), lower=3, upper=3)
545 548 with nt.assert_raises(ValueError):
546 549 irsw(min=2, max=1)
547 550 with nt.assert_raises(ValueError):
548 551 irsw(lower=5)
549 552 with nt.assert_raises(ValueError):
550 553 irsw(upper=5)
551 554
552 555
553 556 def test_float_range_logic():
554 557 frsw = widgets.FloatRangeSlider
555 558 w = frsw(value=(.2, .4), min=0., max=.6)
556 559 check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6)
557 560 w.value = (.4, .2)
558 561 check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6)
559 562 w.value = (-.1, .7)
560 563 check_widget(w, cls=frsw, value=(0., .6), min=0., max=.6)
561 564 w.min = .3
562 565 check_widget(w, cls=frsw, value=(.3, .6), min=.3, max=.6)
563 566 w.max = .3
564 567 check_widget(w, cls=frsw, value=(.3, .3), min=.3, max=.3)
565 568
566 569 w.min = 0.
567 570 w.max = .6
568 571 w.lower = .2
569 572 w.upper = .4
570 573 check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6)
571 574 w.value = (0., .1) #lower non-overlapping range
572 575 check_widget(w, cls=frsw, value=(0., .1), min=0., max=.6)
573 576 w.value = (.5, .6) #upper non-overlapping range
574 577 check_widget(w, cls=frsw, value=(.5, .6), min=0., max=.6)
575 578 w.value = (-.1, .4) #semi out-of-range
576 579 check_widget(w, cls=frsw, value=(0., .4), min=0., max=.6)
577 580 w.lower = .2
578 581 check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6)
579 582 w.value = (-.2, -.1) #wholly out of range
580 583 check_widget(w, cls=frsw, value=(0., 0.), min=0., max=.6)
581 584 w.value = (.7, .8)
582 585 check_widget(w, cls=frsw, value=(.6, .6), min=.0, max=.6)
583 586
584 587 with nt.assert_raises(ValueError):
585 588 w.min = .7
586 589 with nt.assert_raises(ValueError):
587 590 w.max = -.1
588 591 with nt.assert_raises(ValueError):
589 592 w.lower = .5
590 593 with nt.assert_raises(ValueError):
591 594 w.upper = .1
592 595
593 596 w = frsw(min=2, max=3)
594 597 check_widget(w, min=2, max=3)
595 598 w = frsw(min=1., max=2.)
596 599 check_widget(w, lower=1.25, upper=1.75, value=(1.25, 1.75))
597 600
598 601 with nt.assert_raises(ValueError):
599 602 frsw(value=(2, 4), lower=3)
600 603 with nt.assert_raises(ValueError):
601 604 frsw(value=(2, 4), upper=3)
602 605 with nt.assert_raises(ValueError):
603 606 frsw(value=(2, 4), lower=3, upper=3)
604 607 with nt.assert_raises(ValueError):
605 608 frsw(min=.2, max=.1)
606 609 with nt.assert_raises(ValueError):
607 610 frsw(lower=5)
608 611 with nt.assert_raises(ValueError):
609 612 frsw(upper=5)
@@ -1,141 +1,144 b''
1 1 """Base class for a Comm"""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 import uuid
7 7
8 8 from IPython.config import LoggingConfigurable
9 from IPython.core.getipython import get_ipython
9 from IPython.kernel.zmq.kernelbase import Kernel
10 10
11 11 from IPython.utils.jsonutil import json_clean
12 12 from IPython.utils.traitlets import Instance, Unicode, Bytes, Bool, Dict, Any
13 13
14 14
15 15 class Comm(LoggingConfigurable):
16 16
17 17 # If this is instantiated by a non-IPython kernel, shell will be None
18 18 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
19 19 allow_none=True)
20 20 kernel = Instance('IPython.kernel.zmq.kernelbase.Kernel')
21 def _kernel_default(self):
22 if Kernel.initialized():
23 return Kernel.instance()
21 24
22 25 iopub_socket = Any()
23 26 def _iopub_socket_default(self):
24 27 return self.kernel.iopub_socket
25 28 session = Instance('IPython.kernel.zmq.session.Session')
26 29 def _session_default(self):
27 30 return self.kernel.session
28 31
29 32 target_name = Unicode('comm')
30 33
31 34 topic = Bytes()
32 35 def _topic_default(self):
33 36 return ('comm-%s' % self.comm_id).encode('ascii')
34 37
35 38 _open_data = Dict(help="data dict, if any, to be included in comm_open")
36 39 _close_data = Dict(help="data dict, if any, to be included in comm_close")
37 40
38 41 _msg_callback = Any()
39 42 _close_callback = Any()
40 43
41 44 _closed = Bool(False)
42 45 comm_id = Unicode()
43 46 def _comm_id_default(self):
44 47 return uuid.uuid4().hex
45 48
46 49 primary = Bool(True, help="Am I the primary or secondary Comm?")
47 50
48 51 def __init__(self, target_name='', data=None, **kwargs):
49 52 if target_name:
50 53 kwargs['target_name'] = target_name
51 54 super(Comm, self).__init__(**kwargs)
52 55 if self.primary:
53 56 # I am primary, open my peer.
54 57 self.open(data)
55 58
56 59 def _publish_msg(self, msg_type, data=None, metadata=None, **keys):
57 60 """Helper for sending a comm message on IOPub"""
58 if self.session is not None:
59 data = {} if data is None else data
60 metadata = {} if metadata is None else metadata
61 content = json_clean(dict(data=data, comm_id=self.comm_id, **keys))
62 self.session.send(self.iopub_socket, msg_type,
63 content,
64 metadata=json_clean(metadata),
65 parent=self.kernel._parent_header,
66 ident=self.topic,
67 )
61 data = {} if data is None else data
62 metadata = {} if metadata is None else metadata
63 content = json_clean(dict(data=data, comm_id=self.comm_id, **keys))
64 self.session.send(self.iopub_socket, msg_type,
65 content,
66 metadata=json_clean(metadata),
67 parent=self.kernel._parent_header,
68 ident=self.topic,
69 )
68 70
69 71 def __del__(self):
70 72 """trigger close on gc"""
71 73 self.close()
72 74
73 75 # publishing messages
74 76
75 77 def open(self, data=None, metadata=None):
76 78 """Open the frontend-side version of this comm"""
77 79 if data is None:
78 80 data = self._open_data
81 comm_manager = getattr(self.kernel, 'comm_manager', None)
82 if comm_manager is None:
83 raise RuntimeError("Comms cannot be opened without a kernel "
84 "and a comm_manager attached to that kernel.")
85
86 comm_manager.register_comm(self)
79 87 self._closed = False
80 ip = get_ipython()
81 if hasattr(ip, 'comm_manager'):
82 ip.comm_manager.register_comm(self)
83 88 self._publish_msg('comm_open', data, metadata, target_name=self.target_name)
84 89
85 90 def close(self, data=None, metadata=None):
86 91 """Close the frontend-side version of this comm"""
87 92 if self._closed:
88 93 # only close once
89 94 return
90 95 if data is None:
91 96 data = self._close_data
92 97 self._publish_msg('comm_close', data, metadata)
93 ip = get_ipython()
94 if hasattr(ip, 'comm_manager'):
95 ip.comm_manager.unregister_comm(self)
98 self.kernel.comm_manager.unregister_comm(self)
96 99 self._closed = True
97 100
98 101 def send(self, data=None, metadata=None):
99 102 """Send a message to the frontend-side version of this comm"""
100 103 self._publish_msg('comm_msg', data, metadata)
101 104
102 105 # registering callbacks
103 106
104 107 def on_close(self, callback):
105 108 """Register a callback for comm_close
106 109
107 110 Will be called with the `data` of the close message.
108 111
109 112 Call `on_close(None)` to disable an existing callback.
110 113 """
111 114 self._close_callback = callback
112 115
113 116 def on_msg(self, callback):
114 117 """Register a callback for comm_msg
115 118
116 119 Will be called with the `data` of any comm_msg messages.
117 120
118 121 Call `on_msg(None)` to disable an existing callback.
119 122 """
120 123 self._msg_callback = callback
121 124
122 125 # handling of incoming messages
123 126
124 127 def handle_close(self, msg):
125 128 """Handle a comm_close message"""
126 129 self.log.debug("handle_close[%s](%s)", self.comm_id, msg)
127 130 if self._close_callback:
128 131 self._close_callback(msg)
129 132
130 133 def handle_msg(self, msg):
131 134 """Handle a comm_msg message"""
132 135 self.log.debug("handle_msg[%s](%s)", self.comm_id, msg)
133 136 if self._msg_callback:
134 137 if self.shell:
135 138 self.shell.events.trigger('pre_execute')
136 139 self._msg_callback(msg)
137 140 if self.shell:
138 141 self.shell.events.trigger('post_execute')
139 142
140 143
141 144 __all__ = ['Comm']
@@ -1,302 +1,305 b''
1 1 """The IPython kernel implementation"""
2 2
3 3 import getpass
4 4 import sys
5 5 import traceback
6 6
7 7 from IPython.core import release
8 8 from IPython.utils.py3compat import builtin_mod, PY3
9 9 from IPython.utils.tokenutil import token_at_cursor
10 10 from IPython.utils.traitlets import Instance, Type, Any
11 11 from IPython.utils.decorators import undoc
12 12
13 from ..comm import CommManager
13 14 from .kernelbase import Kernel as KernelBase
14 15 from .serialize import serialize_object, unpack_apply_message
15 16 from .zmqshell import ZMQInteractiveShell
16 17
17 18 class IPythonKernel(KernelBase):
18 19 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
19 20 shell_class = Type(ZMQInteractiveShell)
20 21
21 22 user_module = Any()
22 23 def _user_module_changed(self, name, old, new):
23 24 if self.shell is not None:
24 25 self.shell.user_module = new
25 26
26 27 user_ns = Instance(dict, args=None, allow_none=True)
27 28 def _user_ns_changed(self, name, old, new):
28 29 if self.shell is not None:
29 30 self.shell.user_ns = new
30 31 self.shell.init_user_ns()
31 32
32 33 # A reference to the Python builtin 'raw_input' function.
33 34 # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3)
34 35 _sys_raw_input = Any()
35 36 _sys_eval_input = Any()
36 37
37 38 def __init__(self, **kwargs):
38 39 super(IPythonKernel, self).__init__(**kwargs)
39 40
40 41 # Initialize the InteractiveShell subclass
41 42 self.shell = self.shell_class.instance(parent=self,
42 43 profile_dir = self.profile_dir,
43 44 user_module = self.user_module,
44 45 user_ns = self.user_ns,
45 46 kernel = self,
46 47 )
47 48 self.shell.displayhook.session = self.session
48 49 self.shell.displayhook.pub_socket = self.iopub_socket
49 50 self.shell.displayhook.topic = self._topic('execute_result')
50 51 self.shell.display_pub.session = self.session
51 52 self.shell.display_pub.pub_socket = self.iopub_socket
52 53 self.shell.data_pub.session = self.session
53 54 self.shell.data_pub.pub_socket = self.iopub_socket
54 55
55 56 # TMP - hack while developing
56 57 self.shell._reply_content = None
57 58
59 self.comm_manager = CommManager(shell=self.shell, parent=self,
60 kernel=self)
61 self.shell.configurables.append(self.comm_manager)
58 62 comm_msg_types = [ 'comm_open', 'comm_msg', 'comm_close' ]
59 comm_manager = self.shell.comm_manager
60 63 for msg_type in comm_msg_types:
61 self.shell_handlers[msg_type] = getattr(comm_manager, msg_type)
64 self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type)
62 65
63 66 # Kernel info fields
64 67 implementation = 'ipython'
65 68 implementation_version = release.version
66 69 language = 'python'
67 70 language_version = sys.version.split()[0]
68 71 @property
69 72 def banner(self):
70 73 return self.shell.banner
71 74
72 75 def start(self):
73 76 self.shell.exit_now = False
74 77 super(IPythonKernel, self).start()
75 78
76 79 def set_parent(self, ident, parent):
77 80 """Overridden from parent to tell the display hook and output streams
78 81 about the parent message.
79 82 """
80 83 super(IPythonKernel, self).set_parent(ident, parent)
81 84 self.shell.set_parent(parent)
82 85
83 86 def _forward_input(self, allow_stdin=False):
84 87 """Forward raw_input and getpass to the current frontend.
85 88
86 89 via input_request
87 90 """
88 91 self._allow_stdin = allow_stdin
89 92
90 93 if PY3:
91 94 self._sys_raw_input = builtin_mod.input
92 95 builtin_mod.input = self.raw_input
93 96 else:
94 97 self._sys_raw_input = builtin_mod.raw_input
95 98 self._sys_eval_input = builtin_mod.input
96 99 builtin_mod.raw_input = self.raw_input
97 100 builtin_mod.input = lambda prompt='': eval(self.raw_input(prompt))
98 101 self._save_getpass = getpass.getpass
99 102 getpass.getpass = self.getpass
100 103
101 104 def _restore_input(self):
102 105 """Restore raw_input, getpass"""
103 106 if PY3:
104 107 builtin_mod.input = self._sys_raw_input
105 108 else:
106 109 builtin_mod.raw_input = self._sys_raw_input
107 110 builtin_mod.input = self._sys_eval_input
108 111
109 112 getpass.getpass = self._save_getpass
110 113
111 114 @property
112 115 def execution_count(self):
113 116 return self.shell.execution_count
114 117
115 118 @execution_count.setter
116 119 def execution_count(self, value):
117 120 # Ignore the incrememnting done by KernelBase, in favour of our shell's
118 121 # execution counter.
119 122 pass
120 123
121 124 def do_execute(self, code, silent, store_history=True,
122 125 user_expressions=None, allow_stdin=False):
123 126 shell = self.shell # we'll need this a lot here
124 127
125 128 self._forward_input(allow_stdin)
126 129
127 130 reply_content = {}
128 131 # FIXME: the shell calls the exception handler itself.
129 132 shell._reply_content = None
130 133 try:
131 134 shell.run_cell(code, store_history=store_history, silent=silent)
132 135 except:
133 136 status = u'error'
134 137 # FIXME: this code right now isn't being used yet by default,
135 138 # because the run_cell() call above directly fires off exception
136 139 # reporting. This code, therefore, is only active in the scenario
137 140 # where runlines itself has an unhandled exception. We need to
138 141 # uniformize this, for all exception construction to come from a
139 142 # single location in the codbase.
140 143 etype, evalue, tb = sys.exc_info()
141 144 tb_list = traceback.format_exception(etype, evalue, tb)
142 145 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
143 146 else:
144 147 status = u'ok'
145 148 finally:
146 149 self._restore_input()
147 150
148 151 reply_content[u'status'] = status
149 152
150 153 # Return the execution counter so clients can display prompts
151 154 reply_content['execution_count'] = shell.execution_count - 1
152 155
153 156 # FIXME - fish exception info out of shell, possibly left there by
154 157 # runlines. We'll need to clean up this logic later.
155 158 if shell._reply_content is not None:
156 159 reply_content.update(shell._reply_content)
157 160 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='execute')
158 161 reply_content['engine_info'] = e_info
159 162 # reset after use
160 163 shell._reply_content = None
161 164
162 165 if 'traceback' in reply_content:
163 166 self.log.info("Exception in execute request:\n%s", '\n'.join(reply_content['traceback']))
164 167
165 168
166 169 # At this point, we can tell whether the main code execution succeeded
167 170 # or not. If it did, we proceed to evaluate user_expressions
168 171 if reply_content['status'] == 'ok':
169 172 reply_content[u'user_expressions'] = \
170 173 shell.user_expressions(user_expressions or {})
171 174 else:
172 175 # If there was an error, don't even try to compute expressions
173 176 reply_content[u'user_expressions'] = {}
174 177
175 178 # Payloads should be retrieved regardless of outcome, so we can both
176 179 # recover partial output (that could have been generated early in a
177 180 # block, before an error) and clear the payload system always.
178 181 reply_content[u'payload'] = shell.payload_manager.read_payload()
179 182 # Be agressive about clearing the payload because we don't want
180 183 # it to sit in memory until the next execute_request comes in.
181 184 shell.payload_manager.clear_payload()
182 185
183 186 return reply_content
184 187
185 188 def do_complete(self, code, cursor_pos):
186 189 txt, matches = self.shell.complete('', code, cursor_pos)
187 190 return {'matches' : matches,
188 191 'cursor_end' : cursor_pos,
189 192 'cursor_start' : cursor_pos - len(txt),
190 193 'metadata' : {},
191 194 'status' : 'ok'}
192 195
193 196 def do_inspect(self, code, cursor_pos, detail_level=0):
194 197 name = token_at_cursor(code, cursor_pos)
195 198 info = self.shell.object_inspect(name)
196 199
197 200 reply_content = {'status' : 'ok'}
198 201 reply_content['data'] = data = {}
199 202 reply_content['metadata'] = {}
200 203 reply_content['found'] = info['found']
201 204 if info['found']:
202 205 info_text = self.shell.object_inspect_text(
203 206 name,
204 207 detail_level=detail_level,
205 208 )
206 209 data['text/plain'] = info_text
207 210
208 211 return reply_content
209 212
210 213 def do_history(self, hist_access_type, output, raw, session=None, start=None,
211 214 stop=None, n=None, pattern=None, unique=False):
212 215 if hist_access_type == 'tail':
213 216 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
214 217 include_latest=True)
215 218
216 219 elif hist_access_type == 'range':
217 220 hist = self.shell.history_manager.get_range(session, start, stop,
218 221 raw=raw, output=output)
219 222
220 223 elif hist_access_type == 'search':
221 224 hist = self.shell.history_manager.search(
222 225 pattern, raw=raw, output=output, n=n, unique=unique)
223 226 else:
224 227 hist = []
225 228
226 229 return {'history' : list(hist)}
227 230
228 231 def do_shutdown(self, restart):
229 232 self.shell.exit_now = True
230 233 return dict(status='ok', restart=restart)
231 234
232 235 def do_apply(self, content, bufs, msg_id, reply_metadata):
233 236 shell = self.shell
234 237 try:
235 238 working = shell.user_ns
236 239
237 240 prefix = "_"+str(msg_id).replace("-","")+"_"
238 241
239 242 f,args,kwargs = unpack_apply_message(bufs, working, copy=False)
240 243
241 244 fname = getattr(f, '__name__', 'f')
242 245
243 246 fname = prefix+"f"
244 247 argname = prefix+"args"
245 248 kwargname = prefix+"kwargs"
246 249 resultname = prefix+"result"
247 250
248 251 ns = { fname : f, argname : args, kwargname : kwargs , resultname : None }
249 252 # print ns
250 253 working.update(ns)
251 254 code = "%s = %s(*%s,**%s)" % (resultname, fname, argname, kwargname)
252 255 try:
253 256 exec(code, shell.user_global_ns, shell.user_ns)
254 257 result = working.get(resultname)
255 258 finally:
256 259 for key in ns:
257 260 working.pop(key)
258 261
259 262 result_buf = serialize_object(result,
260 263 buffer_threshold=self.session.buffer_threshold,
261 264 item_threshold=self.session.item_threshold,
262 265 )
263 266
264 267 except:
265 268 # invoke IPython traceback formatting
266 269 shell.showtraceback()
267 270 # FIXME - fish exception info out of shell, possibly left there by
268 271 # run_code. We'll need to clean up this logic later.
269 272 reply_content = {}
270 273 if shell._reply_content is not None:
271 274 reply_content.update(shell._reply_content)
272 275 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='apply')
273 276 reply_content['engine_info'] = e_info
274 277 # reset after use
275 278 shell._reply_content = None
276 279
277 280 self.send_response(self.iopub_socket, u'error', reply_content,
278 281 ident=self._topic('error'))
279 282 self.log.info("Exception in apply request:\n%s", '\n'.join(reply_content['traceback']))
280 283 result_buf = []
281 284
282 285 if reply_content['ename'] == 'UnmetDependency':
283 286 reply_metadata['dependencies_met'] = False
284 287 else:
285 288 reply_content = {'status' : 'ok'}
286 289
287 290 return reply_content, result_buf
288 291
289 292 def do_clear(self):
290 293 self.shell.reset(False)
291 294 return dict(status='ok')
292 295
293 296
294 297 # This exists only for backwards compatibility - use IPythonKernel instead
295 298
296 299 @undoc
297 300 class Kernel(IPythonKernel):
298 301 def __init__(self, *args, **kwargs):
299 302 import warnings
300 303 warnings.warn('Kernel is a deprecated alias of IPython.kernel.zmq.ipkernel.IPythonKernel',
301 304 DeprecationWarning)
302 305 super(Kernel, self).__init__(*args, **kwargs) No newline at end of file
@@ -1,395 +1,395 b''
1 1 """An Application for launching a kernel"""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 from __future__ import print_function
7 7
8 8 import atexit
9 9 import os
10 10 import sys
11 11 import signal
12 12
13 13 import zmq
14 14 from zmq.eventloop import ioloop
15 15 from zmq.eventloop.zmqstream import ZMQStream
16 16
17 17 from IPython.core.ultratb import FormattedTB
18 18 from IPython.core.application import (
19 19 BaseIPythonApplication, base_flags, base_aliases, catch_config_error
20 20 )
21 21 from IPython.core.profiledir import ProfileDir
22 22 from IPython.core.shellapp import (
23 23 InteractiveShellApp, shell_flags, shell_aliases
24 24 )
25 25 from IPython.utils import io
26 26 from IPython.utils.path import filefind
27 27 from IPython.utils.traitlets import (
28 28 Any, Instance, Dict, Unicode, Integer, Bool, DottedObjectName, Type,
29 29 )
30 30 from IPython.utils.importstring import import_item
31 31 from IPython.kernel import write_connection_file
32 32 from IPython.kernel.connect import ConnectionFileMixin
33 33
34 34 # local imports
35 35 from .heartbeat import Heartbeat
36 36 from .ipkernel import IPythonKernel
37 37 from .parentpoller import ParentPollerUnix, ParentPollerWindows
38 38 from .session import (
39 39 Session, session_flags, session_aliases, default_secure,
40 40 )
41 41 from .zmqshell import ZMQInteractiveShell
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Flags and Aliases
45 45 #-----------------------------------------------------------------------------
46 46
47 47 kernel_aliases = dict(base_aliases)
48 48 kernel_aliases.update({
49 49 'ip' : 'IPKernelApp.ip',
50 50 'hb' : 'IPKernelApp.hb_port',
51 51 'shell' : 'IPKernelApp.shell_port',
52 52 'iopub' : 'IPKernelApp.iopub_port',
53 53 'stdin' : 'IPKernelApp.stdin_port',
54 54 'control' : 'IPKernelApp.control_port',
55 55 'f' : 'IPKernelApp.connection_file',
56 56 'parent': 'IPKernelApp.parent_handle',
57 57 'transport': 'IPKernelApp.transport',
58 58 })
59 59 if sys.platform.startswith('win'):
60 60 kernel_aliases['interrupt'] = 'IPKernelApp.interrupt'
61 61
62 62 kernel_flags = dict(base_flags)
63 63 kernel_flags.update({
64 64 'no-stdout' : (
65 65 {'IPKernelApp' : {'no_stdout' : True}},
66 66 "redirect stdout to the null device"),
67 67 'no-stderr' : (
68 68 {'IPKernelApp' : {'no_stderr' : True}},
69 69 "redirect stderr to the null device"),
70 70 'pylab' : (
71 71 {'IPKernelApp' : {'pylab' : 'auto'}},
72 72 """Pre-load matplotlib and numpy for interactive use with
73 73 the default matplotlib backend."""),
74 74 })
75 75
76 76 # inherit flags&aliases for any IPython shell apps
77 77 kernel_aliases.update(shell_aliases)
78 78 kernel_flags.update(shell_flags)
79 79
80 80 # inherit flags&aliases for Sessions
81 81 kernel_aliases.update(session_aliases)
82 82 kernel_flags.update(session_flags)
83 83
84 84 _ctrl_c_message = """\
85 85 NOTE: When using the `ipython kernel` entry point, Ctrl-C will not work.
86 86
87 87 To exit, you will have to explicitly quit this process, by either sending
88 88 "quit" from a client, or using Ctrl-\\ in UNIX-like environments.
89 89
90 90 To read more about this, see https://github.com/ipython/ipython/issues/2049
91 91
92 92 """
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Application class for starting an IPython Kernel
96 96 #-----------------------------------------------------------------------------
97 97
98 98 class IPKernelApp(BaseIPythonApplication, InteractiveShellApp,
99 99 ConnectionFileMixin):
100 100 name='ipkernel'
101 101 aliases = Dict(kernel_aliases)
102 102 flags = Dict(kernel_flags)
103 103 classes = [IPythonKernel, ZMQInteractiveShell, ProfileDir, Session]
104 104 # the kernel class, as an importstring
105 105 kernel_class = Type('IPython.kernel.zmq.ipkernel.IPythonKernel', config=True,
106 106 klass='IPython.kernel.zmq.kernelbase.Kernel',
107 107 help="""The Kernel subclass to be used.
108 108
109 109 This should allow easy re-use of the IPKernelApp entry point
110 110 to configure and launch kernels other than IPython's own.
111 111 """)
112 112 kernel = Any()
113 113 poller = Any() # don't restrict this even though current pollers are all Threads
114 114 heartbeat = Instance(Heartbeat)
115 115 ports = Dict()
116 116
117 117 # ipkernel doesn't get its own config file
118 118 def _config_file_name_default(self):
119 119 return 'ipython_config.py'
120 120
121 121 # connection info:
122 122
123 123 @property
124 124 def abs_connection_file(self):
125 125 if os.path.basename(self.connection_file) == self.connection_file:
126 126 return os.path.join(self.profile_dir.security_dir, self.connection_file)
127 127 else:
128 128 return self.connection_file
129 129
130 130
131 131 # streams, etc.
132 132 no_stdout = Bool(False, config=True, help="redirect stdout to the null device")
133 133 no_stderr = Bool(False, config=True, help="redirect stderr to the null device")
134 134 outstream_class = DottedObjectName('IPython.kernel.zmq.iostream.OutStream',
135 135 config=True, help="The importstring for the OutStream factory")
136 136 displayhook_class = DottedObjectName('IPython.kernel.zmq.displayhook.ZMQDisplayHook',
137 137 config=True, help="The importstring for the DisplayHook factory")
138 138
139 139 # polling
140 140 parent_handle = Integer(0, config=True,
141 141 help="""kill this process if its parent dies. On Windows, the argument
142 142 specifies the HANDLE of the parent process, otherwise it is simply boolean.
143 143 """)
144 144 interrupt = Integer(0, config=True,
145 145 help="""ONLY USED ON WINDOWS
146 146 Interrupt this process when the parent is signaled.
147 147 """)
148 148
149 149 def init_crash_handler(self):
150 150 # Install minimal exception handling
151 151 sys.excepthook = FormattedTB(mode='Verbose', color_scheme='NoColor',
152 152 ostream=sys.__stdout__)
153 153
154 154 def init_poller(self):
155 155 if sys.platform == 'win32':
156 156 if self.interrupt or self.parent_handle:
157 157 self.poller = ParentPollerWindows(self.interrupt, self.parent_handle)
158 158 elif self.parent_handle:
159 159 self.poller = ParentPollerUnix()
160 160
161 161 def _bind_socket(self, s, port):
162 162 iface = '%s://%s' % (self.transport, self.ip)
163 163 if self.transport == 'tcp':
164 164 if port <= 0:
165 165 port = s.bind_to_random_port(iface)
166 166 else:
167 167 s.bind("tcp://%s:%i" % (self.ip, port))
168 168 elif self.transport == 'ipc':
169 169 if port <= 0:
170 170 port = 1
171 171 path = "%s-%i" % (self.ip, port)
172 172 while os.path.exists(path):
173 173 port = port + 1
174 174 path = "%s-%i" % (self.ip, port)
175 175 else:
176 176 path = "%s-%i" % (self.ip, port)
177 177 s.bind("ipc://%s" % path)
178 178 return port
179 179
180 180 def write_connection_file(self):
181 181 """write connection info to JSON file"""
182 182 cf = self.abs_connection_file
183 183 self.log.debug("Writing connection file: %s", cf)
184 184 write_connection_file(cf, ip=self.ip, key=self.session.key, transport=self.transport,
185 185 shell_port=self.shell_port, stdin_port=self.stdin_port, hb_port=self.hb_port,
186 186 iopub_port=self.iopub_port, control_port=self.control_port)
187 187
188 188 def cleanup_connection_file(self):
189 189 cf = self.abs_connection_file
190 190 self.log.debug("Cleaning up connection file: %s", cf)
191 191 try:
192 192 os.remove(cf)
193 193 except (IOError, OSError):
194 194 pass
195 195
196 196 self.cleanup_ipc_files()
197 197
198 198 def init_connection_file(self):
199 199 if not self.connection_file:
200 200 self.connection_file = "kernel-%s.json"%os.getpid()
201 201 try:
202 202 self.connection_file = filefind(self.connection_file, ['.', self.profile_dir.security_dir])
203 203 except IOError:
204 204 self.log.debug("Connection file not found: %s", self.connection_file)
205 205 # This means I own it, so I will clean it up:
206 206 atexit.register(self.cleanup_connection_file)
207 207 return
208 208 try:
209 209 self.load_connection_file()
210 210 except Exception:
211 211 self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True)
212 212 self.exit(1)
213 213
214 214 def init_sockets(self):
215 215 # Create a context, a session, and the kernel sockets.
216 216 self.log.info("Starting the kernel at pid: %i", os.getpid())
217 217 context = zmq.Context.instance()
218 218 # Uncomment this to try closing the context.
219 219 # atexit.register(context.term)
220 220
221 221 self.shell_socket = context.socket(zmq.ROUTER)
222 222 self.shell_socket.linger = 1000
223 223 self.shell_port = self._bind_socket(self.shell_socket, self.shell_port)
224 224 self.log.debug("shell ROUTER Channel on port: %i" % self.shell_port)
225 225
226 226 self.iopub_socket = context.socket(zmq.PUB)
227 227 self.iopub_socket.linger = 1000
228 228 self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port)
229 229 self.log.debug("iopub PUB Channel on port: %i" % self.iopub_port)
230 230
231 231 self.stdin_socket = context.socket(zmq.ROUTER)
232 232 self.stdin_socket.linger = 1000
233 233 self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port)
234 234 self.log.debug("stdin ROUTER Channel on port: %i" % self.stdin_port)
235 235
236 236 self.control_socket = context.socket(zmq.ROUTER)
237 237 self.control_socket.linger = 1000
238 238 self.control_port = self._bind_socket(self.control_socket, self.control_port)
239 239 self.log.debug("control ROUTER Channel on port: %i" % self.control_port)
240 240
241 241 def init_heartbeat(self):
242 242 """start the heart beating"""
243 243 # heartbeat doesn't share context, because it mustn't be blocked
244 244 # by the GIL, which is accessed by libzmq when freeing zero-copy messages
245 245 hb_ctx = zmq.Context()
246 246 self.heartbeat = Heartbeat(hb_ctx, (self.transport, self.ip, self.hb_port))
247 247 self.hb_port = self.heartbeat.port
248 248 self.log.debug("Heartbeat REP Channel on port: %i" % self.hb_port)
249 249 self.heartbeat.start()
250 250
251 251 def log_connection_info(self):
252 252 """display connection info, and store ports"""
253 253 basename = os.path.basename(self.connection_file)
254 254 if basename == self.connection_file or \
255 255 os.path.dirname(self.connection_file) == self.profile_dir.security_dir:
256 256 # use shortname
257 257 tail = basename
258 258 if self.profile != 'default':
259 259 tail += " --profile %s" % self.profile
260 260 else:
261 261 tail = self.connection_file
262 262 lines = [
263 263 "To connect another client to this kernel, use:",
264 264 " --existing %s" % tail,
265 265 ]
266 266 # log connection info
267 267 # info-level, so often not shown.
268 268 # frontends should use the %connect_info magic
269 269 # to see the connection info
270 270 for line in lines:
271 271 self.log.info(line)
272 272 # also raw print to the terminal if no parent_handle (`ipython kernel`)
273 273 if not self.parent_handle:
274 274 io.rprint(_ctrl_c_message)
275 275 for line in lines:
276 276 io.rprint(line)
277 277
278 278 self.ports = dict(shell=self.shell_port, iopub=self.iopub_port,
279 279 stdin=self.stdin_port, hb=self.hb_port,
280 280 control=self.control_port)
281 281
282 282 def init_blackhole(self):
283 283 """redirects stdout/stderr to devnull if necessary"""
284 284 if self.no_stdout or self.no_stderr:
285 285 blackhole = open(os.devnull, 'w')
286 286 if self.no_stdout:
287 287 sys.stdout = sys.__stdout__ = blackhole
288 288 if self.no_stderr:
289 289 sys.stderr = sys.__stderr__ = blackhole
290 290
291 291 def init_io(self):
292 292 """Redirect input streams and set a display hook."""
293 293 if self.outstream_class:
294 294 outstream_factory = import_item(str(self.outstream_class))
295 295 sys.stdout = outstream_factory(self.session, self.iopub_socket, u'stdout')
296 296 sys.stderr = outstream_factory(self.session, self.iopub_socket, u'stderr')
297 297 if self.displayhook_class:
298 298 displayhook_factory = import_item(str(self.displayhook_class))
299 299 sys.displayhook = displayhook_factory(self.session, self.iopub_socket)
300 300
301 301 def init_signal(self):
302 302 signal.signal(signal.SIGINT, signal.SIG_IGN)
303 303
304 304 def init_kernel(self):
305 305 """Create the Kernel object itself"""
306 306 shell_stream = ZMQStream(self.shell_socket)
307 307 control_stream = ZMQStream(self.control_socket)
308 308
309 kernel_factory = self.kernel_class
309 kernel_factory = self.kernel_class.instance
310 310
311 311 kernel = kernel_factory(parent=self, session=self.session,
312 312 shell_streams=[shell_stream, control_stream],
313 313 iopub_socket=self.iopub_socket,
314 314 stdin_socket=self.stdin_socket,
315 315 log=self.log,
316 316 profile_dir=self.profile_dir,
317 317 user_ns=self.user_ns,
318 318 )
319 319 kernel.record_ports(self.ports)
320 320 self.kernel = kernel
321 321
322 322 def init_gui_pylab(self):
323 323 """Enable GUI event loop integration, taking pylab into account."""
324 324
325 325 # Provide a wrapper for :meth:`InteractiveShellApp.init_gui_pylab`
326 326 # to ensure that any exception is printed straight to stderr.
327 327 # Normally _showtraceback associates the reply with an execution,
328 328 # which means frontends will never draw it, as this exception
329 329 # is not associated with any execute request.
330 330
331 331 shell = self.shell
332 332 _showtraceback = shell._showtraceback
333 333 try:
334 334 # replace error-sending traceback with stderr
335 335 def print_tb(etype, evalue, stb):
336 336 print ("GUI event loop or pylab initialization failed",
337 337 file=io.stderr)
338 338 print (shell.InteractiveTB.stb2text(stb), file=io.stderr)
339 339 shell._showtraceback = print_tb
340 340 InteractiveShellApp.init_gui_pylab(self)
341 341 finally:
342 342 shell._showtraceback = _showtraceback
343 343
344 344 def init_shell(self):
345 345 self.shell = getattr(self.kernel, 'shell', None)
346 346 if self.shell:
347 347 self.shell.configurables.append(self)
348 348
349 349 @catch_config_error
350 350 def initialize(self, argv=None):
351 351 super(IPKernelApp, self).initialize(argv)
352 352 default_secure(self.config)
353 353 self.init_blackhole()
354 354 self.init_connection_file()
355 355 self.init_poller()
356 356 self.init_sockets()
357 357 self.init_heartbeat()
358 358 # writing/displaying connection info must be *after* init_sockets/heartbeat
359 359 self.log_connection_info()
360 360 self.write_connection_file()
361 361 self.init_io()
362 362 self.init_signal()
363 363 self.init_kernel()
364 364 # shell init steps
365 365 self.init_path()
366 366 self.init_shell()
367 367 if self.shell:
368 368 self.init_gui_pylab()
369 369 self.init_extensions()
370 370 self.init_code()
371 371 # flush stdout/stderr, so that anything written to these streams during
372 372 # initialization do not get associated with the first execution request
373 373 sys.stdout.flush()
374 374 sys.stderr.flush()
375 375
376 376 def start(self):
377 377 if self.poller is not None:
378 378 self.poller.start()
379 379 self.kernel.start()
380 380 try:
381 381 ioloop.IOLoop.instance().start()
382 382 except KeyboardInterrupt:
383 383 pass
384 384
385 385 launch_new_instance = IPKernelApp.launch_instance
386 386
387 387 def main():
388 388 """Run an IPKernel as an application"""
389 389 app = IPKernelApp.instance()
390 390 app.initialize()
391 391 app.start()
392 392
393 393
394 394 if __name__ == '__main__':
395 395 main()
@@ -1,676 +1,676 b''
1 1 """Base class for a kernel that talks to frontends over 0MQ."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 from __future__ import print_function
7 7
8 8 import sys
9 9 import time
10 10 import logging
11 11 import uuid
12 12
13 13 from datetime import datetime
14 14 from signal import (
15 15 signal, default_int_handler, SIGINT
16 16 )
17 17
18 18 import zmq
19 19 from zmq.eventloop import ioloop
20 20 from zmq.eventloop.zmqstream import ZMQStream
21 21
22 from IPython.config.configurable import Configurable
22 from IPython.config.configurable import SingletonConfigurable
23 23 from IPython.core.error import StdinNotImplementedError
24 24 from IPython.core import release
25 25 from IPython.utils import py3compat
26 26 from IPython.utils.py3compat import unicode_type, string_types
27 27 from IPython.utils.jsonutil import json_clean
28 28 from IPython.utils.traitlets import (
29 29 Any, Instance, Float, Dict, List, Set, Integer, Unicode, Bool,
30 30 )
31 31
32 32 from .session import Session
33 33
34 34
35 class Kernel(Configurable):
35 class Kernel(SingletonConfigurable):
36 36
37 37 #---------------------------------------------------------------------------
38 38 # Kernel interface
39 39 #---------------------------------------------------------------------------
40 40
41 41 # attribute to override with a GUI
42 42 eventloop = Any(None)
43 43 def _eventloop_changed(self, name, old, new):
44 44 """schedule call to eventloop from IOLoop"""
45 45 loop = ioloop.IOLoop.instance()
46 46 loop.add_callback(self.enter_eventloop)
47 47
48 48 session = Instance(Session)
49 49 profile_dir = Instance('IPython.core.profiledir.ProfileDir')
50 50 shell_streams = List()
51 51 control_stream = Instance(ZMQStream)
52 52 iopub_socket = Instance(zmq.Socket)
53 53 stdin_socket = Instance(zmq.Socket)
54 54 log = Instance(logging.Logger)
55 55
56 56 # identities:
57 57 int_id = Integer(-1)
58 58 ident = Unicode()
59 59
60 60 def _ident_default(self):
61 61 return unicode_type(uuid.uuid4())
62 62
63 63 # Private interface
64 64
65 65 _darwin_app_nap = Bool(True, config=True,
66 66 help="""Whether to use appnope for compatiblity with OS X App Nap.
67 67
68 68 Only affects OS X >= 10.9.
69 69 """
70 70 )
71 71
72 72 # track associations with current request
73 73 _allow_stdin = Bool(False)
74 74 _parent_header = Dict()
75 75 _parent_ident = Any(b'')
76 76 # Time to sleep after flushing the stdout/err buffers in each execute
77 77 # cycle. While this introduces a hard limit on the minimal latency of the
78 78 # execute cycle, it helps prevent output synchronization problems for
79 79 # clients.
80 80 # Units are in seconds. The minimum zmq latency on local host is probably
81 81 # ~150 microseconds, set this to 500us for now. We may need to increase it
82 82 # a little if it's not enough after more interactive testing.
83 83 _execute_sleep = Float(0.0005, config=True)
84 84
85 85 # Frequency of the kernel's event loop.
86 86 # Units are in seconds, kernel subclasses for GUI toolkits may need to
87 87 # adapt to milliseconds.
88 88 _poll_interval = Float(0.05, config=True)
89 89
90 90 # If the shutdown was requested over the network, we leave here the
91 91 # necessary reply message so it can be sent by our registered atexit
92 92 # handler. This ensures that the reply is only sent to clients truly at
93 93 # the end of our shutdown process (which happens after the underlying
94 94 # IPython shell's own shutdown).
95 95 _shutdown_message = None
96 96
97 97 # This is a dict of port number that the kernel is listening on. It is set
98 98 # by record_ports and used by connect_request.
99 99 _recorded_ports = Dict()
100 100
101 101 # set of aborted msg_ids
102 102 aborted = Set()
103 103
104 104 # Track execution count here. For IPython, we override this to use the
105 105 # execution count we store in the shell.
106 106 execution_count = 0
107 107
108 108
109 109 def __init__(self, **kwargs):
110 110 super(Kernel, self).__init__(**kwargs)
111 111
112 112 # Build dict of handlers for message types
113 113 msg_types = [ 'execute_request', 'complete_request',
114 114 'inspect_request', 'history_request',
115 115 'kernel_info_request',
116 116 'connect_request', 'shutdown_request',
117 117 'apply_request',
118 118 ]
119 119 self.shell_handlers = {}
120 120 for msg_type in msg_types:
121 121 self.shell_handlers[msg_type] = getattr(self, msg_type)
122 122
123 123 control_msg_types = msg_types + [ 'clear_request', 'abort_request' ]
124 124 self.control_handlers = {}
125 125 for msg_type in control_msg_types:
126 126 self.control_handlers[msg_type] = getattr(self, msg_type)
127 127
128 128
129 129 def dispatch_control(self, msg):
130 130 """dispatch control requests"""
131 131 idents,msg = self.session.feed_identities(msg, copy=False)
132 132 try:
133 133 msg = self.session.unserialize(msg, content=True, copy=False)
134 134 except:
135 135 self.log.error("Invalid Control Message", exc_info=True)
136 136 return
137 137
138 138 self.log.debug("Control received: %s", msg)
139 139
140 140 # Set the parent message for side effects.
141 141 self.set_parent(idents, msg)
142 142 self._publish_status(u'busy')
143 143
144 144 header = msg['header']
145 145 msg_type = header['msg_type']
146 146
147 147 handler = self.control_handlers.get(msg_type, None)
148 148 if handler is None:
149 149 self.log.error("UNKNOWN CONTROL MESSAGE TYPE: %r", msg_type)
150 150 else:
151 151 try:
152 152 handler(self.control_stream, idents, msg)
153 153 except Exception:
154 154 self.log.error("Exception in control handler:", exc_info=True)
155 155
156 156 sys.stdout.flush()
157 157 sys.stderr.flush()
158 158 self._publish_status(u'idle')
159 159
160 160 def dispatch_shell(self, stream, msg):
161 161 """dispatch shell requests"""
162 162 # flush control requests first
163 163 if self.control_stream:
164 164 self.control_stream.flush()
165 165
166 166 idents,msg = self.session.feed_identities(msg, copy=False)
167 167 try:
168 168 msg = self.session.unserialize(msg, content=True, copy=False)
169 169 except:
170 170 self.log.error("Invalid Message", exc_info=True)
171 171 return
172 172
173 173 # Set the parent message for side effects.
174 174 self.set_parent(idents, msg)
175 175 self._publish_status(u'busy')
176 176
177 177 header = msg['header']
178 178 msg_id = header['msg_id']
179 179 msg_type = msg['header']['msg_type']
180 180
181 181 # Print some info about this message and leave a '--->' marker, so it's
182 182 # easier to trace visually the message chain when debugging. Each
183 183 # handler prints its message at the end.
184 184 self.log.debug('\n*** MESSAGE TYPE:%s***', msg_type)
185 185 self.log.debug(' Content: %s\n --->\n ', msg['content'])
186 186
187 187 if msg_id in self.aborted:
188 188 self.aborted.remove(msg_id)
189 189 # is it safe to assume a msg_id will not be resubmitted?
190 190 reply_type = msg_type.split('_')[0] + '_reply'
191 191 status = {'status' : 'aborted'}
192 192 md = {'engine' : self.ident}
193 193 md.update(status)
194 194 self.session.send(stream, reply_type, metadata=md,
195 195 content=status, parent=msg, ident=idents)
196 196 return
197 197
198 198 handler = self.shell_handlers.get(msg_type, None)
199 199 if handler is None:
200 200 self.log.error("UNKNOWN MESSAGE TYPE: %r", msg_type)
201 201 else:
202 202 # ensure default_int_handler during handler call
203 203 sig = signal(SIGINT, default_int_handler)
204 204 self.log.debug("%s: %s", msg_type, msg)
205 205 try:
206 206 handler(stream, idents, msg)
207 207 except Exception:
208 208 self.log.error("Exception in message handler:", exc_info=True)
209 209 finally:
210 210 signal(SIGINT, sig)
211 211
212 212 sys.stdout.flush()
213 213 sys.stderr.flush()
214 214 self._publish_status(u'idle')
215 215
216 216 def enter_eventloop(self):
217 217 """enter eventloop"""
218 218 self.log.info("entering eventloop %s", self.eventloop)
219 219 for stream in self.shell_streams:
220 220 # flush any pending replies,
221 221 # which may be skipped by entering the eventloop
222 222 stream.flush(zmq.POLLOUT)
223 223 # restore default_int_handler
224 224 signal(SIGINT, default_int_handler)
225 225 while self.eventloop is not None:
226 226 try:
227 227 self.eventloop(self)
228 228 except KeyboardInterrupt:
229 229 # Ctrl-C shouldn't crash the kernel
230 230 self.log.error("KeyboardInterrupt caught in kernel")
231 231 continue
232 232 else:
233 233 # eventloop exited cleanly, this means we should stop (right?)
234 234 self.eventloop = None
235 235 break
236 236 self.log.info("exiting eventloop")
237 237
238 238 def start(self):
239 239 """register dispatchers for streams"""
240 240 if self.control_stream:
241 241 self.control_stream.on_recv(self.dispatch_control, copy=False)
242 242
243 243 def make_dispatcher(stream):
244 244 def dispatcher(msg):
245 245 return self.dispatch_shell(stream, msg)
246 246 return dispatcher
247 247
248 248 for s in self.shell_streams:
249 249 s.on_recv(make_dispatcher(s), copy=False)
250 250
251 251 # publish idle status
252 252 self._publish_status('starting')
253 253
254 254 def do_one_iteration(self):
255 255 """step eventloop just once"""
256 256 if self.control_stream:
257 257 self.control_stream.flush()
258 258 for stream in self.shell_streams:
259 259 # handle at most one request per iteration
260 260 stream.flush(zmq.POLLIN, 1)
261 261 stream.flush(zmq.POLLOUT)
262 262
263 263
264 264 def record_ports(self, ports):
265 265 """Record the ports that this kernel is using.
266 266
267 267 The creator of the Kernel instance must call this methods if they
268 268 want the :meth:`connect_request` method to return the port numbers.
269 269 """
270 270 self._recorded_ports = ports
271 271
272 272 #---------------------------------------------------------------------------
273 273 # Kernel request handlers
274 274 #---------------------------------------------------------------------------
275 275
276 276 def _make_metadata(self, other=None):
277 277 """init metadata dict, for execute/apply_reply"""
278 278 new_md = {
279 279 'dependencies_met' : True,
280 280 'engine' : self.ident,
281 281 'started': datetime.now(),
282 282 }
283 283 if other:
284 284 new_md.update(other)
285 285 return new_md
286 286
287 287 def _publish_execute_input(self, code, parent, execution_count):
288 288 """Publish the code request on the iopub stream."""
289 289
290 290 self.session.send(self.iopub_socket, u'execute_input',
291 291 {u'code':code, u'execution_count': execution_count},
292 292 parent=parent, ident=self._topic('execute_input')
293 293 )
294 294
295 295 def _publish_status(self, status, parent=None):
296 296 """send status (busy/idle) on IOPub"""
297 297 self.session.send(self.iopub_socket,
298 298 u'status',
299 299 {u'execution_state': status},
300 300 parent=parent or self._parent_header,
301 301 ident=self._topic('status'),
302 302 )
303 303
304 304 def set_parent(self, ident, parent):
305 305 """Set the current parent_header
306 306
307 307 Side effects (IOPub messages) and replies are associated with
308 308 the request that caused them via the parent_header.
309 309
310 310 The parent identity is used to route input_request messages
311 311 on the stdin channel.
312 312 """
313 313 self._parent_ident = ident
314 314 self._parent_header = parent
315 315
316 316 def send_response(self, stream, msg_or_type, content=None, ident=None,
317 317 buffers=None, track=False, header=None, metadata=None):
318 318 """Send a response to the message we're currently processing.
319 319
320 320 This accepts all the parameters of :meth:`IPython.kernel.zmq.session.Session.send`
321 321 except ``parent``.
322 322
323 323 This relies on :meth:`set_parent` having been called for the current
324 324 message.
325 325 """
326 326 return self.session.send(stream, msg_or_type, content, self._parent_header,
327 327 ident, buffers, track, header, metadata)
328 328
329 329 def execute_request(self, stream, ident, parent):
330 330 """handle an execute_request"""
331 331
332 332 try:
333 333 content = parent[u'content']
334 334 code = py3compat.cast_unicode_py2(content[u'code'])
335 335 silent = content[u'silent']
336 336 store_history = content.get(u'store_history', not silent)
337 337 user_expressions = content.get('user_expressions', {})
338 338 allow_stdin = content.get('allow_stdin', False)
339 339 except:
340 340 self.log.error("Got bad msg: ")
341 341 self.log.error("%s", parent)
342 342 return
343 343
344 344 md = self._make_metadata(parent['metadata'])
345 345
346 346 # Re-broadcast our input for the benefit of listening clients, and
347 347 # start computing output
348 348 if not silent:
349 349 self.execution_count += 1
350 350 self._publish_execute_input(code, parent, self.execution_count)
351 351
352 352 reply_content = self.do_execute(code, silent, store_history,
353 353 user_expressions, allow_stdin)
354 354
355 355 # Flush output before sending the reply.
356 356 sys.stdout.flush()
357 357 sys.stderr.flush()
358 358 # FIXME: on rare occasions, the flush doesn't seem to make it to the
359 359 # clients... This seems to mitigate the problem, but we definitely need
360 360 # to better understand what's going on.
361 361 if self._execute_sleep:
362 362 time.sleep(self._execute_sleep)
363 363
364 364 # Send the reply.
365 365 reply_content = json_clean(reply_content)
366 366
367 367 md['status'] = reply_content['status']
368 368 if reply_content['status'] == 'error' and \
369 369 reply_content['ename'] == 'UnmetDependency':
370 370 md['dependencies_met'] = False
371 371
372 372 reply_msg = self.session.send(stream, u'execute_reply',
373 373 reply_content, parent, metadata=md,
374 374 ident=ident)
375 375
376 376 self.log.debug("%s", reply_msg)
377 377
378 378 if not silent and reply_msg['content']['status'] == u'error':
379 379 self._abort_queues()
380 380
381 381 def do_execute(self, code, silent, store_history=True,
382 382 user_experssions=None, allow_stdin=False):
383 383 """Execute user code. Must be overridden by subclasses.
384 384 """
385 385 raise NotImplementedError
386 386
387 387 def complete_request(self, stream, ident, parent):
388 388 content = parent['content']
389 389 code = content['code']
390 390 cursor_pos = content['cursor_pos']
391 391
392 392 matches = self.do_complete(code, cursor_pos)
393 393 matches = json_clean(matches)
394 394 completion_msg = self.session.send(stream, 'complete_reply',
395 395 matches, parent, ident)
396 396 self.log.debug("%s", completion_msg)
397 397
398 398 def do_complete(self, code, cursor_pos):
399 399 """Override in subclasses to find completions.
400 400 """
401 401 return {'matches' : [],
402 402 'cursor_end' : cursor_pos,
403 403 'cursor_start' : cursor_pos,
404 404 'metadata' : {},
405 405 'status' : 'ok'}
406 406
407 407 def inspect_request(self, stream, ident, parent):
408 408 content = parent['content']
409 409
410 410 reply_content = self.do_inspect(content['code'], content['cursor_pos'],
411 411 content.get('detail_level', 0))
412 412 # Before we send this object over, we scrub it for JSON usage
413 413 reply_content = json_clean(reply_content)
414 414 msg = self.session.send(stream, 'inspect_reply',
415 415 reply_content, parent, ident)
416 416 self.log.debug("%s", msg)
417 417
418 418 def do_inspect(self, code, cursor_pos, detail_level=0):
419 419 """Override in subclasses to allow introspection.
420 420 """
421 421 return {'status': 'ok', 'data':{}, 'metadata':{}, 'found':False}
422 422
423 423 def history_request(self, stream, ident, parent):
424 424 content = parent['content']
425 425
426 426 reply_content = self.do_history(**content)
427 427
428 428 reply_content = json_clean(reply_content)
429 429 msg = self.session.send(stream, 'history_reply',
430 430 reply_content, parent, ident)
431 431 self.log.debug("%s", msg)
432 432
433 433 def do_history(self, hist_access_type, output, raw, session=None, start=None,
434 434 stop=None, n=None, pattern=None, unique=False):
435 435 """Override in subclasses to access history.
436 436 """
437 437 return {'history': []}
438 438
439 439 def connect_request(self, stream, ident, parent):
440 440 if self._recorded_ports is not None:
441 441 content = self._recorded_ports.copy()
442 442 else:
443 443 content = {}
444 444 msg = self.session.send(stream, 'connect_reply',
445 445 content, parent, ident)
446 446 self.log.debug("%s", msg)
447 447
448 448 @property
449 449 def kernel_info(self):
450 450 return {
451 451 'protocol_version': release.kernel_protocol_version,
452 452 'implementation': self.implementation,
453 453 'implementation_version': self.implementation_version,
454 454 'language': self.language,
455 455 'language_version': self.language_version,
456 456 'banner': self.banner,
457 457 }
458 458
459 459 def kernel_info_request(self, stream, ident, parent):
460 460 msg = self.session.send(stream, 'kernel_info_reply',
461 461 self.kernel_info, parent, ident)
462 462 self.log.debug("%s", msg)
463 463
464 464 def shutdown_request(self, stream, ident, parent):
465 465 content = self.do_shutdown(parent['content']['restart'])
466 466 self.session.send(stream, u'shutdown_reply', content, parent, ident=ident)
467 467 # same content, but different msg_id for broadcasting on IOPub
468 468 self._shutdown_message = self.session.msg(u'shutdown_reply',
469 469 content, parent
470 470 )
471 471
472 472 self._at_shutdown()
473 473 # call sys.exit after a short delay
474 474 loop = ioloop.IOLoop.instance()
475 475 loop.add_timeout(time.time()+0.1, loop.stop)
476 476
477 477 def do_shutdown(self, restart):
478 478 """Override in subclasses to do things when the frontend shuts down the
479 479 kernel.
480 480 """
481 481 return {'status': 'ok', 'restart': restart}
482 482
483 483 #---------------------------------------------------------------------------
484 484 # Engine methods
485 485 #---------------------------------------------------------------------------
486 486
487 487 def apply_request(self, stream, ident, parent):
488 488 try:
489 489 content = parent[u'content']
490 490 bufs = parent[u'buffers']
491 491 msg_id = parent['header']['msg_id']
492 492 except:
493 493 self.log.error("Got bad msg: %s", parent, exc_info=True)
494 494 return
495 495
496 496 md = self._make_metadata(parent['metadata'])
497 497
498 498 reply_content, result_buf = self.do_apply(content, bufs, msg_id, md)
499 499
500 500 # put 'ok'/'error' status in header, for scheduler introspection:
501 501 md['status'] = reply_content['status']
502 502
503 503 # flush i/o
504 504 sys.stdout.flush()
505 505 sys.stderr.flush()
506 506
507 507 self.session.send(stream, u'apply_reply', reply_content,
508 508 parent=parent, ident=ident,buffers=result_buf, metadata=md)
509 509
510 510 def do_apply(self, content, bufs, msg_id, reply_metadata):
511 511 """Override in subclasses to support the IPython parallel framework.
512 512 """
513 513 raise NotImplementedError
514 514
515 515 #---------------------------------------------------------------------------
516 516 # Control messages
517 517 #---------------------------------------------------------------------------
518 518
519 519 def abort_request(self, stream, ident, parent):
520 520 """abort a specific msg by id"""
521 521 msg_ids = parent['content'].get('msg_ids', None)
522 522 if isinstance(msg_ids, string_types):
523 523 msg_ids = [msg_ids]
524 524 if not msg_ids:
525 525 self._abort_queues()
526 526 for mid in msg_ids:
527 527 self.aborted.add(str(mid))
528 528
529 529 content = dict(status='ok')
530 530 reply_msg = self.session.send(stream, 'abort_reply', content=content,
531 531 parent=parent, ident=ident)
532 532 self.log.debug("%s", reply_msg)
533 533
534 534 def clear_request(self, stream, idents, parent):
535 535 """Clear our namespace."""
536 536 content = self.do_clear()
537 537 self.session.send(stream, 'clear_reply', ident=idents, parent=parent,
538 538 content = content)
539 539
540 540 def do_clear(self):
541 541 """Override in subclasses to clear the namespace
542 542
543 543 This is only required for IPython.parallel.
544 544 """
545 545 raise NotImplementedError
546 546
547 547 #---------------------------------------------------------------------------
548 548 # Protected interface
549 549 #---------------------------------------------------------------------------
550 550
551 551 def _topic(self, topic):
552 552 """prefixed topic for IOPub messages"""
553 553 if self.int_id >= 0:
554 554 base = "engine.%i" % self.int_id
555 555 else:
556 556 base = "kernel.%s" % self.ident
557 557
558 558 return py3compat.cast_bytes("%s.%s" % (base, topic))
559 559
560 560 def _abort_queues(self):
561 561 for stream in self.shell_streams:
562 562 if stream:
563 563 self._abort_queue(stream)
564 564
565 565 def _abort_queue(self, stream):
566 566 poller = zmq.Poller()
567 567 poller.register(stream.socket, zmq.POLLIN)
568 568 while True:
569 569 idents,msg = self.session.recv(stream, zmq.NOBLOCK, content=True)
570 570 if msg is None:
571 571 return
572 572
573 573 self.log.info("Aborting:")
574 574 self.log.info("%s", msg)
575 575 msg_type = msg['header']['msg_type']
576 576 reply_type = msg_type.split('_')[0] + '_reply'
577 577
578 578 status = {'status' : 'aborted'}
579 579 md = {'engine' : self.ident}
580 580 md.update(status)
581 581 reply_msg = self.session.send(stream, reply_type, metadata=md,
582 582 content=status, parent=msg, ident=idents)
583 583 self.log.debug("%s", reply_msg)
584 584 # We need to wait a bit for requests to come in. This can probably
585 585 # be set shorter for true asynchronous clients.
586 586 poller.poll(50)
587 587
588 588
589 589 def _no_raw_input(self):
590 590 """Raise StdinNotImplentedError if active frontend doesn't support
591 591 stdin."""
592 592 raise StdinNotImplementedError("raw_input was called, but this "
593 593 "frontend does not support stdin.")
594 594
595 595 def getpass(self, prompt=''):
596 596 """Forward getpass to frontends
597 597
598 598 Raises
599 599 ------
600 600 StdinNotImplentedError if active frontend doesn't support stdin.
601 601 """
602 602 if not self._allow_stdin:
603 603 raise StdinNotImplementedError(
604 604 "getpass was called, but this frontend does not support input requests."
605 605 )
606 606 return self._input_request(prompt,
607 607 self._parent_ident,
608 608 self._parent_header,
609 609 password=True,
610 610 )
611 611
612 612 def raw_input(self, prompt=''):
613 613 """Forward raw_input to frontends
614 614
615 615 Raises
616 616 ------
617 617 StdinNotImplentedError if active frontend doesn't support stdin.
618 618 """
619 619 if not self._allow_stdin:
620 620 raise StdinNotImplementedError(
621 621 "raw_input was called, but this frontend does not support input requests."
622 622 )
623 623 return self._input_request(prompt,
624 624 self._parent_ident,
625 625 self._parent_header,
626 626 password=False,
627 627 )
628 628
629 629 def _input_request(self, prompt, ident, parent, password=False):
630 630 # Flush output before making the request.
631 631 sys.stderr.flush()
632 632 sys.stdout.flush()
633 633 # flush the stdin socket, to purge stale replies
634 634 while True:
635 635 try:
636 636 self.stdin_socket.recv_multipart(zmq.NOBLOCK)
637 637 except zmq.ZMQError as e:
638 638 if e.errno == zmq.EAGAIN:
639 639 break
640 640 else:
641 641 raise
642 642
643 643 # Send the input request.
644 644 content = json_clean(dict(prompt=prompt, password=password))
645 645 self.session.send(self.stdin_socket, u'input_request', content, parent,
646 646 ident=ident)
647 647
648 648 # Await a response.
649 649 while True:
650 650 try:
651 651 ident, reply = self.session.recv(self.stdin_socket, 0)
652 652 except Exception:
653 653 self.log.warn("Invalid Message:", exc_info=True)
654 654 except KeyboardInterrupt:
655 655 # re-raise KeyboardInterrupt, to truncate traceback
656 656 raise KeyboardInterrupt
657 657 else:
658 658 break
659 659 try:
660 660 value = py3compat.unicode_to_str(reply['content']['value'])
661 661 except:
662 662 self.log.error("Bad input_reply: %s", parent)
663 663 value = ''
664 664 if value == '\x04':
665 665 # EOF
666 666 raise EOFError
667 667 return value
668 668
669 669 def _at_shutdown(self):
670 670 """Actions taken at shutdown by the kernel, called by python's atexit.
671 671 """
672 672 # io.rprint("Kernel at_shutdown") # dbg
673 673 if self._shutdown_message is not None:
674 674 self.session.send(self.iopub_socket, self._shutdown_message, ident=self._topic('shutdown'))
675 675 self.log.debug("%s", self._shutdown_message)
676 676 [ s.flush(zmq.POLLOUT) for s in self.shell_streams ]
@@ -1,573 +1,567 b''
1 1 """A ZMQ-based subclass of InteractiveShell.
2 2
3 3 This code is meant to ease the refactoring of the base InteractiveShell into
4 4 something with a cleaner architecture for 2-process use, without actually
5 5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
6 6 we subclass and override what we want to fix. Once this is working well, we
7 7 can go back to the base class and refactor the code for a cleaner inheritance
8 8 implementation that doesn't rely on so much monkeypatching.
9 9
10 10 But this lets us maintain a fully working IPython as we develop the new
11 11 machinery. This should thus be thought of as scaffolding.
12 12 """
13 13
14 14 # Copyright (c) IPython Development Team.
15 15 # Distributed under the terms of the Modified BSD License.
16 16
17 17 from __future__ import print_function
18 18
19 19 import os
20 20 import sys
21 21 import time
22 22
23 23 from zmq.eventloop import ioloop
24 24
25 25 from IPython.core.interactiveshell import (
26 26 InteractiveShell, InteractiveShellABC
27 27 )
28 28 from IPython.core import page
29 29 from IPython.core.autocall import ZMQExitAutocall
30 30 from IPython.core.displaypub import DisplayPublisher
31 31 from IPython.core.error import UsageError
32 32 from IPython.core.magics import MacroToEdit, CodeMagics
33 33 from IPython.core.magic import magics_class, line_magic, Magics
34 34 from IPython.core.payloadpage import install_payload_page
35 35 from IPython.core.usage import default_gui_banner
36 36 from IPython.display import display, Javascript
37 37 from IPython.kernel.inprocess.socket import SocketABC
38 38 from IPython.kernel import (
39 39 get_connection_file, get_connection_info, connect_qtconsole
40 40 )
41 41 from IPython.testing.skipdoctest import skip_doctest
42 42 from IPython.utils import openpy
43 43 from IPython.utils.jsonutil import json_clean, encode_images
44 44 from IPython.utils.process import arg_split
45 45 from IPython.utils import py3compat
46 46 from IPython.utils.py3compat import unicode_type
47 47 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes, Any
48 48 from IPython.utils.warn import error
49 49 from IPython.kernel.zmq.displayhook import ZMQShellDisplayHook
50 50 from IPython.kernel.zmq.datapub import ZMQDataPublisher
51 51 from IPython.kernel.zmq.session import extract_header
52 from IPython.kernel.comm import CommManager
53 52 from .session import Session
54 53
55 54 #-----------------------------------------------------------------------------
56 55 # Functions and classes
57 56 #-----------------------------------------------------------------------------
58 57
59 58 class ZMQDisplayPublisher(DisplayPublisher):
60 59 """A display publisher that publishes data using a ZeroMQ PUB socket."""
61 60
62 61 session = Instance(Session)
63 62 pub_socket = Instance(SocketABC)
64 63 parent_header = Dict({})
65 64 topic = CBytes(b'display_data')
66 65
67 66 def set_parent(self, parent):
68 67 """Set the parent for outbound messages."""
69 68 self.parent_header = extract_header(parent)
70 69
71 70 def _flush_streams(self):
72 71 """flush IO Streams prior to display"""
73 72 sys.stdout.flush()
74 73 sys.stderr.flush()
75 74
76 75 def publish(self, data, metadata=None, source=None):
77 76 self._flush_streams()
78 77 if metadata is None:
79 78 metadata = {}
80 79 self._validate_data(data, metadata)
81 80 content = {}
82 81 content['data'] = encode_images(data)
83 82 content['metadata'] = metadata
84 83 self.session.send(
85 84 self.pub_socket, u'display_data', json_clean(content),
86 85 parent=self.parent_header, ident=self.topic,
87 86 )
88 87
89 88 def clear_output(self, wait=False):
90 89 content = dict(wait=wait)
91 90 self._flush_streams()
92 91 self.session.send(
93 92 self.pub_socket, u'clear_output', content,
94 93 parent=self.parent_header, ident=self.topic,
95 94 )
96 95
97 96 @magics_class
98 97 class KernelMagics(Magics):
99 98 #------------------------------------------------------------------------
100 99 # Magic overrides
101 100 #------------------------------------------------------------------------
102 101 # Once the base class stops inheriting from magic, this code needs to be
103 102 # moved into a separate machinery as well. For now, at least isolate here
104 103 # the magics which this class needs to implement differently from the base
105 104 # class, or that are unique to it.
106 105
107 106 @line_magic
108 107 def doctest_mode(self, parameter_s=''):
109 108 """Toggle doctest mode on and off.
110 109
111 110 This mode is intended to make IPython behave as much as possible like a
112 111 plain Python shell, from the perspective of how its prompts, exceptions
113 112 and output look. This makes it easy to copy and paste parts of a
114 113 session into doctests. It does so by:
115 114
116 115 - Changing the prompts to the classic ``>>>`` ones.
117 116 - Changing the exception reporting mode to 'Plain'.
118 117 - Disabling pretty-printing of output.
119 118
120 119 Note that IPython also supports the pasting of code snippets that have
121 120 leading '>>>' and '...' prompts in them. This means that you can paste
122 121 doctests from files or docstrings (even if they have leading
123 122 whitespace), and the code will execute correctly. You can then use
124 123 '%history -t' to see the translated history; this will give you the
125 124 input after removal of all the leading prompts and whitespace, which
126 125 can be pasted back into an editor.
127 126
128 127 With these features, you can switch into this mode easily whenever you
129 128 need to do testing and changes to doctests, without having to leave
130 129 your existing IPython session.
131 130 """
132 131
133 132 from IPython.utils.ipstruct import Struct
134 133
135 134 # Shorthands
136 135 shell = self.shell
137 136 disp_formatter = self.shell.display_formatter
138 137 ptformatter = disp_formatter.formatters['text/plain']
139 138 # dstore is a data store kept in the instance metadata bag to track any
140 139 # changes we make, so we can undo them later.
141 140 dstore = shell.meta.setdefault('doctest_mode', Struct())
142 141 save_dstore = dstore.setdefault
143 142
144 143 # save a few values we'll need to recover later
145 144 mode = save_dstore('mode', False)
146 145 save_dstore('rc_pprint', ptformatter.pprint)
147 146 save_dstore('rc_active_types',disp_formatter.active_types)
148 147 save_dstore('xmode', shell.InteractiveTB.mode)
149 148
150 149 if mode == False:
151 150 # turn on
152 151 ptformatter.pprint = False
153 152 disp_formatter.active_types = ['text/plain']
154 153 shell.magic('xmode Plain')
155 154 else:
156 155 # turn off
157 156 ptformatter.pprint = dstore.rc_pprint
158 157 disp_formatter.active_types = dstore.rc_active_types
159 158 shell.magic("xmode " + dstore.xmode)
160 159
161 160 # Store new mode and inform on console
162 161 dstore.mode = bool(1-int(mode))
163 162 mode_label = ['OFF','ON'][dstore.mode]
164 163 print('Doctest mode is:', mode_label)
165 164
166 165 # Send the payload back so that clients can modify their prompt display
167 166 payload = dict(
168 167 source='doctest_mode',
169 168 mode=dstore.mode)
170 169 shell.payload_manager.write_payload(payload)
171 170
172 171
173 172 _find_edit_target = CodeMagics._find_edit_target
174 173
175 174 @skip_doctest
176 175 @line_magic
177 176 def edit(self, parameter_s='', last_call=['','']):
178 177 """Bring up an editor and execute the resulting code.
179 178
180 179 Usage:
181 180 %edit [options] [args]
182 181
183 182 %edit runs an external text editor. You will need to set the command for
184 183 this editor via the ``TerminalInteractiveShell.editor`` option in your
185 184 configuration file before it will work.
186 185
187 186 This command allows you to conveniently edit multi-line code right in
188 187 your IPython session.
189 188
190 189 If called without arguments, %edit opens up an empty editor with a
191 190 temporary file and will execute the contents of this file when you
192 191 close it (don't forget to save it!).
193 192
194 193 Options:
195 194
196 195 -n <number>
197 196 Open the editor at a specified line number. By default, the IPython
198 197 editor hook uses the unix syntax 'editor +N filename', but you can
199 198 configure this by providing your own modified hook if your favorite
200 199 editor supports line-number specifications with a different syntax.
201 200
202 201 -p
203 202 Call the editor with the same data as the previous time it was used,
204 203 regardless of how long ago (in your current session) it was.
205 204
206 205 -r
207 206 Use 'raw' input. This option only applies to input taken from the
208 207 user's history. By default, the 'processed' history is used, so that
209 208 magics are loaded in their transformed version to valid Python. If
210 209 this option is given, the raw input as typed as the command line is
211 210 used instead. When you exit the editor, it will be executed by
212 211 IPython's own processor.
213 212
214 213 Arguments:
215 214
216 215 If arguments are given, the following possibilites exist:
217 216
218 217 - The arguments are numbers or pairs of colon-separated numbers (like
219 218 1 4:8 9). These are interpreted as lines of previous input to be
220 219 loaded into the editor. The syntax is the same of the %macro command.
221 220
222 221 - If the argument doesn't start with a number, it is evaluated as a
223 222 variable and its contents loaded into the editor. You can thus edit
224 223 any string which contains python code (including the result of
225 224 previous edits).
226 225
227 226 - If the argument is the name of an object (other than a string),
228 227 IPython will try to locate the file where it was defined and open the
229 228 editor at the point where it is defined. You can use ``%edit function``
230 229 to load an editor exactly at the point where 'function' is defined,
231 230 edit it and have the file be executed automatically.
232 231
233 232 If the object is a macro (see %macro for details), this opens up your
234 233 specified editor with a temporary file containing the macro's data.
235 234 Upon exit, the macro is reloaded with the contents of the file.
236 235
237 236 Note: opening at an exact line is only supported under Unix, and some
238 237 editors (like kedit and gedit up to Gnome 2.8) do not understand the
239 238 '+NUMBER' parameter necessary for this feature. Good editors like
240 239 (X)Emacs, vi, jed, pico and joe all do.
241 240
242 241 - If the argument is not found as a variable, IPython will look for a
243 242 file with that name (adding .py if necessary) and load it into the
244 243 editor. It will execute its contents with execfile() when you exit,
245 244 loading any code in the file into your interactive namespace.
246 245
247 246 Unlike in the terminal, this is designed to use a GUI editor, and we do
248 247 not know when it has closed. So the file you edit will not be
249 248 automatically executed or printed.
250 249
251 250 Note that %edit is also available through the alias %ed.
252 251 """
253 252
254 253 opts,args = self.parse_options(parameter_s,'prn:')
255 254
256 255 try:
257 256 filename, lineno, _ = CodeMagics._find_edit_target(self.shell, args, opts, last_call)
258 257 except MacroToEdit as e:
259 258 # TODO: Implement macro editing over 2 processes.
260 259 print("Macro editing not yet implemented in 2-process model.")
261 260 return
262 261
263 262 # Make sure we send to the client an absolute path, in case the working
264 263 # directory of client and kernel don't match
265 264 filename = os.path.abspath(filename)
266 265
267 266 payload = {
268 267 'source' : 'edit_magic',
269 268 'filename' : filename,
270 269 'line_number' : lineno
271 270 }
272 271 self.shell.payload_manager.write_payload(payload)
273 272
274 273 # A few magics that are adapted to the specifics of using pexpect and a
275 274 # remote terminal
276 275
277 276 @line_magic
278 277 def clear(self, arg_s):
279 278 """Clear the terminal."""
280 279 if os.name == 'posix':
281 280 self.shell.system("clear")
282 281 else:
283 282 self.shell.system("cls")
284 283
285 284 if os.name == 'nt':
286 285 # This is the usual name in windows
287 286 cls = line_magic('cls')(clear)
288 287
289 288 # Terminal pagers won't work over pexpect, but we do have our own pager
290 289
291 290 @line_magic
292 291 def less(self, arg_s):
293 292 """Show a file through the pager.
294 293
295 294 Files ending in .py are syntax-highlighted."""
296 295 if not arg_s:
297 296 raise UsageError('Missing filename.')
298 297
299 298 cont = open(arg_s).read()
300 299 if arg_s.endswith('.py'):
301 300 cont = self.shell.pycolorize(openpy.read_py_file(arg_s, skip_encoding_cookie=False))
302 301 else:
303 302 cont = open(arg_s).read()
304 303 page.page(cont)
305 304
306 305 more = line_magic('more')(less)
307 306
308 307 # Man calls a pager, so we also need to redefine it
309 308 if os.name == 'posix':
310 309 @line_magic
311 310 def man(self, arg_s):
312 311 """Find the man page for the given command and display in pager."""
313 312 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
314 313 split=False))
315 314
316 315 @line_magic
317 316 def connect_info(self, arg_s):
318 317 """Print information for connecting other clients to this kernel
319 318
320 319 It will print the contents of this session's connection file, as well as
321 320 shortcuts for local clients.
322 321
323 322 In the simplest case, when called from the most recently launched kernel,
324 323 secondary clients can be connected, simply with:
325 324
326 325 $> ipython <app> --existing
327 326
328 327 """
329 328
330 329 from IPython.core.application import BaseIPythonApplication as BaseIPApp
331 330
332 331 if BaseIPApp.initialized():
333 332 app = BaseIPApp.instance()
334 333 security_dir = app.profile_dir.security_dir
335 334 profile = app.profile
336 335 else:
337 336 profile = 'default'
338 337 security_dir = ''
339 338
340 339 try:
341 340 connection_file = get_connection_file()
342 341 info = get_connection_info(unpack=False)
343 342 except Exception as e:
344 343 error("Could not get connection info: %r" % e)
345 344 return
346 345
347 346 # add profile flag for non-default profile
348 347 profile_flag = "--profile %s" % profile if profile != 'default' else ""
349 348
350 349 # if it's in the security dir, truncate to basename
351 350 if security_dir == os.path.dirname(connection_file):
352 351 connection_file = os.path.basename(connection_file)
353 352
354 353
355 354 print (info + '\n')
356 355 print ("Paste the above JSON into a file, and connect with:\n"
357 356 " $> ipython <app> --existing <file>\n"
358 357 "or, if you are local, you can connect with just:\n"
359 358 " $> ipython <app> --existing {0} {1}\n"
360 359 "or even just:\n"
361 360 " $> ipython <app> --existing {1}\n"
362 361 "if this is the most recent IPython session you have started.".format(
363 362 connection_file, profile_flag
364 363 )
365 364 )
366 365
367 366 @line_magic
368 367 def qtconsole(self, arg_s):
369 368 """Open a qtconsole connected to this kernel.
370 369
371 370 Useful for connecting a qtconsole to running notebooks, for better
372 371 debugging.
373 372 """
374 373
375 374 # %qtconsole should imply bind_kernel for engines:
376 375 try:
377 376 from IPython.parallel import bind_kernel
378 377 except ImportError:
379 378 # technically possible, because parallel has higher pyzmq min-version
380 379 pass
381 380 else:
382 381 bind_kernel()
383 382
384 383 try:
385 384 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
386 385 except Exception as e:
387 386 error("Could not start qtconsole: %r" % e)
388 387 return
389 388
390 389 @line_magic
391 390 def autosave(self, arg_s):
392 391 """Set the autosave interval in the notebook (in seconds).
393 392
394 393 The default value is 120, or two minutes.
395 394 ``%autosave 0`` will disable autosave.
396 395
397 396 This magic only has an effect when called from the notebook interface.
398 397 It has no effect when called in a startup file.
399 398 """
400 399
401 400 try:
402 401 interval = int(arg_s)
403 402 except ValueError:
404 403 raise UsageError("%%autosave requires an integer, got %r" % arg_s)
405 404
406 405 # javascript wants milliseconds
407 406 milliseconds = 1000 * interval
408 407 display(Javascript("IPython.notebook.set_autosave_interval(%i)" % milliseconds),
409 408 include=['application/javascript']
410 409 )
411 410 if interval:
412 411 print("Autosaving every %i seconds" % interval)
413 412 else:
414 413 print("Autosave disabled")
415 414
416 415
417 416 class ZMQInteractiveShell(InteractiveShell):
418 417 """A subclass of InteractiveShell for ZMQ."""
419 418
420 419 displayhook_class = Type(ZMQShellDisplayHook)
421 420 display_pub_class = Type(ZMQDisplayPublisher)
422 421 data_pub_class = Type(ZMQDataPublisher)
423 422 kernel = Any()
424 423 parent_header = Any()
425 424
426 425 def _banner1_default(self):
427 426 return default_gui_banner
428 427
429 428 # Override the traitlet in the parent class, because there's no point using
430 429 # readline for the kernel. Can be removed when the readline code is moved
431 430 # to the terminal frontend.
432 431 colors_force = CBool(True)
433 432 readline_use = CBool(False)
434 433 # autoindent has no meaning in a zmqshell, and attempting to enable it
435 434 # will print a warning in the absence of readline.
436 435 autoindent = CBool(False)
437 436
438 437 exiter = Instance(ZMQExitAutocall)
439 438 def _exiter_default(self):
440 439 return ZMQExitAutocall(self)
441 440
442 441 def _exit_now_changed(self, name, old, new):
443 442 """stop eventloop when exit_now fires"""
444 443 if new:
445 444 loop = ioloop.IOLoop.instance()
446 445 loop.add_timeout(time.time()+0.1, loop.stop)
447 446
448 447 keepkernel_on_exit = None
449 448
450 449 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
451 450 # interactive input being read; we provide event loop support in ipkernel
452 451 @staticmethod
453 452 def enable_gui(gui):
454 453 from .eventloops import enable_gui as real_enable_gui
455 454 try:
456 455 real_enable_gui(gui)
457 456 except ValueError as e:
458 457 raise UsageError("%s" % e)
459 458
460 459 def init_environment(self):
461 460 """Configure the user's environment.
462 461
463 462 """
464 463 env = os.environ
465 464 # These two ensure 'ls' produces nice coloring on BSD-derived systems
466 465 env['TERM'] = 'xterm-color'
467 466 env['CLICOLOR'] = '1'
468 467 # Since normal pagers don't work at all (over pexpect we don't have
469 468 # single-key control of the subprocess), try to disable paging in
470 469 # subprocesses as much as possible.
471 470 env['PAGER'] = 'cat'
472 471 env['GIT_PAGER'] = 'cat'
473 472
474 473 # And install the payload version of page.
475 474 install_payload_page()
476 475
477 476 def auto_rewrite_input(self, cmd):
478 477 """Called to show the auto-rewritten input for autocall and friends.
479 478
480 479 FIXME: this payload is currently not correctly processed by the
481 480 frontend.
482 481 """
483 482 new = self.prompt_manager.render('rewrite') + cmd
484 483 payload = dict(
485 484 source='auto_rewrite_input',
486 485 transformed_input=new,
487 486 )
488 487 self.payload_manager.write_payload(payload)
489 488
490 489 def ask_exit(self):
491 490 """Engage the exit actions."""
492 491 self.exit_now = (not self.keepkernel_on_exit)
493 492 payload = dict(
494 493 source='ask_exit',
495 494 exit=True,
496 495 keepkernel=self.keepkernel_on_exit,
497 496 )
498 497 self.payload_manager.write_payload(payload)
499 498
500 499 def _showtraceback(self, etype, evalue, stb):
501 500 # try to preserve ordering of tracebacks and print statements
502 501 sys.stdout.flush()
503 502 sys.stderr.flush()
504 503
505 504 exc_content = {
506 505 u'traceback' : stb,
507 506 u'ename' : unicode_type(etype.__name__),
508 507 u'evalue' : py3compat.safe_unicode(evalue),
509 508 }
510 509
511 510 dh = self.displayhook
512 511 # Send exception info over pub socket for other clients than the caller
513 512 # to pick up
514 513 topic = None
515 514 if dh.topic:
516 515 topic = dh.topic.replace(b'execute_result', b'error')
517 516
518 517 exc_msg = dh.session.send(dh.pub_socket, u'error', json_clean(exc_content), dh.parent_header, ident=topic)
519 518
520 519 # FIXME - Hack: store exception info in shell object. Right now, the
521 520 # caller is reading this info after the fact, we need to fix this logic
522 521 # to remove this hack. Even uglier, we need to store the error status
523 522 # here, because in the main loop, the logic that sets it is being
524 523 # skipped because runlines swallows the exceptions.
525 524 exc_content[u'status'] = u'error'
526 525 self._reply_content = exc_content
527 526 # /FIXME
528 527
529 528 return exc_content
530 529
531 530 def set_next_input(self, text):
532 531 """Send the specified text to the frontend to be presented at the next
533 532 input cell."""
534 533 payload = dict(
535 534 source='set_next_input',
536 535 text=text
537 536 )
538 537 self.payload_manager.write_payload(payload)
539 538
540 539 def set_parent(self, parent):
541 540 """Set the parent header for associating output with its triggering input"""
542 541 self.parent_header = parent
543 542 self.displayhook.set_parent(parent)
544 543 self.display_pub.set_parent(parent)
545 544 self.data_pub.set_parent(parent)
546 545 try:
547 546 sys.stdout.set_parent(parent)
548 547 except AttributeError:
549 548 pass
550 549 try:
551 550 sys.stderr.set_parent(parent)
552 551 except AttributeError:
553 552 pass
554 553
555 554 def get_parent(self):
556 555 return self.parent_header
557 556
558 557 #-------------------------------------------------------------------------
559 558 # Things related to magics
560 559 #-------------------------------------------------------------------------
561 560
562 561 def init_magics(self):
563 562 super(ZMQInteractiveShell, self).init_magics()
564 563 self.register_magics(KernelMagics)
565 564 self.magics_manager.register_alias('ed', 'edit')
566
567 def init_comms(self):
568 self.comm_manager = CommManager(shell=self, parent=self,
569 kernel=self.kernel)
570 self.configurables.append(self.comm_manager)
571 565
572 566
573 567 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now