##// END OF EJS Templates
Moving find_exe -> platutils.find_cmd and making is cross platform....
Brian Granger -
Show More
@@ -1,2866 +1,2870 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 IPython -- An enhanced Interactive Python
4 4
5 5 Requires Python 2.4 or newer.
6 6
7 7 This file contains all the classes and helper functions specific to IPython.
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
12 12 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #
17 17 # Note: this code originally subclassed code.InteractiveConsole from the
18 18 # Python standard library. Over time, all of that class has been copied
19 19 # verbatim here for modifications which could not be accomplished by
20 20 # subclassing. At this point, there are no dependencies at all on the code
21 21 # module anymore (it is not even imported). The Python License (sec. 2)
22 22 # allows for this, but it's always nice to acknowledge credit where credit is
23 23 # due.
24 24 #*****************************************************************************
25 25
26 26 #****************************************************************************
27 27 # Modules and globals
28 28
29 29 # Python standard modules
30 30 import __main__
31 31 import __builtin__
32 32 import StringIO
33 33 import bdb
34 34 import cPickle as pickle
35 35 import codeop
36 36 import exceptions
37 37 import glob
38 38 import inspect
39 39 import keyword
40 40 import new
41 41 import os
42 42 import pydoc
43 43 import re
44 44 import shutil
45 45 import string
46 46 import sys
47 47 import tempfile
48 48 import traceback
49 49 import types
50 50 from pprint import pprint, pformat
51 51
52 52 # IPython's own modules
53 53 #import IPython
54 54 from IPython import Debugger,OInspect,PyColorize,ultraTB
55 55 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
56 56 from IPython.Extensions import pickleshare
57 57 from IPython.FakeModule import FakeModule, init_fakemod_dict
58 58 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
59 59 from IPython.Logger import Logger
60 60 from IPython.Magic import Magic
61 61 from IPython.Prompts import CachedOutput
62 62 from IPython.ipstruct import Struct
63 63 from IPython.background_jobs import BackgroundJobManager
64 64 from IPython.usage import cmd_line_usage,interactive_usage
65 65 from IPython.genutils import *
66 66 from IPython.strdispatch import StrDispatch
67 67 import IPython.ipapi
68 68 import IPython.history
69 69 import IPython.prefilter as prefilter
70 70 import IPython.shadowns
71 71 # Globals
72 72
73 73 # store the builtin raw_input globally, and use this always, in case user code
74 74 # overwrites it (like wx.py.PyShell does)
75 75 raw_input_original = raw_input
76 76
77 77 # compiled regexps for autoindent management
78 78 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
79 79
80 80
81 81 #****************************************************************************
82 82 # Some utility function definitions
83 83
84 84 ini_spaces_re = re.compile(r'^(\s+)')
85 85
86 86 def num_ini_spaces(strng):
87 87 """Return the number of initial spaces in a string"""
88 88
89 89 ini_spaces = ini_spaces_re.match(strng)
90 90 if ini_spaces:
91 91 return ini_spaces.end()
92 92 else:
93 93 return 0
94 94
95 95 def softspace(file, newvalue):
96 96 """Copied from code.py, to remove the dependency"""
97 97
98 98 oldvalue = 0
99 99 try:
100 100 oldvalue = file.softspace
101 101 except AttributeError:
102 102 pass
103 103 try:
104 104 file.softspace = newvalue
105 105 except (AttributeError, TypeError):
106 106 # "attribute-less object" or "read-only attributes"
107 107 pass
108 108 return oldvalue
109 109
110 110
111 111 def user_setup(ipythondir,rc_suffix,mode='install',interactive=True):
112 112 """Install or upgrade the user configuration directory.
113 113
114 114 Can be called when running for the first time or to upgrade the user's
115 115 .ipython/ directory.
116 116
117 117 Parameters
118 118 ----------
119 119 ipythondir : path
120 120 The directory to be used for installation/upgrade. In 'install' mode,
121 121 if this path already exists, the function exits immediately.
122 122
123 123 rc_suffix : str
124 124 Extension for the config files. On *nix platforms it is typically the
125 125 empty string, while Windows normally uses '.ini'.
126 126
127 127 mode : str, optional
128 128 Valid modes are 'install' and 'upgrade'.
129 129
130 130 interactive : bool, optional
131 131 If False, do not wait for user input on any errors. Normally after
132 132 printing its status information, this function waits for the user to
133 133 hit Return before proceeding. This is because the default use case is
134 134 when first installing the IPython configuration, so we want the user to
135 135 acknowledge the initial message, which contains some useful
136 136 information.
137 137 """
138 138
139 139 # For automatic use, deactivate all i/o
140 140 if interactive:
141 141 def wait():
142 142 try:
143 143 raw_input("Please press <RETURN> to start IPython.")
144 144 except EOFError:
145 145 print >> Term.cout
146 146 print '*'*70
147 147
148 148 def printf(s):
149 149 print s
150 150 else:
151 151 wait = lambda : None
152 152 printf = lambda s : None
153 153
154 154 # Install mode should be re-entrant: if the install dir already exists,
155 # bail out cleanly
155 # bail out cleanly.
156 # XXX. This is too hasty to return. We need to check to make sure that
157 # all the expected config files and directories are actually there. We
158 # currently have a failure mode if someone deletes a needed config file
159 # but still has the ipythondir.
156 160 if mode == 'install' and os.path.isdir(ipythondir):
157 161 return
158 162
159 163 cwd = os.getcwd() # remember where we started
160 164 glb = glob.glob
161 165
162 166 printf('*'*70)
163 167 if mode == 'install':
164 168 printf(
165 169 """Welcome to IPython. I will try to create a personal configuration directory
166 170 where you can customize many aspects of IPython's functionality in:\n""")
167 171 else:
168 172 printf('I am going to upgrade your configuration in:')
169 173
170 174 printf(ipythondir)
171 175
172 176 rcdirend = os.path.join('IPython','UserConfig')
173 177 cfg = lambda d: os.path.join(d,rcdirend)
174 178 try:
175 179 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
176 180 printf("Initializing from configuration: %s" % rcdir)
177 181 except IndexError:
178 182 warning = """
179 183 Installation error. IPython's directory was not found.
180 184
181 185 Check the following:
182 186
183 187 The ipython/IPython directory should be in a directory belonging to your
184 188 PYTHONPATH environment variable (that is, it should be in a directory
185 189 belonging to sys.path). You can copy it explicitly there or just link to it.
186 190
187 191 IPython will create a minimal default configuration for you.
188 192
189 193 """
190 194 warn(warning)
191 195 wait()
192 196
193 197 if sys.platform =='win32':
194 198 inif = 'ipythonrc.ini'
195 199 else:
196 200 inif = 'ipythonrc'
197 201 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults',
198 202 inif : '# intentionally left blank' }
199 203 os.makedirs(ipythondir, mode = 0777)
200 204 for f, cont in minimal_setup.items():
201 205 # In 2.5, this can be more cleanly done using 'with'
202 206 fobj = file(ipythondir + '/' + f,'w')
203 207 fobj.write(cont)
204 208 fobj.close()
205 209
206 210 return
207 211
208 212 if mode == 'install':
209 213 try:
210 214 shutil.copytree(rcdir,ipythondir)
211 215 os.chdir(ipythondir)
212 216 rc_files = glb("ipythonrc*")
213 217 for rc_file in rc_files:
214 218 os.rename(rc_file,rc_file+rc_suffix)
215 219 except:
216 220 warning = """
217 221
218 222 There was a problem with the installation:
219 223 %s
220 224 Try to correct it or contact the developers if you think it's a bug.
221 225 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
222 226 warn(warning)
223 227 wait()
224 228 return
225 229
226 230 elif mode == 'upgrade':
227 231 try:
228 232 os.chdir(ipythondir)
229 233 except:
230 234 printf("""
231 235 Can not upgrade: changing to directory %s failed. Details:
232 236 %s
233 237 """ % (ipythondir,sys.exc_info()[1]) )
234 238 wait()
235 239 return
236 240 else:
237 241 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
238 242 for new_full_path in sources:
239 243 new_filename = os.path.basename(new_full_path)
240 244 if new_filename.startswith('ipythonrc'):
241 245 new_filename = new_filename + rc_suffix
242 246 # The config directory should only contain files, skip any
243 247 # directories which may be there (like CVS)
244 248 if os.path.isdir(new_full_path):
245 249 continue
246 250 if os.path.exists(new_filename):
247 251 old_file = new_filename+'.old'
248 252 if os.path.exists(old_file):
249 253 os.remove(old_file)
250 254 os.rename(new_filename,old_file)
251 255 shutil.copy(new_full_path,new_filename)
252 256 else:
253 257 raise ValueError('unrecognized mode for install: %r' % mode)
254 258
255 259 # Fix line-endings to those native to each platform in the config
256 260 # directory.
257 261 try:
258 262 os.chdir(ipythondir)
259 263 except:
260 264 printf("""
261 265 Problem: changing to directory %s failed.
262 266 Details:
263 267 %s
264 268
265 269 Some configuration files may have incorrect line endings. This should not
266 270 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1]) )
267 271 wait()
268 272 else:
269 273 for fname in glb('ipythonrc*'):
270 274 try:
271 275 native_line_ends(fname,backup=0)
272 276 except IOError:
273 277 pass
274 278
275 279 if mode == 'install':
276 280 printf("""
277 281 Successful installation!
278 282
279 283 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
280 284 IPython manual (there are both HTML and PDF versions supplied with the
281 285 distribution) to make sure that your system environment is properly configured
282 286 to take advantage of IPython's features.
283 287
284 288 Important note: the configuration system has changed! The old system is
285 289 still in place, but its setting may be partly overridden by the settings in
286 290 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
287 291 if some of the new settings bother you.
288 292
289 293 """)
290 294 else:
291 295 printf("""
292 296 Successful upgrade!
293 297
294 298 All files in your directory:
295 299 %(ipythondir)s
296 300 which would have been overwritten by the upgrade were backed up with a .old
297 301 extension. If you had made particular customizations in those files you may
298 302 want to merge them back into the new files.""" % locals() )
299 303 wait()
300 304 os.chdir(cwd)
301 305
302 306 #****************************************************************************
303 307 # Local use exceptions
304 308 class SpaceInInput(exceptions.Exception): pass
305 309
306 310
307 311 #****************************************************************************
308 312 # Local use classes
309 313 class Bunch: pass
310 314
311 315 class Undefined: pass
312 316
313 317 class Quitter(object):
314 318 """Simple class to handle exit, similar to Python 2.5's.
315 319
316 320 It handles exiting in an ipython-safe manner, which the one in Python 2.5
317 321 doesn't do (obviously, since it doesn't know about ipython)."""
318 322
319 323 def __init__(self,shell,name):
320 324 self.shell = shell
321 325 self.name = name
322 326
323 327 def __repr__(self):
324 328 return 'Type %s() to exit.' % self.name
325 329 __str__ = __repr__
326 330
327 331 def __call__(self):
328 332 self.shell.exit()
329 333
330 334 class InputList(list):
331 335 """Class to store user input.
332 336
333 337 It's basically a list, but slices return a string instead of a list, thus
334 338 allowing things like (assuming 'In' is an instance):
335 339
336 340 exec In[4:7]
337 341
338 342 or
339 343
340 344 exec In[5:9] + In[14] + In[21:25]"""
341 345
342 346 def __getslice__(self,i,j):
343 347 return ''.join(list.__getslice__(self,i,j))
344 348
345 349 class SyntaxTB(ultraTB.ListTB):
346 350 """Extension which holds some state: the last exception value"""
347 351
348 352 def __init__(self,color_scheme = 'NoColor'):
349 353 ultraTB.ListTB.__init__(self,color_scheme)
350 354 self.last_syntax_error = None
351 355
352 356 def __call__(self, etype, value, elist):
353 357 self.last_syntax_error = value
354 358 ultraTB.ListTB.__call__(self,etype,value,elist)
355 359
356 360 def clear_err_state(self):
357 361 """Return the current error state and clear it"""
358 362 e = self.last_syntax_error
359 363 self.last_syntax_error = None
360 364 return e
361 365
362 366 #****************************************************************************
363 367 # Main IPython class
364 368
365 369 # FIXME: the Magic class is a mixin for now, and will unfortunately remain so
366 370 # until a full rewrite is made. I've cleaned all cross-class uses of
367 371 # attributes and methods, but too much user code out there relies on the
368 372 # equlity %foo == __IP.magic_foo, so I can't actually remove the mixin usage.
369 373 #
370 374 # But at least now, all the pieces have been separated and we could, in
371 375 # principle, stop using the mixin. This will ease the transition to the
372 376 # chainsaw branch.
373 377
374 378 # For reference, the following is the list of 'self.foo' uses in the Magic
375 379 # class as of 2005-12-28. These are names we CAN'T use in the main ipython
376 380 # class, to prevent clashes.
377 381
378 382 # ['self.__class__', 'self.__dict__', 'self._inspect', 'self._ofind',
379 383 # 'self.arg_err', 'self.extract_input', 'self.format_', 'self.lsmagic',
380 384 # 'self.magic_', 'self.options_table', 'self.parse', 'self.shell',
381 385 # 'self.value']
382 386
383 387 class InteractiveShell(object,Magic):
384 388 """An enhanced console for Python."""
385 389
386 390 # class attribute to indicate whether the class supports threads or not.
387 391 # Subclasses with thread support should override this as needed.
388 392 isthreaded = False
389 393
390 394 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
391 395 user_ns=None,user_global_ns=None,banner2='',
392 396 custom_exceptions=((),None),embedded=False):
393 397
394 398 # log system
395 399 self.logger = Logger(self,logfname='ipython_log.py',logmode='rotate')
396 400
397 401 # Job manager (for jobs run as background threads)
398 402 self.jobs = BackgroundJobManager()
399 403
400 404 # Store the actual shell's name
401 405 self.name = name
402 406 self.more = False
403 407
404 408 # We need to know whether the instance is meant for embedding, since
405 409 # global/local namespaces need to be handled differently in that case
406 410 self.embedded = embedded
407 411 if embedded:
408 412 # Control variable so users can, from within the embedded instance,
409 413 # permanently deactivate it.
410 414 self.embedded_active = True
411 415
412 416 # command compiler
413 417 self.compile = codeop.CommandCompiler()
414 418
415 419 # User input buffer
416 420 self.buffer = []
417 421
418 422 # Default name given in compilation of code
419 423 self.filename = '<ipython console>'
420 424
421 425 # Install our own quitter instead of the builtins. For python2.3-2.4,
422 426 # this brings in behavior like 2.5, and for 2.5 it's identical.
423 427 __builtin__.exit = Quitter(self,'exit')
424 428 __builtin__.quit = Quitter(self,'quit')
425 429
426 430 # Make an empty namespace, which extension writers can rely on both
427 431 # existing and NEVER being used by ipython itself. This gives them a
428 432 # convenient location for storing additional information and state
429 433 # their extensions may require, without fear of collisions with other
430 434 # ipython names that may develop later.
431 435 self.meta = Struct()
432 436
433 437 # Create the namespace where the user will operate. user_ns is
434 438 # normally the only one used, and it is passed to the exec calls as
435 439 # the locals argument. But we do carry a user_global_ns namespace
436 440 # given as the exec 'globals' argument, This is useful in embedding
437 441 # situations where the ipython shell opens in a context where the
438 442 # distinction between locals and globals is meaningful. For
439 443 # non-embedded contexts, it is just the same object as the user_ns dict.
440 444
441 445 # FIXME. For some strange reason, __builtins__ is showing up at user
442 446 # level as a dict instead of a module. This is a manual fix, but I
443 447 # should really track down where the problem is coming from. Alex
444 448 # Schmolck reported this problem first.
445 449
446 450 # A useful post by Alex Martelli on this topic:
447 451 # Re: inconsistent value from __builtins__
448 452 # Von: Alex Martelli <aleaxit@yahoo.com>
449 453 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
450 454 # Gruppen: comp.lang.python
451 455
452 456 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
453 457 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
454 458 # > <type 'dict'>
455 459 # > >>> print type(__builtins__)
456 460 # > <type 'module'>
457 461 # > Is this difference in return value intentional?
458 462
459 463 # Well, it's documented that '__builtins__' can be either a dictionary
460 464 # or a module, and it's been that way for a long time. Whether it's
461 465 # intentional (or sensible), I don't know. In any case, the idea is
462 466 # that if you need to access the built-in namespace directly, you
463 467 # should start with "import __builtin__" (note, no 's') which will
464 468 # definitely give you a module. Yeah, it's somewhat confusing:-(.
465 469
466 470 # These routines return properly built dicts as needed by the rest of
467 471 # the code, and can also be used by extension writers to generate
468 472 # properly initialized namespaces.
469 473 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
470 474 user_global_ns)
471 475
472 476 # Assign namespaces
473 477 # This is the namespace where all normal user variables live
474 478 self.user_ns = user_ns
475 479 self.user_global_ns = user_global_ns
476 480
477 481 # An auxiliary namespace that checks what parts of the user_ns were
478 482 # loaded at startup, so we can list later only variables defined in
479 483 # actual interactive use. Since it is always a subset of user_ns, it
480 484 # doesn't need to be seaparately tracked in the ns_table
481 485 self.user_config_ns = {}
482 486
483 487 # A namespace to keep track of internal data structures to prevent
484 488 # them from cluttering user-visible stuff. Will be updated later
485 489 self.internal_ns = {}
486 490
487 491 # Namespace of system aliases. Each entry in the alias
488 492 # table must be a 2-tuple of the form (N,name), where N is the number
489 493 # of positional arguments of the alias.
490 494 self.alias_table = {}
491 495
492 496 # Now that FakeModule produces a real module, we've run into a nasty
493 497 # problem: after script execution (via %run), the module where the user
494 498 # code ran is deleted. Now that this object is a true module (needed
495 499 # so docetst and other tools work correctly), the Python module
496 500 # teardown mechanism runs over it, and sets to None every variable
497 501 # present in that module. Top-level references to objects from the
498 502 # script survive, because the user_ns is updated with them. However,
499 503 # calling functions defined in the script that use other things from
500 504 # the script will fail, because the function's closure had references
501 505 # to the original objects, which are now all None. So we must protect
502 506 # these modules from deletion by keeping a cache.
503 507 #
504 508 # To avoid keeping stale modules around (we only need the one from the
505 509 # last run), we use a dict keyed with the full path to the script, so
506 510 # only the last version of the module is held in the cache. Note,
507 511 # however, that we must cache the module *namespace contents* (their
508 512 # __dict__). Because if we try to cache the actual modules, old ones
509 513 # (uncached) could be destroyed while still holding references (such as
510 514 # those held by GUI objects that tend to be long-lived)>
511 515 #
512 516 # The %reset command will flush this cache. See the cache_main_mod()
513 517 # and clear_main_mod_cache() methods for details on use.
514 518
515 519 # This is the cache used for 'main' namespaces
516 520 self._main_ns_cache = {}
517 521 # And this is the single instance of FakeModule whose __dict__ we keep
518 522 # copying and clearing for reuse on each %run
519 523 self._user_main_module = FakeModule()
520 524
521 525 # A table holding all the namespaces IPython deals with, so that
522 526 # introspection facilities can search easily.
523 527 self.ns_table = {'user':user_ns,
524 528 'user_global':user_global_ns,
525 529 'alias':self.alias_table,
526 530 'internal':self.internal_ns,
527 531 'builtin':__builtin__.__dict__
528 532 }
529 533
530 534 # Similarly, track all namespaces where references can be held and that
531 535 # we can safely clear (so it can NOT include builtin). This one can be
532 536 # a simple list.
533 537 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
534 538 self.alias_table, self.internal_ns,
535 539 self._main_ns_cache ]
536 540
537 541 # We need to insert into sys.modules something that looks like a
538 542 # module but which accesses the IPython namespace, for shelve and
539 543 # pickle to work interactively. Normally they rely on getting
540 544 # everything out of __main__, but for embedding purposes each IPython
541 545 # instance has its own private namespace, so we can't go shoving
542 546 # everything into __main__.
543 547
544 548 # note, however, that we should only do this for non-embedded
545 549 # ipythons, which really mimic the __main__.__dict__ with their own
546 550 # namespace. Embedded instances, on the other hand, should not do
547 551 # this because they need to manage the user local/global namespaces
548 552 # only, but they live within a 'normal' __main__ (meaning, they
549 553 # shouldn't overtake the execution environment of the script they're
550 554 # embedded in).
551 555
552 556 if not embedded:
553 557 try:
554 558 main_name = self.user_ns['__name__']
555 559 except KeyError:
556 560 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
557 561 else:
558 562 #print "pickle hack in place" # dbg
559 563 #print 'main_name:',main_name # dbg
560 564 sys.modules[main_name] = FakeModule(self.user_ns)
561 565
562 566 # List of input with multi-line handling.
563 567 self.input_hist = InputList()
564 568 # This one will hold the 'raw' input history, without any
565 569 # pre-processing. This will allow users to retrieve the input just as
566 570 # it was exactly typed in by the user, with %hist -r.
567 571 self.input_hist_raw = InputList()
568 572
569 573 # list of visited directories
570 574 try:
571 575 self.dir_hist = [os.getcwd()]
572 576 except OSError:
573 577 self.dir_hist = []
574 578
575 579 # dict of output history
576 580 self.output_hist = {}
577 581
578 582 # Get system encoding at startup time. Certain terminals (like Emacs
579 583 # under Win32 have it set to None, and we need to have a known valid
580 584 # encoding to use in the raw_input() method
581 585 try:
582 586 self.stdin_encoding = sys.stdin.encoding or 'ascii'
583 587 except AttributeError:
584 588 self.stdin_encoding = 'ascii'
585 589
586 590 # dict of things NOT to alias (keywords, builtins and some magics)
587 591 no_alias = {}
588 592 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
589 593 for key in keyword.kwlist + no_alias_magics:
590 594 no_alias[key] = 1
591 595 no_alias.update(__builtin__.__dict__)
592 596 self.no_alias = no_alias
593 597
594 598 # Object variable to store code object waiting execution. This is
595 599 # used mainly by the multithreaded shells, but it can come in handy in
596 600 # other situations. No need to use a Queue here, since it's a single
597 601 # item which gets cleared once run.
598 602 self.code_to_run = None
599 603
600 604 # escapes for automatic behavior on the command line
601 605 self.ESC_SHELL = '!'
602 606 self.ESC_SH_CAP = '!!'
603 607 self.ESC_HELP = '?'
604 608 self.ESC_MAGIC = '%'
605 609 self.ESC_QUOTE = ','
606 610 self.ESC_QUOTE2 = ';'
607 611 self.ESC_PAREN = '/'
608 612
609 613 # And their associated handlers
610 614 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
611 615 self.ESC_QUOTE : self.handle_auto,
612 616 self.ESC_QUOTE2 : self.handle_auto,
613 617 self.ESC_MAGIC : self.handle_magic,
614 618 self.ESC_HELP : self.handle_help,
615 619 self.ESC_SHELL : self.handle_shell_escape,
616 620 self.ESC_SH_CAP : self.handle_shell_escape,
617 621 }
618 622
619 623 # class initializations
620 624 Magic.__init__(self,self)
621 625
622 626 # Python source parser/formatter for syntax highlighting
623 627 pyformat = PyColorize.Parser().format
624 628 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
625 629
626 630 # hooks holds pointers used for user-side customizations
627 631 self.hooks = Struct()
628 632
629 633 self.strdispatchers = {}
630 634
631 635 # Set all default hooks, defined in the IPython.hooks module.
632 636 hooks = IPython.hooks
633 637 for hook_name in hooks.__all__:
634 638 # default hooks have priority 100, i.e. low; user hooks should have
635 639 # 0-100 priority
636 640 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
637 641 #print "bound hook",hook_name
638 642
639 643 # Flag to mark unconditional exit
640 644 self.exit_now = False
641 645
642 646 self.usage_min = """\
643 647 An enhanced console for Python.
644 648 Some of its features are:
645 649 - Readline support if the readline library is present.
646 650 - Tab completion in the local namespace.
647 651 - Logging of input, see command-line options.
648 652 - System shell escape via ! , eg !ls.
649 653 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
650 654 - Keeps track of locally defined variables via %who, %whos.
651 655 - Show object information with a ? eg ?x or x? (use ?? for more info).
652 656 """
653 657 if usage: self.usage = usage
654 658 else: self.usage = self.usage_min
655 659
656 660 # Storage
657 661 self.rc = rc # This will hold all configuration information
658 662 self.pager = 'less'
659 663 # temporary files used for various purposes. Deleted at exit.
660 664 self.tempfiles = []
661 665
662 666 # Keep track of readline usage (later set by init_readline)
663 667 self.has_readline = False
664 668
665 669 # template for logfile headers. It gets resolved at runtime by the
666 670 # logstart method.
667 671 self.loghead_tpl = \
668 672 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
669 673 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
670 674 #log# opts = %s
671 675 #log# args = %s
672 676 #log# It is safe to make manual edits below here.
673 677 #log#-----------------------------------------------------------------------
674 678 """
675 679 # for pushd/popd management
676 680 try:
677 681 self.home_dir = get_home_dir()
678 682 except HomeDirError,msg:
679 683 fatal(msg)
680 684
681 685 self.dir_stack = []
682 686
683 687 # Functions to call the underlying shell.
684 688
685 689 # The first is similar to os.system, but it doesn't return a value,
686 690 # and it allows interpolation of variables in the user's namespace.
687 691 self.system = lambda cmd: \
688 692 self.hooks.shell_hook(self.var_expand(cmd,depth=2))
689 693
690 694 # These are for getoutput and getoutputerror:
691 695 self.getoutput = lambda cmd: \
692 696 getoutput(self.var_expand(cmd,depth=2),
693 697 header=self.rc.system_header,
694 698 verbose=self.rc.system_verbose)
695 699
696 700 self.getoutputerror = lambda cmd: \
697 701 getoutputerror(self.var_expand(cmd,depth=2),
698 702 header=self.rc.system_header,
699 703 verbose=self.rc.system_verbose)
700 704
701 705
702 706 # keep track of where we started running (mainly for crash post-mortem)
703 707 self.starting_dir = os.getcwd()
704 708
705 709 # Various switches which can be set
706 710 self.CACHELENGTH = 5000 # this is cheap, it's just text
707 711 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
708 712 self.banner2 = banner2
709 713
710 714 # TraceBack handlers:
711 715
712 716 # Syntax error handler.
713 717 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
714 718
715 719 # The interactive one is initialized with an offset, meaning we always
716 720 # want to remove the topmost item in the traceback, which is our own
717 721 # internal code. Valid modes: ['Plain','Context','Verbose']
718 722 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
719 723 color_scheme='NoColor',
720 724 tb_offset = 1)
721 725
722 726 # IPython itself shouldn't crash. This will produce a detailed
723 727 # post-mortem if it does. But we only install the crash handler for
724 728 # non-threaded shells, the threaded ones use a normal verbose reporter
725 729 # and lose the crash handler. This is because exceptions in the main
726 730 # thread (such as in GUI code) propagate directly to sys.excepthook,
727 731 # and there's no point in printing crash dumps for every user exception.
728 732 if self.isthreaded:
729 733 ipCrashHandler = ultraTB.FormattedTB()
730 734 else:
731 735 from IPython import CrashHandler
732 736 ipCrashHandler = CrashHandler.IPythonCrashHandler(self)
733 737 self.set_crash_handler(ipCrashHandler)
734 738
735 739 # and add any custom exception handlers the user may have specified
736 740 self.set_custom_exc(*custom_exceptions)
737 741
738 742 # indentation management
739 743 self.autoindent = False
740 744 self.indent_current_nsp = 0
741 745
742 746 # Make some aliases automatically
743 747 # Prepare list of shell aliases to auto-define
744 748 if os.name == 'posix':
745 749 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
746 750 'mv mv -i','rm rm -i','cp cp -i',
747 751 'cat cat','less less','clear clear',
748 752 # a better ls
749 753 'ls ls -F',
750 754 # long ls
751 755 'll ls -lF')
752 756 # Extra ls aliases with color, which need special treatment on BSD
753 757 # variants
754 758 ls_extra = ( # color ls
755 759 'lc ls -F -o --color',
756 760 # ls normal files only
757 761 'lf ls -F -o --color %l | grep ^-',
758 762 # ls symbolic links
759 763 'lk ls -F -o --color %l | grep ^l',
760 764 # directories or links to directories,
761 765 'ldir ls -F -o --color %l | grep /$',
762 766 # things which are executable
763 767 'lx ls -F -o --color %l | grep ^-..x',
764 768 )
765 769 # The BSDs don't ship GNU ls, so they don't understand the
766 770 # --color switch out of the box
767 771 if 'bsd' in sys.platform:
768 772 ls_extra = ( # ls normal files only
769 773 'lf ls -lF | grep ^-',
770 774 # ls symbolic links
771 775 'lk ls -lF | grep ^l',
772 776 # directories or links to directories,
773 777 'ldir ls -lF | grep /$',
774 778 # things which are executable
775 779 'lx ls -lF | grep ^-..x',
776 780 )
777 781 auto_alias = auto_alias + ls_extra
778 782 elif os.name in ['nt','dos']:
779 783 auto_alias = ('ls dir /on',
780 784 'ddir dir /ad /on', 'ldir dir /ad /on',
781 785 'mkdir mkdir','rmdir rmdir','echo echo',
782 786 'ren ren','cls cls','copy copy')
783 787 else:
784 788 auto_alias = ()
785 789 self.auto_alias = [s.split(None,1) for s in auto_alias]
786 790
787 791 # Produce a public API instance
788 792 self.api = IPython.ipapi.IPApi(self)
789 793
790 794 # Initialize all user-visible namespaces
791 795 self.init_namespaces()
792 796
793 797 # Call the actual (public) initializer
794 798 self.init_auto_alias()
795 799
796 800 # track which builtins we add, so we can clean up later
797 801 self.builtins_added = {}
798 802 # This method will add the necessary builtins for operation, but
799 803 # tracking what it did via the builtins_added dict.
800 804
801 805 #TODO: remove this, redundant
802 806 self.add_builtins()
803 807 # end __init__
804 808
805 809 def var_expand(self,cmd,depth=0):
806 810 """Expand python variables in a string.
807 811
808 812 The depth argument indicates how many frames above the caller should
809 813 be walked to look for the local namespace where to expand variables.
810 814
811 815 The global namespace for expansion is always the user's interactive
812 816 namespace.
813 817 """
814 818
815 819 return str(ItplNS(cmd,
816 820 self.user_ns, # globals
817 821 # Skip our own frame in searching for locals:
818 822 sys._getframe(depth+1).f_locals # locals
819 823 ))
820 824
821 825 def pre_config_initialization(self):
822 826 """Pre-configuration init method
823 827
824 828 This is called before the configuration files are processed to
825 829 prepare the services the config files might need.
826 830
827 831 self.rc already has reasonable default values at this point.
828 832 """
829 833 rc = self.rc
830 834 try:
831 835 self.db = pickleshare.PickleShareDB(rc.ipythondir + "/db")
832 836 except exceptions.UnicodeDecodeError:
833 837 print "Your ipythondir can't be decoded to unicode!"
834 838 print "Please set HOME environment variable to something that"
835 839 print r"only has ASCII characters, e.g. c:\home"
836 840 print "Now it is",rc.ipythondir
837 841 sys.exit()
838 842 self.shadowhist = IPython.history.ShadowHist(self.db)
839 843
840 844 def post_config_initialization(self):
841 845 """Post configuration init method
842 846
843 847 This is called after the configuration files have been processed to
844 848 'finalize' the initialization."""
845 849
846 850 rc = self.rc
847 851
848 852 # Object inspector
849 853 self.inspector = OInspect.Inspector(OInspect.InspectColors,
850 854 PyColorize.ANSICodeColors,
851 855 'NoColor',
852 856 rc.object_info_string_level)
853 857
854 858 self.rl_next_input = None
855 859 self.rl_do_indent = False
856 860 # Load readline proper
857 861 if rc.readline:
858 862 self.init_readline()
859 863
860 864 # local shortcut, this is used a LOT
861 865 self.log = self.logger.log
862 866
863 867 # Initialize cache, set in/out prompts and printing system
864 868 self.outputcache = CachedOutput(self,
865 869 rc.cache_size,
866 870 rc.pprint,
867 871 input_sep = rc.separate_in,
868 872 output_sep = rc.separate_out,
869 873 output_sep2 = rc.separate_out2,
870 874 ps1 = rc.prompt_in1,
871 875 ps2 = rc.prompt_in2,
872 876 ps_out = rc.prompt_out,
873 877 pad_left = rc.prompts_pad_left)
874 878
875 879 # user may have over-ridden the default print hook:
876 880 try:
877 881 self.outputcache.__class__.display = self.hooks.display
878 882 except AttributeError:
879 883 pass
880 884
881 885 # I don't like assigning globally to sys, because it means when
882 886 # embedding instances, each embedded instance overrides the previous
883 887 # choice. But sys.displayhook seems to be called internally by exec,
884 888 # so I don't see a way around it. We first save the original and then
885 889 # overwrite it.
886 890 self.sys_displayhook = sys.displayhook
887 891 sys.displayhook = self.outputcache
888 892
889 893 # Do a proper resetting of doctest, including the necessary displayhook
890 894 # monkeypatching
891 895 try:
892 896 doctest_reload()
893 897 except ImportError:
894 898 warn("doctest module does not exist.")
895 899
896 900 # Set user colors (don't do it in the constructor above so that it
897 901 # doesn't crash if colors option is invalid)
898 902 self.magic_colors(rc.colors)
899 903
900 904 # Set calling of pdb on exceptions
901 905 self.call_pdb = rc.pdb
902 906
903 907 # Load user aliases
904 908 for alias in rc.alias:
905 909 self.magic_alias(alias)
906 910
907 911 self.hooks.late_startup_hook()
908 912
909 913 for cmd in self.rc.autoexec:
910 914 #print "autoexec>",cmd #dbg
911 915 self.api.runlines(cmd)
912 916
913 917 batchrun = False
914 918 for batchfile in [path(arg) for arg in self.rc.args
915 919 if arg.lower().endswith('.ipy')]:
916 920 if not batchfile.isfile():
917 921 print "No such batch file:", batchfile
918 922 continue
919 923 self.api.runlines(batchfile.text())
920 924 batchrun = True
921 925 # without -i option, exit after running the batch file
922 926 if batchrun and not self.rc.interact:
923 927 self.ask_exit()
924 928
925 929 def init_namespaces(self):
926 930 """Initialize all user-visible namespaces to their minimum defaults.
927 931
928 932 Certain history lists are also initialized here, as they effectively
929 933 act as user namespaces.
930 934
931 935 Note
932 936 ----
933 937 All data structures here are only filled in, they are NOT reset by this
934 938 method. If they were not empty before, data will simply be added to
935 939 therm.
936 940 """
937 941 # The user namespace MUST have a pointer to the shell itself.
938 942 self.user_ns[self.name] = self
939 943
940 944 # Store the public api instance
941 945 self.user_ns['_ip'] = self.api
942 946
943 947 # make global variables for user access to the histories
944 948 self.user_ns['_ih'] = self.input_hist
945 949 self.user_ns['_oh'] = self.output_hist
946 950 self.user_ns['_dh'] = self.dir_hist
947 951
948 952 # user aliases to input and output histories
949 953 self.user_ns['In'] = self.input_hist
950 954 self.user_ns['Out'] = self.output_hist
951 955
952 956 self.user_ns['_sh'] = IPython.shadowns
953 957
954 958 # Fill the history zero entry, user counter starts at 1
955 959 self.input_hist.append('\n')
956 960 self.input_hist_raw.append('\n')
957 961
958 962 def add_builtins(self):
959 963 """Store ipython references into the builtin namespace.
960 964
961 965 Some parts of ipython operate via builtins injected here, which hold a
962 966 reference to IPython itself."""
963 967
964 968 # TODO: deprecate all of these, they are unsafe
965 969 builtins_new = dict(__IPYTHON__ = self,
966 970 ip_set_hook = self.set_hook,
967 971 jobs = self.jobs,
968 972 ipmagic = wrap_deprecated(self.ipmagic,'_ip.magic()'),
969 973 ipalias = wrap_deprecated(self.ipalias),
970 974 ipsystem = wrap_deprecated(self.ipsystem,'_ip.system()'),
971 975 #_ip = self.api
972 976 )
973 977 for biname,bival in builtins_new.items():
974 978 try:
975 979 # store the orignal value so we can restore it
976 980 self.builtins_added[biname] = __builtin__.__dict__[biname]
977 981 except KeyError:
978 982 # or mark that it wasn't defined, and we'll just delete it at
979 983 # cleanup
980 984 self.builtins_added[biname] = Undefined
981 985 __builtin__.__dict__[biname] = bival
982 986
983 987 # Keep in the builtins a flag for when IPython is active. We set it
984 988 # with setdefault so that multiple nested IPythons don't clobber one
985 989 # another. Each will increase its value by one upon being activated,
986 990 # which also gives us a way to determine the nesting level.
987 991 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
988 992
989 993 def clean_builtins(self):
990 994 """Remove any builtins which might have been added by add_builtins, or
991 995 restore overwritten ones to their previous values."""
992 996 for biname,bival in self.builtins_added.items():
993 997 if bival is Undefined:
994 998 del __builtin__.__dict__[biname]
995 999 else:
996 1000 __builtin__.__dict__[biname] = bival
997 1001 self.builtins_added.clear()
998 1002
999 1003 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
1000 1004 """set_hook(name,hook) -> sets an internal IPython hook.
1001 1005
1002 1006 IPython exposes some of its internal API as user-modifiable hooks. By
1003 1007 adding your function to one of these hooks, you can modify IPython's
1004 1008 behavior to call at runtime your own routines."""
1005 1009
1006 1010 # At some point in the future, this should validate the hook before it
1007 1011 # accepts it. Probably at least check that the hook takes the number
1008 1012 # of args it's supposed to.
1009 1013
1010 1014 f = new.instancemethod(hook,self,self.__class__)
1011 1015
1012 1016 # check if the hook is for strdispatcher first
1013 1017 if str_key is not None:
1014 1018 sdp = self.strdispatchers.get(name, StrDispatch())
1015 1019 sdp.add_s(str_key, f, priority )
1016 1020 self.strdispatchers[name] = sdp
1017 1021 return
1018 1022 if re_key is not None:
1019 1023 sdp = self.strdispatchers.get(name, StrDispatch())
1020 1024 sdp.add_re(re.compile(re_key), f, priority )
1021 1025 self.strdispatchers[name] = sdp
1022 1026 return
1023 1027
1024 1028 dp = getattr(self.hooks, name, None)
1025 1029 if name not in IPython.hooks.__all__:
1026 1030 print "Warning! Hook '%s' is not one of %s" % (name, IPython.hooks.__all__ )
1027 1031 if not dp:
1028 1032 dp = IPython.hooks.CommandChainDispatcher()
1029 1033
1030 1034 try:
1031 1035 dp.add(f,priority)
1032 1036 except AttributeError:
1033 1037 # it was not commandchain, plain old func - replace
1034 1038 dp = f
1035 1039
1036 1040 setattr(self.hooks,name, dp)
1037 1041
1038 1042
1039 1043 #setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
1040 1044
1041 1045 def set_crash_handler(self,crashHandler):
1042 1046 """Set the IPython crash handler.
1043 1047
1044 1048 This must be a callable with a signature suitable for use as
1045 1049 sys.excepthook."""
1046 1050
1047 1051 # Install the given crash handler as the Python exception hook
1048 1052 sys.excepthook = crashHandler
1049 1053
1050 1054 # The instance will store a pointer to this, so that runtime code
1051 1055 # (such as magics) can access it. This is because during the
1052 1056 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1053 1057 # frameworks).
1054 1058 self.sys_excepthook = sys.excepthook
1055 1059
1056 1060
1057 1061 def set_custom_exc(self,exc_tuple,handler):
1058 1062 """set_custom_exc(exc_tuple,handler)
1059 1063
1060 1064 Set a custom exception handler, which will be called if any of the
1061 1065 exceptions in exc_tuple occur in the mainloop (specifically, in the
1062 1066 runcode() method.
1063 1067
1064 1068 Inputs:
1065 1069
1066 1070 - exc_tuple: a *tuple* of valid exceptions to call the defined
1067 1071 handler for. It is very important that you use a tuple, and NOT A
1068 1072 LIST here, because of the way Python's except statement works. If
1069 1073 you only want to trap a single exception, use a singleton tuple:
1070 1074
1071 1075 exc_tuple == (MyCustomException,)
1072 1076
1073 1077 - handler: this must be defined as a function with the following
1074 1078 basic interface: def my_handler(self,etype,value,tb).
1075 1079
1076 1080 This will be made into an instance method (via new.instancemethod)
1077 1081 of IPython itself, and it will be called if any of the exceptions
1078 1082 listed in the exc_tuple are caught. If the handler is None, an
1079 1083 internal basic one is used, which just prints basic info.
1080 1084
1081 1085 WARNING: by putting in your own exception handler into IPython's main
1082 1086 execution loop, you run a very good chance of nasty crashes. This
1083 1087 facility should only be used if you really know what you are doing."""
1084 1088
1085 1089 assert type(exc_tuple)==type(()) , \
1086 1090 "The custom exceptions must be given AS A TUPLE."
1087 1091
1088 1092 def dummy_handler(self,etype,value,tb):
1089 1093 print '*** Simple custom exception handler ***'
1090 1094 print 'Exception type :',etype
1091 1095 print 'Exception value:',value
1092 1096 print 'Traceback :',tb
1093 1097 print 'Source code :','\n'.join(self.buffer)
1094 1098
1095 1099 if handler is None: handler = dummy_handler
1096 1100
1097 1101 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1098 1102 self.custom_exceptions = exc_tuple
1099 1103
1100 1104 def set_custom_completer(self,completer,pos=0):
1101 1105 """set_custom_completer(completer,pos=0)
1102 1106
1103 1107 Adds a new custom completer function.
1104 1108
1105 1109 The position argument (defaults to 0) is the index in the completers
1106 1110 list where you want the completer to be inserted."""
1107 1111
1108 1112 newcomp = new.instancemethod(completer,self.Completer,
1109 1113 self.Completer.__class__)
1110 1114 self.Completer.matchers.insert(pos,newcomp)
1111 1115
1112 1116 def set_completer(self):
1113 1117 """reset readline's completer to be our own."""
1114 1118 self.readline.set_completer(self.Completer.complete)
1115 1119
1116 1120 def _get_call_pdb(self):
1117 1121 return self._call_pdb
1118 1122
1119 1123 def _set_call_pdb(self,val):
1120 1124
1121 1125 if val not in (0,1,False,True):
1122 1126 raise ValueError,'new call_pdb value must be boolean'
1123 1127
1124 1128 # store value in instance
1125 1129 self._call_pdb = val
1126 1130
1127 1131 # notify the actual exception handlers
1128 1132 self.InteractiveTB.call_pdb = val
1129 1133 if self.isthreaded:
1130 1134 try:
1131 1135 self.sys_excepthook.call_pdb = val
1132 1136 except:
1133 1137 warn('Failed to activate pdb for threaded exception handler')
1134 1138
1135 1139 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1136 1140 'Control auto-activation of pdb at exceptions')
1137 1141
1138 1142 # These special functions get installed in the builtin namespace, to
1139 1143 # provide programmatic (pure python) access to magics, aliases and system
1140 1144 # calls. This is important for logging, user scripting, and more.
1141 1145
1142 1146 # We are basically exposing, via normal python functions, the three
1143 1147 # mechanisms in which ipython offers special call modes (magics for
1144 1148 # internal control, aliases for direct system access via pre-selected
1145 1149 # names, and !cmd for calling arbitrary system commands).
1146 1150
1147 1151 def ipmagic(self,arg_s):
1148 1152 """Call a magic function by name.
1149 1153
1150 1154 Input: a string containing the name of the magic function to call and any
1151 1155 additional arguments to be passed to the magic.
1152 1156
1153 1157 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
1154 1158 prompt:
1155 1159
1156 1160 In[1]: %name -opt foo bar
1157 1161
1158 1162 To call a magic without arguments, simply use ipmagic('name').
1159 1163
1160 1164 This provides a proper Python function to call IPython's magics in any
1161 1165 valid Python code you can type at the interpreter, including loops and
1162 1166 compound statements. It is added by IPython to the Python builtin
1163 1167 namespace upon initialization."""
1164 1168
1165 1169 args = arg_s.split(' ',1)
1166 1170 magic_name = args[0]
1167 1171 magic_name = magic_name.lstrip(self.ESC_MAGIC)
1168 1172
1169 1173 try:
1170 1174 magic_args = args[1]
1171 1175 except IndexError:
1172 1176 magic_args = ''
1173 1177 fn = getattr(self,'magic_'+magic_name,None)
1174 1178 if fn is None:
1175 1179 error("Magic function `%s` not found." % magic_name)
1176 1180 else:
1177 1181 magic_args = self.var_expand(magic_args,1)
1178 1182 return fn(magic_args)
1179 1183
1180 1184 def ipalias(self,arg_s):
1181 1185 """Call an alias by name.
1182 1186
1183 1187 Input: a string containing the name of the alias to call and any
1184 1188 additional arguments to be passed to the magic.
1185 1189
1186 1190 ipalias('name -opt foo bar') is equivalent to typing at the ipython
1187 1191 prompt:
1188 1192
1189 1193 In[1]: name -opt foo bar
1190 1194
1191 1195 To call an alias without arguments, simply use ipalias('name').
1192 1196
1193 1197 This provides a proper Python function to call IPython's aliases in any
1194 1198 valid Python code you can type at the interpreter, including loops and
1195 1199 compound statements. It is added by IPython to the Python builtin
1196 1200 namespace upon initialization."""
1197 1201
1198 1202 args = arg_s.split(' ',1)
1199 1203 alias_name = args[0]
1200 1204 try:
1201 1205 alias_args = args[1]
1202 1206 except IndexError:
1203 1207 alias_args = ''
1204 1208 if alias_name in self.alias_table:
1205 1209 self.call_alias(alias_name,alias_args)
1206 1210 else:
1207 1211 error("Alias `%s` not found." % alias_name)
1208 1212
1209 1213 def ipsystem(self,arg_s):
1210 1214 """Make a system call, using IPython."""
1211 1215
1212 1216 self.system(arg_s)
1213 1217
1214 1218 def complete(self,text):
1215 1219 """Return a sorted list of all possible completions on text.
1216 1220
1217 1221 Inputs:
1218 1222
1219 1223 - text: a string of text to be completed on.
1220 1224
1221 1225 This is a wrapper around the completion mechanism, similar to what
1222 1226 readline does at the command line when the TAB key is hit. By
1223 1227 exposing it as a method, it can be used by other non-readline
1224 1228 environments (such as GUIs) for text completion.
1225 1229
1226 1230 Simple usage example:
1227 1231
1228 1232 In [7]: x = 'hello'
1229 1233
1230 1234 In [8]: x
1231 1235 Out[8]: 'hello'
1232 1236
1233 1237 In [9]: print x
1234 1238 hello
1235 1239
1236 1240 In [10]: _ip.IP.complete('x.l')
1237 1241 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1238 1242 """
1239 1243
1240 1244 complete = self.Completer.complete
1241 1245 state = 0
1242 1246 # use a dict so we get unique keys, since ipyhton's multiple
1243 1247 # completers can return duplicates. When we make 2.4 a requirement,
1244 1248 # start using sets instead, which are faster.
1245 1249 comps = {}
1246 1250 while True:
1247 1251 newcomp = complete(text,state,line_buffer=text)
1248 1252 if newcomp is None:
1249 1253 break
1250 1254 comps[newcomp] = 1
1251 1255 state += 1
1252 1256 outcomps = comps.keys()
1253 1257 outcomps.sort()
1254 1258 #print "T:",text,"OC:",outcomps # dbg
1255 1259 #print "vars:",self.user_ns.keys()
1256 1260 return outcomps
1257 1261
1258 1262 def set_completer_frame(self, frame=None):
1259 1263 if frame:
1260 1264 self.Completer.namespace = frame.f_locals
1261 1265 self.Completer.global_namespace = frame.f_globals
1262 1266 else:
1263 1267 self.Completer.namespace = self.user_ns
1264 1268 self.Completer.global_namespace = self.user_global_ns
1265 1269
1266 1270 def init_auto_alias(self):
1267 1271 """Define some aliases automatically.
1268 1272
1269 1273 These are ALL parameter-less aliases"""
1270 1274
1271 1275 for alias,cmd in self.auto_alias:
1272 1276 self.getapi().defalias(alias,cmd)
1273 1277
1274 1278
1275 1279 def alias_table_validate(self,verbose=0):
1276 1280 """Update information about the alias table.
1277 1281
1278 1282 In particular, make sure no Python keywords/builtins are in it."""
1279 1283
1280 1284 no_alias = self.no_alias
1281 1285 for k in self.alias_table.keys():
1282 1286 if k in no_alias:
1283 1287 del self.alias_table[k]
1284 1288 if verbose:
1285 1289 print ("Deleting alias <%s>, it's a Python "
1286 1290 "keyword or builtin." % k)
1287 1291
1288 1292 def set_autoindent(self,value=None):
1289 1293 """Set the autoindent flag, checking for readline support.
1290 1294
1291 1295 If called with no arguments, it acts as a toggle."""
1292 1296
1293 1297 if not self.has_readline:
1294 1298 if os.name == 'posix':
1295 1299 warn("The auto-indent feature requires the readline library")
1296 1300 self.autoindent = 0
1297 1301 return
1298 1302 if value is None:
1299 1303 self.autoindent = not self.autoindent
1300 1304 else:
1301 1305 self.autoindent = value
1302 1306
1303 1307 def rc_set_toggle(self,rc_field,value=None):
1304 1308 """Set or toggle a field in IPython's rc config. structure.
1305 1309
1306 1310 If called with no arguments, it acts as a toggle.
1307 1311
1308 1312 If called with a non-existent field, the resulting AttributeError
1309 1313 exception will propagate out."""
1310 1314
1311 1315 rc_val = getattr(self.rc,rc_field)
1312 1316 if value is None:
1313 1317 value = not rc_val
1314 1318 setattr(self.rc,rc_field,value)
1315 1319
1316 1320 def user_setup(self,ipythondir,rc_suffix,mode='install'):
1317 1321 """Install the user configuration directory.
1318 1322
1319 1323 Note
1320 1324 ----
1321 1325 DEPRECATED: use the top-level user_setup() function instead.
1322 1326 """
1323 1327 return user_setup(ipythondir,rc_suffix,mode)
1324 1328
1325 1329 def atexit_operations(self):
1326 1330 """This will be executed at the time of exit.
1327 1331
1328 1332 Saving of persistent data should be performed here. """
1329 1333
1330 1334 #print '*** IPython exit cleanup ***' # dbg
1331 1335 # input history
1332 1336 self.savehist()
1333 1337
1334 1338 # Cleanup all tempfiles left around
1335 1339 for tfile in self.tempfiles:
1336 1340 try:
1337 1341 os.unlink(tfile)
1338 1342 except OSError:
1339 1343 pass
1340 1344
1341 1345 # Clear all user namespaces to release all references cleanly.
1342 1346 self.reset()
1343 1347
1344 1348 # Run user hooks
1345 1349 self.hooks.shutdown_hook()
1346 1350
1347 1351 def reset(self):
1348 1352 """Clear all internal namespaces.
1349 1353
1350 1354 Note that this is much more aggressive than %reset, since it clears
1351 1355 fully all namespaces, as well as all input/output lists.
1352 1356 """
1353 1357 for ns in self.ns_refs_table:
1354 1358 ns.clear()
1355 1359
1356 1360 # Clear input and output histories
1357 1361 self.input_hist[:] = []
1358 1362 self.input_hist_raw[:] = []
1359 1363 self.output_hist.clear()
1360 1364 # Restore the user namespaces to minimal usability
1361 1365 self.init_namespaces()
1362 1366
1363 1367 def savehist(self):
1364 1368 """Save input history to a file (via readline library)."""
1365 1369
1366 1370 if not self.has_readline:
1367 1371 return
1368 1372
1369 1373 try:
1370 1374 self.readline.write_history_file(self.histfile)
1371 1375 except:
1372 1376 print 'Unable to save IPython command history to file: ' + \
1373 1377 `self.histfile`
1374 1378
1375 1379 def reloadhist(self):
1376 1380 """Reload the input history from disk file."""
1377 1381
1378 1382 if self.has_readline:
1379 1383 try:
1380 1384 self.readline.clear_history()
1381 1385 self.readline.read_history_file(self.shell.histfile)
1382 1386 except AttributeError:
1383 1387 pass
1384 1388
1385 1389
1386 1390 def history_saving_wrapper(self, func):
1387 1391 """ Wrap func for readline history saving
1388 1392
1389 1393 Convert func into callable that saves & restores
1390 1394 history around the call """
1391 1395
1392 1396 if not self.has_readline:
1393 1397 return func
1394 1398
1395 1399 def wrapper():
1396 1400 self.savehist()
1397 1401 try:
1398 1402 func()
1399 1403 finally:
1400 1404 readline.read_history_file(self.histfile)
1401 1405 return wrapper
1402 1406
1403 1407 def pre_readline(self):
1404 1408 """readline hook to be used at the start of each line.
1405 1409
1406 1410 Currently it handles auto-indent only."""
1407 1411
1408 1412 #debugx('self.indent_current_nsp','pre_readline:')
1409 1413
1410 1414 if self.rl_do_indent:
1411 1415 self.readline.insert_text(self.indent_current_str())
1412 1416 if self.rl_next_input is not None:
1413 1417 self.readline.insert_text(self.rl_next_input)
1414 1418 self.rl_next_input = None
1415 1419
1416 1420 def init_readline(self):
1417 1421 """Command history completion/saving/reloading."""
1418 1422
1419 1423
1420 1424 import IPython.rlineimpl as readline
1421 1425
1422 1426 if not readline.have_readline:
1423 1427 self.has_readline = 0
1424 1428 self.readline = None
1425 1429 # no point in bugging windows users with this every time:
1426 1430 warn('Readline services not available on this platform.')
1427 1431 else:
1428 1432 sys.modules['readline'] = readline
1429 1433 import atexit
1430 1434 from IPython.completer import IPCompleter
1431 1435 self.Completer = IPCompleter(self,
1432 1436 self.user_ns,
1433 1437 self.user_global_ns,
1434 1438 self.rc.readline_omit__names,
1435 1439 self.alias_table)
1436 1440 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1437 1441 self.strdispatchers['complete_command'] = sdisp
1438 1442 self.Completer.custom_completers = sdisp
1439 1443 # Platform-specific configuration
1440 1444 if os.name == 'nt':
1441 1445 self.readline_startup_hook = readline.set_pre_input_hook
1442 1446 else:
1443 1447 self.readline_startup_hook = readline.set_startup_hook
1444 1448
1445 1449 # Load user's initrc file (readline config)
1446 1450 # Or if libedit is used, load editrc.
1447 1451 inputrc_name = os.environ.get('INPUTRC')
1448 1452 if inputrc_name is None:
1449 1453 home_dir = get_home_dir()
1450 1454 if home_dir is not None:
1451 1455 inputrc_name = '.inputrc'
1452 1456 if readline.uses_libedit:
1453 1457 inputrc_name = '.editrc'
1454 1458 inputrc_name = os.path.join(home_dir, inputrc_name)
1455 1459 if os.path.isfile(inputrc_name):
1456 1460 try:
1457 1461 readline.read_init_file(inputrc_name)
1458 1462 except:
1459 1463 warn('Problems reading readline initialization file <%s>'
1460 1464 % inputrc_name)
1461 1465
1462 1466 self.has_readline = 1
1463 1467 self.readline = readline
1464 1468 # save this in sys so embedded copies can restore it properly
1465 1469 sys.ipcompleter = self.Completer.complete
1466 1470 self.set_completer()
1467 1471
1468 1472 # Configure readline according to user's prefs
1469 1473 # This is only done if GNU readline is being used. If libedit
1470 1474 # is being used (as on Leopard) the readline config is
1471 1475 # not run as the syntax for libedit is different.
1472 1476 if not readline.uses_libedit:
1473 1477 for rlcommand in self.rc.readline_parse_and_bind:
1474 1478 #print "loading rl:",rlcommand # dbg
1475 1479 readline.parse_and_bind(rlcommand)
1476 1480
1477 1481 # Remove some chars from the delimiters list. If we encounter
1478 1482 # unicode chars, discard them.
1479 1483 delims = readline.get_completer_delims().encode("ascii", "ignore")
1480 1484 delims = delims.translate(string._idmap,
1481 1485 self.rc.readline_remove_delims)
1482 1486 readline.set_completer_delims(delims)
1483 1487 # otherwise we end up with a monster history after a while:
1484 1488 readline.set_history_length(1000)
1485 1489 try:
1486 1490 #print '*** Reading readline history' # dbg
1487 1491 readline.read_history_file(self.histfile)
1488 1492 except IOError:
1489 1493 pass # It doesn't exist yet.
1490 1494
1491 1495 atexit.register(self.atexit_operations)
1492 1496 del atexit
1493 1497
1494 1498 # Configure auto-indent for all platforms
1495 1499 self.set_autoindent(self.rc.autoindent)
1496 1500
1497 1501 def ask_yes_no(self,prompt,default=True):
1498 1502 if self.rc.quiet:
1499 1503 return True
1500 1504 return ask_yes_no(prompt,default)
1501 1505
1502 1506 def new_main_mod(self,ns=None):
1503 1507 """Return a new 'main' module object for user code execution.
1504 1508 """
1505 1509 main_mod = self._user_main_module
1506 1510 init_fakemod_dict(main_mod,ns)
1507 1511 return main_mod
1508 1512
1509 1513 def cache_main_mod(self,ns,fname):
1510 1514 """Cache a main module's namespace.
1511 1515
1512 1516 When scripts are executed via %run, we must keep a reference to the
1513 1517 namespace of their __main__ module (a FakeModule instance) around so
1514 1518 that Python doesn't clear it, rendering objects defined therein
1515 1519 useless.
1516 1520
1517 1521 This method keeps said reference in a private dict, keyed by the
1518 1522 absolute path of the module object (which corresponds to the script
1519 1523 path). This way, for multiple executions of the same script we only
1520 1524 keep one copy of the namespace (the last one), thus preventing memory
1521 1525 leaks from old references while allowing the objects from the last
1522 1526 execution to be accessible.
1523 1527
1524 1528 Note: we can not allow the actual FakeModule instances to be deleted,
1525 1529 because of how Python tears down modules (it hard-sets all their
1526 1530 references to None without regard for reference counts). This method
1527 1531 must therefore make a *copy* of the given namespace, to allow the
1528 1532 original module's __dict__ to be cleared and reused.
1529 1533
1530 1534
1531 1535 Parameters
1532 1536 ----------
1533 1537 ns : a namespace (a dict, typically)
1534 1538
1535 1539 fname : str
1536 1540 Filename associated with the namespace.
1537 1541
1538 1542 Examples
1539 1543 --------
1540 1544
1541 1545 In [10]: import IPython
1542 1546
1543 1547 In [11]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1544 1548
1545 1549 In [12]: IPython.__file__ in _ip.IP._main_ns_cache
1546 1550 Out[12]: True
1547 1551 """
1548 1552 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
1549 1553
1550 1554 def clear_main_mod_cache(self):
1551 1555 """Clear the cache of main modules.
1552 1556
1553 1557 Mainly for use by utilities like %reset.
1554 1558
1555 1559 Examples
1556 1560 --------
1557 1561
1558 1562 In [15]: import IPython
1559 1563
1560 1564 In [16]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1561 1565
1562 1566 In [17]: len(_ip.IP._main_ns_cache) > 0
1563 1567 Out[17]: True
1564 1568
1565 1569 In [18]: _ip.IP.clear_main_mod_cache()
1566 1570
1567 1571 In [19]: len(_ip.IP._main_ns_cache) == 0
1568 1572 Out[19]: True
1569 1573 """
1570 1574 self._main_ns_cache.clear()
1571 1575
1572 1576 def _should_recompile(self,e):
1573 1577 """Utility routine for edit_syntax_error"""
1574 1578
1575 1579 if e.filename in ('<ipython console>','<input>','<string>',
1576 1580 '<console>','<BackgroundJob compilation>',
1577 1581 None):
1578 1582
1579 1583 return False
1580 1584 try:
1581 1585 if (self.rc.autoedit_syntax and
1582 1586 not self.ask_yes_no('Return to editor to correct syntax error? '
1583 1587 '[Y/n] ','y')):
1584 1588 return False
1585 1589 except EOFError:
1586 1590 return False
1587 1591
1588 1592 def int0(x):
1589 1593 try:
1590 1594 return int(x)
1591 1595 except TypeError:
1592 1596 return 0
1593 1597 # always pass integer line and offset values to editor hook
1594 1598 try:
1595 1599 self.hooks.fix_error_editor(e.filename,
1596 1600 int0(e.lineno),int0(e.offset),e.msg)
1597 1601 except IPython.ipapi.TryNext:
1598 1602 warn('Could not open editor')
1599 1603 return False
1600 1604 return True
1601 1605
1602 1606 def edit_syntax_error(self):
1603 1607 """The bottom half of the syntax error handler called in the main loop.
1604 1608
1605 1609 Loop until syntax error is fixed or user cancels.
1606 1610 """
1607 1611
1608 1612 while self.SyntaxTB.last_syntax_error:
1609 1613 # copy and clear last_syntax_error
1610 1614 err = self.SyntaxTB.clear_err_state()
1611 1615 if not self._should_recompile(err):
1612 1616 return
1613 1617 try:
1614 1618 # may set last_syntax_error again if a SyntaxError is raised
1615 1619 self.safe_execfile(err.filename,self.user_ns)
1616 1620 except:
1617 1621 self.showtraceback()
1618 1622 else:
1619 1623 try:
1620 1624 f = file(err.filename)
1621 1625 try:
1622 1626 sys.displayhook(f.read())
1623 1627 finally:
1624 1628 f.close()
1625 1629 except:
1626 1630 self.showtraceback()
1627 1631
1628 1632 def showsyntaxerror(self, filename=None):
1629 1633 """Display the syntax error that just occurred.
1630 1634
1631 1635 This doesn't display a stack trace because there isn't one.
1632 1636
1633 1637 If a filename is given, it is stuffed in the exception instead
1634 1638 of what was there before (because Python's parser always uses
1635 1639 "<string>" when reading from a string).
1636 1640 """
1637 1641 etype, value, last_traceback = sys.exc_info()
1638 1642
1639 1643 # See note about these variables in showtraceback() below
1640 1644 sys.last_type = etype
1641 1645 sys.last_value = value
1642 1646 sys.last_traceback = last_traceback
1643 1647
1644 1648 if filename and etype is SyntaxError:
1645 1649 # Work hard to stuff the correct filename in the exception
1646 1650 try:
1647 1651 msg, (dummy_filename, lineno, offset, line) = value
1648 1652 except:
1649 1653 # Not the format we expect; leave it alone
1650 1654 pass
1651 1655 else:
1652 1656 # Stuff in the right filename
1653 1657 try:
1654 1658 # Assume SyntaxError is a class exception
1655 1659 value = SyntaxError(msg, (filename, lineno, offset, line))
1656 1660 except:
1657 1661 # If that failed, assume SyntaxError is a string
1658 1662 value = msg, (filename, lineno, offset, line)
1659 1663 self.SyntaxTB(etype,value,[])
1660 1664
1661 1665 def debugger(self,force=False):
1662 1666 """Call the pydb/pdb debugger.
1663 1667
1664 1668 Keywords:
1665 1669
1666 1670 - force(False): by default, this routine checks the instance call_pdb
1667 1671 flag and does not actually invoke the debugger if the flag is false.
1668 1672 The 'force' option forces the debugger to activate even if the flag
1669 1673 is false.
1670 1674 """
1671 1675
1672 1676 if not (force or self.call_pdb):
1673 1677 return
1674 1678
1675 1679 if not hasattr(sys,'last_traceback'):
1676 1680 error('No traceback has been produced, nothing to debug.')
1677 1681 return
1678 1682
1679 1683 # use pydb if available
1680 1684 if Debugger.has_pydb:
1681 1685 from pydb import pm
1682 1686 else:
1683 1687 # fallback to our internal debugger
1684 1688 pm = lambda : self.InteractiveTB.debugger(force=True)
1685 1689 self.history_saving_wrapper(pm)()
1686 1690
1687 1691 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1688 1692 """Display the exception that just occurred.
1689 1693
1690 1694 If nothing is known about the exception, this is the method which
1691 1695 should be used throughout the code for presenting user tracebacks,
1692 1696 rather than directly invoking the InteractiveTB object.
1693 1697
1694 1698 A specific showsyntaxerror() also exists, but this method can take
1695 1699 care of calling it if needed, so unless you are explicitly catching a
1696 1700 SyntaxError exception, don't try to analyze the stack manually and
1697 1701 simply call this method."""
1698 1702
1699 1703
1700 1704 # Though this won't be called by syntax errors in the input line,
1701 1705 # there may be SyntaxError cases whith imported code.
1702 1706
1703 1707 try:
1704 1708 if exc_tuple is None:
1705 1709 etype, value, tb = sys.exc_info()
1706 1710 else:
1707 1711 etype, value, tb = exc_tuple
1708 1712
1709 1713 if etype is SyntaxError:
1710 1714 self.showsyntaxerror(filename)
1711 1715 elif etype is IPython.ipapi.UsageError:
1712 1716 print "UsageError:", value
1713 1717 else:
1714 1718 # WARNING: these variables are somewhat deprecated and not
1715 1719 # necessarily safe to use in a threaded environment, but tools
1716 1720 # like pdb depend on their existence, so let's set them. If we
1717 1721 # find problems in the field, we'll need to revisit their use.
1718 1722 sys.last_type = etype
1719 1723 sys.last_value = value
1720 1724 sys.last_traceback = tb
1721 1725
1722 1726 if etype in self.custom_exceptions:
1723 1727 self.CustomTB(etype,value,tb)
1724 1728 else:
1725 1729 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1726 1730 if self.InteractiveTB.call_pdb and self.has_readline:
1727 1731 # pdb mucks up readline, fix it back
1728 1732 self.set_completer()
1729 1733 except KeyboardInterrupt:
1730 1734 self.write("\nKeyboardInterrupt\n")
1731 1735
1732 1736 def mainloop(self,banner=None):
1733 1737 """Creates the local namespace and starts the mainloop.
1734 1738
1735 1739 If an optional banner argument is given, it will override the
1736 1740 internally created default banner."""
1737 1741
1738 1742 if self.rc.c: # Emulate Python's -c option
1739 1743 self.exec_init_cmd()
1740 1744 if banner is None:
1741 1745 if not self.rc.banner:
1742 1746 banner = ''
1743 1747 # banner is string? Use it directly!
1744 1748 elif isinstance(self.rc.banner,basestring):
1745 1749 banner = self.rc.banner
1746 1750 else:
1747 1751 banner = self.BANNER+self.banner2
1748 1752
1749 1753 # if you run stuff with -c <cmd>, raw hist is not updated
1750 1754 # ensure that it's in sync
1751 1755 if len(self.input_hist) != len (self.input_hist_raw):
1752 1756 self.input_hist_raw = InputList(self.input_hist)
1753 1757
1754 1758 while 1:
1755 1759 try:
1756 1760 self.interact(banner)
1757 1761 #self.interact_with_readline()
1758 1762
1759 1763 # XXX for testing of a readline-decoupled repl loop, call
1760 1764 # interact_with_readline above
1761 1765
1762 1766 break
1763 1767 except KeyboardInterrupt:
1764 1768 # this should not be necessary, but KeyboardInterrupt
1765 1769 # handling seems rather unpredictable...
1766 1770 self.write("\nKeyboardInterrupt in interact()\n")
1767 1771
1768 1772 def exec_init_cmd(self):
1769 1773 """Execute a command given at the command line.
1770 1774
1771 1775 This emulates Python's -c option."""
1772 1776
1773 1777 #sys.argv = ['-c']
1774 1778 self.push(self.prefilter(self.rc.c, False))
1775 1779 if not self.rc.interact:
1776 1780 self.ask_exit()
1777 1781
1778 1782 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1779 1783 """Embeds IPython into a running python program.
1780 1784
1781 1785 Input:
1782 1786
1783 1787 - header: An optional header message can be specified.
1784 1788
1785 1789 - local_ns, global_ns: working namespaces. If given as None, the
1786 1790 IPython-initialized one is updated with __main__.__dict__, so that
1787 1791 program variables become visible but user-specific configuration
1788 1792 remains possible.
1789 1793
1790 1794 - stack_depth: specifies how many levels in the stack to go to
1791 1795 looking for namespaces (when local_ns and global_ns are None). This
1792 1796 allows an intermediate caller to make sure that this function gets
1793 1797 the namespace from the intended level in the stack. By default (0)
1794 1798 it will get its locals and globals from the immediate caller.
1795 1799
1796 1800 Warning: it's possible to use this in a program which is being run by
1797 1801 IPython itself (via %run), but some funny things will happen (a few
1798 1802 globals get overwritten). In the future this will be cleaned up, as
1799 1803 there is no fundamental reason why it can't work perfectly."""
1800 1804
1801 1805 # Get locals and globals from caller
1802 1806 if local_ns is None or global_ns is None:
1803 1807 call_frame = sys._getframe(stack_depth).f_back
1804 1808
1805 1809 if local_ns is None:
1806 1810 local_ns = call_frame.f_locals
1807 1811 if global_ns is None:
1808 1812 global_ns = call_frame.f_globals
1809 1813
1810 1814 # Update namespaces and fire up interpreter
1811 1815
1812 1816 # The global one is easy, we can just throw it in
1813 1817 self.user_global_ns = global_ns
1814 1818
1815 1819 # but the user/local one is tricky: ipython needs it to store internal
1816 1820 # data, but we also need the locals. We'll copy locals in the user
1817 1821 # one, but will track what got copied so we can delete them at exit.
1818 1822 # This is so that a later embedded call doesn't see locals from a
1819 1823 # previous call (which most likely existed in a separate scope).
1820 1824 local_varnames = local_ns.keys()
1821 1825 self.user_ns.update(local_ns)
1822 1826 #self.user_ns['local_ns'] = local_ns # dbg
1823 1827
1824 1828 # Patch for global embedding to make sure that things don't overwrite
1825 1829 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1826 1830 # FIXME. Test this a bit more carefully (the if.. is new)
1827 1831 if local_ns is None and global_ns is None:
1828 1832 self.user_global_ns.update(__main__.__dict__)
1829 1833
1830 1834 # make sure the tab-completer has the correct frame information, so it
1831 1835 # actually completes using the frame's locals/globals
1832 1836 self.set_completer_frame()
1833 1837
1834 1838 # before activating the interactive mode, we need to make sure that
1835 1839 # all names in the builtin namespace needed by ipython point to
1836 1840 # ourselves, and not to other instances.
1837 1841 self.add_builtins()
1838 1842
1839 1843 self.interact(header)
1840 1844
1841 1845 # now, purge out the user namespace from anything we might have added
1842 1846 # from the caller's local namespace
1843 1847 delvar = self.user_ns.pop
1844 1848 for var in local_varnames:
1845 1849 delvar(var,None)
1846 1850 # and clean builtins we may have overridden
1847 1851 self.clean_builtins()
1848 1852
1849 1853 def interact_prompt(self):
1850 1854 """ Print the prompt (in read-eval-print loop)
1851 1855
1852 1856 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1853 1857 used in standard IPython flow.
1854 1858 """
1855 1859 if self.more:
1856 1860 try:
1857 1861 prompt = self.hooks.generate_prompt(True)
1858 1862 except:
1859 1863 self.showtraceback()
1860 1864 if self.autoindent:
1861 1865 self.rl_do_indent = True
1862 1866
1863 1867 else:
1864 1868 try:
1865 1869 prompt = self.hooks.generate_prompt(False)
1866 1870 except:
1867 1871 self.showtraceback()
1868 1872 self.write(prompt)
1869 1873
1870 1874 def interact_handle_input(self,line):
1871 1875 """ Handle the input line (in read-eval-print loop)
1872 1876
1873 1877 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1874 1878 used in standard IPython flow.
1875 1879 """
1876 1880 if line.lstrip() == line:
1877 1881 self.shadowhist.add(line.strip())
1878 1882 lineout = self.prefilter(line,self.more)
1879 1883
1880 1884 if line.strip():
1881 1885 if self.more:
1882 1886 self.input_hist_raw[-1] += '%s\n' % line
1883 1887 else:
1884 1888 self.input_hist_raw.append('%s\n' % line)
1885 1889
1886 1890
1887 1891 self.more = self.push(lineout)
1888 1892 if (self.SyntaxTB.last_syntax_error and
1889 1893 self.rc.autoedit_syntax):
1890 1894 self.edit_syntax_error()
1891 1895
1892 1896 def interact_with_readline(self):
1893 1897 """ Demo of using interact_handle_input, interact_prompt
1894 1898
1895 1899 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1896 1900 it should work like this.
1897 1901 """
1898 1902 self.readline_startup_hook(self.pre_readline)
1899 1903 while not self.exit_now:
1900 1904 self.interact_prompt()
1901 1905 if self.more:
1902 1906 self.rl_do_indent = True
1903 1907 else:
1904 1908 self.rl_do_indent = False
1905 1909 line = raw_input_original().decode(self.stdin_encoding)
1906 1910 self.interact_handle_input(line)
1907 1911
1908 1912
1909 1913 def interact(self, banner=None):
1910 1914 """Closely emulate the interactive Python console.
1911 1915
1912 1916 The optional banner argument specify the banner to print
1913 1917 before the first interaction; by default it prints a banner
1914 1918 similar to the one printed by the real Python interpreter,
1915 1919 followed by the current class name in parentheses (so as not
1916 1920 to confuse this with the real interpreter -- since it's so
1917 1921 close!).
1918 1922
1919 1923 """
1920 1924
1921 1925 if self.exit_now:
1922 1926 # batch run -> do not interact
1923 1927 return
1924 1928 cprt = 'Type "copyright", "credits" or "license" for more information.'
1925 1929 if banner is None:
1926 1930 self.write("Python %s on %s\n%s\n(%s)\n" %
1927 1931 (sys.version, sys.platform, cprt,
1928 1932 self.__class__.__name__))
1929 1933 else:
1930 1934 self.write(banner)
1931 1935
1932 1936 more = 0
1933 1937
1934 1938 # Mark activity in the builtins
1935 1939 __builtin__.__dict__['__IPYTHON__active'] += 1
1936 1940
1937 1941 if self.has_readline:
1938 1942 self.readline_startup_hook(self.pre_readline)
1939 1943 # exit_now is set by a call to %Exit or %Quit, through the
1940 1944 # ask_exit callback.
1941 1945
1942 1946 while not self.exit_now:
1943 1947 self.hooks.pre_prompt_hook()
1944 1948 if more:
1945 1949 try:
1946 1950 prompt = self.hooks.generate_prompt(True)
1947 1951 except:
1948 1952 self.showtraceback()
1949 1953 if self.autoindent:
1950 1954 self.rl_do_indent = True
1951 1955
1952 1956 else:
1953 1957 try:
1954 1958 prompt = self.hooks.generate_prompt(False)
1955 1959 except:
1956 1960 self.showtraceback()
1957 1961 try:
1958 1962 line = self.raw_input(prompt,more)
1959 1963 if self.exit_now:
1960 1964 # quick exit on sys.std[in|out] close
1961 1965 break
1962 1966 if self.autoindent:
1963 1967 self.rl_do_indent = False
1964 1968
1965 1969 except KeyboardInterrupt:
1966 1970 #double-guard against keyboardinterrupts during kbdint handling
1967 1971 try:
1968 1972 self.write('\nKeyboardInterrupt\n')
1969 1973 self.resetbuffer()
1970 1974 # keep cache in sync with the prompt counter:
1971 1975 self.outputcache.prompt_count -= 1
1972 1976
1973 1977 if self.autoindent:
1974 1978 self.indent_current_nsp = 0
1975 1979 more = 0
1976 1980 except KeyboardInterrupt:
1977 1981 pass
1978 1982 except EOFError:
1979 1983 if self.autoindent:
1980 1984 self.rl_do_indent = False
1981 1985 self.readline_startup_hook(None)
1982 1986 self.write('\n')
1983 1987 self.exit()
1984 1988 except bdb.BdbQuit:
1985 1989 warn('The Python debugger has exited with a BdbQuit exception.\n'
1986 1990 'Because of how pdb handles the stack, it is impossible\n'
1987 1991 'for IPython to properly format this particular exception.\n'
1988 1992 'IPython will resume normal operation.')
1989 1993 except:
1990 1994 # exceptions here are VERY RARE, but they can be triggered
1991 1995 # asynchronously by signal handlers, for example.
1992 1996 self.showtraceback()
1993 1997 else:
1994 1998 more = self.push(line)
1995 1999 if (self.SyntaxTB.last_syntax_error and
1996 2000 self.rc.autoedit_syntax):
1997 2001 self.edit_syntax_error()
1998 2002
1999 2003 # We are off again...
2000 2004 __builtin__.__dict__['__IPYTHON__active'] -= 1
2001 2005
2002 2006 def excepthook(self, etype, value, tb):
2003 2007 """One more defense for GUI apps that call sys.excepthook.
2004 2008
2005 2009 GUI frameworks like wxPython trap exceptions and call
2006 2010 sys.excepthook themselves. I guess this is a feature that
2007 2011 enables them to keep running after exceptions that would
2008 2012 otherwise kill their mainloop. This is a bother for IPython
2009 2013 which excepts to catch all of the program exceptions with a try:
2010 2014 except: statement.
2011 2015
2012 2016 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
2013 2017 any app directly invokes sys.excepthook, it will look to the user like
2014 2018 IPython crashed. In order to work around this, we can disable the
2015 2019 CrashHandler and replace it with this excepthook instead, which prints a
2016 2020 regular traceback using our InteractiveTB. In this fashion, apps which
2017 2021 call sys.excepthook will generate a regular-looking exception from
2018 2022 IPython, and the CrashHandler will only be triggered by real IPython
2019 2023 crashes.
2020 2024
2021 2025 This hook should be used sparingly, only in places which are not likely
2022 2026 to be true IPython errors.
2023 2027 """
2024 2028 self.showtraceback((etype,value,tb),tb_offset=0)
2025 2029
2026 2030 def expand_aliases(self,fn,rest):
2027 2031 """ Expand multiple levels of aliases:
2028 2032
2029 2033 if:
2030 2034
2031 2035 alias foo bar /tmp
2032 2036 alias baz foo
2033 2037
2034 2038 then:
2035 2039
2036 2040 baz huhhahhei -> bar /tmp huhhahhei
2037 2041
2038 2042 """
2039 2043 line = fn + " " + rest
2040 2044
2041 2045 done = set()
2042 2046 while 1:
2043 2047 pre,fn,rest = prefilter.splitUserInput(line,
2044 2048 prefilter.shell_line_split)
2045 2049 if fn in self.alias_table:
2046 2050 if fn in done:
2047 2051 warn("Cyclic alias definition, repeated '%s'" % fn)
2048 2052 return ""
2049 2053 done.add(fn)
2050 2054
2051 2055 l2 = self.transform_alias(fn,rest)
2052 2056 # dir -> dir
2053 2057 # print "alias",line, "->",l2 #dbg
2054 2058 if l2 == line:
2055 2059 break
2056 2060 # ls -> ls -F should not recurse forever
2057 2061 if l2.split(None,1)[0] == line.split(None,1)[0]:
2058 2062 line = l2
2059 2063 break
2060 2064
2061 2065 line=l2
2062 2066
2063 2067
2064 2068 # print "al expand to",line #dbg
2065 2069 else:
2066 2070 break
2067 2071
2068 2072 return line
2069 2073
2070 2074 def transform_alias(self, alias,rest=''):
2071 2075 """ Transform alias to system command string.
2072 2076 """
2073 2077 trg = self.alias_table[alias]
2074 2078
2075 2079 nargs,cmd = trg
2076 2080 # print trg #dbg
2077 2081 if ' ' in cmd and os.path.isfile(cmd):
2078 2082 cmd = '"%s"' % cmd
2079 2083
2080 2084 # Expand the %l special to be the user's input line
2081 2085 if cmd.find('%l') >= 0:
2082 2086 cmd = cmd.replace('%l',rest)
2083 2087 rest = ''
2084 2088 if nargs==0:
2085 2089 # Simple, argument-less aliases
2086 2090 cmd = '%s %s' % (cmd,rest)
2087 2091 else:
2088 2092 # Handle aliases with positional arguments
2089 2093 args = rest.split(None,nargs)
2090 2094 if len(args)< nargs:
2091 2095 error('Alias <%s> requires %s arguments, %s given.' %
2092 2096 (alias,nargs,len(args)))
2093 2097 return None
2094 2098 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
2095 2099 # Now call the macro, evaluating in the user's namespace
2096 2100 #print 'new command: <%r>' % cmd # dbg
2097 2101 return cmd
2098 2102
2099 2103 def call_alias(self,alias,rest=''):
2100 2104 """Call an alias given its name and the rest of the line.
2101 2105
2102 2106 This is only used to provide backwards compatibility for users of
2103 2107 ipalias(), use of which is not recommended for anymore."""
2104 2108
2105 2109 # Now call the macro, evaluating in the user's namespace
2106 2110 cmd = self.transform_alias(alias, rest)
2107 2111 try:
2108 2112 self.system(cmd)
2109 2113 except:
2110 2114 self.showtraceback()
2111 2115
2112 2116 def indent_current_str(self):
2113 2117 """return the current level of indentation as a string"""
2114 2118 return self.indent_current_nsp * ' '
2115 2119
2116 2120 def autoindent_update(self,line):
2117 2121 """Keep track of the indent level."""
2118 2122
2119 2123 #debugx('line')
2120 2124 #debugx('self.indent_current_nsp')
2121 2125 if self.autoindent:
2122 2126 if line:
2123 2127 inisp = num_ini_spaces(line)
2124 2128 if inisp < self.indent_current_nsp:
2125 2129 self.indent_current_nsp = inisp
2126 2130
2127 2131 if line[-1] == ':':
2128 2132 self.indent_current_nsp += 4
2129 2133 elif dedent_re.match(line):
2130 2134 self.indent_current_nsp -= 4
2131 2135 else:
2132 2136 self.indent_current_nsp = 0
2133 2137
2134 2138 def runlines(self,lines):
2135 2139 """Run a string of one or more lines of source.
2136 2140
2137 2141 This method is capable of running a string containing multiple source
2138 2142 lines, as if they had been entered at the IPython prompt. Since it
2139 2143 exposes IPython's processing machinery, the given strings can contain
2140 2144 magic calls (%magic), special shell access (!cmd), etc."""
2141 2145
2142 2146 # We must start with a clean buffer, in case this is run from an
2143 2147 # interactive IPython session (via a magic, for example).
2144 2148 self.resetbuffer()
2145 2149 lines = lines.split('\n')
2146 2150 more = 0
2147 2151
2148 2152 for line in lines:
2149 2153 # skip blank lines so we don't mess up the prompt counter, but do
2150 2154 # NOT skip even a blank line if we are in a code block (more is
2151 2155 # true)
2152 2156
2153 2157 if line or more:
2154 2158 # push to raw history, so hist line numbers stay in sync
2155 2159 self.input_hist_raw.append("# " + line + "\n")
2156 2160 more = self.push(self.prefilter(line,more))
2157 2161 # IPython's runsource returns None if there was an error
2158 2162 # compiling the code. This allows us to stop processing right
2159 2163 # away, so the user gets the error message at the right place.
2160 2164 if more is None:
2161 2165 break
2162 2166 else:
2163 2167 self.input_hist_raw.append("\n")
2164 2168 # final newline in case the input didn't have it, so that the code
2165 2169 # actually does get executed
2166 2170 if more:
2167 2171 self.push('\n')
2168 2172
2169 2173 def runsource(self, source, filename='<input>', symbol='single'):
2170 2174 """Compile and run some source in the interpreter.
2171 2175
2172 2176 Arguments are as for compile_command().
2173 2177
2174 2178 One several things can happen:
2175 2179
2176 2180 1) The input is incorrect; compile_command() raised an
2177 2181 exception (SyntaxError or OverflowError). A syntax traceback
2178 2182 will be printed by calling the showsyntaxerror() method.
2179 2183
2180 2184 2) The input is incomplete, and more input is required;
2181 2185 compile_command() returned None. Nothing happens.
2182 2186
2183 2187 3) The input is complete; compile_command() returned a code
2184 2188 object. The code is executed by calling self.runcode() (which
2185 2189 also handles run-time exceptions, except for SystemExit).
2186 2190
2187 2191 The return value is:
2188 2192
2189 2193 - True in case 2
2190 2194
2191 2195 - False in the other cases, unless an exception is raised, where
2192 2196 None is returned instead. This can be used by external callers to
2193 2197 know whether to continue feeding input or not.
2194 2198
2195 2199 The return value can be used to decide whether to use sys.ps1 or
2196 2200 sys.ps2 to prompt the next line."""
2197 2201
2198 2202 # if the source code has leading blanks, add 'if 1:\n' to it
2199 2203 # this allows execution of indented pasted code. It is tempting
2200 2204 # to add '\n' at the end of source to run commands like ' a=1'
2201 2205 # directly, but this fails for more complicated scenarios
2202 2206 source=source.encode(self.stdin_encoding)
2203 2207 if source[:1] in [' ', '\t']:
2204 2208 source = 'if 1:\n%s' % source
2205 2209
2206 2210 try:
2207 2211 code = self.compile(source,filename,symbol)
2208 2212 except (OverflowError, SyntaxError, ValueError, TypeError):
2209 2213 # Case 1
2210 2214 self.showsyntaxerror(filename)
2211 2215 return None
2212 2216
2213 2217 if code is None:
2214 2218 # Case 2
2215 2219 return True
2216 2220
2217 2221 # Case 3
2218 2222 # We store the code object so that threaded shells and
2219 2223 # custom exception handlers can access all this info if needed.
2220 2224 # The source corresponding to this can be obtained from the
2221 2225 # buffer attribute as '\n'.join(self.buffer).
2222 2226 self.code_to_run = code
2223 2227 # now actually execute the code object
2224 2228 if self.runcode(code) == 0:
2225 2229 return False
2226 2230 else:
2227 2231 return None
2228 2232
2229 2233 def runcode(self,code_obj):
2230 2234 """Execute a code object.
2231 2235
2232 2236 When an exception occurs, self.showtraceback() is called to display a
2233 2237 traceback.
2234 2238
2235 2239 Return value: a flag indicating whether the code to be run completed
2236 2240 successfully:
2237 2241
2238 2242 - 0: successful execution.
2239 2243 - 1: an error occurred.
2240 2244 """
2241 2245
2242 2246 # Set our own excepthook in case the user code tries to call it
2243 2247 # directly, so that the IPython crash handler doesn't get triggered
2244 2248 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2245 2249
2246 2250 # we save the original sys.excepthook in the instance, in case config
2247 2251 # code (such as magics) needs access to it.
2248 2252 self.sys_excepthook = old_excepthook
2249 2253 outflag = 1 # happens in more places, so it's easier as default
2250 2254 try:
2251 2255 try:
2252 2256 self.hooks.pre_runcode_hook()
2253 2257 exec code_obj in self.user_global_ns, self.user_ns
2254 2258 finally:
2255 2259 # Reset our crash handler in place
2256 2260 sys.excepthook = old_excepthook
2257 2261 except SystemExit:
2258 2262 self.resetbuffer()
2259 2263 self.showtraceback()
2260 2264 warn("Type %exit or %quit to exit IPython "
2261 2265 "(%Exit or %Quit do so unconditionally).",level=1)
2262 2266 except self.custom_exceptions:
2263 2267 etype,value,tb = sys.exc_info()
2264 2268 self.CustomTB(etype,value,tb)
2265 2269 except:
2266 2270 self.showtraceback()
2267 2271 else:
2268 2272 outflag = 0
2269 2273 if softspace(sys.stdout, 0):
2270 2274 print
2271 2275 # Flush out code object which has been run (and source)
2272 2276 self.code_to_run = None
2273 2277 return outflag
2274 2278
2275 2279 def push(self, line):
2276 2280 """Push a line to the interpreter.
2277 2281
2278 2282 The line should not have a trailing newline; it may have
2279 2283 internal newlines. The line is appended to a buffer and the
2280 2284 interpreter's runsource() method is called with the
2281 2285 concatenated contents of the buffer as source. If this
2282 2286 indicates that the command was executed or invalid, the buffer
2283 2287 is reset; otherwise, the command is incomplete, and the buffer
2284 2288 is left as it was after the line was appended. The return
2285 2289 value is 1 if more input is required, 0 if the line was dealt
2286 2290 with in some way (this is the same as runsource()).
2287 2291 """
2288 2292
2289 2293 # autoindent management should be done here, and not in the
2290 2294 # interactive loop, since that one is only seen by keyboard input. We
2291 2295 # need this done correctly even for code run via runlines (which uses
2292 2296 # push).
2293 2297
2294 2298 #print 'push line: <%s>' % line # dbg
2295 2299 for subline in line.splitlines():
2296 2300 self.autoindent_update(subline)
2297 2301 self.buffer.append(line)
2298 2302 more = self.runsource('\n'.join(self.buffer), self.filename)
2299 2303 if not more:
2300 2304 self.resetbuffer()
2301 2305 return more
2302 2306
2303 2307 def split_user_input(self, line):
2304 2308 # This is really a hold-over to support ipapi and some extensions
2305 2309 return prefilter.splitUserInput(line)
2306 2310
2307 2311 def resetbuffer(self):
2308 2312 """Reset the input buffer."""
2309 2313 self.buffer[:] = []
2310 2314
2311 2315 def raw_input(self,prompt='',continue_prompt=False):
2312 2316 """Write a prompt and read a line.
2313 2317
2314 2318 The returned line does not include the trailing newline.
2315 2319 When the user enters the EOF key sequence, EOFError is raised.
2316 2320
2317 2321 Optional inputs:
2318 2322
2319 2323 - prompt(''): a string to be printed to prompt the user.
2320 2324
2321 2325 - continue_prompt(False): whether this line is the first one or a
2322 2326 continuation in a sequence of inputs.
2323 2327 """
2324 2328
2325 2329 # Code run by the user may have modified the readline completer state.
2326 2330 # We must ensure that our completer is back in place.
2327 2331 if self.has_readline:
2328 2332 self.set_completer()
2329 2333
2330 2334 try:
2331 2335 line = raw_input_original(prompt).decode(self.stdin_encoding)
2332 2336 except ValueError:
2333 2337 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2334 2338 " or sys.stdout.close()!\nExiting IPython!")
2335 2339 self.ask_exit()
2336 2340 return ""
2337 2341
2338 2342 # Try to be reasonably smart about not re-indenting pasted input more
2339 2343 # than necessary. We do this by trimming out the auto-indent initial
2340 2344 # spaces, if the user's actual input started itself with whitespace.
2341 2345 #debugx('self.buffer[-1]')
2342 2346
2343 2347 if self.autoindent:
2344 2348 if num_ini_spaces(line) > self.indent_current_nsp:
2345 2349 line = line[self.indent_current_nsp:]
2346 2350 self.indent_current_nsp = 0
2347 2351
2348 2352 # store the unfiltered input before the user has any chance to modify
2349 2353 # it.
2350 2354 if line.strip():
2351 2355 if continue_prompt:
2352 2356 self.input_hist_raw[-1] += '%s\n' % line
2353 2357 if self.has_readline: # and some config option is set?
2354 2358 try:
2355 2359 histlen = self.readline.get_current_history_length()
2356 2360 if histlen > 1:
2357 2361 newhist = self.input_hist_raw[-1].rstrip()
2358 2362 self.readline.remove_history_item(histlen-1)
2359 2363 self.readline.replace_history_item(histlen-2,
2360 2364 newhist.encode(self.stdin_encoding))
2361 2365 except AttributeError:
2362 2366 pass # re{move,place}_history_item are new in 2.4.
2363 2367 else:
2364 2368 self.input_hist_raw.append('%s\n' % line)
2365 2369 # only entries starting at first column go to shadow history
2366 2370 if line.lstrip() == line:
2367 2371 self.shadowhist.add(line.strip())
2368 2372 elif not continue_prompt:
2369 2373 self.input_hist_raw.append('\n')
2370 2374 try:
2371 2375 lineout = self.prefilter(line,continue_prompt)
2372 2376 except:
2373 2377 # blanket except, in case a user-defined prefilter crashes, so it
2374 2378 # can't take all of ipython with it.
2375 2379 self.showtraceback()
2376 2380 return ''
2377 2381 else:
2378 2382 return lineout
2379 2383
2380 2384 def _prefilter(self, line, continue_prompt):
2381 2385 """Calls different preprocessors, depending on the form of line."""
2382 2386
2383 2387 # All handlers *must* return a value, even if it's blank ('').
2384 2388
2385 2389 # Lines are NOT logged here. Handlers should process the line as
2386 2390 # needed, update the cache AND log it (so that the input cache array
2387 2391 # stays synced).
2388 2392
2389 2393 #.....................................................................
2390 2394 # Code begins
2391 2395
2392 2396 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2393 2397
2394 2398 # save the line away in case we crash, so the post-mortem handler can
2395 2399 # record it
2396 2400 self._last_input_line = line
2397 2401
2398 2402 #print '***line: <%s>' % line # dbg
2399 2403
2400 2404 if not line:
2401 2405 # Return immediately on purely empty lines, so that if the user
2402 2406 # previously typed some whitespace that started a continuation
2403 2407 # prompt, he can break out of that loop with just an empty line.
2404 2408 # This is how the default python prompt works.
2405 2409
2406 2410 # Only return if the accumulated input buffer was just whitespace!
2407 2411 if ''.join(self.buffer).isspace():
2408 2412 self.buffer[:] = []
2409 2413 return ''
2410 2414
2411 2415 line_info = prefilter.LineInfo(line, continue_prompt)
2412 2416
2413 2417 # the input history needs to track even empty lines
2414 2418 stripped = line.strip()
2415 2419
2416 2420 if not stripped:
2417 2421 if not continue_prompt:
2418 2422 self.outputcache.prompt_count -= 1
2419 2423 return self.handle_normal(line_info)
2420 2424
2421 2425 # print '***cont',continue_prompt # dbg
2422 2426 # special handlers are only allowed for single line statements
2423 2427 if continue_prompt and not self.rc.multi_line_specials:
2424 2428 return self.handle_normal(line_info)
2425 2429
2426 2430
2427 2431 # See whether any pre-existing handler can take care of it
2428 2432 rewritten = self.hooks.input_prefilter(stripped)
2429 2433 if rewritten != stripped: # ok, some prefilter did something
2430 2434 rewritten = line_info.pre + rewritten # add indentation
2431 2435 return self.handle_normal(prefilter.LineInfo(rewritten,
2432 2436 continue_prompt))
2433 2437
2434 2438 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2435 2439
2436 2440 return prefilter.prefilter(line_info, self)
2437 2441
2438 2442
2439 2443 def _prefilter_dumb(self, line, continue_prompt):
2440 2444 """simple prefilter function, for debugging"""
2441 2445 return self.handle_normal(line,continue_prompt)
2442 2446
2443 2447
2444 2448 def multiline_prefilter(self, line, continue_prompt):
2445 2449 """ Run _prefilter for each line of input
2446 2450
2447 2451 Covers cases where there are multiple lines in the user entry,
2448 2452 which is the case when the user goes back to a multiline history
2449 2453 entry and presses enter.
2450 2454
2451 2455 """
2452 2456 out = []
2453 2457 for l in line.rstrip('\n').split('\n'):
2454 2458 out.append(self._prefilter(l, continue_prompt))
2455 2459 return '\n'.join(out)
2456 2460
2457 2461 # Set the default prefilter() function (this can be user-overridden)
2458 2462 prefilter = multiline_prefilter
2459 2463
2460 2464 def handle_normal(self,line_info):
2461 2465 """Handle normal input lines. Use as a template for handlers."""
2462 2466
2463 2467 # With autoindent on, we need some way to exit the input loop, and I
2464 2468 # don't want to force the user to have to backspace all the way to
2465 2469 # clear the line. The rule will be in this case, that either two
2466 2470 # lines of pure whitespace in a row, or a line of pure whitespace but
2467 2471 # of a size different to the indent level, will exit the input loop.
2468 2472 line = line_info.line
2469 2473 continue_prompt = line_info.continue_prompt
2470 2474
2471 2475 if (continue_prompt and self.autoindent and line.isspace() and
2472 2476 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2473 2477 (self.buffer[-1]).isspace() )):
2474 2478 line = ''
2475 2479
2476 2480 self.log(line,line,continue_prompt)
2477 2481 return line
2478 2482
2479 2483 def handle_alias(self,line_info):
2480 2484 """Handle alias input lines. """
2481 2485 tgt = self.alias_table[line_info.iFun]
2482 2486 # print "=>",tgt #dbg
2483 2487 if callable(tgt):
2484 2488 if '$' in line_info.line:
2485 2489 call_meth = '(_ip, _ip.itpl(%s))'
2486 2490 else:
2487 2491 call_meth = '(_ip,%s)'
2488 2492 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2489 2493 line_info.iFun,
2490 2494 make_quoted_expr(line_info.line))
2491 2495 else:
2492 2496 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2493 2497
2494 2498 # pre is needed, because it carries the leading whitespace. Otherwise
2495 2499 # aliases won't work in indented sections.
2496 2500 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2497 2501 make_quoted_expr( transformed ))
2498 2502
2499 2503 self.log(line_info.line,line_out,line_info.continue_prompt)
2500 2504 #print 'line out:',line_out # dbg
2501 2505 return line_out
2502 2506
2503 2507 def handle_shell_escape(self, line_info):
2504 2508 """Execute the line in a shell, empty return value"""
2505 2509 #print 'line in :', `line` # dbg
2506 2510 line = line_info.line
2507 2511 if line.lstrip().startswith('!!'):
2508 2512 # rewrite LineInfo's line, iFun and theRest to properly hold the
2509 2513 # call to %sx and the actual command to be executed, so
2510 2514 # handle_magic can work correctly. Note that this works even if
2511 2515 # the line is indented, so it handles multi_line_specials
2512 2516 # properly.
2513 2517 new_rest = line.lstrip()[2:]
2514 2518 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2515 2519 line_info.iFun = 'sx'
2516 2520 line_info.theRest = new_rest
2517 2521 return self.handle_magic(line_info)
2518 2522 else:
2519 2523 cmd = line.lstrip().lstrip('!')
2520 2524 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2521 2525 make_quoted_expr(cmd))
2522 2526 # update cache/log and return
2523 2527 self.log(line,line_out,line_info.continue_prompt)
2524 2528 return line_out
2525 2529
2526 2530 def handle_magic(self, line_info):
2527 2531 """Execute magic functions."""
2528 2532 iFun = line_info.iFun
2529 2533 theRest = line_info.theRest
2530 2534 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2531 2535 make_quoted_expr(iFun + " " + theRest))
2532 2536 self.log(line_info.line,cmd,line_info.continue_prompt)
2533 2537 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2534 2538 return cmd
2535 2539
2536 2540 def handle_auto(self, line_info):
2537 2541 """Hande lines which can be auto-executed, quoting if requested."""
2538 2542
2539 2543 line = line_info.line
2540 2544 iFun = line_info.iFun
2541 2545 theRest = line_info.theRest
2542 2546 pre = line_info.pre
2543 2547 continue_prompt = line_info.continue_prompt
2544 2548 obj = line_info.ofind(self)['obj']
2545 2549
2546 2550 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2547 2551
2548 2552 # This should only be active for single-line input!
2549 2553 if continue_prompt:
2550 2554 self.log(line,line,continue_prompt)
2551 2555 return line
2552 2556
2553 2557 force_auto = isinstance(obj, IPython.ipapi.IPyAutocall)
2554 2558 auto_rewrite = True
2555 2559
2556 2560 if pre == self.ESC_QUOTE:
2557 2561 # Auto-quote splitting on whitespace
2558 2562 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2559 2563 elif pre == self.ESC_QUOTE2:
2560 2564 # Auto-quote whole string
2561 2565 newcmd = '%s("%s")' % (iFun,theRest)
2562 2566 elif pre == self.ESC_PAREN:
2563 2567 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2564 2568 else:
2565 2569 # Auto-paren.
2566 2570 # We only apply it to argument-less calls if the autocall
2567 2571 # parameter is set to 2. We only need to check that autocall is <
2568 2572 # 2, since this function isn't called unless it's at least 1.
2569 2573 if not theRest and (self.rc.autocall < 2) and not force_auto:
2570 2574 newcmd = '%s %s' % (iFun,theRest)
2571 2575 auto_rewrite = False
2572 2576 else:
2573 2577 if not force_auto and theRest.startswith('['):
2574 2578 if hasattr(obj,'__getitem__'):
2575 2579 # Don't autocall in this case: item access for an object
2576 2580 # which is BOTH callable and implements __getitem__.
2577 2581 newcmd = '%s %s' % (iFun,theRest)
2578 2582 auto_rewrite = False
2579 2583 else:
2580 2584 # if the object doesn't support [] access, go ahead and
2581 2585 # autocall
2582 2586 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2583 2587 elif theRest.endswith(';'):
2584 2588 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2585 2589 else:
2586 2590 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2587 2591
2588 2592 if auto_rewrite:
2589 2593 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2590 2594
2591 2595 try:
2592 2596 # plain ascii works better w/ pyreadline, on some machines, so
2593 2597 # we use it and only print uncolored rewrite if we have unicode
2594 2598 rw = str(rw)
2595 2599 print >>Term.cout, rw
2596 2600 except UnicodeEncodeError:
2597 2601 print "-------------->" + newcmd
2598 2602
2599 2603 # log what is now valid Python, not the actual user input (without the
2600 2604 # final newline)
2601 2605 self.log(line,newcmd,continue_prompt)
2602 2606 return newcmd
2603 2607
2604 2608 def handle_help(self, line_info):
2605 2609 """Try to get some help for the object.
2606 2610
2607 2611 obj? or ?obj -> basic information.
2608 2612 obj?? or ??obj -> more details.
2609 2613 """
2610 2614
2611 2615 line = line_info.line
2612 2616 # We need to make sure that we don't process lines which would be
2613 2617 # otherwise valid python, such as "x=1 # what?"
2614 2618 try:
2615 2619 codeop.compile_command(line)
2616 2620 except SyntaxError:
2617 2621 # We should only handle as help stuff which is NOT valid syntax
2618 2622 if line[0]==self.ESC_HELP:
2619 2623 line = line[1:]
2620 2624 elif line[-1]==self.ESC_HELP:
2621 2625 line = line[:-1]
2622 2626 self.log(line,'#?'+line,line_info.continue_prompt)
2623 2627 if line:
2624 2628 #print 'line:<%r>' % line # dbg
2625 2629 self.magic_pinfo(line)
2626 2630 else:
2627 2631 page(self.usage,screen_lines=self.rc.screen_length)
2628 2632 return '' # Empty string is needed here!
2629 2633 except:
2630 2634 # Pass any other exceptions through to the normal handler
2631 2635 return self.handle_normal(line_info)
2632 2636 else:
2633 2637 # If the code compiles ok, we should handle it normally
2634 2638 return self.handle_normal(line_info)
2635 2639
2636 2640 def getapi(self):
2637 2641 """ Get an IPApi object for this shell instance
2638 2642
2639 2643 Getting an IPApi object is always preferable to accessing the shell
2640 2644 directly, but this holds true especially for extensions.
2641 2645
2642 2646 It should always be possible to implement an extension with IPApi
2643 2647 alone. If not, contact maintainer to request an addition.
2644 2648
2645 2649 """
2646 2650 return self.api
2647 2651
2648 2652 def handle_emacs(self, line_info):
2649 2653 """Handle input lines marked by python-mode."""
2650 2654
2651 2655 # Currently, nothing is done. Later more functionality can be added
2652 2656 # here if needed.
2653 2657
2654 2658 # The input cache shouldn't be updated
2655 2659 return line_info.line
2656 2660
2657 2661
2658 2662 def mktempfile(self,data=None):
2659 2663 """Make a new tempfile and return its filename.
2660 2664
2661 2665 This makes a call to tempfile.mktemp, but it registers the created
2662 2666 filename internally so ipython cleans it up at exit time.
2663 2667
2664 2668 Optional inputs:
2665 2669
2666 2670 - data(None): if data is given, it gets written out to the temp file
2667 2671 immediately, and the file is closed again."""
2668 2672
2669 2673 filename = tempfile.mktemp('.py','ipython_edit_')
2670 2674 self.tempfiles.append(filename)
2671 2675
2672 2676 if data:
2673 2677 tmp_file = open(filename,'w')
2674 2678 tmp_file.write(data)
2675 2679 tmp_file.close()
2676 2680 return filename
2677 2681
2678 2682 def write(self,data):
2679 2683 """Write a string to the default output"""
2680 2684 Term.cout.write(data)
2681 2685
2682 2686 def write_err(self,data):
2683 2687 """Write a string to the default error output"""
2684 2688 Term.cerr.write(data)
2685 2689
2686 2690 def ask_exit(self):
2687 2691 """ Call for exiting. Can be overiden and used as a callback. """
2688 2692 self.exit_now = True
2689 2693
2690 2694 def exit(self):
2691 2695 """Handle interactive exit.
2692 2696
2693 2697 This method calls the ask_exit callback."""
2694 2698
2695 2699 if self.rc.confirm_exit:
2696 2700 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2697 2701 self.ask_exit()
2698 2702 else:
2699 2703 self.ask_exit()
2700 2704
2701 2705 def safe_execfile(self,fname,*where,**kw):
2702 2706 """A safe version of the builtin execfile().
2703 2707
2704 2708 This version will never throw an exception, and knows how to handle
2705 2709 ipython logs as well.
2706 2710
2707 2711 :Parameters:
2708 2712 fname : string
2709 2713 Name of the file to be executed.
2710 2714
2711 2715 where : tuple
2712 2716 One or two namespaces, passed to execfile() as (globals,locals).
2713 2717 If only one is given, it is passed as both.
2714 2718
2715 2719 :Keywords:
2716 2720 islog : boolean (False)
2717 2721
2718 2722 quiet : boolean (True)
2719 2723
2720 2724 exit_ignore : boolean (False)
2721 2725 """
2722 2726
2723 2727 def syspath_cleanup():
2724 2728 """Internal cleanup routine for sys.path."""
2725 2729 if add_dname:
2726 2730 try:
2727 2731 sys.path.remove(dname)
2728 2732 except ValueError:
2729 2733 # For some reason the user has already removed it, ignore.
2730 2734 pass
2731 2735
2732 2736 fname = os.path.expanduser(fname)
2733 2737
2734 2738 # Find things also in current directory. This is needed to mimic the
2735 2739 # behavior of running a script from the system command line, where
2736 2740 # Python inserts the script's directory into sys.path
2737 2741 dname = os.path.dirname(os.path.abspath(fname))
2738 2742 add_dname = False
2739 2743 if dname not in sys.path:
2740 2744 sys.path.insert(0,dname)
2741 2745 add_dname = True
2742 2746
2743 2747 try:
2744 2748 xfile = open(fname)
2745 2749 except:
2746 2750 print >> Term.cerr, \
2747 2751 'Could not open file <%s> for safe execution.' % fname
2748 2752 syspath_cleanup()
2749 2753 return None
2750 2754
2751 2755 kw.setdefault('islog',0)
2752 2756 kw.setdefault('quiet',1)
2753 2757 kw.setdefault('exit_ignore',0)
2754 2758
2755 2759 first = xfile.readline()
2756 2760 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2757 2761 xfile.close()
2758 2762 # line by line execution
2759 2763 if first.startswith(loghead) or kw['islog']:
2760 2764 print 'Loading log file <%s> one line at a time...' % fname
2761 2765 if kw['quiet']:
2762 2766 stdout_save = sys.stdout
2763 2767 sys.stdout = StringIO.StringIO()
2764 2768 try:
2765 2769 globs,locs = where[0:2]
2766 2770 except:
2767 2771 try:
2768 2772 globs = locs = where[0]
2769 2773 except:
2770 2774 globs = locs = globals()
2771 2775 badblocks = []
2772 2776
2773 2777 # we also need to identify indented blocks of code when replaying
2774 2778 # logs and put them together before passing them to an exec
2775 2779 # statement. This takes a bit of regexp and look-ahead work in the
2776 2780 # file. It's easiest if we swallow the whole thing in memory
2777 2781 # first, and manually walk through the lines list moving the
2778 2782 # counter ourselves.
2779 2783 indent_re = re.compile('\s+\S')
2780 2784 xfile = open(fname)
2781 2785 filelines = xfile.readlines()
2782 2786 xfile.close()
2783 2787 nlines = len(filelines)
2784 2788 lnum = 0
2785 2789 while lnum < nlines:
2786 2790 line = filelines[lnum]
2787 2791 lnum += 1
2788 2792 # don't re-insert logger status info into cache
2789 2793 if line.startswith('#log#'):
2790 2794 continue
2791 2795 else:
2792 2796 # build a block of code (maybe a single line) for execution
2793 2797 block = line
2794 2798 try:
2795 2799 next = filelines[lnum] # lnum has already incremented
2796 2800 except:
2797 2801 next = None
2798 2802 while next and indent_re.match(next):
2799 2803 block += next
2800 2804 lnum += 1
2801 2805 try:
2802 2806 next = filelines[lnum]
2803 2807 except:
2804 2808 next = None
2805 2809 # now execute the block of one or more lines
2806 2810 try:
2807 2811 exec block in globs,locs
2808 2812 except SystemExit:
2809 2813 pass
2810 2814 except:
2811 2815 badblocks.append(block.rstrip())
2812 2816 if kw['quiet']: # restore stdout
2813 2817 sys.stdout.close()
2814 2818 sys.stdout = stdout_save
2815 2819 print 'Finished replaying log file <%s>' % fname
2816 2820 if badblocks:
2817 2821 print >> sys.stderr, ('\nThe following lines/blocks in file '
2818 2822 '<%s> reported errors:' % fname)
2819 2823
2820 2824 for badline in badblocks:
2821 2825 print >> sys.stderr, badline
2822 2826 else: # regular file execution
2823 2827 try:
2824 2828 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2825 2829 # Work around a bug in Python for Windows. The bug was
2826 2830 # fixed in in Python 2.5 r54159 and 54158, but that's still
2827 2831 # SVN Python as of March/07. For details, see:
2828 2832 # http://projects.scipy.org/ipython/ipython/ticket/123
2829 2833 try:
2830 2834 globs,locs = where[0:2]
2831 2835 except:
2832 2836 try:
2833 2837 globs = locs = where[0]
2834 2838 except:
2835 2839 globs = locs = globals()
2836 2840 exec file(fname) in globs,locs
2837 2841 else:
2838 2842 execfile(fname,*where)
2839 2843 except SyntaxError:
2840 2844 self.showsyntaxerror()
2841 2845 warn('Failure executing file: <%s>' % fname)
2842 2846 except SystemExit,status:
2843 2847 # Code that correctly sets the exit status flag to success (0)
2844 2848 # shouldn't be bothered with a traceback. Note that a plain
2845 2849 # sys.exit() does NOT set the message to 0 (it's empty) so that
2846 2850 # will still get a traceback. Note that the structure of the
2847 2851 # SystemExit exception changed between Python 2.4 and 2.5, so
2848 2852 # the checks must be done in a version-dependent way.
2849 2853 show = False
2850 2854
2851 2855 if sys.version_info[:2] > (2,5):
2852 2856 if status.message!=0 and not kw['exit_ignore']:
2853 2857 show = True
2854 2858 else:
2855 2859 if status.code and not kw['exit_ignore']:
2856 2860 show = True
2857 2861 if show:
2858 2862 self.showtraceback()
2859 2863 warn('Failure executing file: <%s>' % fname)
2860 2864 except:
2861 2865 self.showtraceback()
2862 2866 warn('Failure executing file: <%s>' % fname)
2863 2867
2864 2868 syspath_cleanup()
2865 2869
2866 2870 #************************* end of file <iplib.py> *****************************
@@ -1,825 +1,813 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3
4 4 """Start an IPython cluster = (controller + engines)."""
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008 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 import os
18 18 import re
19 19 import sys
20 20 import signal
21 21 import tempfile
22 22 pjoin = os.path.join
23 23
24 24 from twisted.internet import reactor, defer
25 25 from twisted.internet.protocol import ProcessProtocol
26 26 from twisted.internet.error import ProcessDone, ProcessTerminated
27 27 from twisted.internet.utils import getProcessOutput
28 28 from twisted.python import failure, log
29 29
30 30 from IPython.external import argparse
31 31 from IPython.external import Itpl
32 32 from IPython.genutils import (
33 33 get_ipython_dir,
34 34 get_log_dir,
35 35 get_security_dir,
36 36 num_cpus
37 37 )
38 38 from IPython.kernel.fcutil import have_crypto
39 39
40 40 # Create various ipython directories if they don't exist.
41 41 # This must be done before IPython.kernel.config is imported.
42 42 from IPython.iplib import user_setup
43 43 if os.name == 'posix':
44 44 rc_suffix = ''
45 45 else:
46 46 rc_suffix = '.ini'
47 47 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
48 48 get_log_dir()
49 49 get_security_dir()
50 50
51 51 from IPython.kernel.config import config_manager as kernel_config_manager
52 52 from IPython.kernel.error import SecurityError, FileTimeoutError
53 53 from IPython.kernel.fcutil import have_crypto
54 54 from IPython.kernel.twistedutil import gatherBoth, wait_for_file
55 55 from IPython.kernel.util import printer
56 56
57
58 57 #-----------------------------------------------------------------------------
59 58 # General process handling code
60 59 #-----------------------------------------------------------------------------
61 60
62 def find_exe(cmd):
63 try:
64 import win32api
65 except ImportError:
66 raise ImportError('you need to have pywin32 installed for this to work')
67 else:
68 try:
69 (path, offest) = win32api.SearchPath(os.environ['PATH'],cmd + '.exe')
70 except:
71 (path, offset) = win32api.SearchPath(os.environ['PATH'],cmd + '.bat')
72 return path
73 61
74 62 class ProcessStateError(Exception):
75 63 pass
76 64
77 65 class UnknownStatus(Exception):
78 66 pass
79 67
80 68 class LauncherProcessProtocol(ProcessProtocol):
81 69 """
82 70 A ProcessProtocol to go with the ProcessLauncher.
83 71 """
84 72 def __init__(self, process_launcher):
85 73 self.process_launcher = process_launcher
86 74
87 75 def connectionMade(self):
88 76 self.process_launcher.fire_start_deferred(self.transport.pid)
89 77
90 78 def processEnded(self, status):
91 79 value = status.value
92 80 if isinstance(value, ProcessDone):
93 81 self.process_launcher.fire_stop_deferred(0)
94 82 elif isinstance(value, ProcessTerminated):
95 83 self.process_launcher.fire_stop_deferred(
96 84 {'exit_code':value.exitCode,
97 85 'signal':value.signal,
98 86 'status':value.status
99 87 }
100 88 )
101 89 else:
102 90 raise UnknownStatus("unknown exit status, this is probably a bug in Twisted")
103 91
104 92 def outReceived(self, data):
105 93 log.msg(data)
106 94
107 95 def errReceived(self, data):
108 96 log.err(data)
109 97
110 98 class ProcessLauncher(object):
111 99 """
112 100 Start and stop an external process in an asynchronous manner.
113 101
114 102 Currently this uses deferreds to notify other parties of process state
115 103 changes. This is an awkward design and should be moved to using
116 104 a formal NotificationCenter.
117 105 """
118 106 def __init__(self, cmd_and_args):
119 107 self.cmd = cmd_and_args[0]
120 108 self.args = cmd_and_args
121 109 self._reset()
122 110
123 111 def _reset(self):
124 112 self.process_protocol = None
125 113 self.pid = None
126 114 self.start_deferred = None
127 115 self.stop_deferreds = []
128 116 self.state = 'before' # before, running, or after
129 117
130 118 @property
131 119 def running(self):
132 120 if self.state == 'running':
133 121 return True
134 122 else:
135 123 return False
136 124
137 125 def fire_start_deferred(self, pid):
138 126 self.pid = pid
139 127 self.state = 'running'
140 128 log.msg('Process %r has started with pid=%i' % (self.args, pid))
141 129 self.start_deferred.callback(pid)
142 130
143 131 def start(self):
144 132 if self.state == 'before':
145 133 self.process_protocol = LauncherProcessProtocol(self)
146 134 self.start_deferred = defer.Deferred()
147 135 self.process_transport = reactor.spawnProcess(
148 136 self.process_protocol,
149 137 self.cmd,
150 138 self.args,
151 139 env=os.environ
152 140 )
153 141 return self.start_deferred
154 142 else:
155 143 s = 'the process has already been started and has state: %r' % \
156 144 self.state
157 145 return defer.fail(ProcessStateError(s))
158 146
159 147 def get_stop_deferred(self):
160 148 if self.state == 'running' or self.state == 'before':
161 149 d = defer.Deferred()
162 150 self.stop_deferreds.append(d)
163 151 return d
164 152 else:
165 153 s = 'this process is already complete'
166 154 return defer.fail(ProcessStateError(s))
167 155
168 156 def fire_stop_deferred(self, exit_code):
169 157 log.msg('Process %r has stopped with %r' % (self.args, exit_code))
170 158 self.state = 'after'
171 159 for d in self.stop_deferreds:
172 160 d.callback(exit_code)
173 161
174 162 def signal(self, sig):
175 163 """
176 164 Send a signal to the process.
177 165
178 166 The argument sig can be ('KILL','INT', etc.) or any signal number.
179 167 """
180 168 if self.state == 'running':
181 169 self.process_transport.signalProcess(sig)
182 170
183 171 # def __del__(self):
184 172 # self.signal('KILL')
185 173
186 174 def interrupt_then_kill(self, delay=1.0):
187 175 self.signal('INT')
188 176 reactor.callLater(delay, self.signal, 'KILL')
189 177
190 178
191 179 #-----------------------------------------------------------------------------
192 180 # Code for launching controller and engines
193 181 #-----------------------------------------------------------------------------
194 182
195 183
196 184 class ControllerLauncher(ProcessLauncher):
197 185
198 186 def __init__(self, extra_args=None):
199 187 if sys.platform == 'win32':
200 188 # This logic is needed because the ipcontroller script doesn't
201 189 # always get installed in the same way or in the same location.
202 190 from IPython.kernel.scripts import ipcontroller
203 191 script_location = ipcontroller.__file__.replace('.pyc', '.py')
204 192 # The -u option here turns on unbuffered output, which is required
205 193 # on Win32 to prevent wierd conflict and problems with Twisted.
206 194 # Also, use sys.executable to make sure we are picking up the
207 195 # right python exe.
208 196 args = [sys.executable, '-u', script_location]
209 197 else:
210 198 args = ['ipcontroller']
211 199 self.extra_args = extra_args
212 200 if extra_args is not None:
213 201 args.extend(extra_args)
214 202
215 203 ProcessLauncher.__init__(self, args)
216 204
217 205
218 206 class EngineLauncher(ProcessLauncher):
219 207
220 208 def __init__(self, extra_args=None):
221 209 if sys.platform == 'win32':
222 210 # This logic is needed because the ipcontroller script doesn't
223 211 # always get installed in the same way or in the same location.
224 212 from IPython.kernel.scripts import ipengine
225 213 script_location = ipengine.__file__.replace('.pyc', '.py')
226 214 # The -u option here turns on unbuffered output, which is required
227 215 # on Win32 to prevent wierd conflict and problems with Twisted.
228 216 # Also, use sys.executable to make sure we are picking up the
229 217 # right python exe.
230 218 args = [sys.executable, '-u', script_location]
231 219 else:
232 220 args = ['ipengine']
233 221 self.extra_args = extra_args
234 222 if extra_args is not None:
235 223 args.extend(extra_args)
236 224
237 225 ProcessLauncher.__init__(self, args)
238 226
239 227
240 228 class LocalEngineSet(object):
241 229
242 230 def __init__(self, extra_args=None):
243 231 self.extra_args = extra_args
244 232 self.launchers = []
245 233
246 234 def start(self, n):
247 235 dlist = []
248 236 for i in range(n):
249 237 el = EngineLauncher(extra_args=self.extra_args)
250 238 d = el.start()
251 239 self.launchers.append(el)
252 240 dlist.append(d)
253 241 dfinal = gatherBoth(dlist, consumeErrors=True)
254 242 dfinal.addCallback(self._handle_start)
255 243 return dfinal
256 244
257 245 def _handle_start(self, r):
258 246 log.msg('Engines started with pids: %r' % r)
259 247 return r
260 248
261 249 def _handle_stop(self, r):
262 250 log.msg('Engines received signal: %r' % r)
263 251 return r
264 252
265 253 def signal(self, sig):
266 254 dlist = []
267 255 for el in self.launchers:
268 256 d = el.get_stop_deferred()
269 257 dlist.append(d)
270 258 el.signal(sig)
271 259 dfinal = gatherBoth(dlist, consumeErrors=True)
272 260 dfinal.addCallback(self._handle_stop)
273 261 return dfinal
274 262
275 263 def interrupt_then_kill(self, delay=1.0):
276 264 dlist = []
277 265 for el in self.launchers:
278 266 d = el.get_stop_deferred()
279 267 dlist.append(d)
280 268 el.interrupt_then_kill(delay)
281 269 dfinal = gatherBoth(dlist, consumeErrors=True)
282 270 dfinal.addCallback(self._handle_stop)
283 271 return dfinal
284 272
285 273
286 274 class BatchEngineSet(object):
287 275
288 276 # Subclasses must fill these in. See PBSEngineSet
289 277 submit_command = ''
290 278 delete_command = ''
291 279 job_id_regexp = ''
292 280
293 281 def __init__(self, template_file, **kwargs):
294 282 self.template_file = template_file
295 283 self.context = {}
296 284 self.context.update(kwargs)
297 285 self.batch_file = self.template_file+'-run'
298 286
299 287 def parse_job_id(self, output):
300 288 m = re.match(self.job_id_regexp, output)
301 289 if m is not None:
302 290 job_id = m.group()
303 291 else:
304 292 raise Exception("job id couldn't be determined: %s" % output)
305 293 self.job_id = job_id
306 294 log.msg('Job started with job id: %r' % job_id)
307 295 return job_id
308 296
309 297 def write_batch_script(self, n):
310 298 self.context['n'] = n
311 299 template = open(self.template_file, 'r').read()
312 300 log.msg('Using template for batch script: %s' % self.template_file)
313 301 script_as_string = Itpl.itplns(template, self.context)
314 302 log.msg('Writing instantiated batch script: %s' % self.batch_file)
315 303 f = open(self.batch_file,'w')
316 304 f.write(script_as_string)
317 305 f.close()
318 306
319 307 def handle_error(self, f):
320 308 f.printTraceback()
321 309 f.raiseException()
322 310
323 311 def start(self, n):
324 312 self.write_batch_script(n)
325 313 d = getProcessOutput(self.submit_command,
326 314 [self.batch_file],env=os.environ)
327 315 d.addCallback(self.parse_job_id)
328 316 d.addErrback(self.handle_error)
329 317 return d
330 318
331 319 def kill(self):
332 320 d = getProcessOutput(self.delete_command,
333 321 [self.job_id],env=os.environ)
334 322 return d
335 323
336 324 class PBSEngineSet(BatchEngineSet):
337 325
338 326 submit_command = 'qsub'
339 327 delete_command = 'qdel'
340 328 job_id_regexp = '\d+'
341 329
342 330 def __init__(self, template_file, **kwargs):
343 331 BatchEngineSet.__init__(self, template_file, **kwargs)
344 332
345 333
346 334 sshx_template="""#!/bin/sh
347 335 "$@" &> /dev/null &
348 336 echo $!
349 337 """
350 338
351 339 engine_killer_template="""#!/bin/sh
352 340 ps -fu `whoami` | grep '[i]pengine' | awk '{print $2}' | xargs kill -TERM
353 341 """
354 342
355 343 class SSHEngineSet(object):
356 344 sshx_template=sshx_template
357 345 engine_killer_template=engine_killer_template
358 346
359 347 def __init__(self, engine_hosts, sshx=None, ipengine="ipengine"):
360 348 """Start a controller on localhost and engines using ssh.
361 349
362 350 The engine_hosts argument is a dict with hostnames as keys and
363 351 the number of engine (int) as values. sshx is the name of a local
364 352 file that will be used to run remote commands. This file is used
365 353 to setup the environment properly.
366 354 """
367 355
368 356 self.temp_dir = tempfile.gettempdir()
369 357 if sshx is not None:
370 358 self.sshx = sshx
371 359 else:
372 360 # Write the sshx.sh file locally from our template.
373 361 self.sshx = os.path.join(
374 362 self.temp_dir,
375 363 '%s-main-sshx.sh' % os.environ['USER']
376 364 )
377 365 f = open(self.sshx, 'w')
378 366 f.writelines(self.sshx_template)
379 367 f.close()
380 368 self.engine_command = ipengine
381 369 self.engine_hosts = engine_hosts
382 370 # Write the engine killer script file locally from our template.
383 371 self.engine_killer = os.path.join(
384 372 self.temp_dir,
385 373 '%s-local-engine_killer.sh' % os.environ['USER']
386 374 )
387 375 f = open(self.engine_killer, 'w')
388 376 f.writelines(self.engine_killer_template)
389 377 f.close()
390 378
391 379 def start(self, send_furl=False):
392 380 dlist = []
393 381 for host in self.engine_hosts.keys():
394 382 count = self.engine_hosts[host]
395 383 d = self._start(host, count, send_furl)
396 384 dlist.append(d)
397 385 return gatherBoth(dlist, consumeErrors=True)
398 386
399 387 def _start(self, hostname, count=1, send_furl=False):
400 388 if send_furl:
401 389 d = self._scp_furl(hostname)
402 390 else:
403 391 d = defer.succeed(None)
404 392 d.addCallback(lambda r: self._scp_sshx(hostname))
405 393 d.addCallback(lambda r: self._ssh_engine(hostname, count))
406 394 return d
407 395
408 396 def _scp_furl(self, hostname):
409 397 scp_cmd = "scp ~/.ipython/security/ipcontroller-engine.furl %s:.ipython/security/" % (hostname)
410 398 cmd_list = scp_cmd.split()
411 399 cmd_list[1] = os.path.expanduser(cmd_list[1])
412 400 log.msg('Copying furl file: %s' % scp_cmd)
413 401 d = getProcessOutput(cmd_list[0], cmd_list[1:], env=os.environ)
414 402 return d
415 403
416 404 def _scp_sshx(self, hostname):
417 405 scp_cmd = "scp %s %s:%s/%s-sshx.sh" % (
418 406 self.sshx, hostname,
419 407 self.temp_dir, os.environ['USER']
420 408 )
421 409 print
422 410 log.msg("Copying sshx: %s" % scp_cmd)
423 411 sshx_scp = scp_cmd.split()
424 412 d = getProcessOutput(sshx_scp[0], sshx_scp[1:], env=os.environ)
425 413 return d
426 414
427 415 def _ssh_engine(self, hostname, count):
428 416 exec_engine = "ssh %s sh %s/%s-sshx.sh %s" % (
429 417 hostname, self.temp_dir,
430 418 os.environ['USER'], self.engine_command
431 419 )
432 420 cmds = exec_engine.split()
433 421 dlist = []
434 422 log.msg("about to start engines...")
435 423 for i in range(count):
436 424 log.msg('Starting engines: %s' % exec_engine)
437 425 d = getProcessOutput(cmds[0], cmds[1:], env=os.environ)
438 426 dlist.append(d)
439 427 return gatherBoth(dlist, consumeErrors=True)
440 428
441 429 def kill(self):
442 430 dlist = []
443 431 for host in self.engine_hosts.keys():
444 432 d = self._killall(host)
445 433 dlist.append(d)
446 434 return gatherBoth(dlist, consumeErrors=True)
447 435
448 436 def _killall(self, hostname):
449 437 d = self._scp_engine_killer(hostname)
450 438 d.addCallback(lambda r: self._ssh_kill(hostname))
451 439 # d.addErrback(self._exec_err)
452 440 return d
453 441
454 442 def _scp_engine_killer(self, hostname):
455 443 scp_cmd = "scp %s %s:%s/%s-engine_killer.sh" % (
456 444 self.engine_killer,
457 445 hostname,
458 446 self.temp_dir,
459 447 os.environ['USER']
460 448 )
461 449 cmds = scp_cmd.split()
462 450 log.msg('Copying engine_killer: %s' % scp_cmd)
463 451 d = getProcessOutput(cmds[0], cmds[1:], env=os.environ)
464 452 return d
465 453
466 454 def _ssh_kill(self, hostname):
467 455 kill_cmd = "ssh %s sh %s/%s-engine_killer.sh" % (
468 456 hostname,
469 457 self.temp_dir,
470 458 os.environ['USER']
471 459 )
472 460 log.msg('Killing engine: %s' % kill_cmd)
473 461 kill_cmd = kill_cmd.split()
474 462 d = getProcessOutput(kill_cmd[0], kill_cmd[1:], env=os.environ)
475 463 return d
476 464
477 465 def _exec_err(self, r):
478 466 log.msg(r)
479 467
480 468 #-----------------------------------------------------------------------------
481 469 # Main functions for the different types of clusters
482 470 #-----------------------------------------------------------------------------
483 471
484 472 # TODO:
485 473 # The logic in these codes should be moved into classes like LocalCluster
486 474 # MpirunCluster, PBSCluster, etc. This would remove alot of the duplications.
487 475 # The main functions should then just parse the command line arguments, create
488 476 # the appropriate class and call a 'start' method.
489 477
490 478
491 479 def check_security(args, cont_args):
492 480 """Check to see if we should run with SSL support."""
493 481 if (not args.x or not args.y) and not have_crypto:
494 482 log.err("""
495 483 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
496 484 Try running ipcluster with the -xy flags: ipcluster local -xy -n 4""")
497 485 reactor.stop()
498 486 return False
499 487 if args.x:
500 488 cont_args.append('-x')
501 489 if args.y:
502 490 cont_args.append('-y')
503 491 return True
504 492
505 493
506 494 def check_reuse(args, cont_args):
507 495 """Check to see if we should try to resuse FURL files."""
508 496 if args.r:
509 497 cont_args.append('-r')
510 498 if args.client_port == 0 or args.engine_port == 0:
511 499 log.err("""
512 500 To reuse FURL files, you must also set the client and engine ports using
513 501 the --client-port and --engine-port options.""")
514 502 reactor.stop()
515 503 return False
516 504 cont_args.append('--client-port=%i' % args.client_port)
517 505 cont_args.append('--engine-port=%i' % args.engine_port)
518 506 return True
519 507
520 508
521 509 def _err_and_stop(f):
522 510 """Errback to log a failure and halt the reactor on a fatal error."""
523 511 log.err(f)
524 512 reactor.stop()
525 513
526 514
527 515 def _delay_start(cont_pid, start_engines, furl_file, reuse):
528 516 """Wait for controller to create FURL files and the start the engines."""
529 517 if not reuse:
530 518 if os.path.isfile(furl_file):
531 519 os.unlink(furl_file)
532 520 log.msg('Waiting for controller to finish starting...')
533 521 d = wait_for_file(furl_file, delay=0.2, max_tries=50)
534 522 d.addCallback(lambda _: log.msg('Controller started'))
535 523 d.addCallback(lambda _: start_engines(cont_pid))
536 524 return d
537 525
538 526
539 527 def main_local(args):
540 528 cont_args = []
541 529 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
542 530
543 531 # Check security settings before proceeding
544 532 if not check_security(args, cont_args):
545 533 return
546 534
547 535 # See if we are reusing FURL files
548 536 if not check_reuse(args, cont_args):
549 537 return
550 538
551 539 cl = ControllerLauncher(extra_args=cont_args)
552 540 dstart = cl.start()
553 541 def start_engines(cont_pid):
554 542 engine_args = []
555 543 engine_args.append('--logfile=%s' % \
556 544 pjoin(args.logdir,'ipengine%s-' % cont_pid))
557 545 eset = LocalEngineSet(extra_args=engine_args)
558 546 def shutdown(signum, frame):
559 547 log.msg('Stopping local cluster')
560 548 # We are still playing with the times here, but these seem
561 549 # to be reliable in allowing everything to exit cleanly.
562 550 eset.interrupt_then_kill(0.5)
563 551 cl.interrupt_then_kill(0.5)
564 552 reactor.callLater(1.0, reactor.stop)
565 553 signal.signal(signal.SIGINT,shutdown)
566 554 d = eset.start(args.n)
567 555 return d
568 556 config = kernel_config_manager.get_config_obj()
569 557 furl_file = config['controller']['engine_furl_file']
570 558 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
571 559 dstart.addErrback(_err_and_stop)
572 560
573 561
574 562 def main_mpi(args):
575 563 cont_args = []
576 564 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
577 565
578 566 # Check security settings before proceeding
579 567 if not check_security(args, cont_args):
580 568 return
581 569
582 570 # See if we are reusing FURL files
583 571 if not check_reuse(args, cont_args):
584 572 return
585 573
586 574 cl = ControllerLauncher(extra_args=cont_args)
587 575 dstart = cl.start()
588 576 def start_engines(cont_pid):
589 577 raw_args = [args.cmd]
590 578 raw_args.extend(['-n',str(args.n)])
591 579 raw_args.append('ipengine')
592 580 raw_args.append('-l')
593 581 raw_args.append(pjoin(args.logdir,'ipengine%s-' % cont_pid))
594 582 if args.mpi:
595 583 raw_args.append('--mpi=%s' % args.mpi)
596 584 eset = ProcessLauncher(raw_args)
597 585 def shutdown(signum, frame):
598 586 log.msg('Stopping local cluster')
599 587 # We are still playing with the times here, but these seem
600 588 # to be reliable in allowing everything to exit cleanly.
601 589 eset.interrupt_then_kill(1.0)
602 590 cl.interrupt_then_kill(1.0)
603 591 reactor.callLater(2.0, reactor.stop)
604 592 signal.signal(signal.SIGINT,shutdown)
605 593 d = eset.start()
606 594 return d
607 595 config = kernel_config_manager.get_config_obj()
608 596 furl_file = config['controller']['engine_furl_file']
609 597 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
610 598 dstart.addErrback(_err_and_stop)
611 599
612 600
613 601 def main_pbs(args):
614 602 cont_args = []
615 603 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
616 604
617 605 # Check security settings before proceeding
618 606 if not check_security(args, cont_args):
619 607 return
620 608
621 609 # See if we are reusing FURL files
622 610 if not check_reuse(args, cont_args):
623 611 return
624 612
625 613 cl = ControllerLauncher(extra_args=cont_args)
626 614 dstart = cl.start()
627 615 def start_engines(r):
628 616 pbs_set = PBSEngineSet(args.pbsscript)
629 617 def shutdown(signum, frame):
630 618 log.msg('Stopping pbs cluster')
631 619 d = pbs_set.kill()
632 620 d.addBoth(lambda _: cl.interrupt_then_kill(1.0))
633 621 d.addBoth(lambda _: reactor.callLater(2.0, reactor.stop))
634 622 signal.signal(signal.SIGINT,shutdown)
635 623 d = pbs_set.start(args.n)
636 624 return d
637 625 config = kernel_config_manager.get_config_obj()
638 626 furl_file = config['controller']['engine_furl_file']
639 627 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
640 628 dstart.addErrback(_err_and_stop)
641 629
642 630
643 631 def main_ssh(args):
644 632 """Start a controller on localhost and engines using ssh.
645 633
646 634 Your clusterfile should look like::
647 635
648 636 send_furl = False # True, if you want
649 637 engines = {
650 638 'engine_host1' : engine_count,
651 639 'engine_host2' : engine_count2
652 640 }
653 641 """
654 642 clusterfile = {}
655 643 execfile(args.clusterfile, clusterfile)
656 644 if not clusterfile.has_key('send_furl'):
657 645 clusterfile['send_furl'] = False
658 646
659 647 cont_args = []
660 648 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
661 649
662 650 # Check security settings before proceeding
663 651 if not check_security(args, cont_args):
664 652 return
665 653
666 654 # See if we are reusing FURL files
667 655 if not check_reuse(args, cont_args):
668 656 return
669 657
670 658 cl = ControllerLauncher(extra_args=cont_args)
671 659 dstart = cl.start()
672 660 def start_engines(cont_pid):
673 661 ssh_set = SSHEngineSet(clusterfile['engines'], sshx=args.sshx)
674 662 def shutdown(signum, frame):
675 663 d = ssh_set.kill()
676 664 cl.interrupt_then_kill(1.0)
677 665 reactor.callLater(2.0, reactor.stop)
678 666 signal.signal(signal.SIGINT,shutdown)
679 667 d = ssh_set.start(clusterfile['send_furl'])
680 668 return d
681 669 config = kernel_config_manager.get_config_obj()
682 670 furl_file = config['controller']['engine_furl_file']
683 671 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
684 672 dstart.addErrback(_err_and_stop)
685 673
686 674
687 675 def get_args():
688 676 base_parser = argparse.ArgumentParser(add_help=False)
689 677 base_parser.add_argument(
690 678 '-r',
691 679 action='store_true',
692 680 dest='r',
693 681 help='try to reuse FURL files. Use with --client-port and --engine-port'
694 682 )
695 683 base_parser.add_argument(
696 684 '--client-port',
697 685 type=int,
698 686 dest='client_port',
699 687 help='the port the controller will listen on for client connections',
700 688 default=0
701 689 )
702 690 base_parser.add_argument(
703 691 '--engine-port',
704 692 type=int,
705 693 dest='engine_port',
706 694 help='the port the controller will listen on for engine connections',
707 695 default=0
708 696 )
709 697 base_parser.add_argument(
710 698 '-x',
711 699 action='store_true',
712 700 dest='x',
713 701 help='turn off client security'
714 702 )
715 703 base_parser.add_argument(
716 704 '-y',
717 705 action='store_true',
718 706 dest='y',
719 707 help='turn off engine security'
720 708 )
721 709 base_parser.add_argument(
722 710 "--logdir",
723 711 type=str,
724 712 dest="logdir",
725 713 help="directory to put log files (default=$IPYTHONDIR/log)",
726 714 default=pjoin(get_ipython_dir(),'log')
727 715 )
728 716 base_parser.add_argument(
729 717 "-n",
730 718 "--num",
731 719 type=int,
732 720 dest="n",
733 721 default=2,
734 722 help="the number of engines to start"
735 723 )
736 724
737 725 parser = argparse.ArgumentParser(
738 726 description='IPython cluster startup. This starts a controller and\
739 727 engines using various approaches. Use the IPYTHONDIR environment\
740 728 variable to change your IPython directory from the default of\
741 729 .ipython or _ipython. The log and security subdirectories of your\
742 730 IPython directory will be used by this script for log files and\
743 731 security files.'
744 732 )
745 733 subparsers = parser.add_subparsers(
746 734 help='available cluster types. For help, do "ipcluster TYPE --help"')
747 735
748 736 parser_local = subparsers.add_parser(
749 737 'local',
750 738 help='run a local cluster',
751 739 parents=[base_parser]
752 740 )
753 741 parser_local.set_defaults(func=main_local)
754 742
755 743 parser_mpirun = subparsers.add_parser(
756 744 'mpirun',
757 745 help='run a cluster using mpirun (mpiexec also works)',
758 746 parents=[base_parser]
759 747 )
760 748 parser_mpirun.add_argument(
761 749 "--mpi",
762 750 type=str,
763 751 dest="mpi", # Don't put a default here to allow no MPI support
764 752 help="how to call MPI_Init (default=mpi4py)"
765 753 )
766 754 parser_mpirun.set_defaults(func=main_mpi, cmd='mpirun')
767 755
768 756 parser_mpiexec = subparsers.add_parser(
769 757 'mpiexec',
770 758 help='run a cluster using mpiexec (mpirun also works)',
771 759 parents=[base_parser]
772 760 )
773 761 parser_mpiexec.add_argument(
774 762 "--mpi",
775 763 type=str,
776 764 dest="mpi", # Don't put a default here to allow no MPI support
777 765 help="how to call MPI_Init (default=mpi4py)"
778 766 )
779 767 parser_mpiexec.set_defaults(func=main_mpi, cmd='mpiexec')
780 768
781 769 parser_pbs = subparsers.add_parser(
782 770 'pbs',
783 771 help='run a pbs cluster',
784 772 parents=[base_parser]
785 773 )
786 774 parser_pbs.add_argument(
787 775 '--pbs-script',
788 776 type=str,
789 777 dest='pbsscript',
790 778 help='PBS script template',
791 779 default='pbs.template'
792 780 )
793 781 parser_pbs.set_defaults(func=main_pbs)
794 782
795 783 parser_ssh = subparsers.add_parser(
796 784 'ssh',
797 785 help='run a cluster using ssh, should have ssh-keys setup',
798 786 parents=[base_parser]
799 787 )
800 788 parser_ssh.add_argument(
801 789 '--clusterfile',
802 790 type=str,
803 791 dest='clusterfile',
804 792 help='python file describing the cluster',
805 793 default='clusterfile.py',
806 794 )
807 795 parser_ssh.add_argument(
808 796 '--sshx',
809 797 type=str,
810 798 dest='sshx',
811 799 help='sshx launcher helper'
812 800 )
813 801 parser_ssh.set_defaults(func=main_ssh)
814 802
815 803 args = parser.parse_args()
816 804 return args
817 805
818 806 def main():
819 807 args = get_args()
820 808 reactor.callWhenRunning(args.func, args)
821 809 log.startLogging(sys.stdout)
822 810 reactor.run()
823 811
824 812 if __name__ == '__main__':
825 813 main()
@@ -1,70 +1,97 b''
1 1 # -*- coding: utf-8 -*-
2 2 """ Proxy module for accessing platform specific utility functions.
3 3
4 4 Importing this module should give you the implementations that are correct
5 5 for your operation system, from platutils_PLATFORMNAME module.
6 6 """
7 7
8 8 #*****************************************************************************
9 9 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #*****************************************************************************
14 14
15 15 import os
16 16 import sys
17 17
18 18 # Import the platform-specific implementations
19 19 if os.name == 'posix':
20 20 import platutils_posix as _platutils
21 21 elif sys.platform == 'win32':
22 22 import platutils_win32 as _platutils
23 23 else:
24 24 import platutils_dummy as _platutils
25 25 import warnings
26 26 warnings.warn("Platutils not available for platform '%s', some features may be missing" %
27 27 os.name)
28 28 del warnings
29 29
30 30
31 31 # Functionality that's logically common to all platforms goes here, each
32 32 # platform-specific module only provides the bits that are OS-dependent.
33 33
34 34 # XXX - I'm still not happy with a module global for this, but at least now
35 35 # there is a public, cross-platform way of toggling the term title control on
36 36 # and off. We should make this a stateful object later on so that each user
37 37 # can have its own instance if needed.
38 38 def toggle_set_term_title(val):
39 39 """Control whether set_term_title is active or not.
40 40
41 41 set_term_title() allows writing to the console titlebar. In embedded
42 42 widgets this can cause problems, so this call can be used to toggle it on
43 43 or off as needed.
44 44
45 45 The default state of the module is for the function to be disabled.
46 46
47 47 Parameters
48 48 ----------
49 49 val : bool
50 50 If True, set_term_title() actually writes to the terminal (using the
51 51 appropriate platform-specific module). If False, it is a no-op.
52 52 """
53 53 _platutils.ignore_termtitle = not(val)
54 54
55 55
56 56 def set_term_title(title):
57 57 """Set terminal title using the necessary platform-dependent calls."""
58 58
59 59 if _platutils.ignore_termtitle:
60 60 return
61 61 _platutils.set_term_title(title)
62 62
63 63
64 class FindCmdError(Exception):
65 pass
66
67 def find_cmd(cmd):
68 """Find full path to executable cmd in a cross platform manner.
69
70 This function tries to determine the full path to a command line program
71 using `which` on Unix/Linux/OS X and `win32api` on Windows. Most of the
72 time it will use the version that is first on the users `PATH`. If
73 cmd is `python` return `sys.executable`.
74
75 Parameters
76 ----------
77 cmd : str
78 The command line program to look for.
79 """
80 if cmd == 'python':
81 return sys.executable
82 try:
83 path = _platutils.find_cmd(cmd)
84 except:
85 raise FindCmdError('command could not be found: %s' % cmd)
86 # which returns empty if not found
87 if path == '':
88 raise FindCmdError('command could not be found: %s' % cmd)
89 return path
90
64 91 #-----------------------------------------------------------------------------
65 92 # Deprecated functions
66 93 #-----------------------------------------------------------------------------
67 94 def freeze_term_title():
68 95 warnings.warn("This function is deprecated, use toggle_set_term_title()")
69 96 _platutils.ignore_termtitle = True
70 97
@@ -1,25 +1,29 b''
1 1 # -*- coding: utf-8 -*-
2 2 """ Platform specific utility functions, dummy version
3 3
4 4 This has empty implementation of the platutils functions, used for
5 5 unsupported operating systems.
6 6
7 7 Authors
8 8 -------
9 9 - Ville Vainio <vivainio@gmail.com>
10 10 """
11 11
12 12 #*****************************************************************************
13 13 # Copyright (C) 2008-2009 The IPython Development Team
14 14 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #*****************************************************************************
19 19
20 20 # This variable is part of the expected API of the module:
21 21 ignore_termtitle = True
22 22
23 23 def set_term_title(*args,**kw):
24 24 """Dummy no-op."""
25 25 pass
26
27 def find_cmd(cmd):
28 """Find the full path to a command using which."""
29 return os.popen('which %s' % cmd).read().strip()
@@ -1,32 +1,36 b''
1 1 # -*- coding: utf-8 -*-
2 2 """ Platform specific utility functions, posix version
3 3
4 4 Importing this module directly is not portable - rather, import platutils
5 5 to use these functions in platform agnostic fashion.
6 6 """
7 7
8 8 #*****************************************************************************
9 9 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #*****************************************************************************
14 14
15 15 import sys
16 16 import os
17 17
18 18 ignore_termtitle = True
19 19
20 20 def _dummy_op(*a, **b):
21 21 """ A no-op function """
22 22
23 23 def _set_term_title_xterm(title):
24 24 """ Change virtual terminal title in xterm-workalikes """
25 25
26 26 sys.stdout.write('\033]0;%s\007' % title)
27 27
28 28
29 29 if os.environ.get('TERM','') == 'xterm':
30 30 set_term_title = _set_term_title_xterm
31 31 else:
32 32 set_term_title = _dummy_op
33
34 def find_cmd(cmd):
35 """Find the full path to a command using which."""
36 return os.popen('which %s' % cmd).read().strip()
@@ -1,43 +1,56 b''
1 1 # -*- coding: utf-8 -*-
2 2 """ Platform specific utility functions, win32 version
3 3
4 4 Importing this module directly is not portable - rather, import platutils
5 5 to use these functions in platform agnostic fashion.
6 6 """
7 7
8 8 #*****************************************************************************
9 9 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #*****************************************************************************
14 14
15 15 import os
16 16
17 17 ignore_termtitle = True
18 18
19 19 try:
20 20 import ctypes
21 21
22 22 SetConsoleTitleW = ctypes.windll.kernel32.SetConsoleTitleW
23 23 SetConsoleTitleW.argtypes = [ctypes.c_wchar_p]
24 24
25 25 def set_term_title(title):
26 26 """Set terminal title using ctypes to access the Win32 APIs."""
27 27 SetConsoleTitleW(title)
28 28
29 29 except ImportError:
30 30 def set_term_title(title):
31 31 """Set terminal title using the 'title' command."""
32 32 global ignore_termtitle
33 33
34 34 try:
35 35 # Cannot be on network share when issuing system commands
36 36 curr = os.getcwd()
37 37 os.chdir("C:")
38 38 ret = os.system("title " + title)
39 39 finally:
40 40 os.chdir(curr)
41 41 if ret:
42 42 # non-zero return code signals error, don't try again
43 43 ignore_termtitle = True
44
45 def find_cmd(cmd):
46 """Find the full path to a .bat or .exe using the win32api module."""
47 try:
48 import win32api
49 except ImportError:
50 raise ImportError('you need to have pywin32 installed for this to work')
51 else:
52 try:
53 (path, offest) = win32api.SearchPath(os.environ['PATH'],cmd + '.exe')
54 except:
55 (path, offset) = win32api.SearchPath(os.environ['PATH'],cmd + '.bat')
56 return path
General Comments 0
You need to be logged in to leave comments. Login now