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