##// END OF EJS Templates
Merge branch 'newkernel' into upstream-newkernel...
Brian Granger -
r2873:087388fb merge
parent child Browse files
Show More
@@ -1,2151 +1,2151 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-2010 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 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from __future__ import with_statement
18 18 from __future__ import absolute_import
19 19
20 20 import __builtin__
21 21 import abc
22 22 import codeop
23 23 import exceptions
24 24 import new
25 25 import os
26 26 import re
27 27 import string
28 28 import sys
29 29 import tempfile
30 30 from contextlib import nested
31 31
32 32 from IPython.config.configurable import Configurable
33 33 from IPython.core import debugger, oinspect
34 34 from IPython.core import history as ipcorehist
35 35 from IPython.core import prefilter
36 36 from IPython.core import shadowns
37 37 from IPython.core import ultratb
38 38 from IPython.core.alias import AliasManager
39 39 from IPython.core.builtin_trap import BuiltinTrap
40 40 from IPython.core.display_trap import DisplayTrap
41 41 from IPython.core.displayhook import DisplayHook
42 42 from IPython.core.error import UsageError
43 43 from IPython.core.extensions import ExtensionManager
44 44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 45 from IPython.core.inputlist import InputList
46 46 from IPython.core.logger import Logger
47 47 from IPython.core.magic import Magic
48 48 from IPython.core.payload import PayloadManager
49 49 from IPython.core.plugin import PluginManager
50 50 from IPython.core.prefilter import PrefilterManager
51 51 from IPython.external.Itpl import ItplNS
52 52 from IPython.utils import PyColorize
53 53 from IPython.utils import io
54 54 from IPython.utils import pickleshare
55 55 from IPython.utils.doctestreload import doctest_reload
56 56 from IPython.utils.io import ask_yes_no, rprint
57 57 from IPython.utils.ipstruct import Struct
58 58 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
59 59 from IPython.utils.process import getoutput, getoutputerror
60 60 from IPython.utils.strdispatch import StrDispatch
61 61 from IPython.utils.syspathcontext import prepended_to_syspath
62 62 from IPython.utils.text import num_ini_spaces
63 63 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
64 64 List, Unicode, Instance, Type)
65 65 from IPython.utils.warn import warn, error, fatal
66 66 import IPython.core.hooks
67 67
68 68 # from IPython.utils import growl
69 69 # growl.start("IPython")
70 70
71 71 #-----------------------------------------------------------------------------
72 72 # Globals
73 73 #-----------------------------------------------------------------------------
74 74
75 75 # compiled regexps for autoindent management
76 76 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
77 77
78 78 #-----------------------------------------------------------------------------
79 79 # Utilities
80 80 #-----------------------------------------------------------------------------
81 81
82 82 # store the builtin raw_input globally, and use this always, in case user code
83 83 # overwrites it (like wx.py.PyShell does)
84 84 raw_input_original = raw_input
85 85
86 86 def softspace(file, newvalue):
87 87 """Copied from code.py, to remove the dependency"""
88 88
89 89 oldvalue = 0
90 90 try:
91 91 oldvalue = file.softspace
92 92 except AttributeError:
93 93 pass
94 94 try:
95 95 file.softspace = newvalue
96 96 except (AttributeError, TypeError):
97 97 # "attribute-less object" or "read-only attributes"
98 98 pass
99 99 return oldvalue
100 100
101 101
102 102 def no_op(*a, **kw): pass
103 103
104 104 class SpaceInInput(exceptions.Exception): pass
105 105
106 106 class Bunch: pass
107 107
108 108
109 109 def get_default_colors():
110 110 if sys.platform=='darwin':
111 111 return "LightBG"
112 112 elif os.name=='nt':
113 113 return 'Linux'
114 114 else:
115 115 return 'Linux'
116 116
117 117
118 118 class SeparateStr(Str):
119 119 """A Str subclass to validate separate_in, separate_out, etc.
120 120
121 121 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
122 122 """
123 123
124 124 def validate(self, obj, value):
125 125 if value == '0': value = ''
126 126 value = value.replace('\\n','\n')
127 127 return super(SeparateStr, self).validate(obj, value)
128 128
129 129 class MultipleInstanceError(Exception):
130 130 pass
131 131
132 132
133 133 #-----------------------------------------------------------------------------
134 134 # Main IPython class
135 135 #-----------------------------------------------------------------------------
136 136
137 137
138 138 class InteractiveShell(Configurable, Magic):
139 139 """An enhanced, interactive shell for Python."""
140 140
141 141 _instance = None
142 142 autocall = Enum((0,1,2), default_value=1, config=True)
143 143 # TODO: remove all autoindent logic and put into frontends.
144 144 # We can't do this yet because even runlines uses the autoindent.
145 145 autoindent = CBool(True, config=True)
146 146 automagic = CBool(True, config=True)
147 147 cache_size = Int(1000, config=True)
148 148 color_info = CBool(True, config=True)
149 149 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
150 150 default_value=get_default_colors(), config=True)
151 151 debug = CBool(False, config=True)
152 152 deep_reload = CBool(False, config=True)
153 153 displayhook_class = Type(DisplayHook)
154 154 filename = Str("<ipython console>")
155 155 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
156 156 logstart = CBool(False, config=True)
157 157 logfile = Str('', config=True)
158 158 logappend = Str('', config=True)
159 159 object_info_string_level = Enum((0,1,2), default_value=0,
160 160 config=True)
161 161 pdb = CBool(False, config=True)
162 162 pprint = CBool(True, config=True)
163 163 profile = Str('', config=True)
164 164 prompt_in1 = Str('In [\\#]: ', config=True)
165 165 prompt_in2 = Str(' .\\D.: ', config=True)
166 166 prompt_out = Str('Out[\\#]: ', config=True)
167 167 prompts_pad_left = CBool(True, config=True)
168 168 quiet = CBool(False, config=True)
169 169
170 170 # The readline stuff will eventually be moved to the terminal subclass
171 171 # but for now, we can't do that as readline is welded in everywhere.
172 172 readline_use = CBool(True, config=True)
173 173 readline_merge_completions = CBool(True, config=True)
174 174 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
175 175 readline_remove_delims = Str('-/~', config=True)
176 176 readline_parse_and_bind = List([
177 177 'tab: complete',
178 178 '"\C-l": clear-screen',
179 179 'set show-all-if-ambiguous on',
180 180 '"\C-o": tab-insert',
181 181 '"\M-i": " "',
182 182 '"\M-o": "\d\d\d\d"',
183 183 '"\M-I": "\d\d\d\d"',
184 184 '"\C-r": reverse-search-history',
185 185 '"\C-s": forward-search-history',
186 186 '"\C-p": history-search-backward',
187 187 '"\C-n": history-search-forward',
188 188 '"\e[A": history-search-backward',
189 189 '"\e[B": history-search-forward',
190 190 '"\C-k": kill-line',
191 191 '"\C-u": unix-line-discard',
192 192 ], allow_none=False, config=True)
193 193
194 194 # TODO: this part of prompt management should be moved to the frontends.
195 195 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
196 196 separate_in = SeparateStr('\n', config=True)
197 separate_out = SeparateStr('\n', config=True)
198 separate_out2 = SeparateStr('\n', config=True)
197 separate_out = SeparateStr('', config=True)
198 separate_out2 = SeparateStr('', config=True)
199 199 system_header = Str('IPython system call: ', config=True)
200 200 system_verbose = CBool(False, config=True)
201 201 wildcards_case_sensitive = CBool(True, config=True)
202 202 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
203 203 default_value='Context', config=True)
204 204
205 205 # Subcomponents of InteractiveShell
206 206 alias_manager = Instance('IPython.core.alias.AliasManager')
207 207 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
208 208 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
209 209 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
210 210 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
211 211 plugin_manager = Instance('IPython.core.plugin.PluginManager')
212 212 payload_manager = Instance('IPython.core.payload.PayloadManager')
213 213
214 214 def __init__(self, config=None, ipython_dir=None,
215 215 user_ns=None, user_global_ns=None,
216 216 custom_exceptions=((),None)):
217 217
218 218 # This is where traits with a config_key argument are updated
219 219 # from the values on config.
220 220 super(InteractiveShell, self).__init__(config=config)
221 221
222 222 # These are relatively independent and stateless
223 223 self.init_ipython_dir(ipython_dir)
224 224 self.init_instance_attrs()
225 225
226 226 # Create namespaces (user_ns, user_global_ns, etc.)
227 227 self.init_create_namespaces(user_ns, user_global_ns)
228 228 # This has to be done after init_create_namespaces because it uses
229 229 # something in self.user_ns, but before init_sys_modules, which
230 230 # is the first thing to modify sys.
231 231 # TODO: When we override sys.stdout and sys.stderr before this class
232 232 # is created, we are saving the overridden ones here. Not sure if this
233 233 # is what we want to do.
234 234 self.save_sys_module_state()
235 235 self.init_sys_modules()
236 236
237 237 self.init_history()
238 238 self.init_encoding()
239 239 self.init_prefilter()
240 240
241 241 Magic.__init__(self, self)
242 242
243 243 self.init_syntax_highlighting()
244 244 self.init_hooks()
245 245 self.init_pushd_popd_magic()
246 246 # self.init_traceback_handlers use to be here, but we moved it below
247 247 # because it and init_io have to come after init_readline.
248 248 self.init_user_ns()
249 249 self.init_logger()
250 250 self.init_alias()
251 251 self.init_builtins()
252 252
253 253 # pre_config_initialization
254 254 self.init_shadow_hist()
255 255
256 256 # The next section should contain averything that was in ipmaker.
257 257 self.init_logstart()
258 258
259 259 # The following was in post_config_initialization
260 260 self.init_inspector()
261 261 # init_readline() must come before init_io(), because init_io uses
262 262 # readline related things.
263 263 self.init_readline()
264 264 # TODO: init_io() needs to happen before init_traceback handlers
265 265 # because the traceback handlers hardcode the stdout/stderr streams.
266 266 # This logic in in debugger.Pdb and should eventually be changed.
267 267 self.init_io()
268 268 self.init_traceback_handlers(custom_exceptions)
269 269 self.init_prompts()
270 270 self.init_displayhook()
271 271 self.init_reload_doctest()
272 272 self.init_magics()
273 273 self.init_pdb()
274 274 self.init_extension_manager()
275 275 self.init_plugin_manager()
276 276 self.init_payload()
277 277 self.hooks.late_startup_hook()
278 278
279 279 @classmethod
280 280 def instance(cls, *args, **kwargs):
281 281 """Returns a global InteractiveShell instance."""
282 282 if cls._instance is None:
283 283 inst = cls(*args, **kwargs)
284 284 # Now make sure that the instance will also be returned by
285 285 # the subclasses instance attribute.
286 286 for subclass in cls.mro():
287 287 if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
288 288 subclass._instance = inst
289 289 else:
290 290 break
291 291 if isinstance(cls._instance, cls):
292 292 return cls._instance
293 293 else:
294 294 raise MultipleInstanceError(
295 295 'Multiple incompatible subclass instances of '
296 296 'InteractiveShell are being created.'
297 297 )
298 298
299 299 @classmethod
300 300 def initialized(cls):
301 301 return hasattr(cls, "_instance")
302 302
303 303 def get_ipython(self):
304 304 """Return the currently running IPython instance."""
305 305 return self
306 306
307 307 #-------------------------------------------------------------------------
308 308 # Trait changed handlers
309 309 #-------------------------------------------------------------------------
310 310
311 311 def _ipython_dir_changed(self, name, new):
312 312 if not os.path.isdir(new):
313 313 os.makedirs(new, mode = 0777)
314 314
315 315 def set_autoindent(self,value=None):
316 316 """Set the autoindent flag, checking for readline support.
317 317
318 318 If called with no arguments, it acts as a toggle."""
319 319
320 320 if not self.has_readline:
321 321 if os.name == 'posix':
322 322 warn("The auto-indent feature requires the readline library")
323 323 self.autoindent = 0
324 324 return
325 325 if value is None:
326 326 self.autoindent = not self.autoindent
327 327 else:
328 328 self.autoindent = value
329 329
330 330 #-------------------------------------------------------------------------
331 331 # init_* methods called by __init__
332 332 #-------------------------------------------------------------------------
333 333
334 334 def init_ipython_dir(self, ipython_dir):
335 335 if ipython_dir is not None:
336 336 self.ipython_dir = ipython_dir
337 337 self.config.Global.ipython_dir = self.ipython_dir
338 338 return
339 339
340 340 if hasattr(self.config.Global, 'ipython_dir'):
341 341 self.ipython_dir = self.config.Global.ipython_dir
342 342 else:
343 343 self.ipython_dir = get_ipython_dir()
344 344
345 345 # All children can just read this
346 346 self.config.Global.ipython_dir = self.ipython_dir
347 347
348 348 def init_instance_attrs(self):
349 349 self.more = False
350 350
351 351 # command compiler
352 352 self.compile = codeop.CommandCompiler()
353 353
354 354 # User input buffer
355 355 self.buffer = []
356 356
357 357 # Make an empty namespace, which extension writers can rely on both
358 358 # existing and NEVER being used by ipython itself. This gives them a
359 359 # convenient location for storing additional information and state
360 360 # their extensions may require, without fear of collisions with other
361 361 # ipython names that may develop later.
362 362 self.meta = Struct()
363 363
364 364 # Object variable to store code object waiting execution. This is
365 365 # used mainly by the multithreaded shells, but it can come in handy in
366 366 # other situations. No need to use a Queue here, since it's a single
367 367 # item which gets cleared once run.
368 368 self.code_to_run = None
369 369
370 370 # Temporary files used for various purposes. Deleted at exit.
371 371 self.tempfiles = []
372 372
373 373 # Keep track of readline usage (later set by init_readline)
374 374 self.has_readline = False
375 375
376 376 # keep track of where we started running (mainly for crash post-mortem)
377 377 # This is not being used anywhere currently.
378 378 self.starting_dir = os.getcwd()
379 379
380 380 # Indentation management
381 381 self.indent_current_nsp = 0
382 382
383 383 def init_encoding(self):
384 384 # Get system encoding at startup time. Certain terminals (like Emacs
385 385 # under Win32 have it set to None, and we need to have a known valid
386 386 # encoding to use in the raw_input() method
387 387 try:
388 388 self.stdin_encoding = sys.stdin.encoding or 'ascii'
389 389 except AttributeError:
390 390 self.stdin_encoding = 'ascii'
391 391
392 392 def init_syntax_highlighting(self):
393 393 # Python source parser/formatter for syntax highlighting
394 394 pyformat = PyColorize.Parser().format
395 395 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
396 396
397 397 def init_pushd_popd_magic(self):
398 398 # for pushd/popd management
399 399 try:
400 400 self.home_dir = get_home_dir()
401 401 except HomeDirError, msg:
402 402 fatal(msg)
403 403
404 404 self.dir_stack = []
405 405
406 406 def init_logger(self):
407 407 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
408 408 # local shortcut, this is used a LOT
409 409 self.log = self.logger.log
410 410
411 411 def init_logstart(self):
412 412 if self.logappend:
413 413 self.magic_logstart(self.logappend + ' append')
414 414 elif self.logfile:
415 415 self.magic_logstart(self.logfile)
416 416 elif self.logstart:
417 417 self.magic_logstart()
418 418
419 419 def init_builtins(self):
420 420 self.builtin_trap = BuiltinTrap(shell=self)
421 421
422 422 def init_inspector(self):
423 423 # Object inspector
424 424 self.inspector = oinspect.Inspector(oinspect.InspectColors,
425 425 PyColorize.ANSICodeColors,
426 426 'NoColor',
427 427 self.object_info_string_level)
428 428
429 429 def init_io(self):
430 430 import IPython.utils.io
431 431 if sys.platform == 'win32' and self.has_readline:
432 432 Term = io.IOTerm(
433 433 cout=self.readline._outputfile,cerr=self.readline._outputfile
434 434 )
435 435 else:
436 436 Term = io.IOTerm()
437 437 io.Term = Term
438 438
439 439 def init_prompts(self):
440 440 # TODO: This is a pass for now because the prompts are managed inside
441 441 # the DisplayHook. Once there is a separate prompt manager, this
442 442 # will initialize that object and all prompt related information.
443 443 pass
444 444
445 445 def init_displayhook(self):
446 446 # Initialize displayhook, set in/out prompts and printing system
447 447 self.displayhook = self.displayhook_class(
448 448 shell=self,
449 449 cache_size=self.cache_size,
450 450 input_sep = self.separate_in,
451 451 output_sep = self.separate_out,
452 452 output_sep2 = self.separate_out2,
453 453 ps1 = self.prompt_in1,
454 454 ps2 = self.prompt_in2,
455 455 ps_out = self.prompt_out,
456 456 pad_left = self.prompts_pad_left
457 457 )
458 458 # This is a context manager that installs/revmoes the displayhook at
459 459 # the appropriate time.
460 460 self.display_trap = DisplayTrap(hook=self.displayhook)
461 461
462 462 def init_reload_doctest(self):
463 463 # Do a proper resetting of doctest, including the necessary displayhook
464 464 # monkeypatching
465 465 try:
466 466 doctest_reload()
467 467 except ImportError:
468 468 warn("doctest module does not exist.")
469 469
470 470 #-------------------------------------------------------------------------
471 471 # Things related to injections into the sys module
472 472 #-------------------------------------------------------------------------
473 473
474 474 def save_sys_module_state(self):
475 475 """Save the state of hooks in the sys module.
476 476
477 477 This has to be called after self.user_ns is created.
478 478 """
479 479 self._orig_sys_module_state = {}
480 480 self._orig_sys_module_state['stdin'] = sys.stdin
481 481 self._orig_sys_module_state['stdout'] = sys.stdout
482 482 self._orig_sys_module_state['stderr'] = sys.stderr
483 483 self._orig_sys_module_state['excepthook'] = sys.excepthook
484 484 try:
485 485 self._orig_sys_modules_main_name = self.user_ns['__name__']
486 486 except KeyError:
487 487 pass
488 488
489 489 def restore_sys_module_state(self):
490 490 """Restore the state of the sys module."""
491 491 try:
492 492 for k, v in self._orig_sys_module_state.items():
493 493 setattr(sys, k, v)
494 494 except AttributeError:
495 495 pass
496 496 try:
497 497 delattr(sys, 'ipcompleter')
498 498 except AttributeError:
499 499 pass
500 500 # Reset what what done in self.init_sys_modules
501 501 try:
502 502 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
503 503 except (AttributeError, KeyError):
504 504 pass
505 505
506 506 #-------------------------------------------------------------------------
507 507 # Things related to hooks
508 508 #-------------------------------------------------------------------------
509 509
510 510 def init_hooks(self):
511 511 # hooks holds pointers used for user-side customizations
512 512 self.hooks = Struct()
513 513
514 514 self.strdispatchers = {}
515 515
516 516 # Set all default hooks, defined in the IPython.hooks module.
517 517 hooks = IPython.core.hooks
518 518 for hook_name in hooks.__all__:
519 519 # default hooks have priority 100, i.e. low; user hooks should have
520 520 # 0-100 priority
521 521 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
522 522
523 523 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
524 524 """set_hook(name,hook) -> sets an internal IPython hook.
525 525
526 526 IPython exposes some of its internal API as user-modifiable hooks. By
527 527 adding your function to one of these hooks, you can modify IPython's
528 528 behavior to call at runtime your own routines."""
529 529
530 530 # At some point in the future, this should validate the hook before it
531 531 # accepts it. Probably at least check that the hook takes the number
532 532 # of args it's supposed to.
533 533
534 534 f = new.instancemethod(hook,self,self.__class__)
535 535
536 536 # check if the hook is for strdispatcher first
537 537 if str_key is not None:
538 538 sdp = self.strdispatchers.get(name, StrDispatch())
539 539 sdp.add_s(str_key, f, priority )
540 540 self.strdispatchers[name] = sdp
541 541 return
542 542 if re_key is not None:
543 543 sdp = self.strdispatchers.get(name, StrDispatch())
544 544 sdp.add_re(re.compile(re_key), f, priority )
545 545 self.strdispatchers[name] = sdp
546 546 return
547 547
548 548 dp = getattr(self.hooks, name, None)
549 549 if name not in IPython.core.hooks.__all__:
550 550 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
551 551 if not dp:
552 552 dp = IPython.core.hooks.CommandChainDispatcher()
553 553
554 554 try:
555 555 dp.add(f,priority)
556 556 except AttributeError:
557 557 # it was not commandchain, plain old func - replace
558 558 dp = f
559 559
560 560 setattr(self.hooks,name, dp)
561 561
562 562 #-------------------------------------------------------------------------
563 563 # Things related to the "main" module
564 564 #-------------------------------------------------------------------------
565 565
566 566 def new_main_mod(self,ns=None):
567 567 """Return a new 'main' module object for user code execution.
568 568 """
569 569 main_mod = self._user_main_module
570 570 init_fakemod_dict(main_mod,ns)
571 571 return main_mod
572 572
573 573 def cache_main_mod(self,ns,fname):
574 574 """Cache a main module's namespace.
575 575
576 576 When scripts are executed via %run, we must keep a reference to the
577 577 namespace of their __main__ module (a FakeModule instance) around so
578 578 that Python doesn't clear it, rendering objects defined therein
579 579 useless.
580 580
581 581 This method keeps said reference in a private dict, keyed by the
582 582 absolute path of the module object (which corresponds to the script
583 583 path). This way, for multiple executions of the same script we only
584 584 keep one copy of the namespace (the last one), thus preventing memory
585 585 leaks from old references while allowing the objects from the last
586 586 execution to be accessible.
587 587
588 588 Note: we can not allow the actual FakeModule instances to be deleted,
589 589 because of how Python tears down modules (it hard-sets all their
590 590 references to None without regard for reference counts). This method
591 591 must therefore make a *copy* of the given namespace, to allow the
592 592 original module's __dict__ to be cleared and reused.
593 593
594 594
595 595 Parameters
596 596 ----------
597 597 ns : a namespace (a dict, typically)
598 598
599 599 fname : str
600 600 Filename associated with the namespace.
601 601
602 602 Examples
603 603 --------
604 604
605 605 In [10]: import IPython
606 606
607 607 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
608 608
609 609 In [12]: IPython.__file__ in _ip._main_ns_cache
610 610 Out[12]: True
611 611 """
612 612 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
613 613
614 614 def clear_main_mod_cache(self):
615 615 """Clear the cache of main modules.
616 616
617 617 Mainly for use by utilities like %reset.
618 618
619 619 Examples
620 620 --------
621 621
622 622 In [15]: import IPython
623 623
624 624 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
625 625
626 626 In [17]: len(_ip._main_ns_cache) > 0
627 627 Out[17]: True
628 628
629 629 In [18]: _ip.clear_main_mod_cache()
630 630
631 631 In [19]: len(_ip._main_ns_cache) == 0
632 632 Out[19]: True
633 633 """
634 634 self._main_ns_cache.clear()
635 635
636 636 #-------------------------------------------------------------------------
637 637 # Things related to debugging
638 638 #-------------------------------------------------------------------------
639 639
640 640 def init_pdb(self):
641 641 # Set calling of pdb on exceptions
642 642 # self.call_pdb is a property
643 643 self.call_pdb = self.pdb
644 644
645 645 def _get_call_pdb(self):
646 646 return self._call_pdb
647 647
648 648 def _set_call_pdb(self,val):
649 649
650 650 if val not in (0,1,False,True):
651 651 raise ValueError,'new call_pdb value must be boolean'
652 652
653 653 # store value in instance
654 654 self._call_pdb = val
655 655
656 656 # notify the actual exception handlers
657 657 self.InteractiveTB.call_pdb = val
658 658
659 659 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
660 660 'Control auto-activation of pdb at exceptions')
661 661
662 662 def debugger(self,force=False):
663 663 """Call the pydb/pdb debugger.
664 664
665 665 Keywords:
666 666
667 667 - force(False): by default, this routine checks the instance call_pdb
668 668 flag and does not actually invoke the debugger if the flag is false.
669 669 The 'force' option forces the debugger to activate even if the flag
670 670 is false.
671 671 """
672 672
673 673 if not (force or self.call_pdb):
674 674 return
675 675
676 676 if not hasattr(sys,'last_traceback'):
677 677 error('No traceback has been produced, nothing to debug.')
678 678 return
679 679
680 680 # use pydb if available
681 681 if debugger.has_pydb:
682 682 from pydb import pm
683 683 else:
684 684 # fallback to our internal debugger
685 685 pm = lambda : self.InteractiveTB.debugger(force=True)
686 686 self.history_saving_wrapper(pm)()
687 687
688 688 #-------------------------------------------------------------------------
689 689 # Things related to IPython's various namespaces
690 690 #-------------------------------------------------------------------------
691 691
692 692 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
693 693 # Create the namespace where the user will operate. user_ns is
694 694 # normally the only one used, and it is passed to the exec calls as
695 695 # the locals argument. But we do carry a user_global_ns namespace
696 696 # given as the exec 'globals' argument, This is useful in embedding
697 697 # situations where the ipython shell opens in a context where the
698 698 # distinction between locals and globals is meaningful. For
699 699 # non-embedded contexts, it is just the same object as the user_ns dict.
700 700
701 701 # FIXME. For some strange reason, __builtins__ is showing up at user
702 702 # level as a dict instead of a module. This is a manual fix, but I
703 703 # should really track down where the problem is coming from. Alex
704 704 # Schmolck reported this problem first.
705 705
706 706 # A useful post by Alex Martelli on this topic:
707 707 # Re: inconsistent value from __builtins__
708 708 # Von: Alex Martelli <aleaxit@yahoo.com>
709 709 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
710 710 # Gruppen: comp.lang.python
711 711
712 712 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
713 713 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
714 714 # > <type 'dict'>
715 715 # > >>> print type(__builtins__)
716 716 # > <type 'module'>
717 717 # > Is this difference in return value intentional?
718 718
719 719 # Well, it's documented that '__builtins__' can be either a dictionary
720 720 # or a module, and it's been that way for a long time. Whether it's
721 721 # intentional (or sensible), I don't know. In any case, the idea is
722 722 # that if you need to access the built-in namespace directly, you
723 723 # should start with "import __builtin__" (note, no 's') which will
724 724 # definitely give you a module. Yeah, it's somewhat confusing:-(.
725 725
726 726 # These routines return properly built dicts as needed by the rest of
727 727 # the code, and can also be used by extension writers to generate
728 728 # properly initialized namespaces.
729 729 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
730 730
731 731 # Assign namespaces
732 732 # This is the namespace where all normal user variables live
733 733 self.user_ns = user_ns
734 734 self.user_global_ns = user_global_ns
735 735
736 736 # An auxiliary namespace that checks what parts of the user_ns were
737 737 # loaded at startup, so we can list later only variables defined in
738 738 # actual interactive use. Since it is always a subset of user_ns, it
739 739 # doesn't need to be separately tracked in the ns_table.
740 740 self.user_ns_hidden = {}
741 741
742 742 # A namespace to keep track of internal data structures to prevent
743 743 # them from cluttering user-visible stuff. Will be updated later
744 744 self.internal_ns = {}
745 745
746 746 # Now that FakeModule produces a real module, we've run into a nasty
747 747 # problem: after script execution (via %run), the module where the user
748 748 # code ran is deleted. Now that this object is a true module (needed
749 749 # so docetst and other tools work correctly), the Python module
750 750 # teardown mechanism runs over it, and sets to None every variable
751 751 # present in that module. Top-level references to objects from the
752 752 # script survive, because the user_ns is updated with them. However,
753 753 # calling functions defined in the script that use other things from
754 754 # the script will fail, because the function's closure had references
755 755 # to the original objects, which are now all None. So we must protect
756 756 # these modules from deletion by keeping a cache.
757 757 #
758 758 # To avoid keeping stale modules around (we only need the one from the
759 759 # last run), we use a dict keyed with the full path to the script, so
760 760 # only the last version of the module is held in the cache. Note,
761 761 # however, that we must cache the module *namespace contents* (their
762 762 # __dict__). Because if we try to cache the actual modules, old ones
763 763 # (uncached) could be destroyed while still holding references (such as
764 764 # those held by GUI objects that tend to be long-lived)>
765 765 #
766 766 # The %reset command will flush this cache. See the cache_main_mod()
767 767 # and clear_main_mod_cache() methods for details on use.
768 768
769 769 # This is the cache used for 'main' namespaces
770 770 self._main_ns_cache = {}
771 771 # And this is the single instance of FakeModule whose __dict__ we keep
772 772 # copying and clearing for reuse on each %run
773 773 self._user_main_module = FakeModule()
774 774
775 775 # A table holding all the namespaces IPython deals with, so that
776 776 # introspection facilities can search easily.
777 777 self.ns_table = {'user':user_ns,
778 778 'user_global':user_global_ns,
779 779 'internal':self.internal_ns,
780 780 'builtin':__builtin__.__dict__
781 781 }
782 782
783 783 # Similarly, track all namespaces where references can be held and that
784 784 # we can safely clear (so it can NOT include builtin). This one can be
785 785 # a simple list.
786 786 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
787 787 self.internal_ns, self._main_ns_cache ]
788 788
789 789 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
790 790 """Return a valid local and global user interactive namespaces.
791 791
792 792 This builds a dict with the minimal information needed to operate as a
793 793 valid IPython user namespace, which you can pass to the various
794 794 embedding classes in ipython. The default implementation returns the
795 795 same dict for both the locals and the globals to allow functions to
796 796 refer to variables in the namespace. Customized implementations can
797 797 return different dicts. The locals dictionary can actually be anything
798 798 following the basic mapping protocol of a dict, but the globals dict
799 799 must be a true dict, not even a subclass. It is recommended that any
800 800 custom object for the locals namespace synchronize with the globals
801 801 dict somehow.
802 802
803 803 Raises TypeError if the provided globals namespace is not a true dict.
804 804
805 805 Parameters
806 806 ----------
807 807 user_ns : dict-like, optional
808 808 The current user namespace. The items in this namespace should
809 809 be included in the output. If None, an appropriate blank
810 810 namespace should be created.
811 811 user_global_ns : dict, optional
812 812 The current user global namespace. The items in this namespace
813 813 should be included in the output. If None, an appropriate
814 814 blank namespace should be created.
815 815
816 816 Returns
817 817 -------
818 818 A pair of dictionary-like object to be used as the local namespace
819 819 of the interpreter and a dict to be used as the global namespace.
820 820 """
821 821
822 822
823 823 # We must ensure that __builtin__ (without the final 's') is always
824 824 # available and pointing to the __builtin__ *module*. For more details:
825 825 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
826 826
827 827 if user_ns is None:
828 828 # Set __name__ to __main__ to better match the behavior of the
829 829 # normal interpreter.
830 830 user_ns = {'__name__' :'__main__',
831 831 '__builtin__' : __builtin__,
832 832 '__builtins__' : __builtin__,
833 833 }
834 834 else:
835 835 user_ns.setdefault('__name__','__main__')
836 836 user_ns.setdefault('__builtin__',__builtin__)
837 837 user_ns.setdefault('__builtins__',__builtin__)
838 838
839 839 if user_global_ns is None:
840 840 user_global_ns = user_ns
841 841 if type(user_global_ns) is not dict:
842 842 raise TypeError("user_global_ns must be a true dict; got %r"
843 843 % type(user_global_ns))
844 844
845 845 return user_ns, user_global_ns
846 846
847 847 def init_sys_modules(self):
848 848 # We need to insert into sys.modules something that looks like a
849 849 # module but which accesses the IPython namespace, for shelve and
850 850 # pickle to work interactively. Normally they rely on getting
851 851 # everything out of __main__, but for embedding purposes each IPython
852 852 # instance has its own private namespace, so we can't go shoving
853 853 # everything into __main__.
854 854
855 855 # note, however, that we should only do this for non-embedded
856 856 # ipythons, which really mimic the __main__.__dict__ with their own
857 857 # namespace. Embedded instances, on the other hand, should not do
858 858 # this because they need to manage the user local/global namespaces
859 859 # only, but they live within a 'normal' __main__ (meaning, they
860 860 # shouldn't overtake the execution environment of the script they're
861 861 # embedded in).
862 862
863 863 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
864 864
865 865 try:
866 866 main_name = self.user_ns['__name__']
867 867 except KeyError:
868 868 raise KeyError('user_ns dictionary MUST have a "__name__" key')
869 869 else:
870 870 sys.modules[main_name] = FakeModule(self.user_ns)
871 871
872 872 def init_user_ns(self):
873 873 """Initialize all user-visible namespaces to their minimum defaults.
874 874
875 875 Certain history lists are also initialized here, as they effectively
876 876 act as user namespaces.
877 877
878 878 Notes
879 879 -----
880 880 All data structures here are only filled in, they are NOT reset by this
881 881 method. If they were not empty before, data will simply be added to
882 882 therm.
883 883 """
884 884 # This function works in two parts: first we put a few things in
885 885 # user_ns, and we sync that contents into user_ns_hidden so that these
886 886 # initial variables aren't shown by %who. After the sync, we add the
887 887 # rest of what we *do* want the user to see with %who even on a new
888 888 # session (probably nothing, so theye really only see their own stuff)
889 889
890 890 # The user dict must *always* have a __builtin__ reference to the
891 891 # Python standard __builtin__ namespace, which must be imported.
892 892 # This is so that certain operations in prompt evaluation can be
893 893 # reliably executed with builtins. Note that we can NOT use
894 894 # __builtins__ (note the 's'), because that can either be a dict or a
895 895 # module, and can even mutate at runtime, depending on the context
896 896 # (Python makes no guarantees on it). In contrast, __builtin__ is
897 897 # always a module object, though it must be explicitly imported.
898 898
899 899 # For more details:
900 900 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
901 901 ns = dict(__builtin__ = __builtin__)
902 902
903 903 # Put 'help' in the user namespace
904 904 try:
905 905 from site import _Helper
906 906 ns['help'] = _Helper()
907 907 except ImportError:
908 908 warn('help() not available - check site.py')
909 909
910 910 # make global variables for user access to the histories
911 911 ns['_ih'] = self.input_hist
912 912 ns['_oh'] = self.output_hist
913 913 ns['_dh'] = self.dir_hist
914 914
915 915 ns['_sh'] = shadowns
916 916
917 917 # user aliases to input and output histories. These shouldn't show up
918 918 # in %who, as they can have very large reprs.
919 919 ns['In'] = self.input_hist
920 920 ns['Out'] = self.output_hist
921 921
922 922 # Store myself as the public api!!!
923 923 ns['get_ipython'] = self.get_ipython
924 924
925 925 # Sync what we've added so far to user_ns_hidden so these aren't seen
926 926 # by %who
927 927 self.user_ns_hidden.update(ns)
928 928
929 929 # Anything put into ns now would show up in %who. Think twice before
930 930 # putting anything here, as we really want %who to show the user their
931 931 # stuff, not our variables.
932 932
933 933 # Finally, update the real user's namespace
934 934 self.user_ns.update(ns)
935 935
936 936
937 937 def reset(self):
938 938 """Clear all internal namespaces.
939 939
940 940 Note that this is much more aggressive than %reset, since it clears
941 941 fully all namespaces, as well as all input/output lists.
942 942 """
943 943 for ns in self.ns_refs_table:
944 944 ns.clear()
945 945
946 946 self.alias_manager.clear_aliases()
947 947
948 948 # Clear input and output histories
949 949 self.input_hist[:] = []
950 950 self.input_hist_raw[:] = []
951 951 self.output_hist.clear()
952 952
953 953 # Restore the user namespaces to minimal usability
954 954 self.init_user_ns()
955 955
956 956 # Restore the default and user aliases
957 957 self.alias_manager.init_aliases()
958 958
959 959 def reset_selective(self, regex=None):
960 960 """Clear selective variables from internal namespaces based on a specified regular expression.
961 961
962 962 Parameters
963 963 ----------
964 964 regex : string or compiled pattern, optional
965 965 A regular expression pattern that will be used in searching variable names in the users
966 966 namespaces.
967 967 """
968 968 if regex is not None:
969 969 try:
970 970 m = re.compile(regex)
971 971 except TypeError:
972 972 raise TypeError('regex must be a string or compiled pattern')
973 973 # Search for keys in each namespace that match the given regex
974 974 # If a match is found, delete the key/value pair.
975 975 for ns in self.ns_refs_table:
976 976 for var in ns:
977 977 if m.search(var):
978 978 del ns[var]
979 979
980 980 def push(self, variables, interactive=True):
981 981 """Inject a group of variables into the IPython user namespace.
982 982
983 983 Parameters
984 984 ----------
985 985 variables : dict, str or list/tuple of str
986 986 The variables to inject into the user's namespace. If a dict,
987 987 a simple update is done. If a str, the string is assumed to
988 988 have variable names separated by spaces. A list/tuple of str
989 989 can also be used to give the variable names. If just the variable
990 990 names are give (list/tuple/str) then the variable values looked
991 991 up in the callers frame.
992 992 interactive : bool
993 993 If True (default), the variables will be listed with the ``who``
994 994 magic.
995 995 """
996 996 vdict = None
997 997
998 998 # We need a dict of name/value pairs to do namespace updates.
999 999 if isinstance(variables, dict):
1000 1000 vdict = variables
1001 1001 elif isinstance(variables, (basestring, list, tuple)):
1002 1002 if isinstance(variables, basestring):
1003 1003 vlist = variables.split()
1004 1004 else:
1005 1005 vlist = variables
1006 1006 vdict = {}
1007 1007 cf = sys._getframe(1)
1008 1008 for name in vlist:
1009 1009 try:
1010 1010 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1011 1011 except:
1012 1012 print ('Could not get variable %s from %s' %
1013 1013 (name,cf.f_code.co_name))
1014 1014 else:
1015 1015 raise ValueError('variables must be a dict/str/list/tuple')
1016 1016
1017 1017 # Propagate variables to user namespace
1018 1018 self.user_ns.update(vdict)
1019 1019
1020 1020 # And configure interactive visibility
1021 1021 config_ns = self.user_ns_hidden
1022 1022 if interactive:
1023 1023 for name, val in vdict.iteritems():
1024 1024 config_ns.pop(name, None)
1025 1025 else:
1026 1026 for name,val in vdict.iteritems():
1027 1027 config_ns[name] = val
1028 1028
1029 1029 #-------------------------------------------------------------------------
1030 1030 # Things related to history management
1031 1031 #-------------------------------------------------------------------------
1032 1032
1033 1033 def init_history(self):
1034 1034 # List of input with multi-line handling.
1035 1035 self.input_hist = InputList()
1036 1036 # This one will hold the 'raw' input history, without any
1037 1037 # pre-processing. This will allow users to retrieve the input just as
1038 1038 # it was exactly typed in by the user, with %hist -r.
1039 1039 self.input_hist_raw = InputList()
1040 1040
1041 1041 # list of visited directories
1042 1042 try:
1043 1043 self.dir_hist = [os.getcwd()]
1044 1044 except OSError:
1045 1045 self.dir_hist = []
1046 1046
1047 1047 # dict of output history
1048 1048 self.output_hist = {}
1049 1049
1050 1050 # Now the history file
1051 1051 if self.profile:
1052 1052 histfname = 'history-%s' % self.profile
1053 1053 else:
1054 1054 histfname = 'history'
1055 1055 self.histfile = os.path.join(self.ipython_dir, histfname)
1056 1056
1057 1057 # Fill the history zero entry, user counter starts at 1
1058 1058 self.input_hist.append('\n')
1059 1059 self.input_hist_raw.append('\n')
1060 1060
1061 1061 def init_shadow_hist(self):
1062 1062 try:
1063 1063 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1064 1064 except exceptions.UnicodeDecodeError:
1065 1065 print "Your ipython_dir can't be decoded to unicode!"
1066 1066 print "Please set HOME environment variable to something that"
1067 1067 print r"only has ASCII characters, e.g. c:\home"
1068 1068 print "Now it is", self.ipython_dir
1069 1069 sys.exit()
1070 1070 self.shadowhist = ipcorehist.ShadowHist(self.db)
1071 1071
1072 1072 def savehist(self):
1073 1073 """Save input history to a file (via readline library)."""
1074 1074
1075 1075 try:
1076 1076 self.readline.write_history_file(self.histfile)
1077 1077 except:
1078 1078 print 'Unable to save IPython command history to file: ' + \
1079 1079 `self.histfile`
1080 1080
1081 1081 def reloadhist(self):
1082 1082 """Reload the input history from disk file."""
1083 1083
1084 1084 try:
1085 1085 self.readline.clear_history()
1086 1086 self.readline.read_history_file(self.shell.histfile)
1087 1087 except AttributeError:
1088 1088 pass
1089 1089
1090 1090 def history_saving_wrapper(self, func):
1091 1091 """ Wrap func for readline history saving
1092 1092
1093 1093 Convert func into callable that saves & restores
1094 1094 history around the call """
1095 1095
1096 1096 if self.has_readline:
1097 1097 from IPython.utils import rlineimpl as readline
1098 1098 else:
1099 1099 return func
1100 1100
1101 1101 def wrapper():
1102 1102 self.savehist()
1103 1103 try:
1104 1104 func()
1105 1105 finally:
1106 1106 readline.read_history_file(self.histfile)
1107 1107 return wrapper
1108 1108
1109 1109 def get_history(self, index=None, raw=False, output=True):
1110 1110 """Get the history list.
1111 1111
1112 1112 Get the input and output history.
1113 1113
1114 1114 Parameters
1115 1115 ----------
1116 1116 index : n or (n1, n2) or None
1117 1117 If n, then the last entries. If a tuple, then all in
1118 1118 range(n1, n2). If None, then all entries. Raises IndexError if
1119 1119 the format of index is incorrect.
1120 1120 raw : bool
1121 1121 If True, return the raw input.
1122 1122 output : bool
1123 1123 If True, then return the output as well.
1124 1124
1125 1125 Returns
1126 1126 -------
1127 1127 If output is True, then return a dict of tuples, keyed by the prompt
1128 1128 numbers and with values of (input, output). If output is False, then
1129 1129 a dict, keyed by the prompt number with the values of input. Raises
1130 1130 IndexError if no history is found.
1131 1131 """
1132 1132 if raw:
1133 1133 input_hist = self.input_hist_raw
1134 1134 else:
1135 1135 input_hist = self.input_hist
1136 1136 if output:
1137 1137 output_hist = self.user_ns['Out']
1138 1138 n = len(input_hist)
1139 1139 if index is None:
1140 1140 start=0; stop=n
1141 1141 elif isinstance(index, int):
1142 1142 start=n-index; stop=n
1143 1143 elif isinstance(index, tuple) and len(index) == 2:
1144 1144 start=index[0]; stop=index[1]
1145 1145 else:
1146 1146 raise IndexError('Not a valid index for the input history: %r' % index)
1147 1147 hist = {}
1148 1148 for i in range(start, stop):
1149 1149 if output:
1150 1150 hist[i] = (input_hist[i], output_hist.get(i))
1151 1151 else:
1152 1152 hist[i] = input_hist[i]
1153 1153 if len(hist)==0:
1154 1154 raise IndexError('No history for range of indices: %r' % index)
1155 1155 return hist
1156 1156
1157 1157 #-------------------------------------------------------------------------
1158 1158 # Things related to exception handling and tracebacks (not debugging)
1159 1159 #-------------------------------------------------------------------------
1160 1160
1161 1161 def init_traceback_handlers(self, custom_exceptions):
1162 1162 # Syntax error handler.
1163 1163 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1164 1164
1165 1165 # The interactive one is initialized with an offset, meaning we always
1166 1166 # want to remove the topmost item in the traceback, which is our own
1167 1167 # internal code. Valid modes: ['Plain','Context','Verbose']
1168 1168 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1169 1169 color_scheme='NoColor',
1170 1170 tb_offset = 1)
1171 1171
1172 1172 # The instance will store a pointer to the system-wide exception hook,
1173 1173 # so that runtime code (such as magics) can access it. This is because
1174 1174 # during the read-eval loop, it may get temporarily overwritten.
1175 1175 self.sys_excepthook = sys.excepthook
1176 1176
1177 1177 # and add any custom exception handlers the user may have specified
1178 1178 self.set_custom_exc(*custom_exceptions)
1179 1179
1180 1180 # Set the exception mode
1181 1181 self.InteractiveTB.set_mode(mode=self.xmode)
1182 1182
1183 1183 def set_custom_exc(self, exc_tuple, handler):
1184 1184 """set_custom_exc(exc_tuple,handler)
1185 1185
1186 1186 Set a custom exception handler, which will be called if any of the
1187 1187 exceptions in exc_tuple occur in the mainloop (specifically, in the
1188 1188 runcode() method.
1189 1189
1190 1190 Inputs:
1191 1191
1192 1192 - exc_tuple: a *tuple* of valid exceptions to call the defined
1193 1193 handler for. It is very important that you use a tuple, and NOT A
1194 1194 LIST here, because of the way Python's except statement works. If
1195 1195 you only want to trap a single exception, use a singleton tuple:
1196 1196
1197 1197 exc_tuple == (MyCustomException,)
1198 1198
1199 1199 - handler: this must be defined as a function with the following
1200 1200 basic interface::
1201 1201
1202 1202 def my_handler(self, etype, value, tb, tb_offset=None)
1203 1203 ...
1204 1204 # The return value must be
1205 1205 return structured_traceback
1206 1206
1207 1207 This will be made into an instance method (via new.instancemethod)
1208 1208 of IPython itself, and it will be called if any of the exceptions
1209 1209 listed in the exc_tuple are caught. If the handler is None, an
1210 1210 internal basic one is used, which just prints basic info.
1211 1211
1212 1212 WARNING: by putting in your own exception handler into IPython's main
1213 1213 execution loop, you run a very good chance of nasty crashes. This
1214 1214 facility should only be used if you really know what you are doing."""
1215 1215
1216 1216 assert type(exc_tuple)==type(()) , \
1217 1217 "The custom exceptions must be given AS A TUPLE."
1218 1218
1219 1219 def dummy_handler(self,etype,value,tb):
1220 1220 print '*** Simple custom exception handler ***'
1221 1221 print 'Exception type :',etype
1222 1222 print 'Exception value:',value
1223 1223 print 'Traceback :',tb
1224 1224 print 'Source code :','\n'.join(self.buffer)
1225 1225
1226 1226 if handler is None: handler = dummy_handler
1227 1227
1228 1228 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1229 1229 self.custom_exceptions = exc_tuple
1230 1230
1231 1231 def excepthook(self, etype, value, tb):
1232 1232 """One more defense for GUI apps that call sys.excepthook.
1233 1233
1234 1234 GUI frameworks like wxPython trap exceptions and call
1235 1235 sys.excepthook themselves. I guess this is a feature that
1236 1236 enables them to keep running after exceptions that would
1237 1237 otherwise kill their mainloop. This is a bother for IPython
1238 1238 which excepts to catch all of the program exceptions with a try:
1239 1239 except: statement.
1240 1240
1241 1241 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1242 1242 any app directly invokes sys.excepthook, it will look to the user like
1243 1243 IPython crashed. In order to work around this, we can disable the
1244 1244 CrashHandler and replace it with this excepthook instead, which prints a
1245 1245 regular traceback using our InteractiveTB. In this fashion, apps which
1246 1246 call sys.excepthook will generate a regular-looking exception from
1247 1247 IPython, and the CrashHandler will only be triggered by real IPython
1248 1248 crashes.
1249 1249
1250 1250 This hook should be used sparingly, only in places which are not likely
1251 1251 to be true IPython errors.
1252 1252 """
1253 1253 self.showtraceback((etype,value,tb),tb_offset=0)
1254 1254
1255 1255 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1256 1256 exception_only=False):
1257 1257 """Display the exception that just occurred.
1258 1258
1259 1259 If nothing is known about the exception, this is the method which
1260 1260 should be used throughout the code for presenting user tracebacks,
1261 1261 rather than directly invoking the InteractiveTB object.
1262 1262
1263 1263 A specific showsyntaxerror() also exists, but this method can take
1264 1264 care of calling it if needed, so unless you are explicitly catching a
1265 1265 SyntaxError exception, don't try to analyze the stack manually and
1266 1266 simply call this method."""
1267 1267
1268 1268 try:
1269 1269 if exc_tuple is None:
1270 1270 etype, value, tb = sys.exc_info()
1271 1271 else:
1272 1272 etype, value, tb = exc_tuple
1273 1273
1274 1274 if etype is None:
1275 1275 if hasattr(sys, 'last_type'):
1276 1276 etype, value, tb = sys.last_type, sys.last_value, \
1277 1277 sys.last_traceback
1278 1278 else:
1279 1279 self.write_err('No traceback available to show.\n')
1280 1280 return
1281 1281
1282 1282 if etype is SyntaxError:
1283 1283 # Though this won't be called by syntax errors in the input
1284 1284 # line, there may be SyntaxError cases whith imported code.
1285 1285 self.showsyntaxerror(filename)
1286 1286 elif etype is UsageError:
1287 1287 print "UsageError:", value
1288 1288 else:
1289 1289 # WARNING: these variables are somewhat deprecated and not
1290 1290 # necessarily safe to use in a threaded environment, but tools
1291 1291 # like pdb depend on their existence, so let's set them. If we
1292 1292 # find problems in the field, we'll need to revisit their use.
1293 1293 sys.last_type = etype
1294 1294 sys.last_value = value
1295 1295 sys.last_traceback = tb
1296 1296
1297 1297 if etype in self.custom_exceptions:
1298 1298 # FIXME: Old custom traceback objects may just return a
1299 1299 # string, in that case we just put it into a list
1300 1300 stb = self.CustomTB(etype, value, tb, tb_offset)
1301 1301 if isinstance(ctb, basestring):
1302 1302 stb = [stb]
1303 1303 else:
1304 1304 if exception_only:
1305 1305 stb = ['An exception has occurred, use %tb to see '
1306 1306 'the full traceback.\n']
1307 1307 stb.extend(self.InteractiveTB.get_exception_only(etype,
1308 1308 value))
1309 1309 else:
1310 1310 stb = self.InteractiveTB.structured_traceback(etype,
1311 1311 value, tb, tb_offset=tb_offset)
1312 1312 # FIXME: the pdb calling should be done by us, not by
1313 1313 # the code computing the traceback.
1314 1314 if self.InteractiveTB.call_pdb:
1315 1315 # pdb mucks up readline, fix it back
1316 1316 self.set_completer()
1317 1317
1318 1318 # Actually show the traceback
1319 1319 self._showtraceback(etype, value, stb)
1320 1320
1321 1321 except KeyboardInterrupt:
1322 1322 self.write_err("\nKeyboardInterrupt\n")
1323 1323
1324 1324 def _showtraceback(self, etype, evalue, stb):
1325 1325 """Actually show a traceback.
1326 1326
1327 1327 Subclasses may override this method to put the traceback on a different
1328 1328 place, like a side channel.
1329 1329 """
1330 1330 # FIXME: this should use the proper write channels, but our test suite
1331 1331 # relies on it coming out of stdout...
1332 1332 print >> sys.stdout, self.InteractiveTB.stb2text(stb)
1333 1333
1334 1334 def showsyntaxerror(self, filename=None):
1335 1335 """Display the syntax error that just occurred.
1336 1336
1337 1337 This doesn't display a stack trace because there isn't one.
1338 1338
1339 1339 If a filename is given, it is stuffed in the exception instead
1340 1340 of what was there before (because Python's parser always uses
1341 1341 "<string>" when reading from a string).
1342 1342 """
1343 1343 etype, value, last_traceback = sys.exc_info()
1344 1344
1345 1345 # See note about these variables in showtraceback() above
1346 1346 sys.last_type = etype
1347 1347 sys.last_value = value
1348 1348 sys.last_traceback = last_traceback
1349 1349
1350 1350 if filename and etype is SyntaxError:
1351 1351 # Work hard to stuff the correct filename in the exception
1352 1352 try:
1353 1353 msg, (dummy_filename, lineno, offset, line) = value
1354 1354 except:
1355 1355 # Not the format we expect; leave it alone
1356 1356 pass
1357 1357 else:
1358 1358 # Stuff in the right filename
1359 1359 try:
1360 1360 # Assume SyntaxError is a class exception
1361 1361 value = SyntaxError(msg, (filename, lineno, offset, line))
1362 1362 except:
1363 1363 # If that failed, assume SyntaxError is a string
1364 1364 value = msg, (filename, lineno, offset, line)
1365 1365 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1366 1366 self._showtraceback(etype, value, stb)
1367 1367
1368 1368 #-------------------------------------------------------------------------
1369 1369 # Things related to tab completion
1370 1370 #-------------------------------------------------------------------------
1371 1371
1372 1372 def complete(self, text, line=None, cursor_pos=None):
1373 1373 """Return the completed text and a list of completions.
1374 1374
1375 1375 Parameters
1376 1376 ----------
1377 1377
1378 1378 text : string
1379 1379 A string of text to be completed on. It can be given as empty and
1380 1380 instead a line/position pair are given. In this case, the
1381 1381 completer itself will split the line like readline does.
1382 1382
1383 1383 line : string, optional
1384 1384 The complete line that text is part of.
1385 1385
1386 1386 cursor_pos : int, optional
1387 1387 The position of the cursor on the input line.
1388 1388
1389 1389 Returns
1390 1390 -------
1391 1391 text : string
1392 1392 The actual text that was completed.
1393 1393
1394 1394 matches : list
1395 1395 A sorted list with all possible completions.
1396 1396
1397 1397 The optional arguments allow the completion to take more context into
1398 1398 account, and are part of the low-level completion API.
1399 1399
1400 1400 This is a wrapper around the completion mechanism, similar to what
1401 1401 readline does at the command line when the TAB key is hit. By
1402 1402 exposing it as a method, it can be used by other non-readline
1403 1403 environments (such as GUIs) for text completion.
1404 1404
1405 1405 Simple usage example:
1406 1406
1407 1407 In [1]: x = 'hello'
1408 1408
1409 1409 In [2]: _ip.complete('x.l')
1410 1410 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1411 1411 """
1412 1412
1413 1413 # Inject names into __builtin__ so we can complete on the added names.
1414 1414 with self.builtin_trap:
1415 1415 return self.Completer.complete(text, line, cursor_pos)
1416 1416
1417 1417 def set_custom_completer(self, completer, pos=0):
1418 1418 """Adds a new custom completer function.
1419 1419
1420 1420 The position argument (defaults to 0) is the index in the completers
1421 1421 list where you want the completer to be inserted."""
1422 1422
1423 1423 newcomp = new.instancemethod(completer,self.Completer,
1424 1424 self.Completer.__class__)
1425 1425 self.Completer.matchers.insert(pos,newcomp)
1426 1426
1427 1427 def set_completer(self):
1428 1428 """Reset readline's completer to be our own."""
1429 1429 self.readline.set_completer(self.Completer.rlcomplete)
1430 1430
1431 1431 def set_completer_frame(self, frame=None):
1432 1432 """Set the frame of the completer."""
1433 1433 if frame:
1434 1434 self.Completer.namespace = frame.f_locals
1435 1435 self.Completer.global_namespace = frame.f_globals
1436 1436 else:
1437 1437 self.Completer.namespace = self.user_ns
1438 1438 self.Completer.global_namespace = self.user_global_ns
1439 1439
1440 1440 #-------------------------------------------------------------------------
1441 1441 # Things related to readline
1442 1442 #-------------------------------------------------------------------------
1443 1443
1444 1444 def init_readline(self):
1445 1445 """Command history completion/saving/reloading."""
1446 1446
1447 1447 if self.readline_use:
1448 1448 import IPython.utils.rlineimpl as readline
1449 1449
1450 1450 self.rl_next_input = None
1451 1451 self.rl_do_indent = False
1452 1452
1453 1453 if not self.readline_use or not readline.have_readline:
1454 1454 self.has_readline = False
1455 1455 self.readline = None
1456 1456 # Set a number of methods that depend on readline to be no-op
1457 1457 self.savehist = no_op
1458 1458 self.reloadhist = no_op
1459 1459 self.set_completer = no_op
1460 1460 self.set_custom_completer = no_op
1461 1461 self.set_completer_frame = no_op
1462 1462 warn('Readline services not available or not loaded.')
1463 1463 else:
1464 1464 self.has_readline = True
1465 1465 self.readline = readline
1466 1466 sys.modules['readline'] = readline
1467 1467 import atexit
1468 1468 from IPython.core.completer import IPCompleter
1469 1469 self.Completer = IPCompleter(self,
1470 1470 self.user_ns,
1471 1471 self.user_global_ns,
1472 1472 self.readline_omit__names,
1473 1473 self.alias_manager.alias_table)
1474 1474 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1475 1475 self.strdispatchers['complete_command'] = sdisp
1476 1476 self.Completer.custom_completers = sdisp
1477 1477 # Platform-specific configuration
1478 1478 if os.name == 'nt':
1479 1479 self.readline_startup_hook = readline.set_pre_input_hook
1480 1480 else:
1481 1481 self.readline_startup_hook = readline.set_startup_hook
1482 1482
1483 1483 # Load user's initrc file (readline config)
1484 1484 # Or if libedit is used, load editrc.
1485 1485 inputrc_name = os.environ.get('INPUTRC')
1486 1486 if inputrc_name is None:
1487 1487 home_dir = get_home_dir()
1488 1488 if home_dir is not None:
1489 1489 inputrc_name = '.inputrc'
1490 1490 if readline.uses_libedit:
1491 1491 inputrc_name = '.editrc'
1492 1492 inputrc_name = os.path.join(home_dir, inputrc_name)
1493 1493 if os.path.isfile(inputrc_name):
1494 1494 try:
1495 1495 readline.read_init_file(inputrc_name)
1496 1496 except:
1497 1497 warn('Problems reading readline initialization file <%s>'
1498 1498 % inputrc_name)
1499 1499
1500 1500 # save this in sys so embedded copies can restore it properly
1501 1501 sys.ipcompleter = self.Completer.rlcomplete
1502 1502 self.set_completer()
1503 1503
1504 1504 # Configure readline according to user's prefs
1505 1505 # This is only done if GNU readline is being used. If libedit
1506 1506 # is being used (as on Leopard) the readline config is
1507 1507 # not run as the syntax for libedit is different.
1508 1508 if not readline.uses_libedit:
1509 1509 for rlcommand in self.readline_parse_and_bind:
1510 1510 #print "loading rl:",rlcommand # dbg
1511 1511 readline.parse_and_bind(rlcommand)
1512 1512
1513 1513 # Remove some chars from the delimiters list. If we encounter
1514 1514 # unicode chars, discard them.
1515 1515 delims = readline.get_completer_delims().encode("ascii", "ignore")
1516 1516 delims = delims.translate(string._idmap,
1517 1517 self.readline_remove_delims)
1518 1518 readline.set_completer_delims(delims)
1519 1519 # otherwise we end up with a monster history after a while:
1520 1520 readline.set_history_length(1000)
1521 1521 try:
1522 1522 #print '*** Reading readline history' # dbg
1523 1523 readline.read_history_file(self.histfile)
1524 1524 except IOError:
1525 1525 pass # It doesn't exist yet.
1526 1526
1527 1527 atexit.register(self.atexit_operations)
1528 1528 del atexit
1529 1529
1530 1530 # Configure auto-indent for all platforms
1531 1531 self.set_autoindent(self.autoindent)
1532 1532
1533 1533 def set_next_input(self, s):
1534 1534 """ Sets the 'default' input string for the next command line.
1535 1535
1536 1536 Requires readline.
1537 1537
1538 1538 Example:
1539 1539
1540 1540 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1541 1541 [D:\ipython]|2> Hello Word_ # cursor is here
1542 1542 """
1543 1543
1544 1544 self.rl_next_input = s
1545 1545
1546 1546 # Maybe move this to the terminal subclass?
1547 1547 def pre_readline(self):
1548 1548 """readline hook to be used at the start of each line.
1549 1549
1550 1550 Currently it handles auto-indent only."""
1551 1551
1552 1552 if self.rl_do_indent:
1553 1553 self.readline.insert_text(self._indent_current_str())
1554 1554 if self.rl_next_input is not None:
1555 1555 self.readline.insert_text(self.rl_next_input)
1556 1556 self.rl_next_input = None
1557 1557
1558 1558 def _indent_current_str(self):
1559 1559 """return the current level of indentation as a string"""
1560 1560 return self.indent_current_nsp * ' '
1561 1561
1562 1562 #-------------------------------------------------------------------------
1563 1563 # Things related to magics
1564 1564 #-------------------------------------------------------------------------
1565 1565
1566 1566 def init_magics(self):
1567 1567 # FIXME: Move the color initialization to the DisplayHook, which
1568 1568 # should be split into a prompt manager and displayhook. We probably
1569 1569 # even need a centralize colors management object.
1570 1570 self.magic_colors(self.colors)
1571 1571 # History was moved to a separate module
1572 1572 from . import history
1573 1573 history.init_ipython(self)
1574 1574
1575 1575 def magic(self,arg_s):
1576 1576 """Call a magic function by name.
1577 1577
1578 1578 Input: a string containing the name of the magic function to call and any
1579 1579 additional arguments to be passed to the magic.
1580 1580
1581 1581 magic('name -opt foo bar') is equivalent to typing at the ipython
1582 1582 prompt:
1583 1583
1584 1584 In[1]: %name -opt foo bar
1585 1585
1586 1586 To call a magic without arguments, simply use magic('name').
1587 1587
1588 1588 This provides a proper Python function to call IPython's magics in any
1589 1589 valid Python code you can type at the interpreter, including loops and
1590 1590 compound statements.
1591 1591 """
1592 1592 args = arg_s.split(' ',1)
1593 1593 magic_name = args[0]
1594 1594 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1595 1595
1596 1596 try:
1597 1597 magic_args = args[1]
1598 1598 except IndexError:
1599 1599 magic_args = ''
1600 1600 fn = getattr(self,'magic_'+magic_name,None)
1601 1601 if fn is None:
1602 1602 error("Magic function `%s` not found." % magic_name)
1603 1603 else:
1604 1604 magic_args = self.var_expand(magic_args,1)
1605 1605 with nested(self.builtin_trap,):
1606 1606 result = fn(magic_args)
1607 1607 return result
1608 1608
1609 1609 def define_magic(self, magicname, func):
1610 1610 """Expose own function as magic function for ipython
1611 1611
1612 1612 def foo_impl(self,parameter_s=''):
1613 1613 'My very own magic!. (Use docstrings, IPython reads them).'
1614 1614 print 'Magic function. Passed parameter is between < >:'
1615 1615 print '<%s>' % parameter_s
1616 1616 print 'The self object is:',self
1617 1617
1618 1618 self.define_magic('foo',foo_impl)
1619 1619 """
1620 1620
1621 1621 import new
1622 1622 im = new.instancemethod(func,self, self.__class__)
1623 1623 old = getattr(self, "magic_" + magicname, None)
1624 1624 setattr(self, "magic_" + magicname, im)
1625 1625 return old
1626 1626
1627 1627 #-------------------------------------------------------------------------
1628 1628 # Things related to macros
1629 1629 #-------------------------------------------------------------------------
1630 1630
1631 1631 def define_macro(self, name, themacro):
1632 1632 """Define a new macro
1633 1633
1634 1634 Parameters
1635 1635 ----------
1636 1636 name : str
1637 1637 The name of the macro.
1638 1638 themacro : str or Macro
1639 1639 The action to do upon invoking the macro. If a string, a new
1640 1640 Macro object is created by passing the string to it.
1641 1641 """
1642 1642
1643 1643 from IPython.core import macro
1644 1644
1645 1645 if isinstance(themacro, basestring):
1646 1646 themacro = macro.Macro(themacro)
1647 1647 if not isinstance(themacro, macro.Macro):
1648 1648 raise ValueError('A macro must be a string or a Macro instance.')
1649 1649 self.user_ns[name] = themacro
1650 1650
1651 1651 #-------------------------------------------------------------------------
1652 1652 # Things related to the running of system commands
1653 1653 #-------------------------------------------------------------------------
1654 1654
1655 1655 def system(self, cmd):
1656 1656 """Make a system call, using IPython."""
1657 1657 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1658 1658
1659 1659 #-------------------------------------------------------------------------
1660 1660 # Things related to aliases
1661 1661 #-------------------------------------------------------------------------
1662 1662
1663 1663 def init_alias(self):
1664 1664 self.alias_manager = AliasManager(shell=self, config=self.config)
1665 1665 self.ns_table['alias'] = self.alias_manager.alias_table,
1666 1666
1667 1667 #-------------------------------------------------------------------------
1668 1668 # Things related to extensions and plugins
1669 1669 #-------------------------------------------------------------------------
1670 1670
1671 1671 def init_extension_manager(self):
1672 1672 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1673 1673
1674 1674 def init_plugin_manager(self):
1675 1675 self.plugin_manager = PluginManager(config=self.config)
1676 1676
1677 1677 #-------------------------------------------------------------------------
1678 1678 # Things related to payloads
1679 1679 #-------------------------------------------------------------------------
1680 1680
1681 1681 def init_payload(self):
1682 1682 self.payload_manager = PayloadManager(config=self.config)
1683 1683
1684 1684 #-------------------------------------------------------------------------
1685 1685 # Things related to the prefilter
1686 1686 #-------------------------------------------------------------------------
1687 1687
1688 1688 def init_prefilter(self):
1689 1689 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1690 1690 # Ultimately this will be refactored in the new interpreter code, but
1691 1691 # for now, we should expose the main prefilter method (there's legacy
1692 1692 # code out there that may rely on this).
1693 1693 self.prefilter = self.prefilter_manager.prefilter_lines
1694 1694
1695 1695 #-------------------------------------------------------------------------
1696 1696 # Things related to the running of code
1697 1697 #-------------------------------------------------------------------------
1698 1698
1699 1699 def ex(self, cmd):
1700 1700 """Execute a normal python statement in user namespace."""
1701 1701 with nested(self.builtin_trap,):
1702 1702 exec cmd in self.user_global_ns, self.user_ns
1703 1703
1704 1704 def ev(self, expr):
1705 1705 """Evaluate python expression expr in user namespace.
1706 1706
1707 1707 Returns the result of evaluation
1708 1708 """
1709 1709 with nested(self.builtin_trap,):
1710 1710 return eval(expr, self.user_global_ns, self.user_ns)
1711 1711
1712 1712 def safe_execfile(self, fname, *where, **kw):
1713 1713 """A safe version of the builtin execfile().
1714 1714
1715 1715 This version will never throw an exception, but instead print
1716 1716 helpful error messages to the screen. This only works on pure
1717 1717 Python files with the .py extension.
1718 1718
1719 1719 Parameters
1720 1720 ----------
1721 1721 fname : string
1722 1722 The name of the file to be executed.
1723 1723 where : tuple
1724 1724 One or two namespaces, passed to execfile() as (globals,locals).
1725 1725 If only one is given, it is passed as both.
1726 1726 exit_ignore : bool (False)
1727 1727 If True, then silence SystemExit for non-zero status (it is always
1728 1728 silenced for zero status, as it is so common).
1729 1729 """
1730 1730 kw.setdefault('exit_ignore', False)
1731 1731
1732 1732 fname = os.path.abspath(os.path.expanduser(fname))
1733 1733
1734 1734 # Make sure we have a .py file
1735 1735 if not fname.endswith('.py'):
1736 1736 warn('File must end with .py to be run using execfile: <%s>' % fname)
1737 1737
1738 1738 # Make sure we can open the file
1739 1739 try:
1740 1740 with open(fname) as thefile:
1741 1741 pass
1742 1742 except:
1743 1743 warn('Could not open file <%s> for safe execution.' % fname)
1744 1744 return
1745 1745
1746 1746 # Find things also in current directory. This is needed to mimic the
1747 1747 # behavior of running a script from the system command line, where
1748 1748 # Python inserts the script's directory into sys.path
1749 1749 dname = os.path.dirname(fname)
1750 1750
1751 1751 with prepended_to_syspath(dname):
1752 1752 try:
1753 1753 execfile(fname,*where)
1754 1754 except SystemExit, status:
1755 1755 # If the call was made with 0 or None exit status (sys.exit(0)
1756 1756 # or sys.exit() ), don't bother showing a traceback, as both of
1757 1757 # these are considered normal by the OS:
1758 1758 # > python -c'import sys;sys.exit(0)'; echo $?
1759 1759 # 0
1760 1760 # > python -c'import sys;sys.exit()'; echo $?
1761 1761 # 0
1762 1762 # For other exit status, we show the exception unless
1763 1763 # explicitly silenced, but only in short form.
1764 1764 if status.code not in (0, None) and not kw['exit_ignore']:
1765 1765 self.showtraceback(exception_only=True)
1766 1766 except:
1767 1767 self.showtraceback()
1768 1768
1769 1769 def safe_execfile_ipy(self, fname):
1770 1770 """Like safe_execfile, but for .ipy files with IPython syntax.
1771 1771
1772 1772 Parameters
1773 1773 ----------
1774 1774 fname : str
1775 1775 The name of the file to execute. The filename must have a
1776 1776 .ipy extension.
1777 1777 """
1778 1778 fname = os.path.abspath(os.path.expanduser(fname))
1779 1779
1780 1780 # Make sure we have a .py file
1781 1781 if not fname.endswith('.ipy'):
1782 1782 warn('File must end with .py to be run using execfile: <%s>' % fname)
1783 1783
1784 1784 # Make sure we can open the file
1785 1785 try:
1786 1786 with open(fname) as thefile:
1787 1787 pass
1788 1788 except:
1789 1789 warn('Could not open file <%s> for safe execution.' % fname)
1790 1790 return
1791 1791
1792 1792 # Find things also in current directory. This is needed to mimic the
1793 1793 # behavior of running a script from the system command line, where
1794 1794 # Python inserts the script's directory into sys.path
1795 1795 dname = os.path.dirname(fname)
1796 1796
1797 1797 with prepended_to_syspath(dname):
1798 1798 try:
1799 1799 with open(fname) as thefile:
1800 1800 script = thefile.read()
1801 1801 # self.runlines currently captures all exceptions
1802 1802 # raise in user code. It would be nice if there were
1803 1803 # versions of runlines, execfile that did raise, so
1804 1804 # we could catch the errors.
1805 1805 self.runlines(script, clean=True)
1806 1806 except:
1807 1807 self.showtraceback()
1808 1808 warn('Unknown failure executing file: <%s>' % fname)
1809 1809
1810 1810 def runlines(self, lines, clean=False):
1811 1811 """Run a string of one or more lines of source.
1812 1812
1813 1813 This method is capable of running a string containing multiple source
1814 1814 lines, as if they had been entered at the IPython prompt. Since it
1815 1815 exposes IPython's processing machinery, the given strings can contain
1816 1816 magic calls (%magic), special shell access (!cmd), etc.
1817 1817 """
1818 1818
1819 1819 if isinstance(lines, (list, tuple)):
1820 1820 lines = '\n'.join(lines)
1821 1821
1822 1822 if clean:
1823 1823 lines = self._cleanup_ipy_script(lines)
1824 1824
1825 1825 # We must start with a clean buffer, in case this is run from an
1826 1826 # interactive IPython session (via a magic, for example).
1827 1827 self.resetbuffer()
1828 1828 lines = lines.splitlines()
1829 1829 more = 0
1830 1830
1831 1831 with nested(self.builtin_trap, self.display_trap):
1832 1832 for line in lines:
1833 1833 # skip blank lines so we don't mess up the prompt counter, but do
1834 1834 # NOT skip even a blank line if we are in a code block (more is
1835 1835 # true)
1836 1836
1837 1837 if line or more:
1838 1838 # push to raw history, so hist line numbers stay in sync
1839 1839 self.input_hist_raw.append("# " + line + "\n")
1840 1840 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
1841 1841 more = self.push_line(prefiltered)
1842 1842 # IPython's runsource returns None if there was an error
1843 1843 # compiling the code. This allows us to stop processing right
1844 1844 # away, so the user gets the error message at the right place.
1845 1845 if more is None:
1846 1846 break
1847 1847 else:
1848 1848 self.input_hist_raw.append("\n")
1849 1849 # final newline in case the input didn't have it, so that the code
1850 1850 # actually does get executed
1851 1851 if more:
1852 1852 self.push_line('\n')
1853 1853
1854 1854 def runsource(self, source, filename='<input>', symbol='single'):
1855 1855 """Compile and run some source in the interpreter.
1856 1856
1857 1857 Arguments are as for compile_command().
1858 1858
1859 1859 One several things can happen:
1860 1860
1861 1861 1) The input is incorrect; compile_command() raised an
1862 1862 exception (SyntaxError or OverflowError). A syntax traceback
1863 1863 will be printed by calling the showsyntaxerror() method.
1864 1864
1865 1865 2) The input is incomplete, and more input is required;
1866 1866 compile_command() returned None. Nothing happens.
1867 1867
1868 1868 3) The input is complete; compile_command() returned a code
1869 1869 object. The code is executed by calling self.runcode() (which
1870 1870 also handles run-time exceptions, except for SystemExit).
1871 1871
1872 1872 The return value is:
1873 1873
1874 1874 - True in case 2
1875 1875
1876 1876 - False in the other cases, unless an exception is raised, where
1877 1877 None is returned instead. This can be used by external callers to
1878 1878 know whether to continue feeding input or not.
1879 1879
1880 1880 The return value can be used to decide whether to use sys.ps1 or
1881 1881 sys.ps2 to prompt the next line."""
1882 1882
1883 1883 # if the source code has leading blanks, add 'if 1:\n' to it
1884 1884 # this allows execution of indented pasted code. It is tempting
1885 1885 # to add '\n' at the end of source to run commands like ' a=1'
1886 1886 # directly, but this fails for more complicated scenarios
1887 1887 source=source.encode(self.stdin_encoding)
1888 1888 if source[:1] in [' ', '\t']:
1889 1889 source = 'if 1:\n%s' % source
1890 1890
1891 1891 try:
1892 1892 code = self.compile(source,filename,symbol)
1893 1893 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1894 1894 # Case 1
1895 1895 self.showsyntaxerror(filename)
1896 1896 return None
1897 1897
1898 1898 if code is None:
1899 1899 # Case 2
1900 1900 return True
1901 1901
1902 1902 # Case 3
1903 1903 # We store the code object so that threaded shells and
1904 1904 # custom exception handlers can access all this info if needed.
1905 1905 # The source corresponding to this can be obtained from the
1906 1906 # buffer attribute as '\n'.join(self.buffer).
1907 1907 self.code_to_run = code
1908 1908 # now actually execute the code object
1909 1909 if self.runcode(code) == 0:
1910 1910 return False
1911 1911 else:
1912 1912 return None
1913 1913
1914 1914 def runcode(self,code_obj):
1915 1915 """Execute a code object.
1916 1916
1917 1917 When an exception occurs, self.showtraceback() is called to display a
1918 1918 traceback.
1919 1919
1920 1920 Return value: a flag indicating whether the code to be run completed
1921 1921 successfully:
1922 1922
1923 1923 - 0: successful execution.
1924 1924 - 1: an error occurred.
1925 1925 """
1926 1926
1927 1927 # Set our own excepthook in case the user code tries to call it
1928 1928 # directly, so that the IPython crash handler doesn't get triggered
1929 1929 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1930 1930
1931 1931 # we save the original sys.excepthook in the instance, in case config
1932 1932 # code (such as magics) needs access to it.
1933 1933 self.sys_excepthook = old_excepthook
1934 1934 outflag = 1 # happens in more places, so it's easier as default
1935 1935 try:
1936 1936 try:
1937 1937 self.hooks.pre_runcode_hook()
1938 1938 #rprint('Running code') # dbg
1939 1939 exec code_obj in self.user_global_ns, self.user_ns
1940 1940 finally:
1941 1941 # Reset our crash handler in place
1942 1942 sys.excepthook = old_excepthook
1943 1943 except SystemExit:
1944 1944 self.resetbuffer()
1945 1945 self.showtraceback(exception_only=True)
1946 1946 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1947 1947 except self.custom_exceptions:
1948 1948 etype,value,tb = sys.exc_info()
1949 1949 self.CustomTB(etype,value,tb)
1950 1950 except:
1951 1951 self.showtraceback()
1952 1952 else:
1953 1953 outflag = 0
1954 1954 if softspace(sys.stdout, 0):
1955 1955 print
1956 1956 # Flush out code object which has been run (and source)
1957 1957 self.code_to_run = None
1958 1958 return outflag
1959 1959
1960 1960 def push_line(self, line):
1961 1961 """Push a line to the interpreter.
1962 1962
1963 1963 The line should not have a trailing newline; it may have
1964 1964 internal newlines. The line is appended to a buffer and the
1965 1965 interpreter's runsource() method is called with the
1966 1966 concatenated contents of the buffer as source. If this
1967 1967 indicates that the command was executed or invalid, the buffer
1968 1968 is reset; otherwise, the command is incomplete, and the buffer
1969 1969 is left as it was after the line was appended. The return
1970 1970 value is 1 if more input is required, 0 if the line was dealt
1971 1971 with in some way (this is the same as runsource()).
1972 1972 """
1973 1973
1974 1974 # autoindent management should be done here, and not in the
1975 1975 # interactive loop, since that one is only seen by keyboard input. We
1976 1976 # need this done correctly even for code run via runlines (which uses
1977 1977 # push).
1978 1978
1979 1979 #print 'push line: <%s>' % line # dbg
1980 1980 for subline in line.splitlines():
1981 1981 self._autoindent_update(subline)
1982 1982 self.buffer.append(line)
1983 1983 more = self.runsource('\n'.join(self.buffer), self.filename)
1984 1984 if not more:
1985 1985 self.resetbuffer()
1986 1986 return more
1987 1987
1988 1988 def resetbuffer(self):
1989 1989 """Reset the input buffer."""
1990 1990 self.buffer[:] = []
1991 1991
1992 1992 def _is_secondary_block_start(self, s):
1993 1993 if not s.endswith(':'):
1994 1994 return False
1995 1995 if (s.startswith('elif') or
1996 1996 s.startswith('else') or
1997 1997 s.startswith('except') or
1998 1998 s.startswith('finally')):
1999 1999 return True
2000 2000
2001 2001 def _cleanup_ipy_script(self, script):
2002 2002 """Make a script safe for self.runlines()
2003 2003
2004 2004 Currently, IPython is lines based, with blocks being detected by
2005 2005 empty lines. This is a problem for block based scripts that may
2006 2006 not have empty lines after blocks. This script adds those empty
2007 2007 lines to make scripts safe for running in the current line based
2008 2008 IPython.
2009 2009 """
2010 2010 res = []
2011 2011 lines = script.splitlines()
2012 2012 level = 0
2013 2013
2014 2014 for l in lines:
2015 2015 lstripped = l.lstrip()
2016 2016 stripped = l.strip()
2017 2017 if not stripped:
2018 2018 continue
2019 2019 newlevel = len(l) - len(lstripped)
2020 2020 if level > 0 and newlevel == 0 and \
2021 2021 not self._is_secondary_block_start(stripped):
2022 2022 # add empty line
2023 2023 res.append('')
2024 2024 res.append(l)
2025 2025 level = newlevel
2026 2026
2027 2027 return '\n'.join(res) + '\n'
2028 2028
2029 2029 def _autoindent_update(self,line):
2030 2030 """Keep track of the indent level."""
2031 2031
2032 2032 #debugx('line')
2033 2033 #debugx('self.indent_current_nsp')
2034 2034 if self.autoindent:
2035 2035 if line:
2036 2036 inisp = num_ini_spaces(line)
2037 2037 if inisp < self.indent_current_nsp:
2038 2038 self.indent_current_nsp = inisp
2039 2039
2040 2040 if line[-1] == ':':
2041 2041 self.indent_current_nsp += 4
2042 2042 elif dedent_re.match(line):
2043 2043 self.indent_current_nsp -= 4
2044 2044 else:
2045 2045 self.indent_current_nsp = 0
2046 2046
2047 2047 #-------------------------------------------------------------------------
2048 2048 # Things related to GUI support and pylab
2049 2049 #-------------------------------------------------------------------------
2050 2050
2051 2051 def enable_pylab(self, gui=None):
2052 2052 raise NotImplementedError('Implement enable_pylab in a subclass')
2053 2053
2054 2054 #-------------------------------------------------------------------------
2055 2055 # Utilities
2056 2056 #-------------------------------------------------------------------------
2057 2057
2058 2058 def getoutput(self, cmd):
2059 2059 return getoutput(self.var_expand(cmd,depth=2),
2060 2060 header=self.system_header,
2061 2061 verbose=self.system_verbose)
2062 2062
2063 2063 def getoutputerror(self, cmd):
2064 2064 return getoutputerror(self.var_expand(cmd,depth=2),
2065 2065 header=self.system_header,
2066 2066 verbose=self.system_verbose)
2067 2067
2068 2068 def var_expand(self,cmd,depth=0):
2069 2069 """Expand python variables in a string.
2070 2070
2071 2071 The depth argument indicates how many frames above the caller should
2072 2072 be walked to look for the local namespace where to expand variables.
2073 2073
2074 2074 The global namespace for expansion is always the user's interactive
2075 2075 namespace.
2076 2076 """
2077 2077
2078 2078 return str(ItplNS(cmd,
2079 2079 self.user_ns, # globals
2080 2080 # Skip our own frame in searching for locals:
2081 2081 sys._getframe(depth+1).f_locals # locals
2082 2082 ))
2083 2083
2084 2084 def mktempfile(self,data=None):
2085 2085 """Make a new tempfile and return its filename.
2086 2086
2087 2087 This makes a call to tempfile.mktemp, but it registers the created
2088 2088 filename internally so ipython cleans it up at exit time.
2089 2089
2090 2090 Optional inputs:
2091 2091
2092 2092 - data(None): if data is given, it gets written out to the temp file
2093 2093 immediately, and the file is closed again."""
2094 2094
2095 2095 filename = tempfile.mktemp('.py','ipython_edit_')
2096 2096 self.tempfiles.append(filename)
2097 2097
2098 2098 if data:
2099 2099 tmp_file = open(filename,'w')
2100 2100 tmp_file.write(data)
2101 2101 tmp_file.close()
2102 2102 return filename
2103 2103
2104 2104 # TODO: This should be removed when Term is refactored.
2105 2105 def write(self,data):
2106 2106 """Write a string to the default output"""
2107 2107 io.Term.cout.write(data)
2108 2108
2109 2109 # TODO: This should be removed when Term is refactored.
2110 2110 def write_err(self,data):
2111 2111 """Write a string to the default error output"""
2112 2112 io.Term.cerr.write(data)
2113 2113
2114 2114 def ask_yes_no(self,prompt,default=True):
2115 2115 if self.quiet:
2116 2116 return True
2117 2117 return ask_yes_no(prompt,default)
2118 2118
2119 2119 #-------------------------------------------------------------------------
2120 2120 # Things related to IPython exiting
2121 2121 #-------------------------------------------------------------------------
2122 2122
2123 2123 def atexit_operations(self):
2124 2124 """This will be executed at the time of exit.
2125 2125
2126 2126 Saving of persistent data should be performed here.
2127 2127 """
2128 2128 self.savehist()
2129 2129
2130 2130 # Cleanup all tempfiles left around
2131 2131 for tfile in self.tempfiles:
2132 2132 try:
2133 2133 os.unlink(tfile)
2134 2134 except OSError:
2135 2135 pass
2136 2136
2137 2137 # Clear all user namespaces to release all references cleanly.
2138 2138 self.reset()
2139 2139
2140 2140 # Run user hooks
2141 2141 self.hooks.shutdown_hook()
2142 2142
2143 2143 def cleanup(self):
2144 2144 self.restore_sys_module_state()
2145 2145
2146 2146
2147 2147 class InteractiveShellABC(object):
2148 2148 """An abstract base class for InteractiveShell."""
2149 2149 __metaclass__ = abc.ABCMeta
2150 2150
2151 2151 InteractiveShellABC.register(InteractiveShell)
@@ -1,1224 +1,1224 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 ultratb.py -- Spice up your tracebacks!
4 4
5 5 * ColorTB
6 6 I've always found it a bit hard to visually parse tracebacks in Python. The
7 7 ColorTB class is a solution to that problem. It colors the different parts of a
8 8 traceback in a manner similar to what you would expect from a syntax-highlighting
9 9 text editor.
10 10
11 11 Installation instructions for ColorTB:
12 12 import sys,ultratb
13 13 sys.excepthook = ultratb.ColorTB()
14 14
15 15 * VerboseTB
16 16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
17 17 of useful info when a traceback occurs. Ping originally had it spit out HTML
18 18 and intended it for CGI programmers, but why should they have all the fun? I
19 19 altered it to spit out colored text to the terminal. It's a bit overwhelming,
20 20 but kind of neat, and maybe useful for long-running programs that you believe
21 21 are bug-free. If a crash *does* occur in that type of program you want details.
22 22 Give it a shot--you'll love it or you'll hate it.
23 23
24 24 Note:
25 25
26 26 The Verbose mode prints the variables currently visible where the exception
27 27 happened (shortening their strings if too long). This can potentially be
28 28 very slow, if you happen to have a huge data structure whose string
29 29 representation is complex to compute. Your computer may appear to freeze for
30 30 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
31 31 with Ctrl-C (maybe hitting it more than once).
32 32
33 33 If you encounter this kind of situation often, you may want to use the
34 34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
35 35 variables (but otherwise includes the information and context given by
36 36 Verbose).
37 37
38 38
39 39 Installation instructions for ColorTB:
40 40 import sys,ultratb
41 41 sys.excepthook = ultratb.VerboseTB()
42 42
43 43 Note: Much of the code in this module was lifted verbatim from the standard
44 44 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
45 45
46 46 * Color schemes
47 47 The colors are defined in the class TBTools through the use of the
48 48 ColorSchemeTable class. Currently the following exist:
49 49
50 50 - NoColor: allows all of this module to be used in any terminal (the color
51 51 escapes are just dummy blank strings).
52 52
53 53 - Linux: is meant to look good in a terminal like the Linux console (black
54 54 or very dark background).
55 55
56 56 - LightBG: similar to Linux but swaps dark/light colors to be more readable
57 57 in light background terminals.
58 58
59 59 You can implement other color schemes easily, the syntax is fairly
60 60 self-explanatory. Please send back new schemes you develop to the author for
61 61 possible inclusion in future releases.
62 62 """
63 63
64 64 #*****************************************************************************
65 65 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
66 66 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
67 67 #
68 68 # Distributed under the terms of the BSD License. The full license is in
69 69 # the file COPYING, distributed as part of this software.
70 70 #*****************************************************************************
71 71
72 72 from __future__ import with_statement
73 73
74 74 import inspect
75 75 import keyword
76 76 import linecache
77 77 import os
78 78 import pydoc
79 79 import re
80 80 import string
81 81 import sys
82 82 import time
83 83 import tokenize
84 84 import traceback
85 85 import types
86 86
87 87 # For purposes of monkeypatching inspect to fix a bug in it.
88 88 from inspect import getsourcefile, getfile, getmodule,\
89 89 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
90 90
91 91 # IPython's own modules
92 92 # Modified pdb which doesn't damage IPython's readline handling
93 93 from IPython.core import debugger, ipapi
94 94 from IPython.core.display_trap import DisplayTrap
95 95 from IPython.core.excolors import exception_colors
96 96 from IPython.utils import PyColorize
97 97 from IPython.utils import io
98 98 from IPython.utils.data import uniq_stable
99 99 from IPython.utils.warn import info, error
100 100
101 101 # Globals
102 102 # amount of space to put line numbers before verbose tracebacks
103 103 INDENT_SIZE = 8
104 104
105 105 # Default color scheme. This is used, for example, by the traceback
106 106 # formatter. When running in an actual IPython instance, the user's rc.colors
107 107 # value is used, but havinga module global makes this functionality available
108 108 # to users of ultratb who are NOT running inside ipython.
109 109 DEFAULT_SCHEME = 'NoColor'
110 110
111 111 #---------------------------------------------------------------------------
112 112 # Code begins
113 113
114 114 # Utility functions
115 115 def inspect_error():
116 116 """Print a message about internal inspect errors.
117 117
118 118 These are unfortunately quite common."""
119 119
120 120 error('Internal Python error in the inspect module.\n'
121 121 'Below is the traceback from this internal error.\n')
122 122
123 123
124 124 def findsource(object):
125 125 """Return the entire source file and starting line number for an object.
126 126
127 127 The argument may be a module, class, method, function, traceback, frame,
128 128 or code object. The source code is returned as a list of all the lines
129 129 in the file and the line number indexes a line in that list. An IOError
130 130 is raised if the source code cannot be retrieved.
131 131
132 132 FIXED version with which we monkeypatch the stdlib to work around a bug."""
133 133
134 134 file = getsourcefile(object) or getfile(object)
135 135 # If the object is a frame, then trying to get the globals dict from its
136 136 # module won't work. Instead, the frame object itself has the globals
137 137 # dictionary.
138 138 globals_dict = None
139 139 if inspect.isframe(object):
140 140 # XXX: can this ever be false?
141 141 globals_dict = object.f_globals
142 142 else:
143 143 module = getmodule(object, file)
144 144 if module:
145 145 globals_dict = module.__dict__
146 146 lines = linecache.getlines(file, globals_dict)
147 147 if not lines:
148 148 raise IOError('could not get source code')
149 149
150 150 if ismodule(object):
151 151 return lines, 0
152 152
153 153 if isclass(object):
154 154 name = object.__name__
155 155 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
156 156 # make some effort to find the best matching class definition:
157 157 # use the one with the least indentation, which is the one
158 158 # that's most probably not inside a function definition.
159 159 candidates = []
160 160 for i in range(len(lines)):
161 161 match = pat.match(lines[i])
162 162 if match:
163 163 # if it's at toplevel, it's already the best one
164 164 if lines[i][0] == 'c':
165 165 return lines, i
166 166 # else add whitespace to candidate list
167 167 candidates.append((match.group(1), i))
168 168 if candidates:
169 169 # this will sort by whitespace, and by line number,
170 170 # less whitespace first
171 171 candidates.sort()
172 172 return lines, candidates[0][1]
173 173 else:
174 174 raise IOError('could not find class definition')
175 175
176 176 if ismethod(object):
177 177 object = object.im_func
178 178 if isfunction(object):
179 179 object = object.func_code
180 180 if istraceback(object):
181 181 object = object.tb_frame
182 182 if isframe(object):
183 183 object = object.f_code
184 184 if iscode(object):
185 185 if not hasattr(object, 'co_firstlineno'):
186 186 raise IOError('could not find function definition')
187 187 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
188 188 pmatch = pat.match
189 189 # fperez - fix: sometimes, co_firstlineno can give a number larger than
190 190 # the length of lines, which causes an error. Safeguard against that.
191 191 lnum = min(object.co_firstlineno,len(lines))-1
192 192 while lnum > 0:
193 193 if pmatch(lines[lnum]): break
194 194 lnum -= 1
195 195
196 196 return lines, lnum
197 197 raise IOError('could not find code object')
198 198
199 199 # Monkeypatch inspect to apply our bugfix. This code only works with py25
200 200 if sys.version_info[:2] >= (2,5):
201 201 inspect.findsource = findsource
202 202
203 203 def fix_frame_records_filenames(records):
204 204 """Try to fix the filenames in each record from inspect.getinnerframes().
205 205
206 206 Particularly, modules loaded from within zip files have useless filenames
207 207 attached to their code object, and inspect.getinnerframes() just uses it.
208 208 """
209 209 fixed_records = []
210 210 for frame, filename, line_no, func_name, lines, index in records:
211 211 # Look inside the frame's globals dictionary for __file__, which should
212 212 # be better.
213 213 better_fn = frame.f_globals.get('__file__', None)
214 214 if isinstance(better_fn, str):
215 215 # Check the type just in case someone did something weird with
216 216 # __file__. It might also be None if the error occurred during
217 217 # import.
218 218 filename = better_fn
219 219 fixed_records.append((frame, filename, line_no, func_name, lines, index))
220 220 return fixed_records
221 221
222 222
223 223 def _fixed_getinnerframes(etb, context=1,tb_offset=0):
224 224 import linecache
225 225 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
226 226
227 227 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
228 228
229 229 # If the error is at the console, don't build any context, since it would
230 230 # otherwise produce 5 blank lines printed out (there is no file at the
231 231 # console)
232 232 rec_check = records[tb_offset:]
233 233 try:
234 234 rname = rec_check[0][1]
235 235 if rname == '<ipython console>' or rname.endswith('<string>'):
236 236 return rec_check
237 237 except IndexError:
238 238 pass
239 239
240 240 aux = traceback.extract_tb(etb)
241 241 assert len(records) == len(aux)
242 242 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
243 243 maybeStart = lnum-1 - context//2
244 244 start = max(maybeStart, 0)
245 245 end = start + context
246 246 lines = linecache.getlines(file)[start:end]
247 247 # pad with empty lines if necessary
248 248 if maybeStart < 0:
249 249 lines = (['\n'] * -maybeStart) + lines
250 250 if len(lines) < context:
251 251 lines += ['\n'] * (context - len(lines))
252 252 buf = list(records[i])
253 253 buf[LNUM_POS] = lnum
254 254 buf[INDEX_POS] = lnum - 1 - start
255 255 buf[LINES_POS] = lines
256 256 records[i] = tuple(buf)
257 257 return records[tb_offset:]
258 258
259 259 # Helper function -- largely belongs to VerboseTB, but we need the same
260 260 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
261 261 # can be recognized properly by ipython.el's py-traceback-line-re
262 262 # (SyntaxErrors have to be treated specially because they have no traceback)
263 263
264 264 _parser = PyColorize.Parser()
265 265
266 266 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):
267 267 numbers_width = INDENT_SIZE - 1
268 268 res = []
269 269 i = lnum - index
270 270
271 271 # This lets us get fully syntax-highlighted tracebacks.
272 272 if scheme is None:
273 273 ipinst = ipapi.get()
274 274 if ipinst is not None:
275 275 scheme = ipinst.colors
276 276 else:
277 277 scheme = DEFAULT_SCHEME
278 278
279 279 _line_format = _parser.format2
280 280
281 281 for line in lines:
282 282 new_line, err = _line_format(line,'str',scheme)
283 283 if not err: line = new_line
284 284
285 285 if i == lnum:
286 286 # This is the line with the error
287 287 pad = numbers_width - len(str(i))
288 288 if pad >= 3:
289 289 marker = '-'*(pad-3) + '-> '
290 290 elif pad == 2:
291 291 marker = '> '
292 292 elif pad == 1:
293 293 marker = '>'
294 294 else:
295 295 marker = ''
296 296 num = marker + str(i)
297 297 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
298 298 Colors.line, line, Colors.Normal)
299 299 else:
300 300 num = '%*s' % (numbers_width,i)
301 301 line = '%s%s%s %s' %(Colors.lineno, num,
302 302 Colors.Normal, line)
303 303
304 304 res.append(line)
305 305 if lvals and i == lnum:
306 306 res.append(lvals + '\n')
307 307 i = i + 1
308 308 return res
309 309
310 310
311 311 #---------------------------------------------------------------------------
312 312 # Module classes
313 313 class TBTools(object):
314 314 """Basic tools used by all traceback printer classes."""
315 315
316 316 # Number of frames to skip when reporting tracebacks
317 317 tb_offset = 0
318 318
319 319 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
320 320 # Whether to call the interactive pdb debugger after printing
321 321 # tracebacks or not
322 322 self.call_pdb = call_pdb
323 323
324 324 # Output stream to write to. Note that we store the original value in
325 325 # a private attribute and then make the public ostream a property, so
326 326 # that we can delay accessing io.Term.cout until runtime. The way
327 327 # things are written now, the Term.cout object is dynamically managed
328 328 # so a reference to it should NEVER be stored statically. This
329 329 # property approach confines this detail to a single location, and all
330 330 # subclasses can simply access self.ostream for writing.
331 331 self._ostream = ostream
332 332
333 333 # Create color table
334 334 self.color_scheme_table = exception_colors()
335 335
336 336 self.set_colors(color_scheme)
337 337 self.old_scheme = color_scheme # save initial value for toggles
338 338
339 339 if call_pdb:
340 340 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
341 341 else:
342 342 self.pdb = None
343 343
344 344 def _get_ostream(self):
345 345 """Output stream that exceptions are written to.
346 346
347 347 Valid values are:
348 348
349 349 - None: the default, which means that IPython will dynamically resolve
350 350 to io.Term.cout. This ensures compatibility with most tools, including
351 351 Windows (where plain stdout doesn't recognize ANSI escapes).
352 352
353 353 - Any object with 'write' and 'flush' attributes.
354 354 """
355 355 return io.Term.cout if self._ostream is None else self._ostream
356 356
357 357 def _set_ostream(self, val):
358 358 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
359 359 self._ostream = val
360 360
361 361 ostream = property(_get_ostream, _set_ostream)
362 362
363 363 def set_colors(self,*args,**kw):
364 364 """Shorthand access to the color table scheme selector method."""
365 365
366 366 # Set own color table
367 367 self.color_scheme_table.set_active_scheme(*args,**kw)
368 368 # for convenience, set Colors to the active scheme
369 369 self.Colors = self.color_scheme_table.active_colors
370 370 # Also set colors of debugger
371 371 if hasattr(self,'pdb') and self.pdb is not None:
372 372 self.pdb.set_colors(*args,**kw)
373 373
374 374 def color_toggle(self):
375 375 """Toggle between the currently active color scheme and NoColor."""
376 376
377 377 if self.color_scheme_table.active_scheme_name == 'NoColor':
378 378 self.color_scheme_table.set_active_scheme(self.old_scheme)
379 379 self.Colors = self.color_scheme_table.active_colors
380 380 else:
381 381 self.old_scheme = self.color_scheme_table.active_scheme_name
382 382 self.color_scheme_table.set_active_scheme('NoColor')
383 383 self.Colors = self.color_scheme_table.active_colors
384 384
385 385 def stb2text(self, stb):
386 386 """Convert a structured traceback (a list) to a string."""
387 387 return '\n'.join(stb)
388 388
389 389 def text(self, etype, value, tb, tb_offset=None, context=5):
390 390 """Return formatted traceback.
391 391
392 392 Subclasses may override this if they add extra arguments.
393 393 """
394 394 tb_list = self.structured_traceback(etype, value, tb,
395 395 tb_offset, context)
396 396 return self.stb2text(tb_list)
397 397
398 398 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
399 399 context=5, mode=None):
400 400 """Return a list of traceback frames.
401 401
402 402 Must be implemented by each class.
403 403 """
404 404 raise NotImplementedError()
405 405
406 406
407 407 #---------------------------------------------------------------------------
408 408 class ListTB(TBTools):
409 409 """Print traceback information from a traceback list, with optional color.
410 410
411 411 Calling: requires 3 arguments:
412 412 (etype, evalue, elist)
413 413 as would be obtained by:
414 414 etype, evalue, tb = sys.exc_info()
415 415 if tb:
416 416 elist = traceback.extract_tb(tb)
417 417 else:
418 418 elist = None
419 419
420 420 It can thus be used by programs which need to process the traceback before
421 421 printing (such as console replacements based on the code module from the
422 422 standard library).
423 423
424 424 Because they are meant to be called without a full traceback (only a
425 425 list), instances of this class can't call the interactive pdb debugger."""
426 426
427 427 def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None):
428 428 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
429 429 ostream=ostream)
430 430
431 431 def __call__(self, etype, value, elist):
432 432 self.ostream.flush()
433 433 self.ostream.write(self.text(etype, value, elist))
434 434 self.ostream.write('\n')
435 435
436 436 def structured_traceback(self, etype, value, elist, tb_offset=None,
437 437 context=5):
438 438 """Return a color formatted string with the traceback info.
439 439
440 440 Parameters
441 441 ----------
442 442 etype : exception type
443 443 Type of the exception raised.
444 444
445 445 value : object
446 446 Data stored in the exception
447 447
448 448 elist : list
449 449 List of frames, see class docstring for details.
450 450
451 451 tb_offset : int, optional
452 452 Number of frames in the traceback to skip. If not given, the
453 453 instance value is used (set in constructor).
454 454
455 455 context : int, optional
456 456 Number of lines of context information to print.
457 457
458 458 Returns
459 459 -------
460 460 String with formatted exception.
461 461 """
462 462 tb_offset = self.tb_offset if tb_offset is None else tb_offset
463 463 Colors = self.Colors
464 464 out_list = []
465 465 if elist:
466 466
467 467 if tb_offset and len(elist) > tb_offset:
468 468 elist = elist[tb_offset:]
469 469
470 470 out_list.append('Traceback %s(most recent call last)%s:' %
471 471 (Colors.normalEm, Colors.Normal) + '\n')
472 472 out_list.extend(self._format_list(elist))
473 473 # The exception info should be a single entry in the list.
474 474 lines = ''.join(self._format_exception_only(etype, value))
475 475 out_list.append(lines)
476 476
477 477 # Note: this code originally read:
478 478
479 479 ## for line in lines[:-1]:
480 480 ## out_list.append(" "+line)
481 481 ## out_list.append(lines[-1])
482 482
483 483 # This means it was indenting everything but the last line by a little
484 484 # bit. I've disabled this for now, but if we see ugliness somewhre we
485 485 # can restore it.
486 486
487 487 return out_list
488 488
489 489 def _format_list(self, extracted_list):
490 490 """Format a list of traceback entry tuples for printing.
491 491
492 492 Given a list of tuples as returned by extract_tb() or
493 493 extract_stack(), return a list of strings ready for printing.
494 494 Each string in the resulting list corresponds to the item with the
495 495 same index in the argument list. Each string ends in a newline;
496 496 the strings may contain internal newlines as well, for those items
497 497 whose source text line is not None.
498 498
499 499 Lifted almost verbatim from traceback.py
500 500 """
501 501
502 502 Colors = self.Colors
503 503 list = []
504 504 for filename, lineno, name, line in extracted_list[:-1]:
505 505 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
506 506 (Colors.filename, filename, Colors.Normal,
507 507 Colors.lineno, lineno, Colors.Normal,
508 508 Colors.name, name, Colors.Normal)
509 509 if line:
510 510 item = item + ' %s\n' % line.strip()
511 511 list.append(item)
512 512 # Emphasize the last entry
513 513 filename, lineno, name, line = extracted_list[-1]
514 514 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
515 515 (Colors.normalEm,
516 516 Colors.filenameEm, filename, Colors.normalEm,
517 517 Colors.linenoEm, lineno, Colors.normalEm,
518 518 Colors.nameEm, name, Colors.normalEm,
519 519 Colors.Normal)
520 520 if line:
521 521 item = item + '%s %s%s\n' % (Colors.line, line.strip(),
522 522 Colors.Normal)
523 523 list.append(item)
524 524 #from pprint import pformat; print 'LISTTB', pformat(list) # dbg
525 525 return list
526 526
527 527 def _format_exception_only(self, etype, value):
528 528 """Format the exception part of a traceback.
529 529
530 530 The arguments are the exception type and value such as given by
531 531 sys.exc_info()[:2]. The return value is a list of strings, each ending
532 532 in a newline. Normally, the list contains a single string; however,
533 533 for SyntaxError exceptions, it contains several lines that (when
534 534 printed) display detailed information about where the syntax error
535 535 occurred. The message indicating which exception occurred is the
536 536 always last string in the list.
537 537
538 538 Also lifted nearly verbatim from traceback.py
539 539 """
540 540
541 541 have_filedata = False
542 542 Colors = self.Colors
543 543 list = []
544 544 try:
545 545 stype = Colors.excName + etype.__name__ + Colors.Normal
546 546 except AttributeError:
547 547 stype = etype # String exceptions don't get special coloring
548 548 if value is None:
549 549 list.append( str(stype) + '\n')
550 550 else:
551 551 if etype is SyntaxError:
552 552 try:
553 553 msg, (filename, lineno, offset, line) = value
554 554 except:
555 555 have_filedata = False
556 556 else:
557 557 have_filedata = True
558 558 #print 'filename is',filename # dbg
559 559 if not filename: filename = "<string>"
560 560 list.append('%s File %s"%s"%s, line %s%d%s\n' % \
561 561 (Colors.normalEm,
562 562 Colors.filenameEm, filename, Colors.normalEm,
563 563 Colors.linenoEm, lineno, Colors.Normal ))
564 564 if line is not None:
565 565 i = 0
566 566 while i < len(line) and line[i].isspace():
567 567 i = i+1
568 568 list.append('%s %s%s\n' % (Colors.line,
569 569 line.strip(),
570 570 Colors.Normal))
571 571 if offset is not None:
572 572 s = ' '
573 573 for c in line[i:offset-1]:
574 574 if c.isspace():
575 575 s = s + c
576 576 else:
577 577 s = s + ' '
578 578 list.append('%s%s^%s\n' % (Colors.caret, s,
579 579 Colors.Normal) )
580 580 value = msg
581 581 s = self._some_str(value)
582 582 if s:
583 583 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
584 584 Colors.Normal, s))
585 585 else:
586 586 list.append('%s\n' % str(stype))
587 587
588 588 # sync with user hooks
589 589 if have_filedata:
590 590 ipinst = ipapi.get()
591 591 if ipinst is not None:
592 592 ipinst.hooks.synchronize_with_editor(filename, lineno, 0)
593 593
594 594 return list
595 595
596 596 def get_exception_only(self, etype, value):
597 597 """Only print the exception type and message, without a traceback.
598 598
599 599 Parameters
600 600 ----------
601 601 etype : exception type
602 602 value : exception value
603 603 """
604 604 return ListTB.structured_traceback(self, etype, value, [])
605 605
606 606
607 def show_exception_only(self, etype, value):
607 def show_exception_only(self, etype, evalue):
608 608 """Only print the exception type and message, without a traceback.
609 609
610 610 Parameters
611 611 ----------
612 612 etype : exception type
613 613 value : exception value
614 614 """
615 615 # This method needs to use __call__ from *this* class, not the one from
616 616 # a subclass whose signature or behavior may be different
617 617 ostream = self.ostream
618 618 ostream.flush()
619 619 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
620 620 ostream.flush()
621 621
622 622 def _some_str(self, value):
623 623 # Lifted from traceback.py
624 624 try:
625 625 return str(value)
626 626 except:
627 627 return '<unprintable %s object>' % type(value).__name__
628 628
629 629 #----------------------------------------------------------------------------
630 630 class VerboseTB(TBTools):
631 631 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
632 632 of HTML. Requires inspect and pydoc. Crazy, man.
633 633
634 634 Modified version which optionally strips the topmost entries from the
635 635 traceback, to be used with alternate interpreters (because their own code
636 636 would appear in the traceback)."""
637 637
638 638 def __init__(self,color_scheme = 'Linux', call_pdb=False, ostream=None,
639 639 tb_offset=0, long_header=False, include_vars=True):
640 640 """Specify traceback offset, headers and color scheme.
641 641
642 642 Define how many frames to drop from the tracebacks. Calling it with
643 643 tb_offset=1 allows use of this handler in interpreters which will have
644 644 their own code at the top of the traceback (VerboseTB will first
645 645 remove that frame before printing the traceback info)."""
646 646 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
647 647 ostream=ostream)
648 648 self.tb_offset = tb_offset
649 649 self.long_header = long_header
650 650 self.include_vars = include_vars
651 651
652 652 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
653 653 context=5):
654 654 """Return a nice text document describing the traceback."""
655 655
656 656 tb_offset = self.tb_offset if tb_offset is None else tb_offset
657 657
658 658 # some locals
659 659 try:
660 660 etype = etype.__name__
661 661 except AttributeError:
662 662 pass
663 663 Colors = self.Colors # just a shorthand + quicker name lookup
664 664 ColorsNormal = Colors.Normal # used a lot
665 665 col_scheme = self.color_scheme_table.active_scheme_name
666 666 indent = ' '*INDENT_SIZE
667 667 em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal)
668 668 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
669 669 exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal)
670 670
671 671 # some internal-use functions
672 672 def text_repr(value):
673 673 """Hopefully pretty robust repr equivalent."""
674 674 # this is pretty horrible but should always return *something*
675 675 try:
676 676 return pydoc.text.repr(value)
677 677 except KeyboardInterrupt:
678 678 raise
679 679 except:
680 680 try:
681 681 return repr(value)
682 682 except KeyboardInterrupt:
683 683 raise
684 684 except:
685 685 try:
686 686 # all still in an except block so we catch
687 687 # getattr raising
688 688 name = getattr(value, '__name__', None)
689 689 if name:
690 690 # ick, recursion
691 691 return text_repr(name)
692 692 klass = getattr(value, '__class__', None)
693 693 if klass:
694 694 return '%s instance' % text_repr(klass)
695 695 except KeyboardInterrupt:
696 696 raise
697 697 except:
698 698 return 'UNRECOVERABLE REPR FAILURE'
699 699 def eqrepr(value, repr=text_repr): return '=%s' % repr(value)
700 700 def nullrepr(value, repr=text_repr): return ''
701 701
702 702 # meat of the code begins
703 703 try:
704 704 etype = etype.__name__
705 705 except AttributeError:
706 706 pass
707 707
708 708 if self.long_header:
709 709 # Header with the exception type, python version, and date
710 710 pyver = 'Python ' + string.split(sys.version)[0] + ': ' + sys.executable
711 711 date = time.ctime(time.time())
712 712
713 713 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
714 714 exc, ' '*(75-len(str(etype))-len(pyver)),
715 715 pyver, string.rjust(date, 75) )
716 716 head += "\nA problem occured executing Python code. Here is the sequence of function"\
717 717 "\ncalls leading up to the error, with the most recent (innermost) call last."
718 718 else:
719 719 # Simplified header
720 720 head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc,
721 721 string.rjust('Traceback (most recent call last)',
722 722 75 - len(str(etype)) ) )
723 723 frames = []
724 724 # Flush cache before calling inspect. This helps alleviate some of the
725 725 # problems with python 2.3's inspect.py.
726 726 linecache.checkcache()
727 727 # Drop topmost frames if requested
728 728 try:
729 729 # Try the default getinnerframes and Alex's: Alex's fixes some
730 730 # problems, but it generates empty tracebacks for console errors
731 731 # (5 blanks lines) where none should be returned.
732 732 #records = inspect.getinnerframes(etb, context)[tb_offset:]
733 733 #print 'python records:', records # dbg
734 734 records = _fixed_getinnerframes(etb, context, tb_offset)
735 735 #print 'alex records:', records # dbg
736 736 except:
737 737
738 738 # FIXME: I've been getting many crash reports from python 2.3
739 739 # users, traceable to inspect.py. If I can find a small test-case
740 740 # to reproduce this, I should either write a better workaround or
741 741 # file a bug report against inspect (if that's the real problem).
742 742 # So far, I haven't been able to find an isolated example to
743 743 # reproduce the problem.
744 744 inspect_error()
745 745 traceback.print_exc(file=self.ostream)
746 746 info('\nUnfortunately, your original traceback can not be constructed.\n')
747 747 return ''
748 748
749 749 # build some color string templates outside these nested loops
750 750 tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal)
751 751 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
752 752 ColorsNormal)
753 753 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
754 754 (Colors.vName, Colors.valEm, ColorsNormal)
755 755 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
756 756 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
757 757 Colors.vName, ColorsNormal)
758 758 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
759 759 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
760 760 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line,
761 761 ColorsNormal)
762 762
763 763 # now, loop over all records printing context and info
764 764 abspath = os.path.abspath
765 765 for frame, file, lnum, func, lines, index in records:
766 766 #print '*** record:',file,lnum,func,lines,index # dbg
767 767 try:
768 768 file = file and abspath(file) or '?'
769 769 except OSError:
770 770 # if file is '<console>' or something not in the filesystem,
771 771 # the abspath call will throw an OSError. Just ignore it and
772 772 # keep the original file string.
773 773 pass
774 774 link = tpl_link % file
775 775 try:
776 776 args, varargs, varkw, locals = inspect.getargvalues(frame)
777 777 except:
778 778 # This can happen due to a bug in python2.3. We should be
779 779 # able to remove this try/except when 2.4 becomes a
780 780 # requirement. Bug details at http://python.org/sf/1005466
781 781 inspect_error()
782 782 traceback.print_exc(file=self.ostream)
783 783 info("\nIPython's exception reporting continues...\n")
784 784
785 785 if func == '?':
786 786 call = ''
787 787 else:
788 788 # Decide whether to include variable details or not
789 789 var_repr = self.include_vars and eqrepr or nullrepr
790 790 try:
791 791 call = tpl_call % (func,inspect.formatargvalues(args,
792 792 varargs, varkw,
793 793 locals,formatvalue=var_repr))
794 794 except KeyError:
795 795 # Very odd crash from inspect.formatargvalues(). The
796 796 # scenario under which it appeared was a call to
797 797 # view(array,scale) in NumTut.view.view(), where scale had
798 798 # been defined as a scalar (it should be a tuple). Somehow
799 799 # inspect messes up resolving the argument list of view()
800 800 # and barfs out. At some point I should dig into this one
801 801 # and file a bug report about it.
802 802 inspect_error()
803 803 traceback.print_exc(file=self.ostream)
804 804 info("\nIPython's exception reporting continues...\n")
805 805 call = tpl_call_fail % func
806 806
807 807 # Initialize a list of names on the current line, which the
808 808 # tokenizer below will populate.
809 809 names = []
810 810
811 811 def tokeneater(token_type, token, start, end, line):
812 812 """Stateful tokeneater which builds dotted names.
813 813
814 814 The list of names it appends to (from the enclosing scope) can
815 815 contain repeated composite names. This is unavoidable, since
816 816 there is no way to disambguate partial dotted structures until
817 817 the full list is known. The caller is responsible for pruning
818 818 the final list of duplicates before using it."""
819 819
820 820 # build composite names
821 821 if token == '.':
822 822 try:
823 823 names[-1] += '.'
824 824 # store state so the next token is added for x.y.z names
825 825 tokeneater.name_cont = True
826 826 return
827 827 except IndexError:
828 828 pass
829 829 if token_type == tokenize.NAME and token not in keyword.kwlist:
830 830 if tokeneater.name_cont:
831 831 # Dotted names
832 832 names[-1] += token
833 833 tokeneater.name_cont = False
834 834 else:
835 835 # Regular new names. We append everything, the caller
836 836 # will be responsible for pruning the list later. It's
837 837 # very tricky to try to prune as we go, b/c composite
838 838 # names can fool us. The pruning at the end is easy
839 839 # to do (or the caller can print a list with repeated
840 840 # names if so desired.
841 841 names.append(token)
842 842 elif token_type == tokenize.NEWLINE:
843 843 raise IndexError
844 844 # we need to store a bit of state in the tokenizer to build
845 845 # dotted names
846 846 tokeneater.name_cont = False
847 847
848 848 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
849 849 line = getline(file, lnum[0])
850 850 lnum[0] += 1
851 851 return line
852 852
853 853 # Build the list of names on this line of code where the exception
854 854 # occurred.
855 855 try:
856 856 # This builds the names list in-place by capturing it from the
857 857 # enclosing scope.
858 858 tokenize.tokenize(linereader, tokeneater)
859 859 except IndexError:
860 860 # signals exit of tokenizer
861 861 pass
862 862 except tokenize.TokenError,msg:
863 863 _m = ("An unexpected error occurred while tokenizing input\n"
864 864 "The following traceback may be corrupted or invalid\n"
865 865 "The error message is: %s\n" % msg)
866 866 error(_m)
867 867
868 868 # prune names list of duplicates, but keep the right order
869 869 unique_names = uniq_stable(names)
870 870
871 871 # Start loop over vars
872 872 lvals = []
873 873 if self.include_vars:
874 874 for name_full in unique_names:
875 875 name_base = name_full.split('.',1)[0]
876 876 if name_base in frame.f_code.co_varnames:
877 877 if locals.has_key(name_base):
878 878 try:
879 879 value = repr(eval(name_full,locals))
880 880 except:
881 881 value = undefined
882 882 else:
883 883 value = undefined
884 884 name = tpl_local_var % name_full
885 885 else:
886 886 if frame.f_globals.has_key(name_base):
887 887 try:
888 888 value = repr(eval(name_full,frame.f_globals))
889 889 except:
890 890 value = undefined
891 891 else:
892 892 value = undefined
893 893 name = tpl_global_var % name_full
894 894 lvals.append(tpl_name_val % (name,value))
895 895 if lvals:
896 896 lvals = '%s%s' % (indent,em_normal.join(lvals))
897 897 else:
898 898 lvals = ''
899 899
900 900 level = '%s %s\n' % (link,call)
901 901
902 902 if index is None:
903 903 frames.append(level)
904 904 else:
905 905 frames.append('%s%s' % (level,''.join(
906 906 _format_traceback_lines(lnum,index,lines,Colors,lvals,
907 907 col_scheme))))
908 908
909 909 # Get (safely) a string form of the exception info
910 910 try:
911 911 etype_str,evalue_str = map(str,(etype,evalue))
912 912 except:
913 913 # User exception is improperly defined.
914 914 etype,evalue = str,sys.exc_info()[:2]
915 915 etype_str,evalue_str = map(str,(etype,evalue))
916 916 # ... and format it
917 917 exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
918 918 ColorsNormal, evalue_str)]
919 919 if type(evalue) is types.InstanceType:
920 920 try:
921 921 names = [w for w in dir(evalue) if isinstance(w, basestring)]
922 922 except:
923 923 # Every now and then, an object with funny inernals blows up
924 924 # when dir() is called on it. We do the best we can to report
925 925 # the problem and continue
926 926 _m = '%sException reporting error (object with broken dir())%s:'
927 927 exception.append(_m % (Colors.excName,ColorsNormal))
928 928 etype_str,evalue_str = map(str,sys.exc_info()[:2])
929 929 exception.append('%s%s%s: %s' % (Colors.excName,etype_str,
930 930 ColorsNormal, evalue_str))
931 931 names = []
932 932 for name in names:
933 933 value = text_repr(getattr(evalue, name))
934 934 exception.append('\n%s%s = %s' % (indent, name, value))
935 935
936 936 # vds: >>
937 937 if records:
938 938 filepath, lnum = records[-1][1:3]
939 939 #print "file:", str(file), "linenb", str(lnum) # dbg
940 940 filepath = os.path.abspath(filepath)
941 941 ipinst = ipapi.get()
942 942 if ipinst is not None:
943 943 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
944 944 # vds: <<
945 945
946 946 # return all our info assembled as a single string
947 947 # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
948 948 return [head] + frames + [''.join(exception[0])]
949 949
950 950 def debugger(self,force=False):
951 951 """Call up the pdb debugger if desired, always clean up the tb
952 952 reference.
953 953
954 954 Keywords:
955 955
956 956 - force(False): by default, this routine checks the instance call_pdb
957 957 flag and does not actually invoke the debugger if the flag is false.
958 958 The 'force' option forces the debugger to activate even if the flag
959 959 is false.
960 960
961 961 If the call_pdb flag is set, the pdb interactive debugger is
962 962 invoked. In all cases, the self.tb reference to the current traceback
963 963 is deleted to prevent lingering references which hamper memory
964 964 management.
965 965
966 966 Note that each call to pdb() does an 'import readline', so if your app
967 967 requires a special setup for the readline completers, you'll have to
968 968 fix that by hand after invoking the exception handler."""
969 969
970 970 if force or self.call_pdb:
971 971 if self.pdb is None:
972 972 self.pdb = debugger.Pdb(
973 973 self.color_scheme_table.active_scheme_name)
974 974 # the system displayhook may have changed, restore the original
975 975 # for pdb
976 976 display_trap = DisplayTrap(hook=sys.__displayhook__)
977 977 with display_trap:
978 978 self.pdb.reset()
979 979 # Find the right frame so we don't pop up inside ipython itself
980 980 if hasattr(self,'tb') and self.tb is not None:
981 981 etb = self.tb
982 982 else:
983 983 etb = self.tb = sys.last_traceback
984 984 while self.tb is not None and self.tb.tb_next is not None:
985 985 self.tb = self.tb.tb_next
986 986 if etb and etb.tb_next:
987 987 etb = etb.tb_next
988 988 self.pdb.botframe = etb.tb_frame
989 989 self.pdb.interaction(self.tb.tb_frame, self.tb)
990 990
991 991 if hasattr(self,'tb'):
992 992 del self.tb
993 993
994 994 def handler(self, info=None):
995 995 (etype, evalue, etb) = info or sys.exc_info()
996 996 self.tb = etb
997 997 ostream = self.ostream
998 998 ostream.flush()
999 999 ostream.write(self.text(etype, evalue, etb))
1000 1000 ostream.write('\n')
1001 1001 ostream.flush()
1002 1002
1003 1003 # Changed so an instance can just be called as VerboseTB_inst() and print
1004 1004 # out the right info on its own.
1005 1005 def __call__(self, etype=None, evalue=None, etb=None):
1006 1006 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1007 1007 if etb is None:
1008 1008 self.handler()
1009 1009 else:
1010 1010 self.handler((etype, evalue, etb))
1011 1011 try:
1012 1012 self.debugger()
1013 1013 except KeyboardInterrupt:
1014 1014 print "\nKeyboardInterrupt"
1015 1015
1016 1016 #----------------------------------------------------------------------------
1017 1017 class FormattedTB(VerboseTB, ListTB):
1018 1018 """Subclass ListTB but allow calling with a traceback.
1019 1019
1020 1020 It can thus be used as a sys.excepthook for Python > 2.1.
1021 1021
1022 1022 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1023 1023
1024 1024 Allows a tb_offset to be specified. This is useful for situations where
1025 1025 one needs to remove a number of topmost frames from the traceback (such as
1026 1026 occurs with python programs that themselves execute other python code,
1027 1027 like Python shells). """
1028 1028
1029 1029 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1030 1030 ostream=None,
1031 1031 tb_offset=0, long_header=False, include_vars=False):
1032 1032
1033 1033 # NEVER change the order of this list. Put new modes at the end:
1034 1034 self.valid_modes = ['Plain','Context','Verbose']
1035 1035 self.verbose_modes = self.valid_modes[1:3]
1036 1036
1037 1037 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1038 1038 ostream=ostream, tb_offset=tb_offset,
1039 1039 long_header=long_header, include_vars=include_vars)
1040 1040
1041 1041 # Different types of tracebacks are joined with different separators to
1042 1042 # form a single string. They are taken from this dict
1043 1043 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1044 1044 # set_mode also sets the tb_join_char attribute
1045 1045 self.set_mode(mode)
1046 1046
1047 1047 def _extract_tb(self,tb):
1048 1048 if tb:
1049 1049 return traceback.extract_tb(tb)
1050 1050 else:
1051 1051 return None
1052 1052
1053 1053 def structured_traceback(self, etype, value, tb, tb_offset=None, context=5):
1054 1054 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1055 1055 mode = self.mode
1056 1056 if mode in self.verbose_modes:
1057 1057 # Verbose modes need a full traceback
1058 1058 return VerboseTB.structured_traceback(
1059 1059 self, etype, value, tb, tb_offset, context
1060 1060 )
1061 1061 else:
1062 1062 # We must check the source cache because otherwise we can print
1063 1063 # out-of-date source code.
1064 1064 linecache.checkcache()
1065 1065 # Now we can extract and format the exception
1066 1066 elist = self._extract_tb(tb)
1067 1067 return ListTB.structured_traceback(
1068 1068 self, etype, value, elist, tb_offset, context
1069 1069 )
1070 1070
1071 1071 def stb2text(self, stb):
1072 1072 """Convert a structured traceback (a list) to a string."""
1073 1073 return self.tb_join_char.join(stb)
1074 1074
1075 1075
1076 1076 def set_mode(self,mode=None):
1077 1077 """Switch to the desired mode.
1078 1078
1079 1079 If mode is not specified, cycles through the available modes."""
1080 1080
1081 1081 if not mode:
1082 1082 new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \
1083 1083 len(self.valid_modes)
1084 1084 self.mode = self.valid_modes[new_idx]
1085 1085 elif mode not in self.valid_modes:
1086 1086 raise ValueError, 'Unrecognized mode in FormattedTB: <'+mode+'>\n'\
1087 1087 'Valid modes: '+str(self.valid_modes)
1088 1088 else:
1089 1089 self.mode = mode
1090 1090 # include variable details only in 'Verbose' mode
1091 1091 self.include_vars = (self.mode == self.valid_modes[2])
1092 1092 # Set the join character for generating text tracebacks
1093 1093 self.tb_join_char = self._join_chars[mode]
1094 1094
1095 1095 # some convenient shorcuts
1096 1096 def plain(self):
1097 1097 self.set_mode(self.valid_modes[0])
1098 1098
1099 1099 def context(self):
1100 1100 self.set_mode(self.valid_modes[1])
1101 1101
1102 1102 def verbose(self):
1103 1103 self.set_mode(self.valid_modes[2])
1104 1104
1105 1105 #----------------------------------------------------------------------------
1106 1106 class AutoFormattedTB(FormattedTB):
1107 1107 """A traceback printer which can be called on the fly.
1108 1108
1109 1109 It will find out about exceptions by itself.
1110 1110
1111 1111 A brief example:
1112 1112
1113 1113 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1114 1114 try:
1115 1115 ...
1116 1116 except:
1117 1117 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1118 1118 """
1119 1119
1120 1120 def __call__(self,etype=None,evalue=None,etb=None,
1121 1121 out=None,tb_offset=None):
1122 1122 """Print out a formatted exception traceback.
1123 1123
1124 1124 Optional arguments:
1125 1125 - out: an open file-like object to direct output to.
1126 1126
1127 1127 - tb_offset: the number of frames to skip over in the stack, on a
1128 1128 per-call basis (this overrides temporarily the instance's tb_offset
1129 1129 given at initialization time. """
1130 1130
1131 1131
1132 1132 if out is None:
1133 1133 out = self.ostream
1134 1134 out.flush()
1135 1135 out.write(self.text(etype, evalue, etb, tb_offset))
1136 1136 out.write('\n')
1137 1137 out.flush()
1138 1138 # FIXME: we should remove the auto pdb behavior from here and leave
1139 1139 # that to the clients.
1140 1140 try:
1141 1141 self.debugger()
1142 1142 except KeyboardInterrupt:
1143 1143 print "\nKeyboardInterrupt"
1144 1144
1145 1145 def structured_traceback(self, etype=None, value=None, tb=None,
1146 1146 tb_offset=None, context=5):
1147 1147 if etype is None:
1148 1148 etype,value,tb = sys.exc_info()
1149 1149 self.tb = tb
1150 1150 return FormattedTB.structured_traceback(
1151 1151 self, etype, value, tb, tb_offset, context)
1152 1152
1153 1153 #---------------------------------------------------------------------------
1154 1154
1155 1155 # A simple class to preserve Nathan's original functionality.
1156 1156 class ColorTB(FormattedTB):
1157 1157 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1158 1158 def __init__(self,color_scheme='Linux',call_pdb=0):
1159 1159 FormattedTB.__init__(self,color_scheme=color_scheme,
1160 1160 call_pdb=call_pdb)
1161 1161
1162 1162
1163 1163 class SyntaxTB(ListTB):
1164 1164 """Extension which holds some state: the last exception value"""
1165 1165
1166 1166 def __init__(self,color_scheme = 'NoColor'):
1167 1167 ListTB.__init__(self,color_scheme)
1168 1168 self.last_syntax_error = None
1169 1169
1170 1170 def __call__(self, etype, value, elist):
1171 1171 self.last_syntax_error = value
1172 1172 ListTB.__call__(self,etype,value,elist)
1173 1173
1174 1174 def clear_err_state(self):
1175 1175 """Return the current error state and clear it"""
1176 1176 e = self.last_syntax_error
1177 1177 self.last_syntax_error = None
1178 1178 return e
1179 1179
1180 1180 def stb2text(self, stb):
1181 1181 """Convert a structured traceback (a list) to a string."""
1182 1182 return ''.join(stb)
1183 1183
1184 1184
1185 1185 #----------------------------------------------------------------------------
1186 1186 # module testing (minimal)
1187 1187 if __name__ == "__main__":
1188 1188 def spam(c, (d, e)):
1189 1189 x = c + d
1190 1190 y = c * d
1191 1191 foo(x, y)
1192 1192
1193 1193 def foo(a, b, bar=1):
1194 1194 eggs(a, b + bar)
1195 1195
1196 1196 def eggs(f, g, z=globals()):
1197 1197 h = f + g
1198 1198 i = f - g
1199 1199 return h / i
1200 1200
1201 1201 print ''
1202 1202 print '*** Before ***'
1203 1203 try:
1204 1204 print spam(1, (2, 3))
1205 1205 except:
1206 1206 traceback.print_exc()
1207 1207 print ''
1208 1208
1209 1209 handler = ColorTB()
1210 1210 print '*** ColorTB ***'
1211 1211 try:
1212 1212 print spam(1, (2, 3))
1213 1213 except:
1214 1214 apply(handler, sys.exc_info() )
1215 1215 print ''
1216 1216
1217 1217 handler = VerboseTB()
1218 1218 print '*** VerboseTB ***'
1219 1219 try:
1220 1220 print spam(1, (2, 3))
1221 1221 except:
1222 1222 apply(handler, sys.exc_info() )
1223 1223 print ''
1224 1224
@@ -1,419 +1,418 b''
1 1 # Standard library imports
2 2 import signal
3 3 import sys
4 4
5 5 # System library imports
6 6 from pygments.lexers import PythonLexer
7 7 from PyQt4 import QtCore, QtGui
8 import zmq
9 8
10 9 # Local imports
11 10 from IPython.core.inputsplitter import InputSplitter
12 11 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
13 12 from call_tip_widget import CallTipWidget
14 13 from completion_lexer import CompletionLexer
15 14 from console_widget import HistoryConsoleWidget
16 15 from pygments_highlighter import PygmentsHighlighter
17 16
18 17
19 18 class FrontendHighlighter(PygmentsHighlighter):
20 19 """ A PygmentsHighlighter that can be turned on and off and that ignores
21 20 prompts.
22 21 """
23 22
24 23 def __init__(self, frontend):
25 24 super(FrontendHighlighter, self).__init__(frontend._control.document())
26 25 self._current_offset = 0
27 26 self._frontend = frontend
28 27 self.highlighting_on = False
29 28
30 29 def highlightBlock(self, qstring):
31 30 """ Highlight a block of text. Reimplemented to highlight selectively.
32 31 """
33 32 if not self.highlighting_on:
34 33 return
35 34
36 35 # The input to this function is unicode string that may contain
37 36 # paragraph break characters, non-breaking spaces, etc. Here we acquire
38 37 # the string as plain text so we can compare it.
39 38 current_block = self.currentBlock()
40 39 string = self._frontend._get_block_plain_text(current_block)
41 40
42 41 # Decide whether to check for the regular or continuation prompt.
43 42 if current_block.contains(self._frontend._prompt_pos):
44 43 prompt = self._frontend._prompt
45 44 else:
46 45 prompt = self._frontend._continuation_prompt
47 46
48 47 # Don't highlight the part of the string that contains the prompt.
49 48 if string.startswith(prompt):
50 49 self._current_offset = len(prompt)
51 50 qstring.remove(0, len(prompt))
52 51 else:
53 52 self._current_offset = 0
54 53
55 54 PygmentsHighlighter.highlightBlock(self, qstring)
56 55
57 56 def rehighlightBlock(self, block):
58 57 """ Reimplemented to temporarily enable highlighting if disabled.
59 58 """
60 59 old = self.highlighting_on
61 60 self.highlighting_on = True
62 61 super(FrontendHighlighter, self).rehighlightBlock(block)
63 62 self.highlighting_on = old
64 63
65 64 def setFormat(self, start, count, format):
66 65 """ Reimplemented to highlight selectively.
67 66 """
68 67 start += self._current_offset
69 68 PygmentsHighlighter.setFormat(self, start, count, format)
70 69
71 70
72 71 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
73 72 """ A Qt frontend for a generic Python kernel.
74 73 """
75 74
76 75 # An option and corresponding signal for overriding the default kernel
77 76 # interrupt behavior.
78 77 custom_interrupt = False
79 78 custom_interrupt_requested = QtCore.pyqtSignal()
80 79
81 80 # An option and corresponding signal for overriding the default kernel
82 81 # restart behavior.
83 82 custom_restart = False
84 83 custom_restart_requested = QtCore.pyqtSignal()
85 84
86 85 # Emitted when an 'execute_reply' has been received from the kernel and
87 86 # processed by the FrontendWidget.
88 87 executed = QtCore.pyqtSignal(object)
89 88
90 89 # Protected class variables.
91 90 _highlighter_class = FrontendHighlighter
92 91 _input_splitter_class = InputSplitter
93 92
94 93 #---------------------------------------------------------------------------
95 94 # 'object' interface
96 95 #---------------------------------------------------------------------------
97 96
98 97 def __init__(self, *args, **kw):
99 98 super(FrontendWidget, self).__init__(*args, **kw)
100 99
101 100 # FrontendWidget protected variables.
102 101 self._call_tip_widget = CallTipWidget(self._control)
103 102 self._completion_lexer = CompletionLexer(PythonLexer())
104 103 self._hidden = False
105 104 self._highlighter = self._highlighter_class(self)
106 105 self._input_splitter = self._input_splitter_class(input_mode='block')
107 106 self._kernel_manager = None
108 107
109 108 # Configure the ConsoleWidget.
110 109 self.tab_width = 4
111 110 self._set_continuation_prompt('... ')
112 111
113 112 # Connect signal handlers.
114 113 document = self._control.document()
115 114 document.contentsChange.connect(self._document_contents_change)
116 115
117 116 #---------------------------------------------------------------------------
118 117 # 'ConsoleWidget' abstract interface
119 118 #---------------------------------------------------------------------------
120 119
121 120 def _is_complete(self, source, interactive):
122 121 """ Returns whether 'source' can be completely processed and a new
123 122 prompt created. When triggered by an Enter/Return key press,
124 123 'interactive' is True; otherwise, it is False.
125 124 """
126 125 complete = self._input_splitter.push(source.expandtabs(4))
127 126 if interactive:
128 127 complete = not self._input_splitter.push_accepts_more()
129 128 return complete
130 129
131 130 def _execute(self, source, hidden):
132 131 """ Execute 'source'. If 'hidden', do not show any output.
133 132 """
134 133 self.kernel_manager.xreq_channel.execute(source, hidden)
135 134 self._hidden = hidden
136 135
137 136 def _prompt_started_hook(self):
138 137 """ Called immediately after a new prompt is displayed.
139 138 """
140 139 if not self._reading:
141 140 self._highlighter.highlighting_on = True
142 141
143 142 def _prompt_finished_hook(self):
144 143 """ Called immediately after a prompt is finished, i.e. when some input
145 144 will be processed and a new prompt displayed.
146 145 """
147 146 if not self._reading:
148 147 self._highlighter.highlighting_on = False
149 148
150 149 def _tab_pressed(self):
151 150 """ Called when the tab key is pressed. Returns whether to continue
152 151 processing the event.
153 152 """
154 153 # Perform tab completion if:
155 154 # 1) The cursor is in the input buffer.
156 155 # 2) There is a non-whitespace character before the cursor.
157 156 text = self._get_input_buffer_cursor_line()
158 157 if text is None:
159 158 return False
160 159 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
161 160 if complete:
162 161 self._complete()
163 162 return not complete
164 163
165 164 #---------------------------------------------------------------------------
166 165 # 'ConsoleWidget' protected interface
167 166 #---------------------------------------------------------------------------
168 167
169 168 def _event_filter_console_keypress(self, event):
170 169 """ Reimplemented to allow execution interruption.
171 170 """
172 171 key = event.key()
173 172 if self._executing and self._control_key_down(event.modifiers()):
174 173 if key == QtCore.Qt.Key_C:
175 174 self._kernel_interrupt()
176 175 return True
177 176 elif key == QtCore.Qt.Key_Period:
178 177 self._kernel_restart()
179 178 return True
180 179 return super(FrontendWidget, self)._event_filter_console_keypress(event)
181 180
182 181 def _show_continuation_prompt(self):
183 182 """ Reimplemented for auto-indentation.
184 183 """
185 184 super(FrontendWidget, self)._show_continuation_prompt()
186 185 spaces = self._input_splitter.indent_spaces
187 186 self._append_plain_text('\t' * (spaces / self.tab_width))
188 187 self._append_plain_text(' ' * (spaces % self.tab_width))
189 188
190 189 #---------------------------------------------------------------------------
191 190 # 'BaseFrontendMixin' abstract interface
192 191 #---------------------------------------------------------------------------
193 192
194 193 def _handle_complete_reply(self, rep):
195 194 """ Handle replies for tab completion.
196 195 """
197 196 cursor = self._get_cursor()
198 197 if rep['parent_header']['msg_id'] == self._complete_id and \
199 198 cursor.position() == self._complete_pos:
200 199 text = '.'.join(self._get_context())
201 200 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
202 201 self._complete_with_items(cursor, rep['content']['matches'])
203 202
204 203 def _handle_execute_reply(self, msg):
205 204 """ Handles replies for code execution.
206 205 """
207 206 if not self._hidden:
208 207 # Make sure that all output from the SUB channel has been processed
209 208 # before writing a new prompt.
210 209 self.kernel_manager.sub_channel.flush()
211 210
212 211 content = msg['content']
213 212 status = content['status']
214 213 if status == 'ok':
215 214 self._process_execute_ok(msg)
216 215 elif status == 'error':
217 216 self._process_execute_error(msg)
218 217 elif status == 'abort':
219 218 self._process_execute_abort(msg)
220 219
221 220 self._show_interpreter_prompt_for_reply(msg)
222 221 self.executed.emit(msg)
223 222
224 223 def _handle_input_request(self, msg):
225 224 """ Handle requests for raw_input.
226 225 """
227 226 if self._hidden:
228 227 raise RuntimeError('Request for raw input during hidden execution.')
229 228
230 229 # Make sure that all output from the SUB channel has been processed
231 230 # before entering readline mode.
232 231 self.kernel_manager.sub_channel.flush()
233 232
234 233 def callback(line):
235 234 self.kernel_manager.rep_channel.input(line)
236 235 self._readline(msg['content']['prompt'], callback=callback)
237 236
238 237 def _handle_object_info_reply(self, rep):
239 238 """ Handle replies for call tips.
240 239 """
241 240 cursor = self._get_cursor()
242 241 if rep['parent_header']['msg_id'] == self._call_tip_id and \
243 242 cursor.position() == self._call_tip_pos:
244 243 doc = rep['content']['docstring']
245 244 if doc:
246 245 self._call_tip_widget.show_docstring(doc)
247 246
248 247 def _handle_pyout(self, msg):
249 248 """ Handle display hook output.
250 249 """
251 250 if not self._hidden and self._is_from_this_session(msg):
252 251 self._append_plain_text(msg['content']['data'] + '\n')
253 252
254 253 def _handle_stream(self, msg):
255 254 """ Handle stdout, stderr, and stdin.
256 255 """
257 256 if not self._hidden and self._is_from_this_session(msg):
258 257 self._append_plain_text(msg['content']['data'])
259 258 self._control.moveCursor(QtGui.QTextCursor.End)
260 259
261 260 def _started_channels(self):
262 261 """ Called when the KernelManager channels have started listening or
263 262 when the frontend is assigned an already listening KernelManager.
264 263 """
265 264 self._control.clear()
266 265 self._append_plain_text(self._get_banner())
267 266 self._show_interpreter_prompt()
268 267
269 268 def _stopped_channels(self):
270 269 """ Called when the KernelManager channels have stopped listening or
271 270 when a listening KernelManager is removed from the frontend.
272 271 """
273 272 self._executing = self._reading = False
274 273 self._highlighter.highlighting_on = False
275 274
276 275 #---------------------------------------------------------------------------
277 276 # 'FrontendWidget' interface
278 277 #---------------------------------------------------------------------------
279 278
280 279 def execute_file(self, path, hidden=False):
281 280 """ Attempts to execute file with 'path'. If 'hidden', no output is
282 281 shown.
283 282 """
284 283 self.execute('execfile("%s")' % path, hidden=hidden)
285 284
286 285 #---------------------------------------------------------------------------
287 286 # 'FrontendWidget' protected interface
288 287 #---------------------------------------------------------------------------
289 288
290 289 def _call_tip(self):
291 290 """ Shows a call tip, if appropriate, at the current cursor location.
292 291 """
293 292 # Decide if it makes sense to show a call tip
294 293 cursor = self._get_cursor()
295 294 cursor.movePosition(QtGui.QTextCursor.Left)
296 295 if cursor.document().characterAt(cursor.position()).toAscii() != '(':
297 296 return False
298 297 context = self._get_context(cursor)
299 298 if not context:
300 299 return False
301 300
302 301 # Send the metadata request to the kernel
303 302 name = '.'.join(context)
304 303 self._call_tip_id = self.kernel_manager.xreq_channel.object_info(name)
305 304 self._call_tip_pos = self._get_cursor().position()
306 305 return True
307 306
308 307 def _complete(self):
309 308 """ Performs completion at the current cursor location.
310 309 """
311 310 context = self._get_context()
312 311 if context:
313 312 # Send the completion request to the kernel
314 313 self._complete_id = self.kernel_manager.xreq_channel.complete(
315 314 '.'.join(context), # text
316 315 self._get_input_buffer_cursor_line(), # line
317 316 self._get_input_buffer_cursor_column(), # cursor_pos
318 317 self.input_buffer) # block
319 318 self._complete_pos = self._get_cursor().position()
320 319
321 320 def _get_banner(self):
322 321 """ Gets a banner to display at the beginning of a session.
323 322 """
324 323 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
325 324 '"license" for more information.'
326 325 return banner % (sys.version, sys.platform)
327 326
328 327 def _get_context(self, cursor=None):
329 328 """ Gets the context for the specified cursor (or the current cursor
330 329 if none is specified).
331 330 """
332 331 if cursor is None:
333 332 cursor = self._get_cursor()
334 333 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
335 334 QtGui.QTextCursor.KeepAnchor)
336 335 text = str(cursor.selection().toPlainText())
337 336 return self._completion_lexer.get_context(text)
338 337
339 338 def _kernel_interrupt(self):
340 339 """ Attempts to interrupt the running kernel.
341 340 """
342 341 if self.custom_interrupt:
343 342 self.custom_interrupt_requested.emit()
344 343 elif self.kernel_manager.has_kernel:
345 344 self.kernel_manager.signal_kernel(signal.SIGINT)
346 345 else:
347 346 self._append_plain_text('Kernel process is either remote or '
348 347 'unspecified. Cannot interrupt.\n')
349 348
350 349 def _kernel_restart(self):
351 350 """ Attempts to restart the running kernel.
352 351 """
353 352 if self.custom_restart:
354 353 self.custom_restart_requested.emit()
355 354 elif self.kernel_manager.has_kernel:
356 355 try:
357 356 self.kernel_manager.restart_kernel()
358 357 except RuntimeError:
359 358 message = 'Kernel started externally. Cannot restart.\n'
360 359 self._append_plain_text(message)
361 360 else:
362 361 self._stopped_channels()
363 362 self._append_plain_text('Kernel restarting...\n')
364 363 self._show_interpreter_prompt()
365 364 else:
366 365 self._append_plain_text('Kernel process is either remote or '
367 366 'unspecified. Cannot restart.\n')
368 367
369 368 def _process_execute_abort(self, msg):
370 369 """ Process a reply for an aborted execution request.
371 370 """
372 371 self._append_plain_text("ERROR: execution aborted\n")
373 372
374 373 def _process_execute_error(self, msg):
375 374 """ Process a reply for an execution request that resulted in an error.
376 375 """
377 376 content = msg['content']
378 377 traceback = ''.join(content['traceback'])
379 378 self._append_plain_text(traceback)
380 379
381 380 def _process_execute_ok(self, msg):
382 381 """ Process a reply for a successful execution equest.
383 382 """
384 383 payload = msg['content']['payload']
385 384 for item in payload:
386 385 if not self._process_execute_payload(item):
387 386 warning = 'Received unknown payload of type %s\n'
388 387 self._append_plain_text(warning % repr(item['source']))
389 388
390 389 def _process_execute_payload(self, item):
391 390 """ Process a single payload item from the list of payload items in an
392 391 execution reply. Returns whether the payload was handled.
393 392 """
394 393 # The basic FrontendWidget doesn't handle payloads, as they are a
395 394 # mechanism for going beyond the standard Python interpreter model.
396 395 return False
397 396
398 397 def _show_interpreter_prompt(self):
399 398 """ Shows a prompt for the interpreter.
400 399 """
401 400 self._show_prompt('>>> ')
402 401
403 402 def _show_interpreter_prompt_for_reply(self, msg):
404 403 """ Shows a prompt for the interpreter given an 'execute_reply' message.
405 404 """
406 405 self._show_interpreter_prompt()
407 406
408 407 #------ Signal handlers ----------------------------------------------------
409 408
410 409 def _document_contents_change(self, position, removed, added):
411 410 """ Called whenever the document's content changes. Display a call tip
412 411 if appropriate.
413 412 """
414 413 # Calculate where the cursor should be *after* the change:
415 414 position += added
416 415
417 416 document = self._control.document()
418 417 if position == self._get_cursor().position():
419 418 self._call_tip()
@@ -1,93 +1,99 b''
1 1 #!/usr/bin/env python
2 2
3 3 """ A minimal application using the Qt console-style IPython frontend.
4 4 """
5 5
6 6 # Systemm library imports
7 from PyQt4 import QtCore, QtGui
7 from PyQt4 import QtGui
8 8
9 9 # Local imports
10 10 from IPython.external.argparse import ArgumentParser
11 11 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
12 12 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
13 13 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
14 14 from IPython.frontend.qt.kernelmanager import QtKernelManager
15 15
16 16 # Constants
17 17 LOCALHOST = '127.0.0.1'
18 18
19 19
20 20 def main():
21 21 """ Entry point for application.
22 22 """
23 23 # Parse command line arguments.
24 24 parser = ArgumentParser()
25 25 kgroup = parser.add_argument_group('kernel options')
26 26 kgroup.add_argument('-e', '--existing', action='store_true',
27 27 help='connect to an existing kernel')
28 28 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
29 29 help='set the kernel\'s IP address [default localhost]')
30 30 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
31 31 help='set the XREQ channel port [default random]')
32 32 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
33 33 help='set the SUB channel port [default random]')
34 34 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
35 35 help='set the REP channel port [default random]')
36 36
37 37 egroup = kgroup.add_mutually_exclusive_group()
38 38 egroup.add_argument('--pure', action='store_true', help = \
39 39 'use a pure Python kernel instead of an IPython kernel')
40 egroup.add_argument('--pylab', action='store_true',
41 help='use a kernel with PyLab enabled')
40 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
41 const='auto', help = \
42 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
43 given, the GUI backend is matplotlib's, otherwise use one of: \
44 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
42 45
43 46 wgroup = parser.add_argument_group('widget options')
44 47 wgroup.add_argument('--paging', type=str, default='inside',
45 48 choices = ['inside', 'hsplit', 'vsplit', 'none'],
46 49 help='set the paging style [default inside]')
47 50 wgroup.add_argument('--rich', action='store_true',
48 51 help='enable rich text support')
49 52 wgroup.add_argument('--tab-simple', action='store_true',
50 53 help='do tab completion ala a Unix terminal')
51
54
52 55 args = parser.parse_args()
53
56
54 57 # Don't let Qt or ZMQ swallow KeyboardInterupts.
55 58 import signal
56 59 signal.signal(signal.SIGINT, signal.SIG_DFL)
57 60
58 61 # Create a KernelManager and start a kernel.
59 62 kernel_manager = QtKernelManager(xreq_address=(args.ip, args.xreq),
60 63 sub_address=(args.ip, args.sub),
61 64 rep_address=(args.ip, args.rep))
62 65 if args.ip == LOCALHOST and not args.existing:
63 66 if args.pure:
64 67 kernel_manager.start_kernel(ipython=False)
65 68 elif args.pylab:
66 69 if args.rich:
67 70 kernel_manager.start_kernel(pylab='payload-svg')
68 71 else:
69 kernel_manager.start_kernel(pylab='qt4')
72 if args.pylab == 'auto':
73 kernel_manager.start_kernel(pylab='qt4')
74 else:
75 kernel_manager.start_kernel(pylab=args.pylab)
70 76 else:
71 77 kernel_manager.start_kernel()
72 78 kernel_manager.start_channels()
73 79
74 80 # Create the widget.
75 81 app = QtGui.QApplication([])
76 82 if args.pure:
77 83 kind = 'rich' if args.rich else 'plain'
78 84 widget = FrontendWidget(kind=kind, paging=args.paging)
79 85 elif args.rich:
80 86 widget = RichIPythonWidget(paging=args.paging)
81 87 else:
82 88 widget = IPythonWidget(paging=args.paging)
83 89 widget.gui_completion = not args.tab_simple
84 90 widget.kernel_manager = kernel_manager
85 91 widget.setWindowTitle('Python' if args.pure else 'IPython')
86 92 widget.show()
87 93
88 94 # Start the application main loop.
89 95 app.exec_()
90 96
91 97
92 98 if __name__ == '__main__':
93 99 main()
@@ -1,571 +1,572 b''
1 1 #!/usr/bin/env python
2 2 # coding: utf-8
3 3 """
4 4 Inputhook management for GUI event loop integration.
5 5 """
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (C) 2008-2009 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 import ctypes
19 19 import sys
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Constants
23 23 #-----------------------------------------------------------------------------
24 24
25 25 # Constants for identifying the GUI toolkits.
26 26 GUI_WX = 'wx'
27 27 GUI_QT = 'qt'
28 28 GUI_QT4 = 'qt4'
29 29 GUI_GTK = 'gtk'
30 30 GUI_TK = 'tk'
31 31
32 32 #-----------------------------------------------------------------------------
33 33 # Utility classes
34 34 #-----------------------------------------------------------------------------
35 35
36 36
37 37 class _DummyMainloop(object):
38 38 """A special manager to hijack GUI mainloops that is mostly a no-op.
39 39
40 40 We are not using this class currently as it breaks GUI code that calls
41 41 a mainloop function after the app has started to process pending events.
42 42 """
43 43 def __init__(self, ml, ihm, gui_type):
44 44 self.ml = ml
45 45 self.ihm = ihm
46 46 self.gui_type = gui_type
47 47
48 48 def __call__(self, *args, **kw):
49 49 if self.ihm.current_gui() == self.gui_type:
50 50 pass
51 51 else:
52 52 self.ml(*args, **kw)
53 53
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Appstart and spin functions
57 57 #-----------------------------------------------------------------------------
58 58
59 59
60 60 def appstart_qt4(app):
61 61 """Start the qt4 event loop in a way that plays with IPython.
62 62
63 63 When a qt4 app is run interactively in IPython, the event loop should
64 64 not be started. This function checks to see if IPython's qt4 integration
65 65 is activated and if so, it passes. If not, it will call the :meth:`exec_`
66 66 method of the main qt4 app.
67 67
68 68 This function should be used by users who want their qt4 scripts to work
69 69 both at the command line and in IPython. These users should put the
70 70 following logic at the bottom on their script, after they create a
71 71 :class:`QApplication` instance (called ``app`` here)::
72 72
73 73 try:
74 74 from IPython.lib.inputhook import appstart_qt4
75 75 appstart_qt4(app)
76 76 except ImportError:
77 77 app.exec_()
78 78 """
79 from PyQt4 import QtCore, QtGui
79 from PyQt4 import QtCore
80 80
81 81 assert isinstance(app, QtCore.QCoreApplication)
82 82 if app is not None:
83 83 if current_gui() == GUI_QT4:
84 84 pass
85 85 else:
86 86 app.exec_()
87 87
88 88
89 89 def appstart_wx(app):
90 90 """Start the wx event loop in a way that plays with IPython.
91 91
92 92 When a wx app is run interactively in IPython, the event loop should
93 93 not be started. This function checks to see if IPython's wx integration
94 94 is activated and if so, it passes. If not, it will call the
95 95 :meth:`MainLoop` method of the main qt4 app.
96 96
97 97 This function should be used by users who want their wx scripts to work
98 98 both at the command line and in IPython. These users should put the
99 99 following logic at the bottom on their script, after they create a
100 100 :class:`App` instance (called ``app`` here)::
101 101
102 102 try:
103 103 from IPython.lib.inputhook import appstart_wx
104 104 appstart_wx(app)
105 105 except ImportError:
106 106 app.MainLoop()
107 107 """
108 108 import wx
109 109
110 110 assert isinstance(app, wx.App)
111 111 if app is not None:
112 112 if current_gui() == GUI_WX:
113 113 pass
114 114 else:
115 115 app.MainLoop()
116 116
117 117
118 118 def appstart_tk(app):
119 119 """Start the tk event loop in a way that plays with IPython.
120 120
121 121 When a tk app is run interactively in IPython, the event loop should
122 122 not be started. This function checks to see if IPython's tk integration
123 123 is activated and if so, it passes. If not, it will call the
124 124 :meth:`mainloop` method of the tk object passed to this method.
125 125
126 126 This function should be used by users who want their tk scripts to work
127 127 both at the command line and in IPython. These users should put the
128 128 following logic at the bottom on their script, after they create a
129 129 :class:`Tk` instance (called ``app`` here)::
130 130
131 131 try:
132 132 from IPython.lib.inputhook import appstart_tk
133 133 appstart_tk(app)
134 134 except ImportError:
135 135 app.mainloop()
136 136 """
137 137 if app is not None:
138 138 if current_gui() == GUI_TK:
139 139 pass
140 140 else:
141 141 app.mainloop()
142 142
143 143 def appstart_gtk():
144 144 """Start the gtk event loop in a way that plays with IPython.
145 145
146 146 When a gtk app is run interactively in IPython, the event loop should
147 147 not be started. This function checks to see if IPython's gtk integration
148 148 is activated and if so, it passes. If not, it will call
149 149 :func:`gtk.main`. Unlike the other appstart implementations, this does
150 150 not take an ``app`` argument.
151 151
152 152 This function should be used by users who want their gtk scripts to work
153 153 both at the command line and in IPython. These users should put the
154 154 following logic at the bottom on their script::
155 155
156 156 try:
157 157 from IPython.lib.inputhook import appstart_gtk
158 158 appstart_gtk()
159 159 except ImportError:
160 160 gtk.main()
161 161 """
162 162 import gtk
163 163 if current_gui() == GUI_GTK:
164 164 pass
165 165 else:
166 166 gtk.main()
167 167
168 168 #-----------------------------------------------------------------------------
169 169 # Main InputHookManager class
170 170 #-----------------------------------------------------------------------------
171 171
172 172
173 173 class InputHookManager(object):
174 174 """Manage PyOS_InputHook for different GUI toolkits.
175 175
176 176 This class installs various hooks under ``PyOSInputHook`` to handle
177 177 GUI event loop integration.
178 178 """
179 179
180 180 def __init__(self):
181 181 self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int)
182 182 self._apps = {}
183 183 self._spinner_dict = {
184 184 GUI_QT4 : self._spin_qt4,
185 185 GUI_WX : self._spin_wx,
186 186 GUI_GTK : self._spin_gtk,
187 187 GUI_TK : self._spin_tk}
188 188 self._reset()
189 189
190 190 def _reset(self):
191 191 self._callback_pyfunctype = None
192 192 self._callback = None
193 193 self._installed = False
194 194 self._current_gui = None
195 195
196 196 def _hijack_wx(self):
197 197 """Hijack the wx mainloop so a user calling it won't cause badness.
198 198
199 199 We are not currently using this as it breaks GUI code that calls a
200 200 mainloop at anytime but startup.
201 201 """
202 202 import wx
203 203 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
204 204 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
205 205 else: raise AttributeError('Could not find wx core module')
206 206 orig_mainloop = core.PyApp_MainLoop
207 207 core.PyApp_MainLoop = _DummyMainloop
208 208 return orig_mainloop
209 209
210 210 def _hijack_qt4(self):
211 211 """Hijack the qt4 mainloop so a user calling it won't cause badness.
212 212
213 213 We are not currently using this as it breaks GUI code that calls a
214 214 mainloop at anytime but startup.
215 215 """
216 216 from PyQt4 import QtGui, QtCore
217 217 orig_mainloop = QtGui.qApp.exec_
218 218 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_QT4)
219 219 QtGui.qApp.exec_ = dumb_ml
220 220 QtGui.QApplication.exec_ = dumb_ml
221 221 QtCore.QCoreApplication.exec_ = dumb_ml
222 222 return orig_mainloop
223 223
224 224 def _hijack_gtk(self):
225 225 """Hijack the gtk mainloop so a user calling it won't cause badness.
226 226
227 227 We are not currently using this as it breaks GUI code that calls a
228 228 mainloop at anytime but startup.
229 229 """
230 230 import gtk
231 231 orig_mainloop = gtk.main
232 232 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_GTK)
233 233 gtk.mainloop = dumb_ml
234 234 gtk.main = dumb_ml
235 235 return orig_mainloop
236 236
237 237 def _hijack_tk(self):
238 238 """Hijack the tk mainloop so a user calling it won't cause badness.
239 239
240 240 We are not currently using this as it breaks GUI code that calls a
241 241 mainloop at anytime but startup.
242 242 """
243 243 import Tkinter
244 # FIXME: gtk is not imported here and we shouldn't be using gtk.main!
244 245 orig_mainloop = gtk.main
245 246 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_TK)
246 247 Tkinter.Misc.mainloop = dumb_ml
247 248 Tkinter.mainloop = dumb_ml
248 249
249 250 def _spin_qt4(self):
250 251 """Process all pending events in the qt4 event loop.
251 252
252 253 This is for internal IPython use only and user code should not call this.
253 254 Instead, they should issue the raw GUI calls themselves.
254 255 """
255 from PyQt4 import QtCore, QtGui
256 from PyQt4 import QtCore
256 257
257 258 app = QtCore.QCoreApplication.instance()
258 259 if app is not None:
259 260 QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents)
260 261
261 262 def _spin_wx(self):
262 263 """Process all pending events in the wx event loop.
263 264
264 265 This is for internal IPython use only and user code should not call this.
265 266 Instead, they should issue the raw GUI calls themselves.
266 267 """
267 268 import wx
268 269 app = wx.GetApp()
269 270 if app is not None and wx.Thread_IsMain():
270 271 evtloop = wx.EventLoop()
271 272 ea = wx.EventLoopActivator(evtloop)
272 273 while evtloop.Pending():
273 274 evtloop.Dispatch()
274 275 app.ProcessIdle()
275 276 del ea
276 277
277 278 def _spin_gtk(self):
278 279 """Process all pending events in the gtk event loop.
279 280
280 281 This is for internal IPython use only and user code should not call this.
281 282 Instead, they should issue the raw GUI calls themselves.
282 283 """
283 284 import gtk
284 285 gtk.gdk.threads_enter()
285 286 while gtk.events_pending():
286 287 gtk.main_iteration(False)
287 288 gtk.gdk.flush()
288 289 gtk.gdk.threads_leave()
289 290
290 291 def _spin_tk(self):
291 292 """Process all pending events in the tk event loop.
292 293
293 294 This is for internal IPython use only and user code should not call this.
294 295 Instead, they should issue the raw GUI calls themselves.
295 296 """
296 297 app = self._apps.get(GUI_TK)
297 298 if app is not None:
298 299 app.update()
299 300
300 301 def spin(self):
301 302 """Process pending events in the current gui.
302 303
303 304 This method is just provided for IPython to use internally if needed
304 305 for things like testing. Third party projects should not call this
305 306 method, but instead should call the underlying GUI toolkit methods
306 307 that we are calling.
307 308 """
308 309 spinner = self._spinner_dict.get(self._current_gui, lambda: None)
309 310 spinner()
310 311
311 312 def get_pyos_inputhook(self):
312 313 """Return the current PyOS_InputHook as a ctypes.c_void_p."""
313 314 return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook")
314 315
315 316 def get_pyos_inputhook_as_func(self):
316 317 """Return the current PyOS_InputHook as a ctypes.PYFUNCYPE."""
317 318 return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook")
318 319
319 320 def set_inputhook(self, callback):
320 321 """Set PyOS_InputHook to callback and return the previous one."""
321 322 self._callback = callback
322 323 self._callback_pyfunctype = self.PYFUNC(callback)
323 324 pyos_inputhook_ptr = self.get_pyos_inputhook()
324 325 original = self.get_pyos_inputhook_as_func()
325 326 pyos_inputhook_ptr.value = \
326 327 ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value
327 328 self._installed = True
328 329 return original
329 330
330 331 def clear_inputhook(self, app=None):
331 332 """Set PyOS_InputHook to NULL and return the previous one.
332 333
333 334 Parameters
334 335 ----------
335 336 app : optional, ignored
336 337 This parameter is allowed only so that clear_inputhook() can be
337 338 called with a similar interface as all the ``enable_*`` methods. But
338 339 the actual value of the parameter is ignored. This uniform interface
339 340 makes it easier to have user-level entry points in the main IPython
340 341 app like :meth:`enable_gui`."""
341 342 pyos_inputhook_ptr = self.get_pyos_inputhook()
342 343 original = self.get_pyos_inputhook_as_func()
343 344 pyos_inputhook_ptr.value = ctypes.c_void_p(None).value
344 345 self._reset()
345 346 return original
346 347
347 348 def clear_app_refs(self, gui=None):
348 349 """Clear IPython's internal reference to an application instance.
349 350
350 351 Whenever we create an app for a user on qt4 or wx, we hold a
351 352 reference to the app. This is needed because in some cases bad things
352 353 can happen if a user doesn't hold a reference themselves. This
353 354 method is provided to clear the references we are holding.
354 355
355 356 Parameters
356 357 ----------
357 358 gui : None or str
358 359 If None, clear all app references. If ('wx', 'qt4') clear
359 360 the app for that toolkit. References are not held for gtk or tk
360 361 as those toolkits don't have the notion of an app.
361 362 """
362 363 if gui is None:
363 364 self._apps = {}
364 365 elif self._apps.has_key(gui):
365 366 del self._apps[gui]
366 367
367 368 def enable_wx(self, app=False):
368 369 """Enable event loop integration with wxPython.
369 370
370 371 Parameters
371 372 ----------
372 373 app : bool
373 374 Create a running application object or not.
374 375
375 376 Notes
376 377 -----
377 378 This methods sets the ``PyOS_InputHook`` for wxPython, which allows
378 379 the wxPython to integrate with terminal based applications like
379 380 IPython.
380 381
381 382 If ``app`` is True, we create an :class:`wx.App` as follows::
382 383
383 384 import wx
384 385 app = wx.App(redirect=False, clearSigInt=False)
385 386
386 387 Both options this constructor are important for things to work
387 388 properly in an interactive context.
388 389
389 390 But, we first check to see if an application has already been
390 391 created. If so, we simply return that instance.
391 392 """
392 393 from IPython.lib.inputhookwx import inputhook_wx
393 394 self.set_inputhook(inputhook_wx)
394 395 self._current_gui = GUI_WX
395 396 if app:
396 397 import wx
397 398 app = wx.GetApp()
398 399 if app is None:
399 400 app = wx.App(redirect=False, clearSigInt=False)
400 401 self._apps[GUI_WX] = app
401 402 return app
402 403
403 404 def disable_wx(self):
404 405 """Disable event loop integration with wxPython.
405 406
406 407 This merely sets PyOS_InputHook to NULL.
407 408 """
408 409 self.clear_inputhook()
409 410
410 411 def enable_qt4(self, app=False):
411 412 """Enable event loop integration with PyQt4.
412 413
413 414 Parameters
414 415 ----------
415 416 app : bool
416 417 Create a running application object or not.
417 418
418 419 Notes
419 420 -----
420 421 This methods sets the PyOS_InputHook for PyQt4, which allows
421 422 the PyQt4 to integrate with terminal based applications like
422 423 IPython.
423 424
424 425 If ``app`` is True, we create an :class:`QApplication` as follows::
425 426
426 427 from PyQt4 import QtCore
427 428 app = QtGui.QApplication(sys.argv)
428 429
429 430 But, we first check to see if an application has already been
430 431 created. If so, we simply return that instance.
431 432 """
432 433 from PyQt4 import QtCore
433 434 # PyQt4 has had this since 4.3.1. In version 4.2, PyOS_InputHook
434 435 # was set when QtCore was imported, but if it ever got removed,
435 436 # you couldn't reset it. For earlier versions we can
436 437 # probably implement a ctypes version.
437 438 try:
438 439 QtCore.pyqtRestoreInputHook()
439 440 except AttributeError:
440 441 pass
441 442 self._current_gui = GUI_QT4
442 443 if app:
443 444 from PyQt4 import QtGui
444 445 app = QtCore.QCoreApplication.instance()
445 446 if app is None:
446 447 app = QtGui.QApplication(sys.argv)
447 448 self._apps[GUI_QT4] = app
448 449 return app
449 450
450 451 def disable_qt4(self):
451 452 """Disable event loop integration with PyQt4.
452 453
453 454 This merely sets PyOS_InputHook to NULL.
454 455 """
455 456 self.clear_inputhook()
456 457
457 458 def enable_gtk(self, app=False):
458 459 """Enable event loop integration with PyGTK.
459 460
460 461 Parameters
461 462 ----------
462 463 app : bool
463 464 Create a running application object or not. Because gtk does't
464 465 have an app class, this does nothing.
465 466
466 467 Notes
467 468 -----
468 469 This methods sets the PyOS_InputHook for PyGTK, which allows
469 470 the PyGTK to integrate with terminal based applications like
470 471 IPython.
471 472 """
472 473 import gtk
473 474 try:
474 475 gtk.set_interactive(True)
475 476 self._current_gui = GUI_GTK
476 477 except AttributeError:
477 478 # For older versions of gtk, use our own ctypes version
478 479 from IPython.lib.inputhookgtk import inputhook_gtk
479 480 self.set_inputhook(inputhook_gtk)
480 481 self._current_gui = GUI_GTK
481 482
482 483 def disable_gtk(self):
483 484 """Disable event loop integration with PyGTK.
484 485
485 486 This merely sets PyOS_InputHook to NULL.
486 487 """
487 488 self.clear_inputhook()
488 489
489 490 def enable_tk(self, app=False):
490 491 """Enable event loop integration with Tk.
491 492
492 493 Parameters
493 494 ----------
494 495 app : bool
495 496 Create a running application object or not.
496 497
497 498 Notes
498 499 -----
499 500 Currently this is a no-op as creating a :class:`Tkinter.Tk` object
500 501 sets ``PyOS_InputHook``.
501 502 """
502 503 self._current_gui = GUI_TK
503 504 if app:
504 505 import Tkinter
505 506 app = Tkinter.Tk()
506 507 app.withdraw()
507 508 self._apps[GUI_TK] = app
508 509 return app
509 510
510 511 def disable_tk(self):
511 512 """Disable event loop integration with Tkinter.
512 513
513 514 This merely sets PyOS_InputHook to NULL.
514 515 """
515 516 self.clear_inputhook()
516 517
517 518 def current_gui(self):
518 519 """Return a string indicating the currently active GUI or None."""
519 520 return self._current_gui
520 521
521 522 inputhook_manager = InputHookManager()
522 523
523 524 enable_wx = inputhook_manager.enable_wx
524 525 disable_wx = inputhook_manager.disable_wx
525 526 enable_qt4 = inputhook_manager.enable_qt4
526 527 disable_qt4 = inputhook_manager.disable_qt4
527 528 enable_gtk = inputhook_manager.enable_gtk
528 529 disable_gtk = inputhook_manager.disable_gtk
529 530 enable_tk = inputhook_manager.enable_tk
530 531 disable_tk = inputhook_manager.disable_tk
531 532 clear_inputhook = inputhook_manager.clear_inputhook
532 533 set_inputhook = inputhook_manager.set_inputhook
533 534 current_gui = inputhook_manager.current_gui
534 535 clear_app_refs = inputhook_manager.clear_app_refs
535 536 spin = inputhook_manager.spin
536 537
537 538
538 539 # Convenience function to switch amongst them
539 540 def enable_gui(gui=None, app=True):
540 541 """Switch amongst GUI input hooks by name.
541 542
542 543 This is just a utility wrapper around the methods of the InputHookManager
543 544 object.
544 545
545 546 Parameters
546 547 ----------
547 548 gui : optional, string or None
548 549 If None, clears input hook, otherwise it must be one of the recognized
549 550 GUI names (see ``GUI_*`` constants in module).
550 551
551 552 app : optional, bool
552 553 If true, create an app object and return it.
553 554
554 555 Returns
555 556 -------
556 557 The output of the underlying gui switch routine, typically the actual
557 558 PyOS_InputHook wrapper object or the GUI toolkit app created, if there was
558 559 one.
559 560 """
560 561 guis = {None: clear_inputhook,
561 562 GUI_TK: enable_tk,
562 563 GUI_GTK: enable_gtk,
563 564 GUI_WX: enable_wx,
564 565 GUI_QT: enable_qt4, # qt3 not supported
565 566 GUI_QT4: enable_qt4 }
566 567 try:
567 568 gui_hook = guis[gui]
568 569 except KeyError:
569 570 e="Invalid GUI request %r, valid ones are:%s" % (gui, guis.keys())
570 571 raise ValueError(e)
571 572 return gui_hook(app)
@@ -1,147 +1,179 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Pylab (matplotlib) support utilities.
3 3
4 4 Authors
5 5 -------
6 6 Fernando Perez.
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2009 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 from IPython.utils.decorators import flag_calls
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Main classes and functions
24 24 #-----------------------------------------------------------------------------
25 25
26 def pylab_activate(user_ns, gui=None, import_all=True):
27 """Activate pylab mode in the user's namespace.
28 26
29 Loads and initializes numpy, matplotlib and friends for interactive use.
27 def find_gui_and_backend(gui=None):
28 """Given a gui string return the gui and mpl backend.
30 29
31 30 Parameters
32 31 ----------
33 user_ns : dict
34 Namespace where the imports will occur.
35
36 gui : optional, string
37 A valid gui name following the conventions of the %gui magic.
38
39 import_all : optional, boolean
40 If true, an 'import *' is done from numpy and pylab.
32 gui : str
33 Can be one of ('tk','gtk','wx','qt','qt4','payload-svg').
41 34
42 35 Returns
43 36 -------
44 The actual gui used (if not given as input, it was obtained from matplotlib
45 itself, and will be needed next to configure IPython's gui integration.
37 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
38 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_payload_svg').
46 39 """
47 40
48 # Initialize matplotlib to interactive mode always
49 41 import matplotlib
50 42
51 43 # If user specifies a GUI, that dictates the backend, otherwise we read the
52 44 # user's mpl default from the mpl rc structure
53 45 g2b = {'tk': 'TkAgg',
54 46 'gtk': 'GTKAgg',
55 47 'wx': 'WXAgg',
56 48 'qt': 'Qt4Agg', # qt3 not supported
57 'qt4': 'Qt4Agg' }
49 'qt4': 'Qt4Agg',
50 'payload-svg' : \
51 'module://IPython.zmq.pylab.backend_payload_svg'}
58 52
59 53 if gui:
60 54 # select backend based on requested gui
61 55 backend = g2b[gui]
62 56 else:
63 57 backend = matplotlib.rcParams['backend']
64 58 # In this case, we need to find what the appropriate gui selection call
65 59 # should be for IPython, so we can activate inputhook accordingly
66 60 b2g = dict(zip(g2b.values(),g2b.keys()))
67 61 gui = b2g.get(backend, None)
62 return gui, backend
63
64
65 def activate_matplotlib(backend):
66 """Activate the given backend and set interactive to True."""
67
68 import matplotlib
69 if backend.startswith('module://'):
70 # Work around bug in matplotlib: matplotlib.use converts the
71 # backend_id to lowercase even if a module name is specified!
72 matplotlib.rcParams['backend'] = backend
73 else:
74 matplotlib.use(backend)
75 matplotlib.interactive(True)
68 76
69 # We must set the desired backend before importing pylab
70 matplotlib.use(backend)
71
72 77 # This must be imported last in the matplotlib series, after
73 78 # backend/interactivity choices have been made
74 79 import matplotlib.pylab as pylab
75 80
76 81 # XXX For now leave this commented out, but depending on discussions with
77 82 # mpl-dev, we may be able to allow interactive switching...
78 83 #import matplotlib.pyplot
79 84 #matplotlib.pyplot.switch_backend(backend)
80 85
81 86 pylab.show._needmain = False
82 87 # We need to detect at runtime whether show() is called by the user.
83 88 # For this, we wrap it into a decorator which adds a 'called' flag.
84 89 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
85 90
91 def import_pylab(user_ns, import_all=True):
92 """Import the standard pylab symbols into user_ns."""
93
86 94 # Import numpy as np/pyplot as plt are conventions we're trying to
87 95 # somewhat standardize on. Making them available to users by default
88 96 # will greatly help this.
89 97 exec ("import numpy\n"
90 98 "import matplotlib\n"
91 99 "from matplotlib import pylab, mlab, pyplot\n"
92 100 "np = numpy\n"
93 101 "plt = pyplot\n"
94 102 ) in user_ns
95 103
96 104 if import_all:
97 105 exec("from matplotlib.pylab import *\n"
98 106 "from numpy import *\n") in user_ns
99 107
100 matplotlib.interactive(True)
108
109 def pylab_activate(user_ns, gui=None, import_all=True):
110 """Activate pylab mode in the user's namespace.
111
112 Loads and initializes numpy, matplotlib and friends for interactive use.
113
114 Parameters
115 ----------
116 user_ns : dict
117 Namespace where the imports will occur.
118
119 gui : optional, string
120 A valid gui name following the conventions of the %gui magic.
121
122 import_all : optional, boolean
123 If true, an 'import *' is done from numpy and pylab.
124
125 Returns
126 -------
127 The actual gui used (if not given as input, it was obtained from matplotlib
128 itself, and will be needed next to configure IPython's gui integration.
129 """
130 gui, backend = find_gui_and_backend(gui)
131 activate_matplotlib(backend)
132 import_pylab(user_ns)
101 133
102 134 print """
103 135 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
104 136 For more information, type 'help(pylab)'.""" % backend
105 137
106 138 return gui
107 139
108 140 # We need a little factory function here to create the closure where
109 141 # safe_execfile can live.
110 142 def mpl_runner(safe_execfile):
111 143 """Factory to return a matplotlib-enabled runner for %run.
112 144
113 145 Parameters
114 146 ----------
115 147 safe_execfile : function
116 148 This must be a function with the same interface as the
117 149 :meth:`safe_execfile` method of IPython.
118 150
119 151 Returns
120 152 -------
121 153 A function suitable for use as the ``runner`` argument of the %run magic
122 154 function.
123 155 """
124 156
125 157 def mpl_execfile(fname,*where,**kw):
126 158 """matplotlib-aware wrapper around safe_execfile.
127 159
128 160 Its interface is identical to that of the :func:`execfile` builtin.
129 161
130 162 This is ultimately a call to execfile(), but wrapped in safeties to
131 163 properly handle interactive rendering."""
132 164
133 165 import matplotlib
134 166 import matplotlib.pylab as pylab
135 167
136 168 #print '*** Matplotlib runner ***' # dbg
137 169 # turn off rendering until end of script
138 170 is_interactive = matplotlib.rcParams['interactive']
139 171 matplotlib.interactive(False)
140 172 safe_execfile(fname,*where,**kw)
141 173 matplotlib.interactive(is_interactive)
142 174 # make rendering call now, if the user tried to do it
143 175 if pylab.draw_if_interactive.called:
144 176 pylab.draw()
145 177 pylab.draw_if_interactive.called = False
146 178
147 179 return mpl_execfile
@@ -1,196 +1,201 b''
1 1 """ Defines helper functions for creating kernel entry points and process
2 2 launchers.
3 3 """
4 4
5 5 # Standard library imports.
6 import os
6 7 import socket
7 8 from subprocess import Popen
8 9 import sys
9 10
10 11 # System library imports.
11 12 import zmq
12 13
13 14 # Local imports.
14 15 from IPython.core.ultratb import FormattedTB
15 16 from IPython.external.argparse import ArgumentParser
16 17 from IPython.utils import io
17 18 from exitpoller import ExitPollerUnix, ExitPollerWindows
18 19 from displayhook import DisplayHook
19 20 from iostream import OutStream
20 21 from session import Session
21 22
22 23
23 24 def bind_port(socket, ip, port):
24 25 """ Binds the specified ZMQ socket. If the port is zero, a random port is
25 26 chosen. Returns the port that was bound.
26 27 """
27 28 connection = 'tcp://%s' % ip
28 29 if port <= 0:
29 30 port = socket.bind_to_random_port(connection)
30 31 else:
31 32 connection += ':%i' % port
32 33 socket.bind(connection)
33 34 return port
34 35
35 36
36 37 def make_argument_parser():
37 38 """ Creates an ArgumentParser for the generic arguments supported by all
38 39 kernel entry points.
39 40 """
40 41 parser = ArgumentParser()
41 42 parser.add_argument('--ip', type=str, default='127.0.0.1',
42 43 help='set the kernel\'s IP address [default: local]')
43 44 parser.add_argument('--xrep', type=int, metavar='PORT', default=0,
44 45 help='set the XREP channel port [default: random]')
45 46 parser.add_argument('--pub', type=int, metavar='PORT', default=0,
46 47 help='set the PUB channel port [default: random]')
47 48 parser.add_argument('--req', type=int, metavar='PORT', default=0,
48 49 help='set the REQ channel port [default: random]')
49 50
50 51 if sys.platform == 'win32':
51 52 parser.add_argument('--parent', type=int, metavar='HANDLE',
52 53 default=0, help='kill this process if the process '
53 54 'with HANDLE dies')
54 55 else:
55 56 parser.add_argument('--parent', action='store_true',
56 57 help='kill this process if its parent dies')
57 58
58 59 return parser
59 60
60 61
61 62 def make_kernel(namespace, kernel_factory,
62 63 out_stream_factory=None, display_hook_factory=None):
63 64 """ Creates a kernel.
64 65 """
65 66 # Install minimal exception handling
66 sys.excepthook = FormattedTB(mode='Verbose', ostream=sys.__stdout__)
67 color_scheme = 'LightBG' if sys.platform == 'darwin' else 'Linux'
68 sys.excepthook = FormattedTB(
69 mode='Verbose', color_scheme=color_scheme, ostream=sys.__stdout__
70 )
67 71
68 72 # Create a context, a session, and the kernel sockets.
69 73 io.rprint("Starting the kernel...")
70 74 context = zmq.Context()
71 75 session = Session(username=u'kernel')
72 76
73 77 reply_socket = context.socket(zmq.XREP)
74 78 xrep_port = bind_port(reply_socket, namespace.ip, namespace.xrep)
75 79 io.rprint("XREP Channel on port", xrep_port)
76 80
77 81 pub_socket = context.socket(zmq.PUB)
78 82 pub_port = bind_port(pub_socket, namespace.ip, namespace.pub)
79 83 io.rprint("PUB Channel on port", pub_port)
80 84
81 85 req_socket = context.socket(zmq.XREQ)
82 86 req_port = bind_port(req_socket, namespace.ip, namespace.req)
83 87 io.rprint("REQ Channel on port", req_port)
84 88
85 89 # Redirect input streams and set a display hook.
86 90 if out_stream_factory:
91 pass
87 92 sys.stdout = out_stream_factory(session, pub_socket, u'stdout')
88 93 sys.stderr = out_stream_factory(session, pub_socket, u'stderr')
89 94 if display_hook_factory:
90 95 sys.displayhook = display_hook_factory(session, pub_socket)
91 96
92 97 # Create the kernel.
93 98 return kernel_factory(session=session, reply_socket=reply_socket,
94 99 pub_socket=pub_socket, req_socket=req_socket)
95 100
96 101
97 102 def start_kernel(namespace, kernel):
98 103 """ Starts a kernel.
99 104 """
100 105 # Configure this kernel/process to die on parent termination, if necessary.
101 106 if namespace.parent:
102 107 if sys.platform == 'win32':
103 108 poller = ExitPollerWindows(namespace.parent)
104 109 else:
105 110 poller = ExitPollerUnix()
106 111 poller.start()
107 112
108 113 # Start the kernel mainloop.
109 114 kernel.start()
110 115
111 116
112 117 def make_default_main(kernel_factory):
113 118 """ Creates the simplest possible kernel entry point.
114 119 """
115 120 def main():
116 121 namespace = make_argument_parser().parse_args()
117 122 kernel = make_kernel(namespace, kernel_factory, OutStream, DisplayHook)
118 123 start_kernel(namespace, kernel)
119 124 return main
120 125
121 126
122 127 def base_launch_kernel(code, xrep_port=0, pub_port=0, req_port=0,
123 128 independent=False, extra_arguments=[]):
124 129 """ Launches a localhost kernel, binding to the specified ports.
125 130
126 131 Parameters
127 132 ----------
128 133 code : str,
129 134 A string of Python code that imports and executes a kernel entry point.
130 135
131 136 xrep_port : int, optional
132 137 The port to use for XREP channel.
133 138
134 139 pub_port : int, optional
135 140 The port to use for the SUB channel.
136 141
137 142 req_port : int, optional
138 143 The port to use for the REQ (raw input) channel.
139 144
140 145 independent : bool, optional (default False)
141 146 If set, the kernel process is guaranteed to survive if this process
142 147 dies. If not set, an effort is made to ensure that the kernel is killed
143 148 when this process dies. Note that in this case it is still good practice
144 149 to kill kernels manually before exiting.
145 150
146 151 extra_arguments = list, optional
147 152 A list of extra arguments to pass when executing the launch code.
148 153
149 154 Returns
150 155 -------
151 156 A tuple of form:
152 157 (kernel_process, xrep_port, pub_port, req_port)
153 158 where kernel_process is a Popen object and the ports are integers.
154 159 """
155 160 # Find open ports as necessary.
156 161 ports = []
157 162 ports_needed = int(xrep_port <= 0) + int(pub_port <= 0) + int(req_port <= 0)
158 163 for i in xrange(ports_needed):
159 164 sock = socket.socket()
160 165 sock.bind(('', 0))
161 166 ports.append(sock)
162 167 for i, sock in enumerate(ports):
163 168 port = sock.getsockname()[1]
164 169 sock.close()
165 170 ports[i] = port
166 171 if xrep_port <= 0:
167 172 xrep_port = ports.pop(0)
168 173 if pub_port <= 0:
169 174 pub_port = ports.pop(0)
170 175 if req_port <= 0:
171 176 req_port = ports.pop(0)
172 177
173 178 # Build the kernel launch command.
174 179 arguments = [ sys.executable, '-c', code, '--xrep', str(xrep_port),
175 180 '--pub', str(pub_port), '--req', str(req_port) ]
176 181 arguments.extend(extra_arguments)
177 182
178 183 # Spawn a kernel.
179 184 if independent:
180 185 if sys.platform == 'win32':
181 186 proc = Popen(['start', '/b'] + arguments, shell=True)
182 187 else:
183 188 proc = Popen(arguments, preexec_fn=lambda: os.setsid())
184 189 else:
185 190 if sys.platform == 'win32':
186 191 from _subprocess import DuplicateHandle, GetCurrentProcess, \
187 192 DUPLICATE_SAME_ACCESS
188 193 pid = GetCurrentProcess()
189 194 handle = DuplicateHandle(pid, pid, pid, 0,
190 195 True, # Inheritable by new processes.
191 196 DUPLICATE_SAME_ACCESS)
192 197 proc = Popen(arguments + ['--parent', str(int(handle))])
193 198 else:
194 199 proc = Popen(arguments + ['--parent'])
195 200
196 201 return proc, xrep_port, pub_port, req_port
@@ -1,400 +1,456 b''
1 1 #!/usr/bin/env python
2 2 """A simple interactive kernel that talks to a frontend over 0MQ.
3 3
4 4 Things to do:
5 5
6 6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
7 7 call set_parent on all the PUB objects with the message about to be executed.
8 8 * Implement random port and security key logic.
9 9 * Implement control messages.
10 10 * Implement event loop and poll version.
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Standard library imports.
19 19 import __builtin__
20 20 import sys
21 21 import time
22 22 import traceback
23 23
24 24 # System library imports.
25 25 import zmq
26 26
27 27 # Local imports.
28 28 from IPython.config.configurable import Configurable
29 29 from IPython.utils import io
30 from IPython.lib import pylabtools
30 31 from IPython.utils.traitlets import Instance
31 from completer import KernelCompleter
32 32 from entry_point import base_launch_kernel, make_argument_parser, make_kernel, \
33 33 start_kernel
34 34 from iostream import OutStream
35 35 from session import Session, Message
36 36 from zmqshell import ZMQInteractiveShell
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Main kernel class
40 40 #-----------------------------------------------------------------------------
41 41
42 42 class Kernel(Configurable):
43 43
44 44 #---------------------------------------------------------------------------
45 45 # Kernel interface
46 46 #---------------------------------------------------------------------------
47 47
48 48 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
49 49 session = Instance(Session)
50 50 reply_socket = Instance('zmq.Socket')
51 51 pub_socket = Instance('zmq.Socket')
52 52 req_socket = Instance('zmq.Socket')
53 53
54 # Maps user-friendly backend names to matplotlib backend identifiers.
55 _pylab_map = { 'tk': 'TkAgg',
56 'gtk': 'GTKAgg',
57 'wx': 'WXAgg',
58 'qt': 'Qt4Agg', # qt3 not supported
59 'qt4': 'Qt4Agg',
60 'payload-svg' : \
61 'module://IPython.zmq.pylab.backend_payload_svg' }
62
63 54 def __init__(self, **kwargs):
64 55 super(Kernel, self).__init__(**kwargs)
65 56
66 57 # Initialize the InteractiveShell subclass
67 58 self.shell = ZMQInteractiveShell.instance()
68 59 self.shell.displayhook.session = self.session
69 60 self.shell.displayhook.pub_socket = self.pub_socket
70 61
71 62 # TMP - hack while developing
72 63 self.shell._reply_content = None
73 64
74 65 # Build dict of handlers for message types
75 66 msg_types = [ 'execute_request', 'complete_request',
76 67 'object_info_request', 'prompt_request',
77 68 'history_request' ]
78 69 self.handlers = {}
79 70 for msg_type in msg_types:
80 71 self.handlers[msg_type] = getattr(self, msg_type)
81 72
82 def activate_pylab(self, backend=None, import_all=True):
83 """ Activates pylab in this kernel's namespace.
84
85 Parameters:
86 -----------
87 backend : str, optional
88 A valid backend name.
89
90 import_all : bool, optional
91 If true, an 'import *' is done from numpy and pylab.
92 """
93 # FIXME: This is adapted from IPython.lib.pylabtools.pylab_activate.
94 # Common functionality should be refactored.
95
96 # We must set the desired backend before importing pylab.
97 import matplotlib
98 if backend:
99 backend_id = self._pylab_map[backend]
100 if backend_id.startswith('module://'):
101 # Work around bug in matplotlib: matplotlib.use converts the
102 # backend_id to lowercase even if a module name is specified!
103 matplotlib.rcParams['backend'] = backend_id
73 def do_one_iteration(self):
74 try:
75 ident = self.reply_socket.recv(zmq.NOBLOCK)
76 except zmq.ZMQError, e:
77 if e.errno == zmq.EAGAIN:
78 return
104 79 else:
105 matplotlib.use(backend_id)
106
107 # Import numpy as np/pyplot as plt are conventions we're trying to
108 # somewhat standardize on. Making them available to users by default
109 # will greatly help this.
110 exec ("import numpy\n"
111 "import matplotlib\n"
112 "from matplotlib import pylab, mlab, pyplot\n"
113 "np = numpy\n"
114 "plt = pyplot\n"
115 ) in self.shell.user_ns
116
117 if import_all:
118 exec("from matplotlib.pylab import *\n"
119 "from numpy import *\n") in self.shell.user_ns
120
121 matplotlib.interactive(True)
80 raise
81 # FIXME: Bug in pyzmq/zmq?
82 # assert self.reply_socket.rcvmore(), "Missing message part."
83 msg = self.reply_socket.recv_json()
84 omsg = Message(msg)
85 io.rprint('\n')
86 io.rprint(omsg)
87 handler = self.handlers.get(omsg.msg_type, None)
88 if handler is None:
89 io.rprinte("UNKNOWN MESSAGE TYPE:", omsg)
90 else:
91 handler(ident, omsg)
122 92
123 93 def start(self):
124 94 """ Start the kernel main loop.
125 95 """
126 96 while True:
127 ident = self.reply_socket.recv()
128 assert self.reply_socket.rcvmore(), "Missing message part."
129 msg = self.reply_socket.recv_json()
130 omsg = Message(msg)
131 io.rprint('\n', omsg)
132 handler = self.handlers.get(omsg.msg_type, None)
133 if handler is None:
134 io.rprinte("UNKNOWN MESSAGE TYPE:", omsg)
135 else:
136 handler(ident, omsg)
97 time.sleep(0.05)
98 self.do_one_iteration()
99
137 100
138 101 #---------------------------------------------------------------------------
139 102 # Kernel request handlers
140 103 #---------------------------------------------------------------------------
141 104
142 105 def execute_request(self, ident, parent):
143 106 try:
144 107 code = parent[u'content'][u'code']
145 108 except:
146 109 io.rprinte("Got bad msg: ")
147 110 io.rprinte(Message(parent))
148 111 return
149 112 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
150 113 self.pub_socket.send_json(pyin_msg)
151 114
152 115 try:
153 116 # Replace raw_input. Note that is not sufficient to replace
154 117 # raw_input in the user namespace.
155 118 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
156 119 __builtin__.raw_input = raw_input
157 120
158 121 # Set the parent message of the display hook and out streams.
159 122 self.shell.displayhook.set_parent(parent)
160 123 sys.stdout.set_parent(parent)
161 124 sys.stderr.set_parent(parent)
162 125
163 126 # FIXME: runlines calls the exception handler itself. We should
164 127 # clean this up.
165 128 self.shell._reply_content = None
166 129 self.shell.runlines(code)
167 130 except:
168 131 # FIXME: this code right now isn't being used yet by default,
169 132 # because the runlines() call above directly fires off exception
170 133 # reporting. This code, therefore, is only active in the scenario
171 134 # where runlines itself has an unhandled exception. We need to
172 135 # uniformize this, for all exception construction to come from a
173 136 # single location in the codbase.
174 137 etype, evalue, tb = sys.exc_info()
175 138 tb_list = traceback.format_exception(etype, evalue, tb)
176 139 reply_content = self.shell._showtraceback(etype, evalue, tb_list)
177 140 else:
178 141 payload = self.shell.payload_manager.read_payload()
179 142 # Be agressive about clearing the payload because we don't want
180 143 # it to sit in memory until the next execute_request comes in.
181 144 self.shell.payload_manager.clear_payload()
182 145 reply_content = { 'status' : 'ok', 'payload' : payload }
183 146
184 147 # Compute the prompt information
185 148 prompt_number = self.shell.displayhook.prompt_count
186 149 reply_content['prompt_number'] = prompt_number
187 150 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
188 151 next_prompt = {'prompt_string' : prompt_string,
189 152 'prompt_number' : prompt_number+1,
190 153 'input_sep' : self.shell.displayhook.input_sep}
191 154 reply_content['next_prompt'] = next_prompt
192 155
193 156 # TMP - fish exception info out of shell, possibly left there by
194 157 # runlines
195 158 if self.shell._reply_content is not None:
196 159 reply_content.update(self.shell._reply_content)
197 160
198 161 # Flush output before sending the reply.
199 162 sys.stderr.flush()
200 163 sys.stdout.flush()
201 164
202 165 # Send the reply.
203 166 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
204 167 io.rprint(Message(reply_msg))
205 168 self.reply_socket.send(ident, zmq.SNDMORE)
206 169 self.reply_socket.send_json(reply_msg)
207 170 if reply_msg['content']['status'] == u'error':
208 171 self._abort_queue()
209 172
210 173 def complete_request(self, ident, parent):
211 174 txt, matches = self._complete(parent)
212 175 matches = {'matches' : matches,
213 176 'matched_text' : txt,
214 177 'status' : 'ok'}
215 178 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
216 179 matches, parent, ident)
217 180 io.rprint(completion_msg)
218 181
219 182 def object_info_request(self, ident, parent):
220 183 context = parent['content']['oname'].split('.')
221 184 object_info = self._object_info(context)
222 185 msg = self.session.send(self.reply_socket, 'object_info_reply',
223 186 object_info, parent, ident)
224 187 io.rprint(msg)
225 188
226 189 def prompt_request(self, ident, parent):
227 190 prompt_number = self.shell.displayhook.prompt_count
228 191 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
229 192 content = {'prompt_string' : prompt_string,
230 193 'prompt_number' : prompt_number+1,
231 194 'input_sep' : self.shell.displayhook.input_sep}
232 195 msg = self.session.send(self.reply_socket, 'prompt_reply',
233 196 content, parent, ident)
234 197 io.rprint(msg)
235 198
236 199 def history_request(self, ident, parent):
237 200 output = parent['content']['output']
238 201 index = parent['content']['index']
239 202 raw = parent['content']['raw']
240 203 hist = self.shell.get_history(index=index, raw=raw, output=output)
241 204 content = {'history' : hist}
242 205 msg = self.session.send(self.reply_socket, 'history_reply',
243 206 content, parent, ident)
244 207 io.rprint(msg)
245 208
246 209 #---------------------------------------------------------------------------
247 210 # Protected interface
248 211 #---------------------------------------------------------------------------
249 212
250 213 def _abort_queue(self):
251 214 while True:
252 215 try:
253 216 ident = self.reply_socket.recv(zmq.NOBLOCK)
254 217 except zmq.ZMQError, e:
255 218 if e.errno == zmq.EAGAIN:
256 219 break
257 220 else:
258 221 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
259 222 msg = self.reply_socket.recv_json()
260 223 io.rprint("Aborting:\n", Message(msg))
261 224 msg_type = msg['msg_type']
262 225 reply_type = msg_type.split('_')[0] + '_reply'
263 226 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
264 227 io.rprint(Message(reply_msg))
265 228 self.reply_socket.send(ident,zmq.SNDMORE)
266 229 self.reply_socket.send_json(reply_msg)
267 230 # We need to wait a bit for requests to come in. This can probably
268 231 # be set shorter for true asynchronous clients.
269 232 time.sleep(0.1)
270 233
271 234 def _raw_input(self, prompt, ident, parent):
272 235 # Flush output before making the request.
273 236 sys.stderr.flush()
274 237 sys.stdout.flush()
275 238
276 239 # Send the input request.
277 240 content = dict(prompt=prompt)
278 241 msg = self.session.msg(u'input_request', content, parent)
279 242 self.req_socket.send_json(msg)
280 243
281 244 # Await a response.
282 245 reply = self.req_socket.recv_json()
283 246 try:
284 247 value = reply['content']['value']
285 248 except:
286 249 io.rprinte("Got bad raw_input reply: ")
287 250 io.rprinte(Message(parent))
288 251 value = ''
289 252 return value
290 253
291 254 def _complete(self, msg):
292 255 c = msg['content']
293 256 try:
294 257 cpos = int(c['cursor_pos'])
295 258 except:
296 259 # If we don't get something that we can convert to an integer, at
297 260 # least attempt the completion guessing the cursor is at the end of
298 261 # the text, if there's any, and otherwise of the line
299 262 cpos = len(c['text'])
300 263 if cpos==0:
301 264 cpos = len(c['line'])
302 265 return self.shell.complete(c['text'], c['line'], cpos)
303 266
304 267 def _object_info(self, context):
305 268 symbol, leftover = self._symbol_from_context(context)
306 269 if symbol is not None and not leftover:
307 270 doc = getattr(symbol, '__doc__', '')
308 271 else:
309 272 doc = ''
310 273 object_info = dict(docstring = doc)
311 274 return object_info
312 275
313 276 def _symbol_from_context(self, context):
314 277 if not context:
315 278 return None, context
316 279
317 280 base_symbol_string = context[0]
318 281 symbol = self.shell.user_ns.get(base_symbol_string, None)
319 282 if symbol is None:
320 283 symbol = __builtin__.__dict__.get(base_symbol_string, None)
321 284 if symbol is None:
322 285 return None, context
323 286
324 287 context = context[1:]
325 288 for i, name in enumerate(context):
326 289 new_symbol = getattr(symbol, name, None)
327 290 if new_symbol is None:
328 291 return symbol, context[i:]
329 292 else:
330 293 symbol = new_symbol
331 294
332 295 return symbol, []
333 296
297
298 class QtKernel(Kernel):
299 """A Kernel subclass with Qt support."""
300
301 def start(self):
302 """Start a kernel with QtPy4 event loop integration."""
303
304 from PyQt4 import QtGui, QtCore
305 self.app = QtGui.QApplication([])
306 self.app.setQuitOnLastWindowClosed (False)
307 self.timer = QtCore.QTimer()
308 self.timer.timeout.connect(self.do_one_iteration)
309 self.timer.start(50)
310 self.app.exec_()
311
312
313 class WxKernel(Kernel):
314 """A Kernel subclass with Wx support."""
315
316 def start(self):
317 """Start a kernel with wx event loop support."""
318
319 import wx
320 doi = self.do_one_iteration
321
322 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
323 # We make the Frame hidden when we create it in the main app below.
324 class TimerFrame(wx.Frame):
325 def __init__(self, func):
326 wx.Frame.__init__(self, None, -1)
327 self.timer = wx.Timer(self)
328 self.timer.Start(50)
329 self.Bind(wx.EVT_TIMER, self.on_timer)
330 self.func = func
331 def on_timer(self, event):
332 self.func()
333
334 # We need a custom wx.App to create our Frame subclass that has the
335 # wx.Timer to drive the ZMQ event loop.
336 class IPWxApp(wx.App):
337 def OnInit(self):
338 self.frame = TimerFrame(doi)
339 self.frame.Show(False)
340 return True
341
342 # The redirect=False here makes sure that wx doesn't replace
343 # sys.stdout/stderr with its own classes.
344 self.app = IPWxApp(redirect=False)
345 self.app.MainLoop()
346
347
348 class TkKernel(Kernel):
349 """A Kernel subclass with Tk support."""
350
351 def start(self):
352 """Start a Tk enabled event loop."""
353
354 import Tkinter
355 doi = self.do_one_iteration
356
357 # For Tkinter, we create a Tk object and call its withdraw method.
358 class Timer(object):
359 def __init__(self, func):
360 self.app = Tkinter.Tk()
361 self.app.withdraw()
362 self.func = func
363 def on_timer(self):
364 self.func()
365 self.app.after(50, self.on_timer)
366 def start(self):
367 self.on_timer() # Call it once to get things going.
368 self.app.mainloop()
369
370 self.timer = Timer(doi)
371 self.timer.start()
372
334 373 #-----------------------------------------------------------------------------
335 374 # Kernel main and launch functions
336 375 #-----------------------------------------------------------------------------
337 376
338 377 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False,
339 378 pylab=False):
340 379 """ Launches a localhost kernel, binding to the specified ports.
341 380
342 381 Parameters
343 382 ----------
344 383 xrep_port : int, optional
345 384 The port to use for XREP channel.
346 385
347 386 pub_port : int, optional
348 387 The port to use for the SUB channel.
349 388
350 389 req_port : int, optional
351 390 The port to use for the REQ (raw input) channel.
352 391
353 392 independent : bool, optional (default False)
354 393 If set, the kernel process is guaranteed to survive if this process
355 394 dies. If not set, an effort is made to ensure that the kernel is killed
356 395 when this process dies. Note that in this case it is still good practice
357 396 to kill kernels manually before exiting.
358 397
359 398 pylab : bool or string, optional (default False)
360 399 If not False, the kernel will be launched with pylab enabled. If a
361 400 string is passed, matplotlib will use the specified backend. Otherwise,
362 401 matplotlib's default backend will be used.
363 402
364 403 Returns
365 404 -------
366 405 A tuple of form:
367 406 (kernel_process, xrep_port, pub_port, req_port)
368 407 where kernel_process is a Popen object and the ports are integers.
369 408 """
370 409 extra_arguments = []
371 410 if pylab:
372 411 extra_arguments.append('--pylab')
373 412 if isinstance(pylab, basestring):
374 413 extra_arguments.append(pylab)
375 414 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
376 415 xrep_port, pub_port, req_port, independent,
377 416 extra_arguments)
378 417
379 418 def main():
380 419 """ The IPython kernel main entry point.
381 420 """
382 421 parser = make_argument_parser()
383 422 parser.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
384 423 const='auto', help = \
385 424 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
386 425 given, the GUI backend is matplotlib's, otherwise use one of: \
387 426 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
388 427 namespace = parser.parse_args()
389 428
390 kernel = make_kernel(namespace, Kernel, OutStream)
429 kernel_class = Kernel
430
431 _kernel_classes = {
432 'qt' : QtKernel,
433 'qt4' : QtKernel,
434 'payload-svg':Kernel,
435 'wx' : WxKernel,
436 'tk' : TkKernel
437 }
391 438 if namespace.pylab:
392 439 if namespace.pylab == 'auto':
393 kernel.activate_pylab()
440 gui, backend = pylabtools.find_gui_and_backend()
394 441 else:
395 kernel.activate_pylab(namespace.pylab)
396
442 gui, backend = pylabtools.find_gui_and_backend(namespace.pylab)
443 kernel_class = _kernel_classes.get(gui)
444 if kernel_class is None:
445 raise ValueError('GUI is not supported: %r' % gui)
446 pylabtools.activate_matplotlib(backend)
447
448 kernel = make_kernel(namespace, kernel_class, OutStream)
449
450 if namespace.pylab:
451 pylabtools.import_pylab(kernel.shell.user_ns)
452
397 453 start_kernel(namespace, kernel)
398 454
399 455 if __name__ == '__main__':
400 456 main()
@@ -1,389 +1,389 b''
1 1 import inspect
2 2 import re
3 3 import sys
4 4 from subprocess import Popen, PIPE
5 5
6 6 from IPython.core.interactiveshell import (
7 7 InteractiveShell, InteractiveShellABC
8 8 )
9 9 from IPython.core.displayhook import DisplayHook
10 10 from IPython.core.macro import Macro
11 11 from IPython.utils.io import rprint
12 12 from IPython.utils.path import get_py_filename
13 13 from IPython.utils.text import StringTypes
14 14 from IPython.utils.traitlets import Instance, Type, Dict
15 15 from IPython.utils.warn import warn
16 16 from IPython.zmq.session import extract_header
17 17 from IPython.core.payloadpage import install_payload_page
18
18 from session import Session
19 19
20 20 # Install the payload version of page.
21 21 install_payload_page()
22 22
23 23
24 24 class ZMQDisplayHook(DisplayHook):
25 25
26 session = Instance('IPython.zmq.session.Session')
26 session = Instance(Session)
27 27 pub_socket = Instance('zmq.Socket')
28 28 parent_header = Dict({})
29 29
30 30 def set_parent(self, parent):
31 31 """Set the parent for outbound messages."""
32 32 self.parent_header = extract_header(parent)
33 33
34 34 def start_displayhook(self):
35 35 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
36 36
37 37 def write_output_prompt(self):
38 38 """Write the output prompt."""
39 39 if self.do_full_cache:
40 40 self.msg['content']['output_sep'] = self.output_sep
41 41 self.msg['content']['prompt_string'] = str(self.prompt_out)
42 42 self.msg['content']['prompt_number'] = self.prompt_count
43 43 self.msg['content']['output_sep2'] = self.output_sep2
44 44
45 45 def write_result_repr(self, result_repr):
46 46 self.msg['content']['data'] = result_repr
47 47
48 48 def finish_displayhook(self):
49 49 """Finish up all displayhook activities."""
50 50 self.pub_socket.send_json(self.msg)
51 51 self.msg = None
52 52
53 53
54 54 class ZMQInteractiveShell(InteractiveShell):
55 55 """A subclass of InteractiveShell for ZMQ."""
56 56
57 57 displayhook_class = Type(ZMQDisplayHook)
58 58
59 59 def system(self, cmd):
60 60 cmd = self.var_expand(cmd, depth=2)
61 61 sys.stdout.flush()
62 62 sys.stderr.flush()
63 63 p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
64 64 for line in p.stdout.read().split('\n'):
65 65 if len(line) > 0:
66 66 print line
67 67 for line in p.stderr.read().split('\n'):
68 68 if len(line) > 0:
69 69 print line
70 70 p.wait()
71 71
72 72 def init_io(self):
73 73 # This will just use sys.stdout and sys.stderr. If you want to
74 74 # override sys.stdout and sys.stderr themselves, you need to do that
75 75 # *before* instantiating this class, because Term holds onto
76 76 # references to the underlying streams.
77 77 import IPython.utils.io
78 78 Term = IPython.utils.io.IOTerm()
79 79 IPython.utils.io.Term = Term
80 80
81 81 def magic_edit(self,parameter_s='',last_call=['','']):
82 82 """Bring up an editor and execute the resulting code.
83 83
84 84 Usage:
85 85 %edit [options] [args]
86 86
87 87 %edit runs IPython's editor hook. The default version of this hook is
88 88 set to call the __IPYTHON__.rc.editor command. This is read from your
89 89 environment variable $EDITOR. If this isn't found, it will default to
90 90 vi under Linux/Unix and to notepad under Windows. See the end of this
91 91 docstring for how to change the editor hook.
92 92
93 93 You can also set the value of this editor via the command line option
94 94 '-editor' or in your ipythonrc file. This is useful if you wish to use
95 95 specifically for IPython an editor different from your typical default
96 96 (and for Windows users who typically don't set environment variables).
97 97
98 98 This command allows you to conveniently edit multi-line code right in
99 99 your IPython session.
100 100
101 101 If called without arguments, %edit opens up an empty editor with a
102 102 temporary file and will execute the contents of this file when you
103 103 close it (don't forget to save it!).
104 104
105 105
106 106 Options:
107 107
108 108 -n <number>: open the editor at a specified line number. By default,
109 109 the IPython editor hook uses the unix syntax 'editor +N filename', but
110 110 you can configure this by providing your own modified hook if your
111 111 favorite editor supports line-number specifications with a different
112 112 syntax.
113 113
114 114 -p: this will call the editor with the same data as the previous time
115 115 it was used, regardless of how long ago (in your current session) it
116 116 was.
117 117
118 118 -r: use 'raw' input. This option only applies to input taken from the
119 119 user's history. By default, the 'processed' history is used, so that
120 120 magics are loaded in their transformed version to valid Python. If
121 121 this option is given, the raw input as typed as the command line is
122 122 used instead. When you exit the editor, it will be executed by
123 123 IPython's own processor.
124 124
125 125 -x: do not execute the edited code immediately upon exit. This is
126 126 mainly useful if you are editing programs which need to be called with
127 127 command line arguments, which you can then do using %run.
128 128
129 129
130 130 Arguments:
131 131
132 132 If arguments are given, the following possibilites exist:
133 133
134 134 - The arguments are numbers or pairs of colon-separated numbers (like
135 135 1 4:8 9). These are interpreted as lines of previous input to be
136 136 loaded into the editor. The syntax is the same of the %macro command.
137 137
138 138 - If the argument doesn't start with a number, it is evaluated as a
139 139 variable and its contents loaded into the editor. You can thus edit
140 140 any string which contains python code (including the result of
141 141 previous edits).
142 142
143 143 - If the argument is the name of an object (other than a string),
144 144 IPython will try to locate the file where it was defined and open the
145 145 editor at the point where it is defined. You can use `%edit function`
146 146 to load an editor exactly at the point where 'function' is defined,
147 147 edit it and have the file be executed automatically.
148 148
149 149 If the object is a macro (see %macro for details), this opens up your
150 150 specified editor with a temporary file containing the macro's data.
151 151 Upon exit, the macro is reloaded with the contents of the file.
152 152
153 153 Note: opening at an exact line is only supported under Unix, and some
154 154 editors (like kedit and gedit up to Gnome 2.8) do not understand the
155 155 '+NUMBER' parameter necessary for this feature. Good editors like
156 156 (X)Emacs, vi, jed, pico and joe all do.
157 157
158 158 - If the argument is not found as a variable, IPython will look for a
159 159 file with that name (adding .py if necessary) and load it into the
160 160 editor. It will execute its contents with execfile() when you exit,
161 161 loading any code in the file into your interactive namespace.
162 162
163 163 After executing your code, %edit will return as output the code you
164 164 typed in the editor (except when it was an existing file). This way
165 165 you can reload the code in further invocations of %edit as a variable,
166 166 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
167 167 the output.
168 168
169 169 Note that %edit is also available through the alias %ed.
170 170
171 171 This is an example of creating a simple function inside the editor and
172 172 then modifying it. First, start up the editor:
173 173
174 174 In [1]: ed
175 175 Editing... done. Executing edited code...
176 176 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
177 177
178 178 We can then call the function foo():
179 179
180 180 In [2]: foo()
181 181 foo() was defined in an editing session
182 182
183 183 Now we edit foo. IPython automatically loads the editor with the
184 184 (temporary) file where foo() was previously defined:
185 185
186 186 In [3]: ed foo
187 187 Editing... done. Executing edited code...
188 188
189 189 And if we call foo() again we get the modified version:
190 190
191 191 In [4]: foo()
192 192 foo() has now been changed!
193 193
194 194 Here is an example of how to edit a code snippet successive
195 195 times. First we call the editor:
196 196
197 197 In [5]: ed
198 198 Editing... done. Executing edited code...
199 199 hello
200 200 Out[5]: "print 'hello'n"
201 201
202 202 Now we call it again with the previous output (stored in _):
203 203
204 204 In [6]: ed _
205 205 Editing... done. Executing edited code...
206 206 hello world
207 207 Out[6]: "print 'hello world'n"
208 208
209 209 Now we call it with the output #8 (stored in _8, also as Out[8]):
210 210
211 211 In [7]: ed _8
212 212 Editing... done. Executing edited code...
213 213 hello again
214 214 Out[7]: "print 'hello again'n"
215 215
216 216
217 217 Changing the default editor hook:
218 218
219 219 If you wish to write your own editor hook, you can put it in a
220 220 configuration file which you load at startup time. The default hook
221 221 is defined in the IPython.core.hooks module, and you can use that as a
222 222 starting example for further modifications. That file also has
223 223 general instructions on how to set a new hook for use once you've
224 224 defined it."""
225 225
226 226 # FIXME: This function has become a convoluted mess. It needs a
227 227 # ground-up rewrite with clean, simple logic.
228 228
229 229 def make_filename(arg):
230 230 "Make a filename from the given args"
231 231 try:
232 232 filename = get_py_filename(arg)
233 233 except IOError:
234 234 if args.endswith('.py'):
235 235 filename = arg
236 236 else:
237 237 filename = None
238 238 return filename
239 239
240 240 # custom exceptions
241 241 class DataIsObject(Exception): pass
242 242
243 243 opts,args = self.parse_options(parameter_s,'prn:')
244 244 # Set a few locals from the options for convenience:
245 245 opts_p = opts.has_key('p')
246 246 opts_r = opts.has_key('r')
247 247
248 248 # Default line number value
249 249 lineno = opts.get('n',None)
250 250 if lineno is not None:
251 251 try:
252 252 lineno = int(lineno)
253 253 except:
254 254 warn("The -n argument must be an integer.")
255 255 return
256 256
257 257 if opts_p:
258 258 args = '_%s' % last_call[0]
259 259 if not self.shell.user_ns.has_key(args):
260 260 args = last_call[1]
261 261
262 262 # use last_call to remember the state of the previous call, but don't
263 263 # let it be clobbered by successive '-p' calls.
264 264 try:
265 265 last_call[0] = self.shell.displayhook.prompt_count
266 266 if not opts_p:
267 267 last_call[1] = parameter_s
268 268 except:
269 269 pass
270 270
271 271 # by default this is done with temp files, except when the given
272 272 # arg is a filename
273 273 use_temp = 1
274 274
275 275 if re.match(r'\d',args):
276 276 # Mode where user specifies ranges of lines, like in %macro.
277 277 # This means that you can't edit files whose names begin with
278 278 # numbers this way. Tough.
279 279 ranges = args.split()
280 280 data = ''.join(self.extract_input_slices(ranges,opts_r))
281 281 elif args.endswith('.py'):
282 282 filename = make_filename(args)
283 283 data = ''
284 284 use_temp = 0
285 285 elif args:
286 286 try:
287 287 # Load the parameter given as a variable. If not a string,
288 288 # process it as an object instead (below)
289 289
290 290 #print '*** args',args,'type',type(args) # dbg
291 291 data = eval(args,self.shell.user_ns)
292 292 if not type(data) in StringTypes:
293 293 raise DataIsObject
294 294
295 295 except (NameError,SyntaxError):
296 296 # given argument is not a variable, try as a filename
297 297 filename = make_filename(args)
298 298 if filename is None:
299 299 warn("Argument given (%s) can't be found as a variable "
300 300 "or as a filename." % args)
301 301 return
302 302
303 303 data = ''
304 304 use_temp = 0
305 305 except DataIsObject:
306 306
307 307 # macros have a special edit function
308 308 if isinstance(data,Macro):
309 309 self._edit_macro(args,data)
310 310 return
311 311
312 312 # For objects, try to edit the file where they are defined
313 313 try:
314 314 filename = inspect.getabsfile(data)
315 315 if 'fakemodule' in filename.lower() and inspect.isclass(data):
316 316 # class created by %edit? Try to find source
317 317 # by looking for method definitions instead, the
318 318 # __module__ in those classes is FakeModule.
319 319 attrs = [getattr(data, aname) for aname in dir(data)]
320 320 for attr in attrs:
321 321 if not inspect.ismethod(attr):
322 322 continue
323 323 filename = inspect.getabsfile(attr)
324 324 if filename and 'fakemodule' not in filename.lower():
325 325 # change the attribute to be the edit target instead
326 326 data = attr
327 327 break
328 328
329 329 datafile = 1
330 330 except TypeError:
331 331 filename = make_filename(args)
332 332 datafile = 1
333 333 warn('Could not find file where `%s` is defined.\n'
334 334 'Opening a file named `%s`' % (args,filename))
335 335 # Now, make sure we can actually read the source (if it was in
336 336 # a temp file it's gone by now).
337 337 if datafile:
338 338 try:
339 339 if lineno is None:
340 340 lineno = inspect.getsourcelines(data)[1]
341 341 except IOError:
342 342 filename = make_filename(args)
343 343 if filename is None:
344 344 warn('The file `%s` where `%s` was defined cannot '
345 345 'be read.' % (filename,data))
346 346 return
347 347 use_temp = 0
348 348 else:
349 349 data = ''
350 350
351 351 if use_temp:
352 352 filename = self.shell.mktempfile(data)
353 353 print 'IPython will make a temporary file named:',filename
354 354
355 355 payload = {
356 356 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
357 357 'filename' : filename,
358 358 'line_number' : lineno
359 359 }
360 360 self.payload_manager.write_payload(payload)
361 361
362 362
363 363 def _showtraceback(self, etype, evalue, stb):
364 364
365 365 exc_content = {
366 366 u'status' : u'error',
367 367 u'traceback' : stb,
368 368 u'ename' : unicode(etype.__name__),
369 369 u'evalue' : unicode(evalue)
370 370 }
371 371
372 372 dh = self.displayhook
373 373 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
374 374 # Send exception info over pub socket for other clients than the caller
375 375 # to pick up
376 376 dh.pub_socket.send_json(exc_msg)
377 377
378 378 # FIXME - Hack: store exception info in shell object. Right now, the
379 379 # caller is reading this info after the fact, we need to fix this logic
380 380 # to remove this hack.
381 381 self._reply_content = exc_content
382 382 # /FIXME
383 383
384 384 return exc_content
385 385
386 386 def runlines(self, lines, clean=False):
387 387 return InteractiveShell.runlines(self, lines, clean)
388 388
389 389 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now