##// END OF EJS Templates
Fix exec statements for Py 3...
Thomas Kluyver -
Show More
@@ -1,821 +1,821 b''
1 """A simple configuration system.
1 """A simple configuration system.
2
2
3 Inheritance diagram:
3 Inheritance diagram:
4
4
5 .. inheritance-diagram:: IPython.config.loader
5 .. inheritance-diagram:: IPython.config.loader
6 :parts: 3
6 :parts: 3
7
7
8 Authors
8 Authors
9 -------
9 -------
10 * Brian Granger
10 * Brian Granger
11 * Fernando Perez
11 * Fernando Perez
12 * Min RK
12 * Min RK
13 """
13 """
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2011 The IPython Development Team
16 # Copyright (C) 2008-2011 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 import __builtin__ as builtin_mod
26 import __builtin__ as builtin_mod
27 import argparse
27 import argparse
28 import copy
28 import copy
29 import os
29 import os
30 import re
30 import re
31 import sys
31 import sys
32
32
33 from IPython.utils.path import filefind, get_ipython_dir
33 from IPython.utils.path import filefind, get_ipython_dir
34 from IPython.utils import py3compat, warn
34 from IPython.utils import py3compat, warn
35 from IPython.utils.encoding import DEFAULT_ENCODING
35 from IPython.utils.encoding import DEFAULT_ENCODING
36 from IPython.utils.traitlets import HasTraits, List, Any, TraitError
36 from IPython.utils.traitlets import HasTraits, List, Any, TraitError
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Exceptions
39 # Exceptions
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42
42
43 class ConfigError(Exception):
43 class ConfigError(Exception):
44 pass
44 pass
45
45
46 class ConfigLoaderError(ConfigError):
46 class ConfigLoaderError(ConfigError):
47 pass
47 pass
48
48
49 class ConfigFileNotFound(ConfigError):
49 class ConfigFileNotFound(ConfigError):
50 pass
50 pass
51
51
52 class ArgumentError(ConfigLoaderError):
52 class ArgumentError(ConfigLoaderError):
53 pass
53 pass
54
54
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 # Argparse fix
56 # Argparse fix
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58
58
59 # Unfortunately argparse by default prints help messages to stderr instead of
59 # Unfortunately argparse by default prints help messages to stderr instead of
60 # stdout. This makes it annoying to capture long help screens at the command
60 # stdout. This makes it annoying to capture long help screens at the command
61 # line, since one must know how to pipe stderr, which many users don't know how
61 # line, since one must know how to pipe stderr, which many users don't know how
62 # to do. So we override the print_help method with one that defaults to
62 # to do. So we override the print_help method with one that defaults to
63 # stdout and use our class instead.
63 # stdout and use our class instead.
64
64
65 class ArgumentParser(argparse.ArgumentParser):
65 class ArgumentParser(argparse.ArgumentParser):
66 """Simple argparse subclass that prints help to stdout by default."""
66 """Simple argparse subclass that prints help to stdout by default."""
67
67
68 def print_help(self, file=None):
68 def print_help(self, file=None):
69 if file is None:
69 if file is None:
70 file = sys.stdout
70 file = sys.stdout
71 return super(ArgumentParser, self).print_help(file)
71 return super(ArgumentParser, self).print_help(file)
72
72
73 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
73 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
74
74
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76 # Config class for holding config information
76 # Config class for holding config information
77 #-----------------------------------------------------------------------------
77 #-----------------------------------------------------------------------------
78
78
79 class LazyConfigValue(HasTraits):
79 class LazyConfigValue(HasTraits):
80 """Proxy object for exposing methods on configurable containers
80 """Proxy object for exposing methods on configurable containers
81
81
82 Exposes:
82 Exposes:
83
83
84 - append, extend, insert on lists
84 - append, extend, insert on lists
85 - update on dicts
85 - update on dicts
86 - update, add on sets
86 - update, add on sets
87 """
87 """
88
88
89 _value = None
89 _value = None
90
90
91 # list methods
91 # list methods
92 _extend = List()
92 _extend = List()
93 _prepend = List()
93 _prepend = List()
94
94
95 def append(self, obj):
95 def append(self, obj):
96 self._extend.append(obj)
96 self._extend.append(obj)
97
97
98 def extend(self, other):
98 def extend(self, other):
99 self._extend.extend(other)
99 self._extend.extend(other)
100
100
101 def prepend(self, other):
101 def prepend(self, other):
102 """like list.extend, but for the front"""
102 """like list.extend, but for the front"""
103 self._prepend[:0] = other
103 self._prepend[:0] = other
104
104
105 _inserts = List()
105 _inserts = List()
106 def insert(self, index, other):
106 def insert(self, index, other):
107 if not isinstance(index, int):
107 if not isinstance(index, int):
108 raise TypeError("An integer is required")
108 raise TypeError("An integer is required")
109 self._inserts.append((index, other))
109 self._inserts.append((index, other))
110
110
111 # dict methods
111 # dict methods
112 # update is used for both dict and set
112 # update is used for both dict and set
113 _update = Any()
113 _update = Any()
114 def update(self, other):
114 def update(self, other):
115 if self._update is None:
115 if self._update is None:
116 if isinstance(other, dict):
116 if isinstance(other, dict):
117 self._update = {}
117 self._update = {}
118 else:
118 else:
119 self._update = set()
119 self._update = set()
120 self._update.update(other)
120 self._update.update(other)
121
121
122 # set methods
122 # set methods
123 def add(self, obj):
123 def add(self, obj):
124 self.update({obj})
124 self.update({obj})
125
125
126 def get_value(self, initial):
126 def get_value(self, initial):
127 """construct the value from the initial one
127 """construct the value from the initial one
128
128
129 after applying any insert / extend / update changes
129 after applying any insert / extend / update changes
130 """
130 """
131 if self._value is not None:
131 if self._value is not None:
132 return self._value
132 return self._value
133 value = copy.deepcopy(initial)
133 value = copy.deepcopy(initial)
134 if isinstance(value, list):
134 if isinstance(value, list):
135 for idx, obj in self._inserts:
135 for idx, obj in self._inserts:
136 value.insert(idx, obj)
136 value.insert(idx, obj)
137 value[:0] = self._prepend
137 value[:0] = self._prepend
138 value.extend(self._extend)
138 value.extend(self._extend)
139
139
140 elif isinstance(value, dict):
140 elif isinstance(value, dict):
141 if self._update:
141 if self._update:
142 value.update(self._update)
142 value.update(self._update)
143 elif isinstance(value, set):
143 elif isinstance(value, set):
144 if self._update:
144 if self._update:
145 value.update(self._update)
145 value.update(self._update)
146 self._value = value
146 self._value = value
147 return value
147 return value
148
148
149 def to_dict(self):
149 def to_dict(self):
150 """return JSONable dict form of my data
150 """return JSONable dict form of my data
151
151
152 Currently update as dict or set, extend, prepend as lists, and inserts as list of tuples.
152 Currently update as dict or set, extend, prepend as lists, and inserts as list of tuples.
153 """
153 """
154 d = {}
154 d = {}
155 if self._update:
155 if self._update:
156 d['update'] = self._update
156 d['update'] = self._update
157 if self._extend:
157 if self._extend:
158 d['extend'] = self._extend
158 d['extend'] = self._extend
159 if self._prepend:
159 if self._prepend:
160 d['prepend'] = self._prepend
160 d['prepend'] = self._prepend
161 elif self._inserts:
161 elif self._inserts:
162 d['inserts'] = self._inserts
162 d['inserts'] = self._inserts
163 return d
163 return d
164
164
165
165
166 class Config(dict):
166 class Config(dict):
167 """An attribute based dict that can do smart merges."""
167 """An attribute based dict that can do smart merges."""
168
168
169 def __init__(self, *args, **kwds):
169 def __init__(self, *args, **kwds):
170 dict.__init__(self, *args, **kwds)
170 dict.__init__(self, *args, **kwds)
171 # This sets self.__dict__ = self, but it has to be done this way
171 # This sets self.__dict__ = self, but it has to be done this way
172 # because we are also overriding __setattr__.
172 # because we are also overriding __setattr__.
173 dict.__setattr__(self, '__dict__', self)
173 dict.__setattr__(self, '__dict__', self)
174 self._ensure_subconfig()
174 self._ensure_subconfig()
175
175
176 def _ensure_subconfig(self):
176 def _ensure_subconfig(self):
177 """ensure that sub-dicts that should be Config objects are
177 """ensure that sub-dicts that should be Config objects are
178
178
179 casts dicts that are under section keys to Config objects,
179 casts dicts that are under section keys to Config objects,
180 which is necessary for constructing Config objects from dict literals.
180 which is necessary for constructing Config objects from dict literals.
181 """
181 """
182 for key in self:
182 for key in self:
183 obj = self[key]
183 obj = self[key]
184 if self._is_section_key(key) \
184 if self._is_section_key(key) \
185 and isinstance(obj, dict) \
185 and isinstance(obj, dict) \
186 and not isinstance(obj, Config):
186 and not isinstance(obj, Config):
187 dict.__setattr__(self, key, Config(obj))
187 dict.__setattr__(self, key, Config(obj))
188
188
189 def _merge(self, other):
189 def _merge(self, other):
190 """deprecated alias, use Config.merge()"""
190 """deprecated alias, use Config.merge()"""
191 self.merge(other)
191 self.merge(other)
192
192
193 def merge(self, other):
193 def merge(self, other):
194 """merge another config object into this one"""
194 """merge another config object into this one"""
195 to_update = {}
195 to_update = {}
196 for k, v in other.iteritems():
196 for k, v in other.iteritems():
197 if k not in self:
197 if k not in self:
198 to_update[k] = v
198 to_update[k] = v
199 else: # I have this key
199 else: # I have this key
200 if isinstance(v, Config) and isinstance(self[k], Config):
200 if isinstance(v, Config) and isinstance(self[k], Config):
201 # Recursively merge common sub Configs
201 # Recursively merge common sub Configs
202 self[k].merge(v)
202 self[k].merge(v)
203 else:
203 else:
204 # Plain updates for non-Configs
204 # Plain updates for non-Configs
205 to_update[k] = v
205 to_update[k] = v
206
206
207 self.update(to_update)
207 self.update(to_update)
208
208
209 def _is_section_key(self, key):
209 def _is_section_key(self, key):
210 if key[0].upper()==key[0] and not key.startswith('_'):
210 if key[0].upper()==key[0] and not key.startswith('_'):
211 return True
211 return True
212 else:
212 else:
213 return False
213 return False
214
214
215 def __contains__(self, key):
215 def __contains__(self, key):
216 # allow nested contains of the form `"Section.key" in config`
216 # allow nested contains of the form `"Section.key" in config`
217 if '.' in key:
217 if '.' in key:
218 first, remainder = key.split('.', 1)
218 first, remainder = key.split('.', 1)
219 if first not in self:
219 if first not in self:
220 return False
220 return False
221 return remainder in self[first]
221 return remainder in self[first]
222
222
223 # we always have Sections
223 # we always have Sections
224 if self._is_section_key(key):
224 if self._is_section_key(key):
225 return True
225 return True
226 else:
226 else:
227 return super(Config, self).__contains__(key)
227 return super(Config, self).__contains__(key)
228 # .has_key is deprecated for dictionaries.
228 # .has_key is deprecated for dictionaries.
229 has_key = __contains__
229 has_key = __contains__
230
230
231 def _has_section(self, key):
231 def _has_section(self, key):
232 if self._is_section_key(key):
232 if self._is_section_key(key):
233 if super(Config, self).__contains__(key):
233 if super(Config, self).__contains__(key):
234 return True
234 return True
235 return False
235 return False
236
236
237 def copy(self):
237 def copy(self):
238 return type(self)(dict.copy(self))
238 return type(self)(dict.copy(self))
239
239
240 def __copy__(self):
240 def __copy__(self):
241 return self.copy()
241 return self.copy()
242
242
243 def __deepcopy__(self, memo):
243 def __deepcopy__(self, memo):
244 import copy
244 import copy
245 return type(self)(copy.deepcopy(self.items()))
245 return type(self)(copy.deepcopy(self.items()))
246
246
247 def __getitem__(self, key):
247 def __getitem__(self, key):
248 # We cannot use directly self._is_section_key, because it triggers
248 # We cannot use directly self._is_section_key, because it triggers
249 # infinite recursion on top of PyPy. Instead, we manually fish the
249 # infinite recursion on top of PyPy. Instead, we manually fish the
250 # bound method.
250 # bound method.
251 is_section_key = self.__class__._is_section_key.__get__(self)
251 is_section_key = self.__class__._is_section_key.__get__(self)
252
252
253 # Because we use this for an exec namespace, we need to delegate
253 # Because we use this for an exec namespace, we need to delegate
254 # the lookup of names in __builtin__ to itself. This means
254 # the lookup of names in __builtin__ to itself. This means
255 # that you can't have section or attribute names that are
255 # that you can't have section or attribute names that are
256 # builtins.
256 # builtins.
257 try:
257 try:
258 return getattr(builtin_mod, key)
258 return getattr(builtin_mod, key)
259 except AttributeError:
259 except AttributeError:
260 pass
260 pass
261 if is_section_key(key):
261 if is_section_key(key):
262 try:
262 try:
263 return dict.__getitem__(self, key)
263 return dict.__getitem__(self, key)
264 except KeyError:
264 except KeyError:
265 c = Config()
265 c = Config()
266 dict.__setitem__(self, key, c)
266 dict.__setitem__(self, key, c)
267 return c
267 return c
268 else:
268 else:
269 try:
269 try:
270 return dict.__getitem__(self, key)
270 return dict.__getitem__(self, key)
271 except KeyError:
271 except KeyError:
272 # undefined
272 # undefined
273 v = LazyConfigValue()
273 v = LazyConfigValue()
274 dict.__setitem__(self, key, v)
274 dict.__setitem__(self, key, v)
275 return v
275 return v
276
276
277
277
278 def __setitem__(self, key, value):
278 def __setitem__(self, key, value):
279 if self._is_section_key(key):
279 if self._is_section_key(key):
280 if not isinstance(value, Config):
280 if not isinstance(value, Config):
281 raise ValueError('values whose keys begin with an uppercase '
281 raise ValueError('values whose keys begin with an uppercase '
282 'char must be Config instances: %r, %r' % (key, value))
282 'char must be Config instances: %r, %r' % (key, value))
283 else:
283 else:
284 dict.__setitem__(self, key, value)
284 dict.__setitem__(self, key, value)
285
285
286 def __getattr__(self, key):
286 def __getattr__(self, key):
287 try:
287 try:
288 return self.__getitem__(key)
288 return self.__getitem__(key)
289 except KeyError as e:
289 except KeyError as e:
290 raise AttributeError(e)
290 raise AttributeError(e)
291
291
292 def __setattr__(self, key, value):
292 def __setattr__(self, key, value):
293 try:
293 try:
294 self.__setitem__(key, value)
294 self.__setitem__(key, value)
295 except KeyError as e:
295 except KeyError as e:
296 raise AttributeError(e)
296 raise AttributeError(e)
297
297
298 def __delattr__(self, key):
298 def __delattr__(self, key):
299 try:
299 try:
300 dict.__delitem__(self, key)
300 dict.__delitem__(self, key)
301 except KeyError as e:
301 except KeyError as e:
302 raise AttributeError(e)
302 raise AttributeError(e)
303
303
304
304
305 #-----------------------------------------------------------------------------
305 #-----------------------------------------------------------------------------
306 # Config loading classes
306 # Config loading classes
307 #-----------------------------------------------------------------------------
307 #-----------------------------------------------------------------------------
308
308
309
309
310 class ConfigLoader(object):
310 class ConfigLoader(object):
311 """A object for loading configurations from just about anywhere.
311 """A object for loading configurations from just about anywhere.
312
312
313 The resulting configuration is packaged as a :class:`Struct`.
313 The resulting configuration is packaged as a :class:`Struct`.
314
314
315 Notes
315 Notes
316 -----
316 -----
317 A :class:`ConfigLoader` does one thing: load a config from a source
317 A :class:`ConfigLoader` does one thing: load a config from a source
318 (file, command line arguments) and returns the data as a :class:`Struct`.
318 (file, command line arguments) and returns the data as a :class:`Struct`.
319 There are lots of things that :class:`ConfigLoader` does not do. It does
319 There are lots of things that :class:`ConfigLoader` does not do. It does
320 not implement complex logic for finding config files. It does not handle
320 not implement complex logic for finding config files. It does not handle
321 default values or merge multiple configs. These things need to be
321 default values or merge multiple configs. These things need to be
322 handled elsewhere.
322 handled elsewhere.
323 """
323 """
324
324
325 def __init__(self):
325 def __init__(self):
326 """A base class for config loaders.
326 """A base class for config loaders.
327
327
328 Examples
328 Examples
329 --------
329 --------
330
330
331 >>> cl = ConfigLoader()
331 >>> cl = ConfigLoader()
332 >>> config = cl.load_config()
332 >>> config = cl.load_config()
333 >>> config
333 >>> config
334 {}
334 {}
335 """
335 """
336 self.clear()
336 self.clear()
337
337
338 def clear(self):
338 def clear(self):
339 self.config = Config()
339 self.config = Config()
340
340
341 def load_config(self):
341 def load_config(self):
342 """Load a config from somewhere, return a :class:`Config` instance.
342 """Load a config from somewhere, return a :class:`Config` instance.
343
343
344 Usually, this will cause self.config to be set and then returned.
344 Usually, this will cause self.config to be set and then returned.
345 However, in most cases, :meth:`ConfigLoader.clear` should be called
345 However, in most cases, :meth:`ConfigLoader.clear` should be called
346 to erase any previous state.
346 to erase any previous state.
347 """
347 """
348 self.clear()
348 self.clear()
349 return self.config
349 return self.config
350
350
351
351
352 class FileConfigLoader(ConfigLoader):
352 class FileConfigLoader(ConfigLoader):
353 """A base class for file based configurations.
353 """A base class for file based configurations.
354
354
355 As we add more file based config loaders, the common logic should go
355 As we add more file based config loaders, the common logic should go
356 here.
356 here.
357 """
357 """
358 pass
358 pass
359
359
360
360
361 class PyFileConfigLoader(FileConfigLoader):
361 class PyFileConfigLoader(FileConfigLoader):
362 """A config loader for pure python files.
362 """A config loader for pure python files.
363
363
364 This calls execfile on a plain python file and looks for attributes
364 This calls execfile on a plain python file and looks for attributes
365 that are all caps. These attribute are added to the config Struct.
365 that are all caps. These attribute are added to the config Struct.
366 """
366 """
367
367
368 def __init__(self, filename, path=None):
368 def __init__(self, filename, path=None):
369 """Build a config loader for a filename and path.
369 """Build a config loader for a filename and path.
370
370
371 Parameters
371 Parameters
372 ----------
372 ----------
373 filename : str
373 filename : str
374 The file name of the config file.
374 The file name of the config file.
375 path : str, list, tuple
375 path : str, list, tuple
376 The path to search for the config file on, or a sequence of
376 The path to search for the config file on, or a sequence of
377 paths to try in order.
377 paths to try in order.
378 """
378 """
379 super(PyFileConfigLoader, self).__init__()
379 super(PyFileConfigLoader, self).__init__()
380 self.filename = filename
380 self.filename = filename
381 self.path = path
381 self.path = path
382 self.full_filename = ''
382 self.full_filename = ''
383 self.data = None
383 self.data = None
384
384
385 def load_config(self):
385 def load_config(self):
386 """Load the config from a file and return it as a Struct."""
386 """Load the config from a file and return it as a Struct."""
387 self.clear()
387 self.clear()
388 try:
388 try:
389 self._find_file()
389 self._find_file()
390 except IOError as e:
390 except IOError as e:
391 raise ConfigFileNotFound(str(e))
391 raise ConfigFileNotFound(str(e))
392 self._read_file_as_dict()
392 self._read_file_as_dict()
393 self._convert_to_config()
393 self._convert_to_config()
394 return self.config
394 return self.config
395
395
396 def _find_file(self):
396 def _find_file(self):
397 """Try to find the file by searching the paths."""
397 """Try to find the file by searching the paths."""
398 self.full_filename = filefind(self.filename, self.path)
398 self.full_filename = filefind(self.filename, self.path)
399
399
400 def _read_file_as_dict(self):
400 def _read_file_as_dict(self):
401 """Load the config file into self.config, with recursive loading."""
401 """Load the config file into self.config, with recursive loading."""
402 # This closure is made available in the namespace that is used
402 # This closure is made available in the namespace that is used
403 # to exec the config file. It allows users to call
403 # to exec the config file. It allows users to call
404 # load_subconfig('myconfig.py') to load config files recursively.
404 # load_subconfig('myconfig.py') to load config files recursively.
405 # It needs to be a closure because it has references to self.path
405 # It needs to be a closure because it has references to self.path
406 # and self.config. The sub-config is loaded with the same path
406 # and self.config. The sub-config is loaded with the same path
407 # as the parent, but it uses an empty config which is then merged
407 # as the parent, but it uses an empty config which is then merged
408 # with the parents.
408 # with the parents.
409
409
410 # If a profile is specified, the config file will be loaded
410 # If a profile is specified, the config file will be loaded
411 # from that profile
411 # from that profile
412
412
413 def load_subconfig(fname, profile=None):
413 def load_subconfig(fname, profile=None):
414 # import here to prevent circular imports
414 # import here to prevent circular imports
415 from IPython.core.profiledir import ProfileDir, ProfileDirError
415 from IPython.core.profiledir import ProfileDir, ProfileDirError
416 if profile is not None:
416 if profile is not None:
417 try:
417 try:
418 profile_dir = ProfileDir.find_profile_dir_by_name(
418 profile_dir = ProfileDir.find_profile_dir_by_name(
419 get_ipython_dir(),
419 get_ipython_dir(),
420 profile,
420 profile,
421 )
421 )
422 except ProfileDirError:
422 except ProfileDirError:
423 return
423 return
424 path = profile_dir.location
424 path = profile_dir.location
425 else:
425 else:
426 path = self.path
426 path = self.path
427 loader = PyFileConfigLoader(fname, path)
427 loader = PyFileConfigLoader(fname, path)
428 try:
428 try:
429 sub_config = loader.load_config()
429 sub_config = loader.load_config()
430 except ConfigFileNotFound:
430 except ConfigFileNotFound:
431 # Pass silently if the sub config is not there. This happens
431 # Pass silently if the sub config is not there. This happens
432 # when a user s using a profile, but not the default config.
432 # when a user s using a profile, but not the default config.
433 pass
433 pass
434 else:
434 else:
435 self.config.merge(sub_config)
435 self.config.merge(sub_config)
436
436
437 # Again, this needs to be a closure and should be used in config
437 # Again, this needs to be a closure and should be used in config
438 # files to get the config being loaded.
438 # files to get the config being loaded.
439 def get_config():
439 def get_config():
440 return self.config
440 return self.config
441
441
442 namespace = dict(
442 namespace = dict(
443 load_subconfig=load_subconfig,
443 load_subconfig=load_subconfig,
444 get_config=get_config,
444 get_config=get_config,
445 __file__=self.full_filename,
445 __file__=self.full_filename,
446 )
446 )
447 fs_encoding = sys.getfilesystemencoding() or 'ascii'
447 fs_encoding = sys.getfilesystemencoding() or 'ascii'
448 conf_filename = self.full_filename.encode(fs_encoding)
448 conf_filename = self.full_filename.encode(fs_encoding)
449 py3compat.execfile(conf_filename, namespace)
449 py3compat.execfile(conf_filename, namespace)
450
450
451 def _convert_to_config(self):
451 def _convert_to_config(self):
452 if self.data is None:
452 if self.data is None:
453 ConfigLoaderError('self.data does not exist')
453 ConfigLoaderError('self.data does not exist')
454
454
455
455
456 class CommandLineConfigLoader(ConfigLoader):
456 class CommandLineConfigLoader(ConfigLoader):
457 """A config loader for command line arguments.
457 """A config loader for command line arguments.
458
458
459 As we add more command line based loaders, the common logic should go
459 As we add more command line based loaders, the common logic should go
460 here.
460 here.
461 """
461 """
462
462
463 def _exec_config_str(self, lhs, rhs):
463 def _exec_config_str(self, lhs, rhs):
464 """execute self.config.<lhs> = <rhs>
464 """execute self.config.<lhs> = <rhs>
465
465
466 * expands ~ with expanduser
466 * expands ~ with expanduser
467 * tries to assign with raw eval, otherwise assigns with just the string,
467 * tries to assign with raw eval, otherwise assigns with just the string,
468 allowing `--C.a=foobar` and `--C.a="foobar"` to be equivalent. *Not*
468 allowing `--C.a=foobar` and `--C.a="foobar"` to be equivalent. *Not*
469 equivalent are `--C.a=4` and `--C.a='4'`.
469 equivalent are `--C.a=4` and `--C.a='4'`.
470 """
470 """
471 rhs = os.path.expanduser(rhs)
471 rhs = os.path.expanduser(rhs)
472 try:
472 try:
473 # Try to see if regular Python syntax will work. This
473 # Try to see if regular Python syntax will work. This
474 # won't handle strings as the quote marks are removed
474 # won't handle strings as the quote marks are removed
475 # by the system shell.
475 # by the system shell.
476 value = eval(rhs)
476 value = eval(rhs)
477 except (NameError, SyntaxError):
477 except (NameError, SyntaxError):
478 # This case happens if the rhs is a string.
478 # This case happens if the rhs is a string.
479 value = rhs
479 value = rhs
480
480
481 exec u'self.config.%s = value' % lhs
481 exec(u'self.config.%s = value' % lhs)
482
482
483 def _load_flag(self, cfg):
483 def _load_flag(self, cfg):
484 """update self.config from a flag, which can be a dict or Config"""
484 """update self.config from a flag, which can be a dict or Config"""
485 if isinstance(cfg, (dict, Config)):
485 if isinstance(cfg, (dict, Config)):
486 # don't clobber whole config sections, update
486 # don't clobber whole config sections, update
487 # each section from config:
487 # each section from config:
488 for sec,c in cfg.iteritems():
488 for sec,c in cfg.iteritems():
489 self.config[sec].update(c)
489 self.config[sec].update(c)
490 else:
490 else:
491 raise TypeError("Invalid flag: %r" % cfg)
491 raise TypeError("Invalid flag: %r" % cfg)
492
492
493 # raw --identifier=value pattern
493 # raw --identifier=value pattern
494 # but *also* accept '-' as wordsep, for aliases
494 # but *also* accept '-' as wordsep, for aliases
495 # accepts: --foo=a
495 # accepts: --foo=a
496 # --Class.trait=value
496 # --Class.trait=value
497 # --alias-name=value
497 # --alias-name=value
498 # rejects: -foo=value
498 # rejects: -foo=value
499 # --foo
499 # --foo
500 # --Class.trait
500 # --Class.trait
501 kv_pattern = re.compile(r'\-\-[A-Za-z][\w\-]*(\.[\w\-]+)*\=.*')
501 kv_pattern = re.compile(r'\-\-[A-Za-z][\w\-]*(\.[\w\-]+)*\=.*')
502
502
503 # just flags, no assignments, with two *or one* leading '-'
503 # just flags, no assignments, with two *or one* leading '-'
504 # accepts: --foo
504 # accepts: --foo
505 # -foo-bar-again
505 # -foo-bar-again
506 # rejects: --anything=anything
506 # rejects: --anything=anything
507 # --two.word
507 # --two.word
508
508
509 flag_pattern = re.compile(r'\-\-?\w+[\-\w]*$')
509 flag_pattern = re.compile(r'\-\-?\w+[\-\w]*$')
510
510
511 class KeyValueConfigLoader(CommandLineConfigLoader):
511 class KeyValueConfigLoader(CommandLineConfigLoader):
512 """A config loader that loads key value pairs from the command line.
512 """A config loader that loads key value pairs from the command line.
513
513
514 This allows command line options to be gives in the following form::
514 This allows command line options to be gives in the following form::
515
515
516 ipython --profile="foo" --InteractiveShell.autocall=False
516 ipython --profile="foo" --InteractiveShell.autocall=False
517 """
517 """
518
518
519 def __init__(self, argv=None, aliases=None, flags=None):
519 def __init__(self, argv=None, aliases=None, flags=None):
520 """Create a key value pair config loader.
520 """Create a key value pair config loader.
521
521
522 Parameters
522 Parameters
523 ----------
523 ----------
524 argv : list
524 argv : list
525 A list that has the form of sys.argv[1:] which has unicode
525 A list that has the form of sys.argv[1:] which has unicode
526 elements of the form u"key=value". If this is None (default),
526 elements of the form u"key=value". If this is None (default),
527 then sys.argv[1:] will be used.
527 then sys.argv[1:] will be used.
528 aliases : dict
528 aliases : dict
529 A dict of aliases for configurable traits.
529 A dict of aliases for configurable traits.
530 Keys are the short aliases, Values are the resolved trait.
530 Keys are the short aliases, Values are the resolved trait.
531 Of the form: `{'alias' : 'Configurable.trait'}`
531 Of the form: `{'alias' : 'Configurable.trait'}`
532 flags : dict
532 flags : dict
533 A dict of flags, keyed by str name. Vaues can be Config objects,
533 A dict of flags, keyed by str name. Vaues can be Config objects,
534 dicts, or "key=value" strings. If Config or dict, when the flag
534 dicts, or "key=value" strings. If Config or dict, when the flag
535 is triggered, The flag is loaded as `self.config.update(m)`.
535 is triggered, The flag is loaded as `self.config.update(m)`.
536
536
537 Returns
537 Returns
538 -------
538 -------
539 config : Config
539 config : Config
540 The resulting Config object.
540 The resulting Config object.
541
541
542 Examples
542 Examples
543 --------
543 --------
544
544
545 >>> from IPython.config.loader import KeyValueConfigLoader
545 >>> from IPython.config.loader import KeyValueConfigLoader
546 >>> cl = KeyValueConfigLoader()
546 >>> cl = KeyValueConfigLoader()
547 >>> d = cl.load_config(["--A.name='brian'","--B.number=0"])
547 >>> d = cl.load_config(["--A.name='brian'","--B.number=0"])
548 >>> sorted(d.items())
548 >>> sorted(d.items())
549 [('A', {'name': 'brian'}), ('B', {'number': 0})]
549 [('A', {'name': 'brian'}), ('B', {'number': 0})]
550 """
550 """
551 self.clear()
551 self.clear()
552 if argv is None:
552 if argv is None:
553 argv = sys.argv[1:]
553 argv = sys.argv[1:]
554 self.argv = argv
554 self.argv = argv
555 self.aliases = aliases or {}
555 self.aliases = aliases or {}
556 self.flags = flags or {}
556 self.flags = flags or {}
557
557
558
558
559 def clear(self):
559 def clear(self):
560 super(KeyValueConfigLoader, self).clear()
560 super(KeyValueConfigLoader, self).clear()
561 self.extra_args = []
561 self.extra_args = []
562
562
563
563
564 def _decode_argv(self, argv, enc=None):
564 def _decode_argv(self, argv, enc=None):
565 """decode argv if bytes, using stin.encoding, falling back on default enc"""
565 """decode argv if bytes, using stin.encoding, falling back on default enc"""
566 uargv = []
566 uargv = []
567 if enc is None:
567 if enc is None:
568 enc = DEFAULT_ENCODING
568 enc = DEFAULT_ENCODING
569 for arg in argv:
569 for arg in argv:
570 if not isinstance(arg, unicode):
570 if not isinstance(arg, unicode):
571 # only decode if not already decoded
571 # only decode if not already decoded
572 arg = arg.decode(enc)
572 arg = arg.decode(enc)
573 uargv.append(arg)
573 uargv.append(arg)
574 return uargv
574 return uargv
575
575
576
576
577 def load_config(self, argv=None, aliases=None, flags=None):
577 def load_config(self, argv=None, aliases=None, flags=None):
578 """Parse the configuration and generate the Config object.
578 """Parse the configuration and generate the Config object.
579
579
580 After loading, any arguments that are not key-value or
580 After loading, any arguments that are not key-value or
581 flags will be stored in self.extra_args - a list of
581 flags will be stored in self.extra_args - a list of
582 unparsed command-line arguments. This is used for
582 unparsed command-line arguments. This is used for
583 arguments such as input files or subcommands.
583 arguments such as input files or subcommands.
584
584
585 Parameters
585 Parameters
586 ----------
586 ----------
587 argv : list, optional
587 argv : list, optional
588 A list that has the form of sys.argv[1:] which has unicode
588 A list that has the form of sys.argv[1:] which has unicode
589 elements of the form u"key=value". If this is None (default),
589 elements of the form u"key=value". If this is None (default),
590 then self.argv will be used.
590 then self.argv will be used.
591 aliases : dict
591 aliases : dict
592 A dict of aliases for configurable traits.
592 A dict of aliases for configurable traits.
593 Keys are the short aliases, Values are the resolved trait.
593 Keys are the short aliases, Values are the resolved trait.
594 Of the form: `{'alias' : 'Configurable.trait'}`
594 Of the form: `{'alias' : 'Configurable.trait'}`
595 flags : dict
595 flags : dict
596 A dict of flags, keyed by str name. Values can be Config objects
596 A dict of flags, keyed by str name. Values can be Config objects
597 or dicts. When the flag is triggered, The config is loaded as
597 or dicts. When the flag is triggered, The config is loaded as
598 `self.config.update(cfg)`.
598 `self.config.update(cfg)`.
599 """
599 """
600 self.clear()
600 self.clear()
601 if argv is None:
601 if argv is None:
602 argv = self.argv
602 argv = self.argv
603 if aliases is None:
603 if aliases is None:
604 aliases = self.aliases
604 aliases = self.aliases
605 if flags is None:
605 if flags is None:
606 flags = self.flags
606 flags = self.flags
607
607
608 # ensure argv is a list of unicode strings:
608 # ensure argv is a list of unicode strings:
609 uargv = self._decode_argv(argv)
609 uargv = self._decode_argv(argv)
610 for idx,raw in enumerate(uargv):
610 for idx,raw in enumerate(uargv):
611 # strip leading '-'
611 # strip leading '-'
612 item = raw.lstrip('-')
612 item = raw.lstrip('-')
613
613
614 if raw == '--':
614 if raw == '--':
615 # don't parse arguments after '--'
615 # don't parse arguments after '--'
616 # this is useful for relaying arguments to scripts, e.g.
616 # this is useful for relaying arguments to scripts, e.g.
617 # ipython -i foo.py --matplotlib=qt -- args after '--' go-to-foo.py
617 # ipython -i foo.py --matplotlib=qt -- args after '--' go-to-foo.py
618 self.extra_args.extend(uargv[idx+1:])
618 self.extra_args.extend(uargv[idx+1:])
619 break
619 break
620
620
621 if kv_pattern.match(raw):
621 if kv_pattern.match(raw):
622 lhs,rhs = item.split('=',1)
622 lhs,rhs = item.split('=',1)
623 # Substitute longnames for aliases.
623 # Substitute longnames for aliases.
624 if lhs in aliases:
624 if lhs in aliases:
625 lhs = aliases[lhs]
625 lhs = aliases[lhs]
626 if '.' not in lhs:
626 if '.' not in lhs:
627 # probably a mistyped alias, but not technically illegal
627 # probably a mistyped alias, but not technically illegal
628 warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
628 warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
629 try:
629 try:
630 self._exec_config_str(lhs, rhs)
630 self._exec_config_str(lhs, rhs)
631 except Exception:
631 except Exception:
632 raise ArgumentError("Invalid argument: '%s'" % raw)
632 raise ArgumentError("Invalid argument: '%s'" % raw)
633
633
634 elif flag_pattern.match(raw):
634 elif flag_pattern.match(raw):
635 if item in flags:
635 if item in flags:
636 cfg,help = flags[item]
636 cfg,help = flags[item]
637 self._load_flag(cfg)
637 self._load_flag(cfg)
638 else:
638 else:
639 raise ArgumentError("Unrecognized flag: '%s'"%raw)
639 raise ArgumentError("Unrecognized flag: '%s'"%raw)
640 elif raw.startswith('-'):
640 elif raw.startswith('-'):
641 kv = '--'+item
641 kv = '--'+item
642 if kv_pattern.match(kv):
642 if kv_pattern.match(kv):
643 raise ArgumentError("Invalid argument: '%s', did you mean '%s'?"%(raw, kv))
643 raise ArgumentError("Invalid argument: '%s', did you mean '%s'?"%(raw, kv))
644 else:
644 else:
645 raise ArgumentError("Invalid argument: '%s'"%raw)
645 raise ArgumentError("Invalid argument: '%s'"%raw)
646 else:
646 else:
647 # keep all args that aren't valid in a list,
647 # keep all args that aren't valid in a list,
648 # in case our parent knows what to do with them.
648 # in case our parent knows what to do with them.
649 self.extra_args.append(item)
649 self.extra_args.append(item)
650 return self.config
650 return self.config
651
651
652 class ArgParseConfigLoader(CommandLineConfigLoader):
652 class ArgParseConfigLoader(CommandLineConfigLoader):
653 """A loader that uses the argparse module to load from the command line."""
653 """A loader that uses the argparse module to load from the command line."""
654
654
655 def __init__(self, argv=None, aliases=None, flags=None, *parser_args, **parser_kw):
655 def __init__(self, argv=None, aliases=None, flags=None, *parser_args, **parser_kw):
656 """Create a config loader for use with argparse.
656 """Create a config loader for use with argparse.
657
657
658 Parameters
658 Parameters
659 ----------
659 ----------
660
660
661 argv : optional, list
661 argv : optional, list
662 If given, used to read command-line arguments from, otherwise
662 If given, used to read command-line arguments from, otherwise
663 sys.argv[1:] is used.
663 sys.argv[1:] is used.
664
664
665 parser_args : tuple
665 parser_args : tuple
666 A tuple of positional arguments that will be passed to the
666 A tuple of positional arguments that will be passed to the
667 constructor of :class:`argparse.ArgumentParser`.
667 constructor of :class:`argparse.ArgumentParser`.
668
668
669 parser_kw : dict
669 parser_kw : dict
670 A tuple of keyword arguments that will be passed to the
670 A tuple of keyword arguments that will be passed to the
671 constructor of :class:`argparse.ArgumentParser`.
671 constructor of :class:`argparse.ArgumentParser`.
672
672
673 Returns
673 Returns
674 -------
674 -------
675 config : Config
675 config : Config
676 The resulting Config object.
676 The resulting Config object.
677 """
677 """
678 super(CommandLineConfigLoader, self).__init__()
678 super(CommandLineConfigLoader, self).__init__()
679 self.clear()
679 self.clear()
680 if argv is None:
680 if argv is None:
681 argv = sys.argv[1:]
681 argv = sys.argv[1:]
682 self.argv = argv
682 self.argv = argv
683 self.aliases = aliases or {}
683 self.aliases = aliases or {}
684 self.flags = flags or {}
684 self.flags = flags or {}
685
685
686 self.parser_args = parser_args
686 self.parser_args = parser_args
687 self.version = parser_kw.pop("version", None)
687 self.version = parser_kw.pop("version", None)
688 kwargs = dict(argument_default=argparse.SUPPRESS)
688 kwargs = dict(argument_default=argparse.SUPPRESS)
689 kwargs.update(parser_kw)
689 kwargs.update(parser_kw)
690 self.parser_kw = kwargs
690 self.parser_kw = kwargs
691
691
692 def load_config(self, argv=None, aliases=None, flags=None):
692 def load_config(self, argv=None, aliases=None, flags=None):
693 """Parse command line arguments and return as a Config object.
693 """Parse command line arguments and return as a Config object.
694
694
695 Parameters
695 Parameters
696 ----------
696 ----------
697
697
698 args : optional, list
698 args : optional, list
699 If given, a list with the structure of sys.argv[1:] to parse
699 If given, a list with the structure of sys.argv[1:] to parse
700 arguments from. If not given, the instance's self.argv attribute
700 arguments from. If not given, the instance's self.argv attribute
701 (given at construction time) is used."""
701 (given at construction time) is used."""
702 self.clear()
702 self.clear()
703 if argv is None:
703 if argv is None:
704 argv = self.argv
704 argv = self.argv
705 if aliases is None:
705 if aliases is None:
706 aliases = self.aliases
706 aliases = self.aliases
707 if flags is None:
707 if flags is None:
708 flags = self.flags
708 flags = self.flags
709 self._create_parser(aliases, flags)
709 self._create_parser(aliases, flags)
710 self._parse_args(argv)
710 self._parse_args(argv)
711 self._convert_to_config()
711 self._convert_to_config()
712 return self.config
712 return self.config
713
713
714 def get_extra_args(self):
714 def get_extra_args(self):
715 if hasattr(self, 'extra_args'):
715 if hasattr(self, 'extra_args'):
716 return self.extra_args
716 return self.extra_args
717 else:
717 else:
718 return []
718 return []
719
719
720 def _create_parser(self, aliases=None, flags=None):
720 def _create_parser(self, aliases=None, flags=None):
721 self.parser = ArgumentParser(*self.parser_args, **self.parser_kw)
721 self.parser = ArgumentParser(*self.parser_args, **self.parser_kw)
722 self._add_arguments(aliases, flags)
722 self._add_arguments(aliases, flags)
723
723
724 def _add_arguments(self, aliases=None, flags=None):
724 def _add_arguments(self, aliases=None, flags=None):
725 raise NotImplementedError("subclasses must implement _add_arguments")
725 raise NotImplementedError("subclasses must implement _add_arguments")
726
726
727 def _parse_args(self, args):
727 def _parse_args(self, args):
728 """self.parser->self.parsed_data"""
728 """self.parser->self.parsed_data"""
729 # decode sys.argv to support unicode command-line options
729 # decode sys.argv to support unicode command-line options
730 enc = DEFAULT_ENCODING
730 enc = DEFAULT_ENCODING
731 uargs = [py3compat.cast_unicode(a, enc) for a in args]
731 uargs = [py3compat.cast_unicode(a, enc) for a in args]
732 self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
732 self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
733
733
734 def _convert_to_config(self):
734 def _convert_to_config(self):
735 """self.parsed_data->self.config"""
735 """self.parsed_data->self.config"""
736 for k, v in vars(self.parsed_data).iteritems():
736 for k, v in vars(self.parsed_data).iteritems():
737 exec "self.config.%s = v"%k in locals(), globals()
737 exec("self.config.%s = v"%k, locals(), globals())
738
738
739 class KVArgParseConfigLoader(ArgParseConfigLoader):
739 class KVArgParseConfigLoader(ArgParseConfigLoader):
740 """A config loader that loads aliases and flags with argparse,
740 """A config loader that loads aliases and flags with argparse,
741 but will use KVLoader for the rest. This allows better parsing
741 but will use KVLoader for the rest. This allows better parsing
742 of common args, such as `ipython -c 'print 5'`, but still gets
742 of common args, such as `ipython -c 'print 5'`, but still gets
743 arbitrary config with `ipython --InteractiveShell.use_readline=False`"""
743 arbitrary config with `ipython --InteractiveShell.use_readline=False`"""
744
744
745 def _add_arguments(self, aliases=None, flags=None):
745 def _add_arguments(self, aliases=None, flags=None):
746 self.alias_flags = {}
746 self.alias_flags = {}
747 # print aliases, flags
747 # print aliases, flags
748 if aliases is None:
748 if aliases is None:
749 aliases = self.aliases
749 aliases = self.aliases
750 if flags is None:
750 if flags is None:
751 flags = self.flags
751 flags = self.flags
752 paa = self.parser.add_argument
752 paa = self.parser.add_argument
753 for key,value in aliases.iteritems():
753 for key,value in aliases.iteritems():
754 if key in flags:
754 if key in flags:
755 # flags
755 # flags
756 nargs = '?'
756 nargs = '?'
757 else:
757 else:
758 nargs = None
758 nargs = None
759 if len(key) is 1:
759 if len(key) is 1:
760 paa('-'+key, '--'+key, type=unicode, dest=value, nargs=nargs)
760 paa('-'+key, '--'+key, type=unicode, dest=value, nargs=nargs)
761 else:
761 else:
762 paa('--'+key, type=unicode, dest=value, nargs=nargs)
762 paa('--'+key, type=unicode, dest=value, nargs=nargs)
763 for key, (value, help) in flags.iteritems():
763 for key, (value, help) in flags.iteritems():
764 if key in self.aliases:
764 if key in self.aliases:
765 #
765 #
766 self.alias_flags[self.aliases[key]] = value
766 self.alias_flags[self.aliases[key]] = value
767 continue
767 continue
768 if len(key) is 1:
768 if len(key) is 1:
769 paa('-'+key, '--'+key, action='append_const', dest='_flags', const=value)
769 paa('-'+key, '--'+key, action='append_const', dest='_flags', const=value)
770 else:
770 else:
771 paa('--'+key, action='append_const', dest='_flags', const=value)
771 paa('--'+key, action='append_const', dest='_flags', const=value)
772
772
773 def _convert_to_config(self):
773 def _convert_to_config(self):
774 """self.parsed_data->self.config, parse unrecognized extra args via KVLoader."""
774 """self.parsed_data->self.config, parse unrecognized extra args via KVLoader."""
775 # remove subconfigs list from namespace before transforming the Namespace
775 # remove subconfigs list from namespace before transforming the Namespace
776 if '_flags' in self.parsed_data:
776 if '_flags' in self.parsed_data:
777 subcs = self.parsed_data._flags
777 subcs = self.parsed_data._flags
778 del self.parsed_data._flags
778 del self.parsed_data._flags
779 else:
779 else:
780 subcs = []
780 subcs = []
781
781
782 for k, v in vars(self.parsed_data).iteritems():
782 for k, v in vars(self.parsed_data).iteritems():
783 if v is None:
783 if v is None:
784 # it was a flag that shares the name of an alias
784 # it was a flag that shares the name of an alias
785 subcs.append(self.alias_flags[k])
785 subcs.append(self.alias_flags[k])
786 else:
786 else:
787 # eval the KV assignment
787 # eval the KV assignment
788 self._exec_config_str(k, v)
788 self._exec_config_str(k, v)
789
789
790 for subc in subcs:
790 for subc in subcs:
791 self._load_flag(subc)
791 self._load_flag(subc)
792
792
793 if self.extra_args:
793 if self.extra_args:
794 sub_parser = KeyValueConfigLoader()
794 sub_parser = KeyValueConfigLoader()
795 sub_parser.load_config(self.extra_args)
795 sub_parser.load_config(self.extra_args)
796 self.config.merge(sub_parser.config)
796 self.config.merge(sub_parser.config)
797 self.extra_args = sub_parser.extra_args
797 self.extra_args = sub_parser.extra_args
798
798
799
799
800 def load_pyconfig_files(config_files, path):
800 def load_pyconfig_files(config_files, path):
801 """Load multiple Python config files, merging each of them in turn.
801 """Load multiple Python config files, merging each of them in turn.
802
802
803 Parameters
803 Parameters
804 ==========
804 ==========
805 config_files : list of str
805 config_files : list of str
806 List of config files names to load and merge into the config.
806 List of config files names to load and merge into the config.
807 path : unicode
807 path : unicode
808 The full path to the location of the config files.
808 The full path to the location of the config files.
809 """
809 """
810 config = Config()
810 config = Config()
811 for cf in config_files:
811 for cf in config_files:
812 loader = PyFileConfigLoader(cf, path=path)
812 loader = PyFileConfigLoader(cf, path=path)
813 try:
813 try:
814 next_config = loader.load_config()
814 next_config = loader.load_config()
815 except ConfigFileNotFound:
815 except ConfigFileNotFound:
816 pass
816 pass
817 except:
817 except:
818 raise
818 raise
819 else:
819 else:
820 config.merge(next_config)
820 config.merge(next_config)
821 return config
821 return config
@@ -1,292 +1,292 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Tests for IPython.config.loader
3 Tests for IPython.config.loader
4
4
5 Authors:
5 Authors:
6
6
7 * Brian Granger
7 * Brian Granger
8 * Fernando Perez (design help)
8 * Fernando Perez (design help)
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008 The IPython Development Team
12 # Copyright (C) 2008 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import os
22 import os
23 import sys
23 import sys
24 from tempfile import mkstemp
24 from tempfile import mkstemp
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from nose import SkipTest
27 from nose import SkipTest
28
28
29 from IPython.testing.tools import mute_warn
29 from IPython.testing.tools import mute_warn
30
30
31 from IPython.config.loader import (
31 from IPython.config.loader import (
32 Config,
32 Config,
33 PyFileConfigLoader,
33 PyFileConfigLoader,
34 KeyValueConfigLoader,
34 KeyValueConfigLoader,
35 ArgParseConfigLoader,
35 ArgParseConfigLoader,
36 KVArgParseConfigLoader,
36 KVArgParseConfigLoader,
37 ConfigError
37 ConfigError
38 )
38 )
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Actual tests
41 # Actual tests
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44
44
45 pyfile = """
45 pyfile = """
46 c = get_config()
46 c = get_config()
47 c.a=10
47 c.a=10
48 c.b=20
48 c.b=20
49 c.Foo.Bar.value=10
49 c.Foo.Bar.value=10
50 c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
50 c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
51 c.D.C.value='hi there'
51 c.D.C.value='hi there'
52 """
52 """
53
53
54 class TestPyFileCL(TestCase):
54 class TestPyFileCL(TestCase):
55
55
56 def test_basic(self):
56 def test_basic(self):
57 fd, fname = mkstemp('.py')
57 fd, fname = mkstemp('.py')
58 f = os.fdopen(fd, 'w')
58 f = os.fdopen(fd, 'w')
59 f.write(pyfile)
59 f.write(pyfile)
60 f.close()
60 f.close()
61 # Unlink the file
61 # Unlink the file
62 cl = PyFileConfigLoader(fname)
62 cl = PyFileConfigLoader(fname)
63 config = cl.load_config()
63 config = cl.load_config()
64 self.assertEqual(config.a, 10)
64 self.assertEqual(config.a, 10)
65 self.assertEqual(config.b, 20)
65 self.assertEqual(config.b, 20)
66 self.assertEqual(config.Foo.Bar.value, 10)
66 self.assertEqual(config.Foo.Bar.value, 10)
67 self.assertEqual(config.Foo.Bam.value, range(10))
67 self.assertEqual(config.Foo.Bam.value, range(10))
68 self.assertEqual(config.D.C.value, 'hi there')
68 self.assertEqual(config.D.C.value, 'hi there')
69
69
70 class MyLoader1(ArgParseConfigLoader):
70 class MyLoader1(ArgParseConfigLoader):
71 def _add_arguments(self, aliases=None, flags=None):
71 def _add_arguments(self, aliases=None, flags=None):
72 p = self.parser
72 p = self.parser
73 p.add_argument('-f', '--foo', dest='Global.foo', type=str)
73 p.add_argument('-f', '--foo', dest='Global.foo', type=str)
74 p.add_argument('-b', dest='MyClass.bar', type=int)
74 p.add_argument('-b', dest='MyClass.bar', type=int)
75 p.add_argument('-n', dest='n', action='store_true')
75 p.add_argument('-n', dest='n', action='store_true')
76 p.add_argument('Global.bam', type=str)
76 p.add_argument('Global.bam', type=str)
77
77
78 class MyLoader2(ArgParseConfigLoader):
78 class MyLoader2(ArgParseConfigLoader):
79 def _add_arguments(self, aliases=None, flags=None):
79 def _add_arguments(self, aliases=None, flags=None):
80 subparsers = self.parser.add_subparsers(dest='subparser_name')
80 subparsers = self.parser.add_subparsers(dest='subparser_name')
81 subparser1 = subparsers.add_parser('1')
81 subparser1 = subparsers.add_parser('1')
82 subparser1.add_argument('-x',dest='Global.x')
82 subparser1.add_argument('-x',dest='Global.x')
83 subparser2 = subparsers.add_parser('2')
83 subparser2 = subparsers.add_parser('2')
84 subparser2.add_argument('y')
84 subparser2.add_argument('y')
85
85
86 class TestArgParseCL(TestCase):
86 class TestArgParseCL(TestCase):
87
87
88 def test_basic(self):
88 def test_basic(self):
89 cl = MyLoader1()
89 cl = MyLoader1()
90 config = cl.load_config('-f hi -b 10 -n wow'.split())
90 config = cl.load_config('-f hi -b 10 -n wow'.split())
91 self.assertEqual(config.Global.foo, 'hi')
91 self.assertEqual(config.Global.foo, 'hi')
92 self.assertEqual(config.MyClass.bar, 10)
92 self.assertEqual(config.MyClass.bar, 10)
93 self.assertEqual(config.n, True)
93 self.assertEqual(config.n, True)
94 self.assertEqual(config.Global.bam, 'wow')
94 self.assertEqual(config.Global.bam, 'wow')
95 config = cl.load_config(['wow'])
95 config = cl.load_config(['wow'])
96 self.assertEqual(config.keys(), ['Global'])
96 self.assertEqual(config.keys(), ['Global'])
97 self.assertEqual(config.Global.keys(), ['bam'])
97 self.assertEqual(config.Global.keys(), ['bam'])
98 self.assertEqual(config.Global.bam, 'wow')
98 self.assertEqual(config.Global.bam, 'wow')
99
99
100 def test_add_arguments(self):
100 def test_add_arguments(self):
101 cl = MyLoader2()
101 cl = MyLoader2()
102 config = cl.load_config('2 frobble'.split())
102 config = cl.load_config('2 frobble'.split())
103 self.assertEqual(config.subparser_name, '2')
103 self.assertEqual(config.subparser_name, '2')
104 self.assertEqual(config.y, 'frobble')
104 self.assertEqual(config.y, 'frobble')
105 config = cl.load_config('1 -x frobble'.split())
105 config = cl.load_config('1 -x frobble'.split())
106 self.assertEqual(config.subparser_name, '1')
106 self.assertEqual(config.subparser_name, '1')
107 self.assertEqual(config.Global.x, 'frobble')
107 self.assertEqual(config.Global.x, 'frobble')
108
108
109 def test_argv(self):
109 def test_argv(self):
110 cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
110 cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
111 config = cl.load_config()
111 config = cl.load_config()
112 self.assertEqual(config.Global.foo, 'hi')
112 self.assertEqual(config.Global.foo, 'hi')
113 self.assertEqual(config.MyClass.bar, 10)
113 self.assertEqual(config.MyClass.bar, 10)
114 self.assertEqual(config.n, True)
114 self.assertEqual(config.n, True)
115 self.assertEqual(config.Global.bam, 'wow')
115 self.assertEqual(config.Global.bam, 'wow')
116
116
117
117
118 class TestKeyValueCL(TestCase):
118 class TestKeyValueCL(TestCase):
119 klass = KeyValueConfigLoader
119 klass = KeyValueConfigLoader
120
120
121 def test_basic(self):
121 def test_basic(self):
122 cl = self.klass()
122 cl = self.klass()
123 argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
123 argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
124 with mute_warn():
124 with mute_warn():
125 config = cl.load_config(argv)
125 config = cl.load_config(argv)
126 self.assertEqual(config.a, 10)
126 self.assertEqual(config.a, 10)
127 self.assertEqual(config.b, 20)
127 self.assertEqual(config.b, 20)
128 self.assertEqual(config.Foo.Bar.value, 10)
128 self.assertEqual(config.Foo.Bar.value, 10)
129 self.assertEqual(config.Foo.Bam.value, range(10))
129 self.assertEqual(config.Foo.Bam.value, range(10))
130 self.assertEqual(config.D.C.value, 'hi there')
130 self.assertEqual(config.D.C.value, 'hi there')
131
131
132 def test_expanduser(self):
132 def test_expanduser(self):
133 cl = self.klass()
133 cl = self.klass()
134 argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"']
134 argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"']
135 with mute_warn():
135 with mute_warn():
136 config = cl.load_config(argv)
136 config = cl.load_config(argv)
137 self.assertEqual(config.a, os.path.expanduser('~/1/2/3'))
137 self.assertEqual(config.a, os.path.expanduser('~/1/2/3'))
138 self.assertEqual(config.b, os.path.expanduser('~'))
138 self.assertEqual(config.b, os.path.expanduser('~'))
139 self.assertEqual(config.c, os.path.expanduser('~/'))
139 self.assertEqual(config.c, os.path.expanduser('~/'))
140 self.assertEqual(config.d, '~/')
140 self.assertEqual(config.d, '~/')
141
141
142 def test_extra_args(self):
142 def test_extra_args(self):
143 cl = self.klass()
143 cl = self.klass()
144 with mute_warn():
144 with mute_warn():
145 config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
145 config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
146 self.assertEqual(cl.extra_args, ['b', 'd'])
146 self.assertEqual(cl.extra_args, ['b', 'd'])
147 self.assertEqual(config.a, 5)
147 self.assertEqual(config.a, 5)
148 self.assertEqual(config.c, 10)
148 self.assertEqual(config.c, 10)
149 with mute_warn():
149 with mute_warn():
150 config = cl.load_config(['--', '--a=5', '--c=10'])
150 config = cl.load_config(['--', '--a=5', '--c=10'])
151 self.assertEqual(cl.extra_args, ['--a=5', '--c=10'])
151 self.assertEqual(cl.extra_args, ['--a=5', '--c=10'])
152
152
153 def test_unicode_args(self):
153 def test_unicode_args(self):
154 cl = self.klass()
154 cl = self.klass()
155 argv = [u'--a=épsîlön']
155 argv = [u'--a=épsîlön']
156 with mute_warn():
156 with mute_warn():
157 config = cl.load_config(argv)
157 config = cl.load_config(argv)
158 self.assertEqual(config.a, u'épsîlön')
158 self.assertEqual(config.a, u'épsîlön')
159
159
160 def test_unicode_bytes_args(self):
160 def test_unicode_bytes_args(self):
161 uarg = u'--a=é'
161 uarg = u'--a=é'
162 try:
162 try:
163 barg = uarg.encode(sys.stdin.encoding)
163 barg = uarg.encode(sys.stdin.encoding)
164 except (TypeError, UnicodeEncodeError):
164 except (TypeError, UnicodeEncodeError):
165 raise SkipTest("sys.stdin.encoding can't handle 'é'")
165 raise SkipTest("sys.stdin.encoding can't handle 'é'")
166
166
167 cl = self.klass()
167 cl = self.klass()
168 with mute_warn():
168 with mute_warn():
169 config = cl.load_config([barg])
169 config = cl.load_config([barg])
170 self.assertEqual(config.a, u'é')
170 self.assertEqual(config.a, u'é')
171
171
172 def test_unicode_alias(self):
172 def test_unicode_alias(self):
173 cl = self.klass()
173 cl = self.klass()
174 argv = [u'--a=épsîlön']
174 argv = [u'--a=épsîlön']
175 with mute_warn():
175 with mute_warn():
176 config = cl.load_config(argv, aliases=dict(a='A.a'))
176 config = cl.load_config(argv, aliases=dict(a='A.a'))
177 self.assertEqual(config.A.a, u'épsîlön')
177 self.assertEqual(config.A.a, u'épsîlön')
178
178
179
179
180 class TestArgParseKVCL(TestKeyValueCL):
180 class TestArgParseKVCL(TestKeyValueCL):
181 klass = KVArgParseConfigLoader
181 klass = KVArgParseConfigLoader
182
182
183 def test_expanduser2(self):
183 def test_expanduser2(self):
184 cl = self.klass()
184 cl = self.klass()
185 argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"]
185 argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"]
186 with mute_warn():
186 with mute_warn():
187 config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b'))
187 config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b'))
188 self.assertEqual(config.A.a, os.path.expanduser('~/1/2/3'))
188 self.assertEqual(config.A.a, os.path.expanduser('~/1/2/3'))
189 self.assertEqual(config.A.b, '~/1/2/3')
189 self.assertEqual(config.A.b, '~/1/2/3')
190
190
191 def test_eval(self):
191 def test_eval(self):
192 cl = self.klass()
192 cl = self.klass()
193 argv = ['-c', 'a=5']
193 argv = ['-c', 'a=5']
194 with mute_warn():
194 with mute_warn():
195 config = cl.load_config(argv, aliases=dict(c='A.c'))
195 config = cl.load_config(argv, aliases=dict(c='A.c'))
196 self.assertEqual(config.A.c, u"a=5")
196 self.assertEqual(config.A.c, u"a=5")
197
197
198
198
199 class TestConfig(TestCase):
199 class TestConfig(TestCase):
200
200
201 def test_setget(self):
201 def test_setget(self):
202 c = Config()
202 c = Config()
203 c.a = 10
203 c.a = 10
204 self.assertEqual(c.a, 10)
204 self.assertEqual(c.a, 10)
205 self.assertEqual('b' in c, False)
205 self.assertEqual('b' in c, False)
206
206
207 def test_auto_section(self):
207 def test_auto_section(self):
208 c = Config()
208 c = Config()
209 self.assertEqual('A' in c, True)
209 self.assertEqual('A' in c, True)
210 self.assertEqual(c._has_section('A'), False)
210 self.assertEqual(c._has_section('A'), False)
211 A = c.A
211 A = c.A
212 A.foo = 'hi there'
212 A.foo = 'hi there'
213 self.assertEqual(c._has_section('A'), True)
213 self.assertEqual(c._has_section('A'), True)
214 self.assertEqual(c.A.foo, 'hi there')
214 self.assertEqual(c.A.foo, 'hi there')
215 del c.A
215 del c.A
216 self.assertEqual(len(c.A.keys()),0)
216 self.assertEqual(len(c.A.keys()),0)
217
217
218 def test_merge_doesnt_exist(self):
218 def test_merge_doesnt_exist(self):
219 c1 = Config()
219 c1 = Config()
220 c2 = Config()
220 c2 = Config()
221 c2.bar = 10
221 c2.bar = 10
222 c2.Foo.bar = 10
222 c2.Foo.bar = 10
223 c1.merge(c2)
223 c1.merge(c2)
224 self.assertEqual(c1.Foo.bar, 10)
224 self.assertEqual(c1.Foo.bar, 10)
225 self.assertEqual(c1.bar, 10)
225 self.assertEqual(c1.bar, 10)
226 c2.Bar.bar = 10
226 c2.Bar.bar = 10
227 c1.merge(c2)
227 c1.merge(c2)
228 self.assertEqual(c1.Bar.bar, 10)
228 self.assertEqual(c1.Bar.bar, 10)
229
229
230 def test_merge_exists(self):
230 def test_merge_exists(self):
231 c1 = Config()
231 c1 = Config()
232 c2 = Config()
232 c2 = Config()
233 c1.Foo.bar = 10
233 c1.Foo.bar = 10
234 c1.Foo.bam = 30
234 c1.Foo.bam = 30
235 c2.Foo.bar = 20
235 c2.Foo.bar = 20
236 c2.Foo.wow = 40
236 c2.Foo.wow = 40
237 c1.merge(c2)
237 c1.merge(c2)
238 self.assertEqual(c1.Foo.bam, 30)
238 self.assertEqual(c1.Foo.bam, 30)
239 self.assertEqual(c1.Foo.bar, 20)
239 self.assertEqual(c1.Foo.bar, 20)
240 self.assertEqual(c1.Foo.wow, 40)
240 self.assertEqual(c1.Foo.wow, 40)
241 c2.Foo.Bam.bam = 10
241 c2.Foo.Bam.bam = 10
242 c1.merge(c2)
242 c1.merge(c2)
243 self.assertEqual(c1.Foo.Bam.bam, 10)
243 self.assertEqual(c1.Foo.Bam.bam, 10)
244
244
245 def test_deepcopy(self):
245 def test_deepcopy(self):
246 c1 = Config()
246 c1 = Config()
247 c1.Foo.bar = 10
247 c1.Foo.bar = 10
248 c1.Foo.bam = 30
248 c1.Foo.bam = 30
249 c1.a = 'asdf'
249 c1.a = 'asdf'
250 c1.b = range(10)
250 c1.b = range(10)
251 import copy
251 import copy
252 c2 = copy.deepcopy(c1)
252 c2 = copy.deepcopy(c1)
253 self.assertEqual(c1, c2)
253 self.assertEqual(c1, c2)
254 self.assertTrue(c1 is not c2)
254 self.assertTrue(c1 is not c2)
255 self.assertTrue(c1.Foo is not c2.Foo)
255 self.assertTrue(c1.Foo is not c2.Foo)
256
256
257 def test_builtin(self):
257 def test_builtin(self):
258 c1 = Config()
258 c1 = Config()
259 exec 'foo = True' in c1
259 exec('foo = True', c1)
260 self.assertEqual(c1.foo, True)
260 self.assertEqual(c1.foo, True)
261 c1.format = "json"
261 c1.format = "json"
262
262
263 def test_fromdict(self):
263 def test_fromdict(self):
264 c1 = Config({'Foo' : {'bar' : 1}})
264 c1 = Config({'Foo' : {'bar' : 1}})
265 self.assertEqual(c1.Foo.__class__, Config)
265 self.assertEqual(c1.Foo.__class__, Config)
266 self.assertEqual(c1.Foo.bar, 1)
266 self.assertEqual(c1.Foo.bar, 1)
267
267
268 def test_fromdictmerge(self):
268 def test_fromdictmerge(self):
269 c1 = Config()
269 c1 = Config()
270 c2 = Config({'Foo' : {'bar' : 1}})
270 c2 = Config({'Foo' : {'bar' : 1}})
271 c1.merge(c2)
271 c1.merge(c2)
272 self.assertEqual(c1.Foo.__class__, Config)
272 self.assertEqual(c1.Foo.__class__, Config)
273 self.assertEqual(c1.Foo.bar, 1)
273 self.assertEqual(c1.Foo.bar, 1)
274
274
275 def test_fromdictmerge2(self):
275 def test_fromdictmerge2(self):
276 c1 = Config({'Foo' : {'baz' : 2}})
276 c1 = Config({'Foo' : {'baz' : 2}})
277 c2 = Config({'Foo' : {'bar' : 1}})
277 c2 = Config({'Foo' : {'bar' : 1}})
278 c1.merge(c2)
278 c1.merge(c2)
279 self.assertEqual(c1.Foo.__class__, Config)
279 self.assertEqual(c1.Foo.__class__, Config)
280 self.assertEqual(c1.Foo.bar, 1)
280 self.assertEqual(c1.Foo.bar, 1)
281 self.assertEqual(c1.Foo.baz, 2)
281 self.assertEqual(c1.Foo.baz, 2)
282 self.assertNotIn('baz', c2.Foo)
282 self.assertNotIn('baz', c2.Foo)
283
283
284 def test_contains(self):
284 def test_contains(self):
285 c1 = Config({'Foo' : {'baz' : 2}})
285 c1 = Config({'Foo' : {'baz' : 2}})
286 c2 = Config({'Foo' : {'bar' : 1}})
286 c2 = Config({'Foo' : {'bar' : 1}})
287 self.assertIn('Foo', c1)
287 self.assertIn('Foo', c1)
288 self.assertIn('Foo.baz', c1)
288 self.assertIn('Foo.baz', c1)
289 self.assertIn('Foo.bar', c2)
289 self.assertIn('Foo.bar', c2)
290 self.assertNotIn('Foo.bar', c1)
290 self.assertNotIn('Foo.bar', c1)
291
291
292
292
@@ -1,3164 +1,3164 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import absolute_import
17 from __future__ import absolute_import
18 from __future__ import print_function
18 from __future__ import print_function
19
19
20 import __builtin__ as builtin_mod
20 import __builtin__ as builtin_mod
21 import __future__
21 import __future__
22 import abc
22 import abc
23 import ast
23 import ast
24 import atexit
24 import atexit
25 import functools
25 import functools
26 import os
26 import os
27 import re
27 import re
28 import runpy
28 import runpy
29 import sys
29 import sys
30 import tempfile
30 import tempfile
31 import types
31 import types
32 import subprocess
32 import subprocess
33 from io import open as io_open
33 from io import open as io_open
34
34
35 from IPython.config.configurable import SingletonConfigurable
35 from IPython.config.configurable import SingletonConfigurable
36 from IPython.core import debugger, oinspect
36 from IPython.core import debugger, oinspect
37 from IPython.core import magic
37 from IPython.core import magic
38 from IPython.core import page
38 from IPython.core import page
39 from IPython.core import prefilter
39 from IPython.core import prefilter
40 from IPython.core import shadowns
40 from IPython.core import shadowns
41 from IPython.core import ultratb
41 from IPython.core import ultratb
42 from IPython.core.alias import AliasManager, AliasError
42 from IPython.core.alias import AliasManager, AliasError
43 from IPython.core.autocall import ExitAutocall
43 from IPython.core.autocall import ExitAutocall
44 from IPython.core.builtin_trap import BuiltinTrap
44 from IPython.core.builtin_trap import BuiltinTrap
45 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
45 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
46 from IPython.core.display_trap import DisplayTrap
46 from IPython.core.display_trap import DisplayTrap
47 from IPython.core.displayhook import DisplayHook
47 from IPython.core.displayhook import DisplayHook
48 from IPython.core.displaypub import DisplayPublisher
48 from IPython.core.displaypub import DisplayPublisher
49 from IPython.core.error import UsageError
49 from IPython.core.error import UsageError
50 from IPython.core.extensions import ExtensionManager
50 from IPython.core.extensions import ExtensionManager
51 from IPython.core.formatters import DisplayFormatter
51 from IPython.core.formatters import DisplayFormatter
52 from IPython.core.history import HistoryManager
52 from IPython.core.history import HistoryManager
53 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
53 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
54 from IPython.core.logger import Logger
54 from IPython.core.logger import Logger
55 from IPython.core.macro import Macro
55 from IPython.core.macro import Macro
56 from IPython.core.payload import PayloadManager
56 from IPython.core.payload import PayloadManager
57 from IPython.core.prefilter import PrefilterManager
57 from IPython.core.prefilter import PrefilterManager
58 from IPython.core.profiledir import ProfileDir
58 from IPython.core.profiledir import ProfileDir
59 from IPython.core.prompts import PromptManager
59 from IPython.core.prompts import PromptManager
60 from IPython.lib.latextools import LaTeXTool
60 from IPython.lib.latextools import LaTeXTool
61 from IPython.testing.skipdoctest import skip_doctest
61 from IPython.testing.skipdoctest import skip_doctest
62 from IPython.utils import PyColorize
62 from IPython.utils import PyColorize
63 from IPython.utils import io
63 from IPython.utils import io
64 from IPython.utils import py3compat
64 from IPython.utils import py3compat
65 from IPython.utils import openpy
65 from IPython.utils import openpy
66 from IPython.utils.decorators import undoc
66 from IPython.utils.decorators import undoc
67 from IPython.utils.io import ask_yes_no
67 from IPython.utils.io import ask_yes_no
68 from IPython.utils.ipstruct import Struct
68 from IPython.utils.ipstruct import Struct
69 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
69 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
70 from IPython.utils.pickleshare import PickleShareDB
70 from IPython.utils.pickleshare import PickleShareDB
71 from IPython.utils.process import system, getoutput
71 from IPython.utils.process import system, getoutput
72 from IPython.utils.strdispatch import StrDispatch
72 from IPython.utils.strdispatch import StrDispatch
73 from IPython.utils.syspathcontext import prepended_to_syspath
73 from IPython.utils.syspathcontext import prepended_to_syspath
74 from IPython.utils.text import (format_screen, LSString, SList,
74 from IPython.utils.text import (format_screen, LSString, SList,
75 DollarFormatter)
75 DollarFormatter)
76 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
76 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
77 List, Unicode, Instance, Type)
77 List, Unicode, Instance, Type)
78 from IPython.utils.warn import warn, error
78 from IPython.utils.warn import warn, error
79 import IPython.core.hooks
79 import IPython.core.hooks
80
80
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82 # Globals
82 # Globals
83 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
84
84
85 # compiled regexps for autoindent management
85 # compiled regexps for autoindent management
86 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
86 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
87
87
88 #-----------------------------------------------------------------------------
88 #-----------------------------------------------------------------------------
89 # Utilities
89 # Utilities
90 #-----------------------------------------------------------------------------
90 #-----------------------------------------------------------------------------
91
91
92 @undoc
92 @undoc
93 def softspace(file, newvalue):
93 def softspace(file, newvalue):
94 """Copied from code.py, to remove the dependency"""
94 """Copied from code.py, to remove the dependency"""
95
95
96 oldvalue = 0
96 oldvalue = 0
97 try:
97 try:
98 oldvalue = file.softspace
98 oldvalue = file.softspace
99 except AttributeError:
99 except AttributeError:
100 pass
100 pass
101 try:
101 try:
102 file.softspace = newvalue
102 file.softspace = newvalue
103 except (AttributeError, TypeError):
103 except (AttributeError, TypeError):
104 # "attribute-less object" or "read-only attributes"
104 # "attribute-less object" or "read-only attributes"
105 pass
105 pass
106 return oldvalue
106 return oldvalue
107
107
108 @undoc
108 @undoc
109 def no_op(*a, **kw): pass
109 def no_op(*a, **kw): pass
110
110
111 @undoc
111 @undoc
112 class NoOpContext(object):
112 class NoOpContext(object):
113 def __enter__(self): pass
113 def __enter__(self): pass
114 def __exit__(self, type, value, traceback): pass
114 def __exit__(self, type, value, traceback): pass
115 no_op_context = NoOpContext()
115 no_op_context = NoOpContext()
116
116
117 class SpaceInInput(Exception): pass
117 class SpaceInInput(Exception): pass
118
118
119 @undoc
119 @undoc
120 class Bunch: pass
120 class Bunch: pass
121
121
122
122
123 def get_default_colors():
123 def get_default_colors():
124 if sys.platform=='darwin':
124 if sys.platform=='darwin':
125 return "LightBG"
125 return "LightBG"
126 elif os.name=='nt':
126 elif os.name=='nt':
127 return 'Linux'
127 return 'Linux'
128 else:
128 else:
129 return 'Linux'
129 return 'Linux'
130
130
131
131
132 class SeparateUnicode(Unicode):
132 class SeparateUnicode(Unicode):
133 """A Unicode subclass to validate separate_in, separate_out, etc.
133 """A Unicode subclass to validate separate_in, separate_out, etc.
134
134
135 This is a Unicode based trait that converts '0'->'' and '\\n'->'\n'.
135 This is a Unicode based trait that converts '0'->'' and '\\n'->'\n'.
136 """
136 """
137
137
138 def validate(self, obj, value):
138 def validate(self, obj, value):
139 if value == '0': value = ''
139 if value == '0': value = ''
140 value = value.replace('\\n','\n')
140 value = value.replace('\\n','\n')
141 return super(SeparateUnicode, self).validate(obj, value)
141 return super(SeparateUnicode, self).validate(obj, value)
142
142
143
143
144 class ReadlineNoRecord(object):
144 class ReadlineNoRecord(object):
145 """Context manager to execute some code, then reload readline history
145 """Context manager to execute some code, then reload readline history
146 so that interactive input to the code doesn't appear when pressing up."""
146 so that interactive input to the code doesn't appear when pressing up."""
147 def __init__(self, shell):
147 def __init__(self, shell):
148 self.shell = shell
148 self.shell = shell
149 self._nested_level = 0
149 self._nested_level = 0
150
150
151 def __enter__(self):
151 def __enter__(self):
152 if self._nested_level == 0:
152 if self._nested_level == 0:
153 try:
153 try:
154 self.orig_length = self.current_length()
154 self.orig_length = self.current_length()
155 self.readline_tail = self.get_readline_tail()
155 self.readline_tail = self.get_readline_tail()
156 except (AttributeError, IndexError): # Can fail with pyreadline
156 except (AttributeError, IndexError): # Can fail with pyreadline
157 self.orig_length, self.readline_tail = 999999, []
157 self.orig_length, self.readline_tail = 999999, []
158 self._nested_level += 1
158 self._nested_level += 1
159
159
160 def __exit__(self, type, value, traceback):
160 def __exit__(self, type, value, traceback):
161 self._nested_level -= 1
161 self._nested_level -= 1
162 if self._nested_level == 0:
162 if self._nested_level == 0:
163 # Try clipping the end if it's got longer
163 # Try clipping the end if it's got longer
164 try:
164 try:
165 e = self.current_length() - self.orig_length
165 e = self.current_length() - self.orig_length
166 if e > 0:
166 if e > 0:
167 for _ in range(e):
167 for _ in range(e):
168 self.shell.readline.remove_history_item(self.orig_length)
168 self.shell.readline.remove_history_item(self.orig_length)
169
169
170 # If it still doesn't match, just reload readline history.
170 # If it still doesn't match, just reload readline history.
171 if self.current_length() != self.orig_length \
171 if self.current_length() != self.orig_length \
172 or self.get_readline_tail() != self.readline_tail:
172 or self.get_readline_tail() != self.readline_tail:
173 self.shell.refill_readline_hist()
173 self.shell.refill_readline_hist()
174 except (AttributeError, IndexError):
174 except (AttributeError, IndexError):
175 pass
175 pass
176 # Returning False will cause exceptions to propagate
176 # Returning False will cause exceptions to propagate
177 return False
177 return False
178
178
179 def current_length(self):
179 def current_length(self):
180 return self.shell.readline.get_current_history_length()
180 return self.shell.readline.get_current_history_length()
181
181
182 def get_readline_tail(self, n=10):
182 def get_readline_tail(self, n=10):
183 """Get the last n items in readline history."""
183 """Get the last n items in readline history."""
184 end = self.shell.readline.get_current_history_length() + 1
184 end = self.shell.readline.get_current_history_length() + 1
185 start = max(end-n, 1)
185 start = max(end-n, 1)
186 ghi = self.shell.readline.get_history_item
186 ghi = self.shell.readline.get_history_item
187 return [ghi(x) for x in range(start, end)]
187 return [ghi(x) for x in range(start, end)]
188
188
189
189
190 @undoc
190 @undoc
191 class DummyMod(object):
191 class DummyMod(object):
192 """A dummy module used for IPython's interactive module when
192 """A dummy module used for IPython's interactive module when
193 a namespace must be assigned to the module's __dict__."""
193 a namespace must be assigned to the module's __dict__."""
194 pass
194 pass
195
195
196 #-----------------------------------------------------------------------------
196 #-----------------------------------------------------------------------------
197 # Main IPython class
197 # Main IPython class
198 #-----------------------------------------------------------------------------
198 #-----------------------------------------------------------------------------
199
199
200 class InteractiveShell(SingletonConfigurable):
200 class InteractiveShell(SingletonConfigurable):
201 """An enhanced, interactive shell for Python."""
201 """An enhanced, interactive shell for Python."""
202
202
203 _instance = None
203 _instance = None
204
204
205 ast_transformers = List([], config=True, help=
205 ast_transformers = List([], config=True, help=
206 """
206 """
207 A list of ast.NodeTransformer subclass instances, which will be applied
207 A list of ast.NodeTransformer subclass instances, which will be applied
208 to user input before code is run.
208 to user input before code is run.
209 """
209 """
210 )
210 )
211
211
212 autocall = Enum((0,1,2), default_value=0, config=True, help=
212 autocall = Enum((0,1,2), default_value=0, config=True, help=
213 """
213 """
214 Make IPython automatically call any callable object even if you didn't
214 Make IPython automatically call any callable object even if you didn't
215 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
215 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
216 automatically. The value can be '0' to disable the feature, '1' for
216 automatically. The value can be '0' to disable the feature, '1' for
217 'smart' autocall, where it is not applied if there are no more
217 'smart' autocall, where it is not applied if there are no more
218 arguments on the line, and '2' for 'full' autocall, where all callable
218 arguments on the line, and '2' for 'full' autocall, where all callable
219 objects are automatically called (even if no arguments are present).
219 objects are automatically called (even if no arguments are present).
220 """
220 """
221 )
221 )
222 # TODO: remove all autoindent logic and put into frontends.
222 # TODO: remove all autoindent logic and put into frontends.
223 # We can't do this yet because even runlines uses the autoindent.
223 # We can't do this yet because even runlines uses the autoindent.
224 autoindent = CBool(True, config=True, help=
224 autoindent = CBool(True, config=True, help=
225 """
225 """
226 Autoindent IPython code entered interactively.
226 Autoindent IPython code entered interactively.
227 """
227 """
228 )
228 )
229 automagic = CBool(True, config=True, help=
229 automagic = CBool(True, config=True, help=
230 """
230 """
231 Enable magic commands to be called without the leading %.
231 Enable magic commands to be called without the leading %.
232 """
232 """
233 )
233 )
234 cache_size = Integer(1000, config=True, help=
234 cache_size = Integer(1000, config=True, help=
235 """
235 """
236 Set the size of the output cache. The default is 1000, you can
236 Set the size of the output cache. The default is 1000, you can
237 change it permanently in your config file. Setting it to 0 completely
237 change it permanently in your config file. Setting it to 0 completely
238 disables the caching system, and the minimum value accepted is 20 (if
238 disables the caching system, and the minimum value accepted is 20 (if
239 you provide a value less than 20, it is reset to 0 and a warning is
239 you provide a value less than 20, it is reset to 0 and a warning is
240 issued). This limit is defined because otherwise you'll spend more
240 issued). This limit is defined because otherwise you'll spend more
241 time re-flushing a too small cache than working
241 time re-flushing a too small cache than working
242 """
242 """
243 )
243 )
244 color_info = CBool(True, config=True, help=
244 color_info = CBool(True, config=True, help=
245 """
245 """
246 Use colors for displaying information about objects. Because this
246 Use colors for displaying information about objects. Because this
247 information is passed through a pager (like 'less'), and some pagers
247 information is passed through a pager (like 'less'), and some pagers
248 get confused with color codes, this capability can be turned off.
248 get confused with color codes, this capability can be turned off.
249 """
249 """
250 )
250 )
251 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
251 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
252 default_value=get_default_colors(), config=True,
252 default_value=get_default_colors(), config=True,
253 help="Set the color scheme (NoColor, Linux, or LightBG)."
253 help="Set the color scheme (NoColor, Linux, or LightBG)."
254 )
254 )
255 colors_force = CBool(False, help=
255 colors_force = CBool(False, help=
256 """
256 """
257 Force use of ANSI color codes, regardless of OS and readline
257 Force use of ANSI color codes, regardless of OS and readline
258 availability.
258 availability.
259 """
259 """
260 # FIXME: This is essentially a hack to allow ZMQShell to show colors
260 # FIXME: This is essentially a hack to allow ZMQShell to show colors
261 # without readline on Win32. When the ZMQ formatting system is
261 # without readline on Win32. When the ZMQ formatting system is
262 # refactored, this should be removed.
262 # refactored, this should be removed.
263 )
263 )
264 debug = CBool(False, config=True)
264 debug = CBool(False, config=True)
265 deep_reload = CBool(False, config=True, help=
265 deep_reload = CBool(False, config=True, help=
266 """
266 """
267 Enable deep (recursive) reloading by default. IPython can use the
267 Enable deep (recursive) reloading by default. IPython can use the
268 deep_reload module which reloads changes in modules recursively (it
268 deep_reload module which reloads changes in modules recursively (it
269 replaces the reload() function, so you don't need to change anything to
269 replaces the reload() function, so you don't need to change anything to
270 use it). deep_reload() forces a full reload of modules whose code may
270 use it). deep_reload() forces a full reload of modules whose code may
271 have changed, which the default reload() function does not. When
271 have changed, which the default reload() function does not. When
272 deep_reload is off, IPython will use the normal reload(), but
272 deep_reload is off, IPython will use the normal reload(), but
273 deep_reload will still be available as dreload().
273 deep_reload will still be available as dreload().
274 """
274 """
275 )
275 )
276 disable_failing_post_execute = CBool(False, config=True,
276 disable_failing_post_execute = CBool(False, config=True,
277 help="Don't call post-execute functions that have failed in the past."
277 help="Don't call post-execute functions that have failed in the past."
278 )
278 )
279 display_formatter = Instance(DisplayFormatter)
279 display_formatter = Instance(DisplayFormatter)
280 displayhook_class = Type(DisplayHook)
280 displayhook_class = Type(DisplayHook)
281 display_pub_class = Type(DisplayPublisher)
281 display_pub_class = Type(DisplayPublisher)
282 data_pub_class = None
282 data_pub_class = None
283
283
284 exit_now = CBool(False)
284 exit_now = CBool(False)
285 exiter = Instance(ExitAutocall)
285 exiter = Instance(ExitAutocall)
286 def _exiter_default(self):
286 def _exiter_default(self):
287 return ExitAutocall(self)
287 return ExitAutocall(self)
288 # Monotonically increasing execution counter
288 # Monotonically increasing execution counter
289 execution_count = Integer(1)
289 execution_count = Integer(1)
290 filename = Unicode("<ipython console>")
290 filename = Unicode("<ipython console>")
291 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
291 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
292
292
293 # Input splitter, to transform input line by line and detect when a block
293 # Input splitter, to transform input line by line and detect when a block
294 # is ready to be executed.
294 # is ready to be executed.
295 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
295 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
296 (), {'line_input_checker': True})
296 (), {'line_input_checker': True})
297
297
298 # This InputSplitter instance is used to transform completed cells before
298 # This InputSplitter instance is used to transform completed cells before
299 # running them. It allows cell magics to contain blank lines.
299 # running them. It allows cell magics to contain blank lines.
300 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
300 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
301 (), {'line_input_checker': False})
301 (), {'line_input_checker': False})
302
302
303 logstart = CBool(False, config=True, help=
303 logstart = CBool(False, config=True, help=
304 """
304 """
305 Start logging to the default log file.
305 Start logging to the default log file.
306 """
306 """
307 )
307 )
308 logfile = Unicode('', config=True, help=
308 logfile = Unicode('', config=True, help=
309 """
309 """
310 The name of the logfile to use.
310 The name of the logfile to use.
311 """
311 """
312 )
312 )
313 logappend = Unicode('', config=True, help=
313 logappend = Unicode('', config=True, help=
314 """
314 """
315 Start logging to the given file in append mode.
315 Start logging to the given file in append mode.
316 """
316 """
317 )
317 )
318 object_info_string_level = Enum((0,1,2), default_value=0,
318 object_info_string_level = Enum((0,1,2), default_value=0,
319 config=True)
319 config=True)
320 pdb = CBool(False, config=True, help=
320 pdb = CBool(False, config=True, help=
321 """
321 """
322 Automatically call the pdb debugger after every exception.
322 Automatically call the pdb debugger after every exception.
323 """
323 """
324 )
324 )
325 multiline_history = CBool(sys.platform != 'win32', config=True,
325 multiline_history = CBool(sys.platform != 'win32', config=True,
326 help="Save multi-line entries as one entry in readline history"
326 help="Save multi-line entries as one entry in readline history"
327 )
327 )
328
328
329 # deprecated prompt traits:
329 # deprecated prompt traits:
330
330
331 prompt_in1 = Unicode('In [\\#]: ', config=True,
331 prompt_in1 = Unicode('In [\\#]: ', config=True,
332 help="Deprecated, use PromptManager.in_template")
332 help="Deprecated, use PromptManager.in_template")
333 prompt_in2 = Unicode(' .\\D.: ', config=True,
333 prompt_in2 = Unicode(' .\\D.: ', config=True,
334 help="Deprecated, use PromptManager.in2_template")
334 help="Deprecated, use PromptManager.in2_template")
335 prompt_out = Unicode('Out[\\#]: ', config=True,
335 prompt_out = Unicode('Out[\\#]: ', config=True,
336 help="Deprecated, use PromptManager.out_template")
336 help="Deprecated, use PromptManager.out_template")
337 prompts_pad_left = CBool(True, config=True,
337 prompts_pad_left = CBool(True, config=True,
338 help="Deprecated, use PromptManager.justify")
338 help="Deprecated, use PromptManager.justify")
339
339
340 def _prompt_trait_changed(self, name, old, new):
340 def _prompt_trait_changed(self, name, old, new):
341 table = {
341 table = {
342 'prompt_in1' : 'in_template',
342 'prompt_in1' : 'in_template',
343 'prompt_in2' : 'in2_template',
343 'prompt_in2' : 'in2_template',
344 'prompt_out' : 'out_template',
344 'prompt_out' : 'out_template',
345 'prompts_pad_left' : 'justify',
345 'prompts_pad_left' : 'justify',
346 }
346 }
347 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
347 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
348 name=name, newname=table[name])
348 name=name, newname=table[name])
349 )
349 )
350 # protect against weird cases where self.config may not exist:
350 # protect against weird cases where self.config may not exist:
351 if self.config is not None:
351 if self.config is not None:
352 # propagate to corresponding PromptManager trait
352 # propagate to corresponding PromptManager trait
353 setattr(self.config.PromptManager, table[name], new)
353 setattr(self.config.PromptManager, table[name], new)
354
354
355 _prompt_in1_changed = _prompt_trait_changed
355 _prompt_in1_changed = _prompt_trait_changed
356 _prompt_in2_changed = _prompt_trait_changed
356 _prompt_in2_changed = _prompt_trait_changed
357 _prompt_out_changed = _prompt_trait_changed
357 _prompt_out_changed = _prompt_trait_changed
358 _prompt_pad_left_changed = _prompt_trait_changed
358 _prompt_pad_left_changed = _prompt_trait_changed
359
359
360 show_rewritten_input = CBool(True, config=True,
360 show_rewritten_input = CBool(True, config=True,
361 help="Show rewritten input, e.g. for autocall."
361 help="Show rewritten input, e.g. for autocall."
362 )
362 )
363
363
364 quiet = CBool(False, config=True)
364 quiet = CBool(False, config=True)
365
365
366 history_length = Integer(10000, config=True)
366 history_length = Integer(10000, config=True)
367
367
368 # The readline stuff will eventually be moved to the terminal subclass
368 # The readline stuff will eventually be moved to the terminal subclass
369 # but for now, we can't do that as readline is welded in everywhere.
369 # but for now, we can't do that as readline is welded in everywhere.
370 readline_use = CBool(True, config=True)
370 readline_use = CBool(True, config=True)
371 readline_remove_delims = Unicode('-/~', config=True)
371 readline_remove_delims = Unicode('-/~', config=True)
372 readline_delims = Unicode() # set by init_readline()
372 readline_delims = Unicode() # set by init_readline()
373 # don't use \M- bindings by default, because they
373 # don't use \M- bindings by default, because they
374 # conflict with 8-bit encodings. See gh-58,gh-88
374 # conflict with 8-bit encodings. See gh-58,gh-88
375 readline_parse_and_bind = List([
375 readline_parse_and_bind = List([
376 'tab: complete',
376 'tab: complete',
377 '"\C-l": clear-screen',
377 '"\C-l": clear-screen',
378 'set show-all-if-ambiguous on',
378 'set show-all-if-ambiguous on',
379 '"\C-o": tab-insert',
379 '"\C-o": tab-insert',
380 '"\C-r": reverse-search-history',
380 '"\C-r": reverse-search-history',
381 '"\C-s": forward-search-history',
381 '"\C-s": forward-search-history',
382 '"\C-p": history-search-backward',
382 '"\C-p": history-search-backward',
383 '"\C-n": history-search-forward',
383 '"\C-n": history-search-forward',
384 '"\e[A": history-search-backward',
384 '"\e[A": history-search-backward',
385 '"\e[B": history-search-forward',
385 '"\e[B": history-search-forward',
386 '"\C-k": kill-line',
386 '"\C-k": kill-line',
387 '"\C-u": unix-line-discard',
387 '"\C-u": unix-line-discard',
388 ], allow_none=False, config=True)
388 ], allow_none=False, config=True)
389
389
390 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
390 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
391 default_value='last_expr', config=True,
391 default_value='last_expr', config=True,
392 help="""
392 help="""
393 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
393 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
394 run interactively (displaying output from expressions).""")
394 run interactively (displaying output from expressions).""")
395
395
396 # TODO: this part of prompt management should be moved to the frontends.
396 # TODO: this part of prompt management should be moved to the frontends.
397 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
397 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
398 separate_in = SeparateUnicode('\n', config=True)
398 separate_in = SeparateUnicode('\n', config=True)
399 separate_out = SeparateUnicode('', config=True)
399 separate_out = SeparateUnicode('', config=True)
400 separate_out2 = SeparateUnicode('', config=True)
400 separate_out2 = SeparateUnicode('', config=True)
401 wildcards_case_sensitive = CBool(True, config=True)
401 wildcards_case_sensitive = CBool(True, config=True)
402 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
402 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
403 default_value='Context', config=True)
403 default_value='Context', config=True)
404
404
405 # Subcomponents of InteractiveShell
405 # Subcomponents of InteractiveShell
406 alias_manager = Instance('IPython.core.alias.AliasManager')
406 alias_manager = Instance('IPython.core.alias.AliasManager')
407 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
407 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
408 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
408 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
409 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
409 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
410 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
410 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
411 payload_manager = Instance('IPython.core.payload.PayloadManager')
411 payload_manager = Instance('IPython.core.payload.PayloadManager')
412 history_manager = Instance('IPython.core.history.HistoryManager')
412 history_manager = Instance('IPython.core.history.HistoryManager')
413 magics_manager = Instance('IPython.core.magic.MagicsManager')
413 magics_manager = Instance('IPython.core.magic.MagicsManager')
414
414
415 profile_dir = Instance('IPython.core.application.ProfileDir')
415 profile_dir = Instance('IPython.core.application.ProfileDir')
416 @property
416 @property
417 def profile(self):
417 def profile(self):
418 if self.profile_dir is not None:
418 if self.profile_dir is not None:
419 name = os.path.basename(self.profile_dir.location)
419 name = os.path.basename(self.profile_dir.location)
420 return name.replace('profile_','')
420 return name.replace('profile_','')
421
421
422
422
423 # Private interface
423 # Private interface
424 _post_execute = Instance(dict)
424 _post_execute = Instance(dict)
425
425
426 # Tracks any GUI loop loaded for pylab
426 # Tracks any GUI loop loaded for pylab
427 pylab_gui_select = None
427 pylab_gui_select = None
428
428
429 def __init__(self, ipython_dir=None, profile_dir=None,
429 def __init__(self, ipython_dir=None, profile_dir=None,
430 user_module=None, user_ns=None,
430 user_module=None, user_ns=None,
431 custom_exceptions=((), None), **kwargs):
431 custom_exceptions=((), None), **kwargs):
432
432
433 # This is where traits with a config_key argument are updated
433 # This is where traits with a config_key argument are updated
434 # from the values on config.
434 # from the values on config.
435 super(InteractiveShell, self).__init__(**kwargs)
435 super(InteractiveShell, self).__init__(**kwargs)
436 self.configurables = [self]
436 self.configurables = [self]
437
437
438 # These are relatively independent and stateless
438 # These are relatively independent and stateless
439 self.init_ipython_dir(ipython_dir)
439 self.init_ipython_dir(ipython_dir)
440 self.init_profile_dir(profile_dir)
440 self.init_profile_dir(profile_dir)
441 self.init_instance_attrs()
441 self.init_instance_attrs()
442 self.init_environment()
442 self.init_environment()
443
443
444 # Check if we're in a virtualenv, and set up sys.path.
444 # Check if we're in a virtualenv, and set up sys.path.
445 self.init_virtualenv()
445 self.init_virtualenv()
446
446
447 # Create namespaces (user_ns, user_global_ns, etc.)
447 # Create namespaces (user_ns, user_global_ns, etc.)
448 self.init_create_namespaces(user_module, user_ns)
448 self.init_create_namespaces(user_module, user_ns)
449 # This has to be done after init_create_namespaces because it uses
449 # This has to be done after init_create_namespaces because it uses
450 # something in self.user_ns, but before init_sys_modules, which
450 # something in self.user_ns, but before init_sys_modules, which
451 # is the first thing to modify sys.
451 # is the first thing to modify sys.
452 # TODO: When we override sys.stdout and sys.stderr before this class
452 # TODO: When we override sys.stdout and sys.stderr before this class
453 # is created, we are saving the overridden ones here. Not sure if this
453 # is created, we are saving the overridden ones here. Not sure if this
454 # is what we want to do.
454 # is what we want to do.
455 self.save_sys_module_state()
455 self.save_sys_module_state()
456 self.init_sys_modules()
456 self.init_sys_modules()
457
457
458 # While we're trying to have each part of the code directly access what
458 # While we're trying to have each part of the code directly access what
459 # it needs without keeping redundant references to objects, we have too
459 # it needs without keeping redundant references to objects, we have too
460 # much legacy code that expects ip.db to exist.
460 # much legacy code that expects ip.db to exist.
461 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
461 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
462
462
463 self.init_history()
463 self.init_history()
464 self.init_encoding()
464 self.init_encoding()
465 self.init_prefilter()
465 self.init_prefilter()
466
466
467 self.init_syntax_highlighting()
467 self.init_syntax_highlighting()
468 self.init_hooks()
468 self.init_hooks()
469 self.init_pushd_popd_magic()
469 self.init_pushd_popd_magic()
470 # self.init_traceback_handlers use to be here, but we moved it below
470 # self.init_traceback_handlers use to be here, but we moved it below
471 # because it and init_io have to come after init_readline.
471 # because it and init_io have to come after init_readline.
472 self.init_user_ns()
472 self.init_user_ns()
473 self.init_logger()
473 self.init_logger()
474 self.init_builtins()
474 self.init_builtins()
475
475
476 # The following was in post_config_initialization
476 # The following was in post_config_initialization
477 self.init_inspector()
477 self.init_inspector()
478 # init_readline() must come before init_io(), because init_io uses
478 # init_readline() must come before init_io(), because init_io uses
479 # readline related things.
479 # readline related things.
480 self.init_readline()
480 self.init_readline()
481 # We save this here in case user code replaces raw_input, but it needs
481 # We save this here in case user code replaces raw_input, but it needs
482 # to be after init_readline(), because PyPy's readline works by replacing
482 # to be after init_readline(), because PyPy's readline works by replacing
483 # raw_input.
483 # raw_input.
484 if py3compat.PY3:
484 if py3compat.PY3:
485 self.raw_input_original = input
485 self.raw_input_original = input
486 else:
486 else:
487 self.raw_input_original = raw_input
487 self.raw_input_original = raw_input
488 # init_completer must come after init_readline, because it needs to
488 # init_completer must come after init_readline, because it needs to
489 # know whether readline is present or not system-wide to configure the
489 # know whether readline is present or not system-wide to configure the
490 # completers, since the completion machinery can now operate
490 # completers, since the completion machinery can now operate
491 # independently of readline (e.g. over the network)
491 # independently of readline (e.g. over the network)
492 self.init_completer()
492 self.init_completer()
493 # TODO: init_io() needs to happen before init_traceback handlers
493 # TODO: init_io() needs to happen before init_traceback handlers
494 # because the traceback handlers hardcode the stdout/stderr streams.
494 # because the traceback handlers hardcode the stdout/stderr streams.
495 # This logic in in debugger.Pdb and should eventually be changed.
495 # This logic in in debugger.Pdb and should eventually be changed.
496 self.init_io()
496 self.init_io()
497 self.init_traceback_handlers(custom_exceptions)
497 self.init_traceback_handlers(custom_exceptions)
498 self.init_prompts()
498 self.init_prompts()
499 self.init_display_formatter()
499 self.init_display_formatter()
500 self.init_display_pub()
500 self.init_display_pub()
501 self.init_data_pub()
501 self.init_data_pub()
502 self.init_displayhook()
502 self.init_displayhook()
503 self.init_latextool()
503 self.init_latextool()
504 self.init_magics()
504 self.init_magics()
505 self.init_alias()
505 self.init_alias()
506 self.init_logstart()
506 self.init_logstart()
507 self.init_pdb()
507 self.init_pdb()
508 self.init_extension_manager()
508 self.init_extension_manager()
509 self.init_payload()
509 self.init_payload()
510 self.init_comms()
510 self.init_comms()
511 self.hooks.late_startup_hook()
511 self.hooks.late_startup_hook()
512 atexit.register(self.atexit_operations)
512 atexit.register(self.atexit_operations)
513
513
514 def get_ipython(self):
514 def get_ipython(self):
515 """Return the currently running IPython instance."""
515 """Return the currently running IPython instance."""
516 return self
516 return self
517
517
518 #-------------------------------------------------------------------------
518 #-------------------------------------------------------------------------
519 # Trait changed handlers
519 # Trait changed handlers
520 #-------------------------------------------------------------------------
520 #-------------------------------------------------------------------------
521
521
522 def _ipython_dir_changed(self, name, new):
522 def _ipython_dir_changed(self, name, new):
523 if not os.path.isdir(new):
523 if not os.path.isdir(new):
524 os.makedirs(new, mode = 0o777)
524 os.makedirs(new, mode = 0o777)
525
525
526 def set_autoindent(self,value=None):
526 def set_autoindent(self,value=None):
527 """Set the autoindent flag, checking for readline support.
527 """Set the autoindent flag, checking for readline support.
528
528
529 If called with no arguments, it acts as a toggle."""
529 If called with no arguments, it acts as a toggle."""
530
530
531 if value != 0 and not self.has_readline:
531 if value != 0 and not self.has_readline:
532 if os.name == 'posix':
532 if os.name == 'posix':
533 warn("The auto-indent feature requires the readline library")
533 warn("The auto-indent feature requires the readline library")
534 self.autoindent = 0
534 self.autoindent = 0
535 return
535 return
536 if value is None:
536 if value is None:
537 self.autoindent = not self.autoindent
537 self.autoindent = not self.autoindent
538 else:
538 else:
539 self.autoindent = value
539 self.autoindent = value
540
540
541 #-------------------------------------------------------------------------
541 #-------------------------------------------------------------------------
542 # init_* methods called by __init__
542 # init_* methods called by __init__
543 #-------------------------------------------------------------------------
543 #-------------------------------------------------------------------------
544
544
545 def init_ipython_dir(self, ipython_dir):
545 def init_ipython_dir(self, ipython_dir):
546 if ipython_dir is not None:
546 if ipython_dir is not None:
547 self.ipython_dir = ipython_dir
547 self.ipython_dir = ipython_dir
548 return
548 return
549
549
550 self.ipython_dir = get_ipython_dir()
550 self.ipython_dir = get_ipython_dir()
551
551
552 def init_profile_dir(self, profile_dir):
552 def init_profile_dir(self, profile_dir):
553 if profile_dir is not None:
553 if profile_dir is not None:
554 self.profile_dir = profile_dir
554 self.profile_dir = profile_dir
555 return
555 return
556 self.profile_dir =\
556 self.profile_dir =\
557 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
557 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
558
558
559 def init_instance_attrs(self):
559 def init_instance_attrs(self):
560 self.more = False
560 self.more = False
561
561
562 # command compiler
562 # command compiler
563 self.compile = CachingCompiler()
563 self.compile = CachingCompiler()
564
564
565 # Make an empty namespace, which extension writers can rely on both
565 # Make an empty namespace, which extension writers can rely on both
566 # existing and NEVER being used by ipython itself. This gives them a
566 # existing and NEVER being used by ipython itself. This gives them a
567 # convenient location for storing additional information and state
567 # convenient location for storing additional information and state
568 # their extensions may require, without fear of collisions with other
568 # their extensions may require, without fear of collisions with other
569 # ipython names that may develop later.
569 # ipython names that may develop later.
570 self.meta = Struct()
570 self.meta = Struct()
571
571
572 # Temporary files used for various purposes. Deleted at exit.
572 # Temporary files used for various purposes. Deleted at exit.
573 self.tempfiles = []
573 self.tempfiles = []
574
574
575 # Keep track of readline usage (later set by init_readline)
575 # Keep track of readline usage (later set by init_readline)
576 self.has_readline = False
576 self.has_readline = False
577
577
578 # keep track of where we started running (mainly for crash post-mortem)
578 # keep track of where we started running (mainly for crash post-mortem)
579 # This is not being used anywhere currently.
579 # This is not being used anywhere currently.
580 self.starting_dir = os.getcwdu()
580 self.starting_dir = os.getcwdu()
581
581
582 # Indentation management
582 # Indentation management
583 self.indent_current_nsp = 0
583 self.indent_current_nsp = 0
584
584
585 # Dict to track post-execution functions that have been registered
585 # Dict to track post-execution functions that have been registered
586 self._post_execute = {}
586 self._post_execute = {}
587
587
588 def init_environment(self):
588 def init_environment(self):
589 """Any changes we need to make to the user's environment."""
589 """Any changes we need to make to the user's environment."""
590 pass
590 pass
591
591
592 def init_encoding(self):
592 def init_encoding(self):
593 # Get system encoding at startup time. Certain terminals (like Emacs
593 # Get system encoding at startup time. Certain terminals (like Emacs
594 # under Win32 have it set to None, and we need to have a known valid
594 # under Win32 have it set to None, and we need to have a known valid
595 # encoding to use in the raw_input() method
595 # encoding to use in the raw_input() method
596 try:
596 try:
597 self.stdin_encoding = sys.stdin.encoding or 'ascii'
597 self.stdin_encoding = sys.stdin.encoding or 'ascii'
598 except AttributeError:
598 except AttributeError:
599 self.stdin_encoding = 'ascii'
599 self.stdin_encoding = 'ascii'
600
600
601 def init_syntax_highlighting(self):
601 def init_syntax_highlighting(self):
602 # Python source parser/formatter for syntax highlighting
602 # Python source parser/formatter for syntax highlighting
603 pyformat = PyColorize.Parser().format
603 pyformat = PyColorize.Parser().format
604 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
604 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
605
605
606 def init_pushd_popd_magic(self):
606 def init_pushd_popd_magic(self):
607 # for pushd/popd management
607 # for pushd/popd management
608 self.home_dir = get_home_dir()
608 self.home_dir = get_home_dir()
609
609
610 self.dir_stack = []
610 self.dir_stack = []
611
611
612 def init_logger(self):
612 def init_logger(self):
613 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
613 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
614 logmode='rotate')
614 logmode='rotate')
615
615
616 def init_logstart(self):
616 def init_logstart(self):
617 """Initialize logging in case it was requested at the command line.
617 """Initialize logging in case it was requested at the command line.
618 """
618 """
619 if self.logappend:
619 if self.logappend:
620 self.magic('logstart %s append' % self.logappend)
620 self.magic('logstart %s append' % self.logappend)
621 elif self.logfile:
621 elif self.logfile:
622 self.magic('logstart %s' % self.logfile)
622 self.magic('logstart %s' % self.logfile)
623 elif self.logstart:
623 elif self.logstart:
624 self.magic('logstart')
624 self.magic('logstart')
625
625
626 def init_builtins(self):
626 def init_builtins(self):
627 # A single, static flag that we set to True. Its presence indicates
627 # A single, static flag that we set to True. Its presence indicates
628 # that an IPython shell has been created, and we make no attempts at
628 # that an IPython shell has been created, and we make no attempts at
629 # removing on exit or representing the existence of more than one
629 # removing on exit or representing the existence of more than one
630 # IPython at a time.
630 # IPython at a time.
631 builtin_mod.__dict__['__IPYTHON__'] = True
631 builtin_mod.__dict__['__IPYTHON__'] = True
632
632
633 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
633 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
634 # manage on enter/exit, but with all our shells it's virtually
634 # manage on enter/exit, but with all our shells it's virtually
635 # impossible to get all the cases right. We're leaving the name in for
635 # impossible to get all the cases right. We're leaving the name in for
636 # those who adapted their codes to check for this flag, but will
636 # those who adapted their codes to check for this flag, but will
637 # eventually remove it after a few more releases.
637 # eventually remove it after a few more releases.
638 builtin_mod.__dict__['__IPYTHON__active'] = \
638 builtin_mod.__dict__['__IPYTHON__active'] = \
639 'Deprecated, check for __IPYTHON__'
639 'Deprecated, check for __IPYTHON__'
640
640
641 self.builtin_trap = BuiltinTrap(shell=self)
641 self.builtin_trap = BuiltinTrap(shell=self)
642
642
643 def init_inspector(self):
643 def init_inspector(self):
644 # Object inspector
644 # Object inspector
645 self.inspector = oinspect.Inspector(oinspect.InspectColors,
645 self.inspector = oinspect.Inspector(oinspect.InspectColors,
646 PyColorize.ANSICodeColors,
646 PyColorize.ANSICodeColors,
647 'NoColor',
647 'NoColor',
648 self.object_info_string_level)
648 self.object_info_string_level)
649
649
650 def init_io(self):
650 def init_io(self):
651 # This will just use sys.stdout and sys.stderr. If you want to
651 # This will just use sys.stdout and sys.stderr. If you want to
652 # override sys.stdout and sys.stderr themselves, you need to do that
652 # override sys.stdout and sys.stderr themselves, you need to do that
653 # *before* instantiating this class, because io holds onto
653 # *before* instantiating this class, because io holds onto
654 # references to the underlying streams.
654 # references to the underlying streams.
655 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
655 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
656 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
656 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
657 else:
657 else:
658 io.stdout = io.IOStream(sys.stdout)
658 io.stdout = io.IOStream(sys.stdout)
659 io.stderr = io.IOStream(sys.stderr)
659 io.stderr = io.IOStream(sys.stderr)
660
660
661 def init_prompts(self):
661 def init_prompts(self):
662 self.prompt_manager = PromptManager(shell=self, parent=self)
662 self.prompt_manager = PromptManager(shell=self, parent=self)
663 self.configurables.append(self.prompt_manager)
663 self.configurables.append(self.prompt_manager)
664 # Set system prompts, so that scripts can decide if they are running
664 # Set system prompts, so that scripts can decide if they are running
665 # interactively.
665 # interactively.
666 sys.ps1 = 'In : '
666 sys.ps1 = 'In : '
667 sys.ps2 = '...: '
667 sys.ps2 = '...: '
668 sys.ps3 = 'Out: '
668 sys.ps3 = 'Out: '
669
669
670 def init_display_formatter(self):
670 def init_display_formatter(self):
671 self.display_formatter = DisplayFormatter(parent=self)
671 self.display_formatter = DisplayFormatter(parent=self)
672 self.configurables.append(self.display_formatter)
672 self.configurables.append(self.display_formatter)
673
673
674 def init_display_pub(self):
674 def init_display_pub(self):
675 self.display_pub = self.display_pub_class(parent=self)
675 self.display_pub = self.display_pub_class(parent=self)
676 self.configurables.append(self.display_pub)
676 self.configurables.append(self.display_pub)
677
677
678 def init_data_pub(self):
678 def init_data_pub(self):
679 if not self.data_pub_class:
679 if not self.data_pub_class:
680 self.data_pub = None
680 self.data_pub = None
681 return
681 return
682 self.data_pub = self.data_pub_class(parent=self)
682 self.data_pub = self.data_pub_class(parent=self)
683 self.configurables.append(self.data_pub)
683 self.configurables.append(self.data_pub)
684
684
685 def init_displayhook(self):
685 def init_displayhook(self):
686 # Initialize displayhook, set in/out prompts and printing system
686 # Initialize displayhook, set in/out prompts and printing system
687 self.displayhook = self.displayhook_class(
687 self.displayhook = self.displayhook_class(
688 parent=self,
688 parent=self,
689 shell=self,
689 shell=self,
690 cache_size=self.cache_size,
690 cache_size=self.cache_size,
691 )
691 )
692 self.configurables.append(self.displayhook)
692 self.configurables.append(self.displayhook)
693 # This is a context manager that installs/revmoes the displayhook at
693 # This is a context manager that installs/revmoes the displayhook at
694 # the appropriate time.
694 # the appropriate time.
695 self.display_trap = DisplayTrap(hook=self.displayhook)
695 self.display_trap = DisplayTrap(hook=self.displayhook)
696
696
697 def init_latextool(self):
697 def init_latextool(self):
698 """Configure LaTeXTool."""
698 """Configure LaTeXTool."""
699 cfg = LaTeXTool.instance(parent=self)
699 cfg = LaTeXTool.instance(parent=self)
700 if cfg not in self.configurables:
700 if cfg not in self.configurables:
701 self.configurables.append(cfg)
701 self.configurables.append(cfg)
702
702
703 def init_virtualenv(self):
703 def init_virtualenv(self):
704 """Add a virtualenv to sys.path so the user can import modules from it.
704 """Add a virtualenv to sys.path so the user can import modules from it.
705 This isn't perfect: it doesn't use the Python interpreter with which the
705 This isn't perfect: it doesn't use the Python interpreter with which the
706 virtualenv was built, and it ignores the --no-site-packages option. A
706 virtualenv was built, and it ignores the --no-site-packages option. A
707 warning will appear suggesting the user installs IPython in the
707 warning will appear suggesting the user installs IPython in the
708 virtualenv, but for many cases, it probably works well enough.
708 virtualenv, but for many cases, it probably works well enough.
709
709
710 Adapted from code snippets online.
710 Adapted from code snippets online.
711
711
712 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
712 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
713 """
713 """
714 if 'VIRTUAL_ENV' not in os.environ:
714 if 'VIRTUAL_ENV' not in os.environ:
715 # Not in a virtualenv
715 # Not in a virtualenv
716 return
716 return
717
717
718 if sys.executable.startswith(os.environ['VIRTUAL_ENV']):
718 if sys.executable.startswith(os.environ['VIRTUAL_ENV']):
719 # Running properly in the virtualenv, don't need to do anything
719 # Running properly in the virtualenv, don't need to do anything
720 return
720 return
721
721
722 warn("Attempting to work in a virtualenv. If you encounter problems, please "
722 warn("Attempting to work in a virtualenv. If you encounter problems, please "
723 "install IPython inside the virtualenv.")
723 "install IPython inside the virtualenv.")
724 if sys.platform == "win32":
724 if sys.platform == "win32":
725 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
725 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
726 else:
726 else:
727 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
727 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
728 'python%d.%d' % sys.version_info[:2], 'site-packages')
728 'python%d.%d' % sys.version_info[:2], 'site-packages')
729
729
730 import site
730 import site
731 sys.path.insert(0, virtual_env)
731 sys.path.insert(0, virtual_env)
732 site.addsitedir(virtual_env)
732 site.addsitedir(virtual_env)
733
733
734 #-------------------------------------------------------------------------
734 #-------------------------------------------------------------------------
735 # Things related to injections into the sys module
735 # Things related to injections into the sys module
736 #-------------------------------------------------------------------------
736 #-------------------------------------------------------------------------
737
737
738 def save_sys_module_state(self):
738 def save_sys_module_state(self):
739 """Save the state of hooks in the sys module.
739 """Save the state of hooks in the sys module.
740
740
741 This has to be called after self.user_module is created.
741 This has to be called after self.user_module is created.
742 """
742 """
743 self._orig_sys_module_state = {}
743 self._orig_sys_module_state = {}
744 self._orig_sys_module_state['stdin'] = sys.stdin
744 self._orig_sys_module_state['stdin'] = sys.stdin
745 self._orig_sys_module_state['stdout'] = sys.stdout
745 self._orig_sys_module_state['stdout'] = sys.stdout
746 self._orig_sys_module_state['stderr'] = sys.stderr
746 self._orig_sys_module_state['stderr'] = sys.stderr
747 self._orig_sys_module_state['excepthook'] = sys.excepthook
747 self._orig_sys_module_state['excepthook'] = sys.excepthook
748 self._orig_sys_modules_main_name = self.user_module.__name__
748 self._orig_sys_modules_main_name = self.user_module.__name__
749 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
749 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
750
750
751 def restore_sys_module_state(self):
751 def restore_sys_module_state(self):
752 """Restore the state of the sys module."""
752 """Restore the state of the sys module."""
753 try:
753 try:
754 for k, v in self._orig_sys_module_state.iteritems():
754 for k, v in self._orig_sys_module_state.iteritems():
755 setattr(sys, k, v)
755 setattr(sys, k, v)
756 except AttributeError:
756 except AttributeError:
757 pass
757 pass
758 # Reset what what done in self.init_sys_modules
758 # Reset what what done in self.init_sys_modules
759 if self._orig_sys_modules_main_mod is not None:
759 if self._orig_sys_modules_main_mod is not None:
760 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
760 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
761
761
762 #-------------------------------------------------------------------------
762 #-------------------------------------------------------------------------
763 # Things related to hooks
763 # Things related to hooks
764 #-------------------------------------------------------------------------
764 #-------------------------------------------------------------------------
765
765
766 def init_hooks(self):
766 def init_hooks(self):
767 # hooks holds pointers used for user-side customizations
767 # hooks holds pointers used for user-side customizations
768 self.hooks = Struct()
768 self.hooks = Struct()
769
769
770 self.strdispatchers = {}
770 self.strdispatchers = {}
771
771
772 # Set all default hooks, defined in the IPython.hooks module.
772 # Set all default hooks, defined in the IPython.hooks module.
773 hooks = IPython.core.hooks
773 hooks = IPython.core.hooks
774 for hook_name in hooks.__all__:
774 for hook_name in hooks.__all__:
775 # default hooks have priority 100, i.e. low; user hooks should have
775 # default hooks have priority 100, i.e. low; user hooks should have
776 # 0-100 priority
776 # 0-100 priority
777 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
777 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
778
778
779 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
779 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
780 """set_hook(name,hook) -> sets an internal IPython hook.
780 """set_hook(name,hook) -> sets an internal IPython hook.
781
781
782 IPython exposes some of its internal API as user-modifiable hooks. By
782 IPython exposes some of its internal API as user-modifiable hooks. By
783 adding your function to one of these hooks, you can modify IPython's
783 adding your function to one of these hooks, you can modify IPython's
784 behavior to call at runtime your own routines."""
784 behavior to call at runtime your own routines."""
785
785
786 # At some point in the future, this should validate the hook before it
786 # At some point in the future, this should validate the hook before it
787 # accepts it. Probably at least check that the hook takes the number
787 # accepts it. Probably at least check that the hook takes the number
788 # of args it's supposed to.
788 # of args it's supposed to.
789
789
790 f = types.MethodType(hook,self)
790 f = types.MethodType(hook,self)
791
791
792 # check if the hook is for strdispatcher first
792 # check if the hook is for strdispatcher first
793 if str_key is not None:
793 if str_key is not None:
794 sdp = self.strdispatchers.get(name, StrDispatch())
794 sdp = self.strdispatchers.get(name, StrDispatch())
795 sdp.add_s(str_key, f, priority )
795 sdp.add_s(str_key, f, priority )
796 self.strdispatchers[name] = sdp
796 self.strdispatchers[name] = sdp
797 return
797 return
798 if re_key is not None:
798 if re_key is not None:
799 sdp = self.strdispatchers.get(name, StrDispatch())
799 sdp = self.strdispatchers.get(name, StrDispatch())
800 sdp.add_re(re.compile(re_key), f, priority )
800 sdp.add_re(re.compile(re_key), f, priority )
801 self.strdispatchers[name] = sdp
801 self.strdispatchers[name] = sdp
802 return
802 return
803
803
804 dp = getattr(self.hooks, name, None)
804 dp = getattr(self.hooks, name, None)
805 if name not in IPython.core.hooks.__all__:
805 if name not in IPython.core.hooks.__all__:
806 print("Warning! Hook '%s' is not one of %s" % \
806 print("Warning! Hook '%s' is not one of %s" % \
807 (name, IPython.core.hooks.__all__ ))
807 (name, IPython.core.hooks.__all__ ))
808 if not dp:
808 if not dp:
809 dp = IPython.core.hooks.CommandChainDispatcher()
809 dp = IPython.core.hooks.CommandChainDispatcher()
810
810
811 try:
811 try:
812 dp.add(f,priority)
812 dp.add(f,priority)
813 except AttributeError:
813 except AttributeError:
814 # it was not commandchain, plain old func - replace
814 # it was not commandchain, plain old func - replace
815 dp = f
815 dp = f
816
816
817 setattr(self.hooks,name, dp)
817 setattr(self.hooks,name, dp)
818
818
819 def register_post_execute(self, func):
819 def register_post_execute(self, func):
820 """Register a function for calling after code execution.
820 """Register a function for calling after code execution.
821 """
821 """
822 if not callable(func):
822 if not callable(func):
823 raise ValueError('argument %s must be callable' % func)
823 raise ValueError('argument %s must be callable' % func)
824 self._post_execute[func] = True
824 self._post_execute[func] = True
825
825
826 #-------------------------------------------------------------------------
826 #-------------------------------------------------------------------------
827 # Things related to the "main" module
827 # Things related to the "main" module
828 #-------------------------------------------------------------------------
828 #-------------------------------------------------------------------------
829
829
830 def new_main_mod(self, filename, modname):
830 def new_main_mod(self, filename, modname):
831 """Return a new 'main' module object for user code execution.
831 """Return a new 'main' module object for user code execution.
832
832
833 ``filename`` should be the path of the script which will be run in the
833 ``filename`` should be the path of the script which will be run in the
834 module. Requests with the same filename will get the same module, with
834 module. Requests with the same filename will get the same module, with
835 its namespace cleared.
835 its namespace cleared.
836
836
837 ``modname`` should be the module name - normally either '__main__' or
837 ``modname`` should be the module name - normally either '__main__' or
838 the basename of the file without the extension.
838 the basename of the file without the extension.
839
839
840 When scripts are executed via %run, we must keep a reference to their
840 When scripts are executed via %run, we must keep a reference to their
841 __main__ module around so that Python doesn't
841 __main__ module around so that Python doesn't
842 clear it, rendering references to module globals useless.
842 clear it, rendering references to module globals useless.
843
843
844 This method keeps said reference in a private dict, keyed by the
844 This method keeps said reference in a private dict, keyed by the
845 absolute path of the script. This way, for multiple executions of the
845 absolute path of the script. This way, for multiple executions of the
846 same script we only keep one copy of the namespace (the last one),
846 same script we only keep one copy of the namespace (the last one),
847 thus preventing memory leaks from old references while allowing the
847 thus preventing memory leaks from old references while allowing the
848 objects from the last execution to be accessible.
848 objects from the last execution to be accessible.
849 """
849 """
850 filename = os.path.abspath(filename)
850 filename = os.path.abspath(filename)
851 try:
851 try:
852 main_mod = self._main_mod_cache[filename]
852 main_mod = self._main_mod_cache[filename]
853 except KeyError:
853 except KeyError:
854 main_mod = self._main_mod_cache[filename] = types.ModuleType(modname,
854 main_mod = self._main_mod_cache[filename] = types.ModuleType(modname,
855 doc="Module created for script run in IPython")
855 doc="Module created for script run in IPython")
856 else:
856 else:
857 main_mod.__dict__.clear()
857 main_mod.__dict__.clear()
858 main_mod.__name__ = modname
858 main_mod.__name__ = modname
859
859
860 main_mod.__file__ = filename
860 main_mod.__file__ = filename
861 # It seems pydoc (and perhaps others) needs any module instance to
861 # It seems pydoc (and perhaps others) needs any module instance to
862 # implement a __nonzero__ method
862 # implement a __nonzero__ method
863 main_mod.__nonzero__ = lambda : True
863 main_mod.__nonzero__ = lambda : True
864
864
865 return main_mod
865 return main_mod
866
866
867 def clear_main_mod_cache(self):
867 def clear_main_mod_cache(self):
868 """Clear the cache of main modules.
868 """Clear the cache of main modules.
869
869
870 Mainly for use by utilities like %reset.
870 Mainly for use by utilities like %reset.
871
871
872 Examples
872 Examples
873 --------
873 --------
874
874
875 In [15]: import IPython
875 In [15]: import IPython
876
876
877 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
877 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
878
878
879 In [17]: len(_ip._main_mod_cache) > 0
879 In [17]: len(_ip._main_mod_cache) > 0
880 Out[17]: True
880 Out[17]: True
881
881
882 In [18]: _ip.clear_main_mod_cache()
882 In [18]: _ip.clear_main_mod_cache()
883
883
884 In [19]: len(_ip._main_mod_cache) == 0
884 In [19]: len(_ip._main_mod_cache) == 0
885 Out[19]: True
885 Out[19]: True
886 """
886 """
887 self._main_mod_cache.clear()
887 self._main_mod_cache.clear()
888
888
889 #-------------------------------------------------------------------------
889 #-------------------------------------------------------------------------
890 # Things related to debugging
890 # Things related to debugging
891 #-------------------------------------------------------------------------
891 #-------------------------------------------------------------------------
892
892
893 def init_pdb(self):
893 def init_pdb(self):
894 # Set calling of pdb on exceptions
894 # Set calling of pdb on exceptions
895 # self.call_pdb is a property
895 # self.call_pdb is a property
896 self.call_pdb = self.pdb
896 self.call_pdb = self.pdb
897
897
898 def _get_call_pdb(self):
898 def _get_call_pdb(self):
899 return self._call_pdb
899 return self._call_pdb
900
900
901 def _set_call_pdb(self,val):
901 def _set_call_pdb(self,val):
902
902
903 if val not in (0,1,False,True):
903 if val not in (0,1,False,True):
904 raise ValueError('new call_pdb value must be boolean')
904 raise ValueError('new call_pdb value must be boolean')
905
905
906 # store value in instance
906 # store value in instance
907 self._call_pdb = val
907 self._call_pdb = val
908
908
909 # notify the actual exception handlers
909 # notify the actual exception handlers
910 self.InteractiveTB.call_pdb = val
910 self.InteractiveTB.call_pdb = val
911
911
912 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
912 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
913 'Control auto-activation of pdb at exceptions')
913 'Control auto-activation of pdb at exceptions')
914
914
915 def debugger(self,force=False):
915 def debugger(self,force=False):
916 """Call the pydb/pdb debugger.
916 """Call the pydb/pdb debugger.
917
917
918 Keywords:
918 Keywords:
919
919
920 - force(False): by default, this routine checks the instance call_pdb
920 - force(False): by default, this routine checks the instance call_pdb
921 flag and does not actually invoke the debugger if the flag is false.
921 flag and does not actually invoke the debugger if the flag is false.
922 The 'force' option forces the debugger to activate even if the flag
922 The 'force' option forces the debugger to activate even if the flag
923 is false.
923 is false.
924 """
924 """
925
925
926 if not (force or self.call_pdb):
926 if not (force or self.call_pdb):
927 return
927 return
928
928
929 if not hasattr(sys,'last_traceback'):
929 if not hasattr(sys,'last_traceback'):
930 error('No traceback has been produced, nothing to debug.')
930 error('No traceback has been produced, nothing to debug.')
931 return
931 return
932
932
933 # use pydb if available
933 # use pydb if available
934 if debugger.has_pydb:
934 if debugger.has_pydb:
935 from pydb import pm
935 from pydb import pm
936 else:
936 else:
937 # fallback to our internal debugger
937 # fallback to our internal debugger
938 pm = lambda : self.InteractiveTB.debugger(force=True)
938 pm = lambda : self.InteractiveTB.debugger(force=True)
939
939
940 with self.readline_no_record:
940 with self.readline_no_record:
941 pm()
941 pm()
942
942
943 #-------------------------------------------------------------------------
943 #-------------------------------------------------------------------------
944 # Things related to IPython's various namespaces
944 # Things related to IPython's various namespaces
945 #-------------------------------------------------------------------------
945 #-------------------------------------------------------------------------
946 default_user_namespaces = True
946 default_user_namespaces = True
947
947
948 def init_create_namespaces(self, user_module=None, user_ns=None):
948 def init_create_namespaces(self, user_module=None, user_ns=None):
949 # Create the namespace where the user will operate. user_ns is
949 # Create the namespace where the user will operate. user_ns is
950 # normally the only one used, and it is passed to the exec calls as
950 # normally the only one used, and it is passed to the exec calls as
951 # the locals argument. But we do carry a user_global_ns namespace
951 # the locals argument. But we do carry a user_global_ns namespace
952 # given as the exec 'globals' argument, This is useful in embedding
952 # given as the exec 'globals' argument, This is useful in embedding
953 # situations where the ipython shell opens in a context where the
953 # situations where the ipython shell opens in a context where the
954 # distinction between locals and globals is meaningful. For
954 # distinction between locals and globals is meaningful. For
955 # non-embedded contexts, it is just the same object as the user_ns dict.
955 # non-embedded contexts, it is just the same object as the user_ns dict.
956
956
957 # FIXME. For some strange reason, __builtins__ is showing up at user
957 # FIXME. For some strange reason, __builtins__ is showing up at user
958 # level as a dict instead of a module. This is a manual fix, but I
958 # level as a dict instead of a module. This is a manual fix, but I
959 # should really track down where the problem is coming from. Alex
959 # should really track down where the problem is coming from. Alex
960 # Schmolck reported this problem first.
960 # Schmolck reported this problem first.
961
961
962 # A useful post by Alex Martelli on this topic:
962 # A useful post by Alex Martelli on this topic:
963 # Re: inconsistent value from __builtins__
963 # Re: inconsistent value from __builtins__
964 # Von: Alex Martelli <aleaxit@yahoo.com>
964 # Von: Alex Martelli <aleaxit@yahoo.com>
965 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
965 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
966 # Gruppen: comp.lang.python
966 # Gruppen: comp.lang.python
967
967
968 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
968 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
969 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
969 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
970 # > <type 'dict'>
970 # > <type 'dict'>
971 # > >>> print type(__builtins__)
971 # > >>> print type(__builtins__)
972 # > <type 'module'>
972 # > <type 'module'>
973 # > Is this difference in return value intentional?
973 # > Is this difference in return value intentional?
974
974
975 # Well, it's documented that '__builtins__' can be either a dictionary
975 # Well, it's documented that '__builtins__' can be either a dictionary
976 # or a module, and it's been that way for a long time. Whether it's
976 # or a module, and it's been that way for a long time. Whether it's
977 # intentional (or sensible), I don't know. In any case, the idea is
977 # intentional (or sensible), I don't know. In any case, the idea is
978 # that if you need to access the built-in namespace directly, you
978 # that if you need to access the built-in namespace directly, you
979 # should start with "import __builtin__" (note, no 's') which will
979 # should start with "import __builtin__" (note, no 's') which will
980 # definitely give you a module. Yeah, it's somewhat confusing:-(.
980 # definitely give you a module. Yeah, it's somewhat confusing:-(.
981
981
982 # These routines return a properly built module and dict as needed by
982 # These routines return a properly built module and dict as needed by
983 # the rest of the code, and can also be used by extension writers to
983 # the rest of the code, and can also be used by extension writers to
984 # generate properly initialized namespaces.
984 # generate properly initialized namespaces.
985 if (user_ns is not None) or (user_module is not None):
985 if (user_ns is not None) or (user_module is not None):
986 self.default_user_namespaces = False
986 self.default_user_namespaces = False
987 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
987 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
988
988
989 # A record of hidden variables we have added to the user namespace, so
989 # A record of hidden variables we have added to the user namespace, so
990 # we can list later only variables defined in actual interactive use.
990 # we can list later only variables defined in actual interactive use.
991 self.user_ns_hidden = {}
991 self.user_ns_hidden = {}
992
992
993 # Now that FakeModule produces a real module, we've run into a nasty
993 # Now that FakeModule produces a real module, we've run into a nasty
994 # problem: after script execution (via %run), the module where the user
994 # problem: after script execution (via %run), the module where the user
995 # code ran is deleted. Now that this object is a true module (needed
995 # code ran is deleted. Now that this object is a true module (needed
996 # so docetst and other tools work correctly), the Python module
996 # so docetst and other tools work correctly), the Python module
997 # teardown mechanism runs over it, and sets to None every variable
997 # teardown mechanism runs over it, and sets to None every variable
998 # present in that module. Top-level references to objects from the
998 # present in that module. Top-level references to objects from the
999 # script survive, because the user_ns is updated with them. However,
999 # script survive, because the user_ns is updated with them. However,
1000 # calling functions defined in the script that use other things from
1000 # calling functions defined in the script that use other things from
1001 # the script will fail, because the function's closure had references
1001 # the script will fail, because the function's closure had references
1002 # to the original objects, which are now all None. So we must protect
1002 # to the original objects, which are now all None. So we must protect
1003 # these modules from deletion by keeping a cache.
1003 # these modules from deletion by keeping a cache.
1004 #
1004 #
1005 # To avoid keeping stale modules around (we only need the one from the
1005 # To avoid keeping stale modules around (we only need the one from the
1006 # last run), we use a dict keyed with the full path to the script, so
1006 # last run), we use a dict keyed with the full path to the script, so
1007 # only the last version of the module is held in the cache. Note,
1007 # only the last version of the module is held in the cache. Note,
1008 # however, that we must cache the module *namespace contents* (their
1008 # however, that we must cache the module *namespace contents* (their
1009 # __dict__). Because if we try to cache the actual modules, old ones
1009 # __dict__). Because if we try to cache the actual modules, old ones
1010 # (uncached) could be destroyed while still holding references (such as
1010 # (uncached) could be destroyed while still holding references (such as
1011 # those held by GUI objects that tend to be long-lived)>
1011 # those held by GUI objects that tend to be long-lived)>
1012 #
1012 #
1013 # The %reset command will flush this cache. See the cache_main_mod()
1013 # The %reset command will flush this cache. See the cache_main_mod()
1014 # and clear_main_mod_cache() methods for details on use.
1014 # and clear_main_mod_cache() methods for details on use.
1015
1015
1016 # This is the cache used for 'main' namespaces
1016 # This is the cache used for 'main' namespaces
1017 self._main_mod_cache = {}
1017 self._main_mod_cache = {}
1018
1018
1019 # A table holding all the namespaces IPython deals with, so that
1019 # A table holding all the namespaces IPython deals with, so that
1020 # introspection facilities can search easily.
1020 # introspection facilities can search easily.
1021 self.ns_table = {'user_global':self.user_module.__dict__,
1021 self.ns_table = {'user_global':self.user_module.__dict__,
1022 'user_local':self.user_ns,
1022 'user_local':self.user_ns,
1023 'builtin':builtin_mod.__dict__
1023 'builtin':builtin_mod.__dict__
1024 }
1024 }
1025
1025
1026 @property
1026 @property
1027 def user_global_ns(self):
1027 def user_global_ns(self):
1028 return self.user_module.__dict__
1028 return self.user_module.__dict__
1029
1029
1030 def prepare_user_module(self, user_module=None, user_ns=None):
1030 def prepare_user_module(self, user_module=None, user_ns=None):
1031 """Prepare the module and namespace in which user code will be run.
1031 """Prepare the module and namespace in which user code will be run.
1032
1032
1033 When IPython is started normally, both parameters are None: a new module
1033 When IPython is started normally, both parameters are None: a new module
1034 is created automatically, and its __dict__ used as the namespace.
1034 is created automatically, and its __dict__ used as the namespace.
1035
1035
1036 If only user_module is provided, its __dict__ is used as the namespace.
1036 If only user_module is provided, its __dict__ is used as the namespace.
1037 If only user_ns is provided, a dummy module is created, and user_ns
1037 If only user_ns is provided, a dummy module is created, and user_ns
1038 becomes the global namespace. If both are provided (as they may be
1038 becomes the global namespace. If both are provided (as they may be
1039 when embedding), user_ns is the local namespace, and user_module
1039 when embedding), user_ns is the local namespace, and user_module
1040 provides the global namespace.
1040 provides the global namespace.
1041
1041
1042 Parameters
1042 Parameters
1043 ----------
1043 ----------
1044 user_module : module, optional
1044 user_module : module, optional
1045 The current user module in which IPython is being run. If None,
1045 The current user module in which IPython is being run. If None,
1046 a clean module will be created.
1046 a clean module will be created.
1047 user_ns : dict, optional
1047 user_ns : dict, optional
1048 A namespace in which to run interactive commands.
1048 A namespace in which to run interactive commands.
1049
1049
1050 Returns
1050 Returns
1051 -------
1051 -------
1052 A tuple of user_module and user_ns, each properly initialised.
1052 A tuple of user_module and user_ns, each properly initialised.
1053 """
1053 """
1054 if user_module is None and user_ns is not None:
1054 if user_module is None and user_ns is not None:
1055 user_ns.setdefault("__name__", "__main__")
1055 user_ns.setdefault("__name__", "__main__")
1056 user_module = DummyMod()
1056 user_module = DummyMod()
1057 user_module.__dict__ = user_ns
1057 user_module.__dict__ = user_ns
1058
1058
1059 if user_module is None:
1059 if user_module is None:
1060 user_module = types.ModuleType("__main__",
1060 user_module = types.ModuleType("__main__",
1061 doc="Automatically created module for IPython interactive environment")
1061 doc="Automatically created module for IPython interactive environment")
1062
1062
1063 # We must ensure that __builtin__ (without the final 's') is always
1063 # We must ensure that __builtin__ (without the final 's') is always
1064 # available and pointing to the __builtin__ *module*. For more details:
1064 # available and pointing to the __builtin__ *module*. For more details:
1065 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1065 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1066 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1066 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1067 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1067 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1068
1068
1069 if user_ns is None:
1069 if user_ns is None:
1070 user_ns = user_module.__dict__
1070 user_ns = user_module.__dict__
1071
1071
1072 return user_module, user_ns
1072 return user_module, user_ns
1073
1073
1074 def init_sys_modules(self):
1074 def init_sys_modules(self):
1075 # We need to insert into sys.modules something that looks like a
1075 # We need to insert into sys.modules something that looks like a
1076 # module but which accesses the IPython namespace, for shelve and
1076 # module but which accesses the IPython namespace, for shelve and
1077 # pickle to work interactively. Normally they rely on getting
1077 # pickle to work interactively. Normally they rely on getting
1078 # everything out of __main__, but for embedding purposes each IPython
1078 # everything out of __main__, but for embedding purposes each IPython
1079 # instance has its own private namespace, so we can't go shoving
1079 # instance has its own private namespace, so we can't go shoving
1080 # everything into __main__.
1080 # everything into __main__.
1081
1081
1082 # note, however, that we should only do this for non-embedded
1082 # note, however, that we should only do this for non-embedded
1083 # ipythons, which really mimic the __main__.__dict__ with their own
1083 # ipythons, which really mimic the __main__.__dict__ with their own
1084 # namespace. Embedded instances, on the other hand, should not do
1084 # namespace. Embedded instances, on the other hand, should not do
1085 # this because they need to manage the user local/global namespaces
1085 # this because they need to manage the user local/global namespaces
1086 # only, but they live within a 'normal' __main__ (meaning, they
1086 # only, but they live within a 'normal' __main__ (meaning, they
1087 # shouldn't overtake the execution environment of the script they're
1087 # shouldn't overtake the execution environment of the script they're
1088 # embedded in).
1088 # embedded in).
1089
1089
1090 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1090 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1091 main_name = self.user_module.__name__
1091 main_name = self.user_module.__name__
1092 sys.modules[main_name] = self.user_module
1092 sys.modules[main_name] = self.user_module
1093
1093
1094 def init_user_ns(self):
1094 def init_user_ns(self):
1095 """Initialize all user-visible namespaces to their minimum defaults.
1095 """Initialize all user-visible namespaces to their minimum defaults.
1096
1096
1097 Certain history lists are also initialized here, as they effectively
1097 Certain history lists are also initialized here, as they effectively
1098 act as user namespaces.
1098 act as user namespaces.
1099
1099
1100 Notes
1100 Notes
1101 -----
1101 -----
1102 All data structures here are only filled in, they are NOT reset by this
1102 All data structures here are only filled in, they are NOT reset by this
1103 method. If they were not empty before, data will simply be added to
1103 method. If they were not empty before, data will simply be added to
1104 therm.
1104 therm.
1105 """
1105 """
1106 # This function works in two parts: first we put a few things in
1106 # This function works in two parts: first we put a few things in
1107 # user_ns, and we sync that contents into user_ns_hidden so that these
1107 # user_ns, and we sync that contents into user_ns_hidden so that these
1108 # initial variables aren't shown by %who. After the sync, we add the
1108 # initial variables aren't shown by %who. After the sync, we add the
1109 # rest of what we *do* want the user to see with %who even on a new
1109 # rest of what we *do* want the user to see with %who even on a new
1110 # session (probably nothing, so theye really only see their own stuff)
1110 # session (probably nothing, so theye really only see their own stuff)
1111
1111
1112 # The user dict must *always* have a __builtin__ reference to the
1112 # The user dict must *always* have a __builtin__ reference to the
1113 # Python standard __builtin__ namespace, which must be imported.
1113 # Python standard __builtin__ namespace, which must be imported.
1114 # This is so that certain operations in prompt evaluation can be
1114 # This is so that certain operations in prompt evaluation can be
1115 # reliably executed with builtins. Note that we can NOT use
1115 # reliably executed with builtins. Note that we can NOT use
1116 # __builtins__ (note the 's'), because that can either be a dict or a
1116 # __builtins__ (note the 's'), because that can either be a dict or a
1117 # module, and can even mutate at runtime, depending on the context
1117 # module, and can even mutate at runtime, depending on the context
1118 # (Python makes no guarantees on it). In contrast, __builtin__ is
1118 # (Python makes no guarantees on it). In contrast, __builtin__ is
1119 # always a module object, though it must be explicitly imported.
1119 # always a module object, though it must be explicitly imported.
1120
1120
1121 # For more details:
1121 # For more details:
1122 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1122 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1123 ns = dict()
1123 ns = dict()
1124
1124
1125 # Put 'help' in the user namespace
1125 # Put 'help' in the user namespace
1126 try:
1126 try:
1127 from site import _Helper
1127 from site import _Helper
1128 ns['help'] = _Helper()
1128 ns['help'] = _Helper()
1129 except ImportError:
1129 except ImportError:
1130 warn('help() not available - check site.py')
1130 warn('help() not available - check site.py')
1131
1131
1132 # make global variables for user access to the histories
1132 # make global variables for user access to the histories
1133 ns['_ih'] = self.history_manager.input_hist_parsed
1133 ns['_ih'] = self.history_manager.input_hist_parsed
1134 ns['_oh'] = self.history_manager.output_hist
1134 ns['_oh'] = self.history_manager.output_hist
1135 ns['_dh'] = self.history_manager.dir_hist
1135 ns['_dh'] = self.history_manager.dir_hist
1136
1136
1137 ns['_sh'] = shadowns
1137 ns['_sh'] = shadowns
1138
1138
1139 # user aliases to input and output histories. These shouldn't show up
1139 # user aliases to input and output histories. These shouldn't show up
1140 # in %who, as they can have very large reprs.
1140 # in %who, as they can have very large reprs.
1141 ns['In'] = self.history_manager.input_hist_parsed
1141 ns['In'] = self.history_manager.input_hist_parsed
1142 ns['Out'] = self.history_manager.output_hist
1142 ns['Out'] = self.history_manager.output_hist
1143
1143
1144 # Store myself as the public api!!!
1144 # Store myself as the public api!!!
1145 ns['get_ipython'] = self.get_ipython
1145 ns['get_ipython'] = self.get_ipython
1146
1146
1147 ns['exit'] = self.exiter
1147 ns['exit'] = self.exiter
1148 ns['quit'] = self.exiter
1148 ns['quit'] = self.exiter
1149
1149
1150 # Sync what we've added so far to user_ns_hidden so these aren't seen
1150 # Sync what we've added so far to user_ns_hidden so these aren't seen
1151 # by %who
1151 # by %who
1152 self.user_ns_hidden.update(ns)
1152 self.user_ns_hidden.update(ns)
1153
1153
1154 # Anything put into ns now would show up in %who. Think twice before
1154 # Anything put into ns now would show up in %who. Think twice before
1155 # putting anything here, as we really want %who to show the user their
1155 # putting anything here, as we really want %who to show the user their
1156 # stuff, not our variables.
1156 # stuff, not our variables.
1157
1157
1158 # Finally, update the real user's namespace
1158 # Finally, update the real user's namespace
1159 self.user_ns.update(ns)
1159 self.user_ns.update(ns)
1160
1160
1161 @property
1161 @property
1162 def all_ns_refs(self):
1162 def all_ns_refs(self):
1163 """Get a list of references to all the namespace dictionaries in which
1163 """Get a list of references to all the namespace dictionaries in which
1164 IPython might store a user-created object.
1164 IPython might store a user-created object.
1165
1165
1166 Note that this does not include the displayhook, which also caches
1166 Note that this does not include the displayhook, which also caches
1167 objects from the output."""
1167 objects from the output."""
1168 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1168 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1169 [m.__dict__ for m in self._main_mod_cache.values()]
1169 [m.__dict__ for m in self._main_mod_cache.values()]
1170
1170
1171 def reset(self, new_session=True):
1171 def reset(self, new_session=True):
1172 """Clear all internal namespaces, and attempt to release references to
1172 """Clear all internal namespaces, and attempt to release references to
1173 user objects.
1173 user objects.
1174
1174
1175 If new_session is True, a new history session will be opened.
1175 If new_session is True, a new history session will be opened.
1176 """
1176 """
1177 # Clear histories
1177 # Clear histories
1178 self.history_manager.reset(new_session)
1178 self.history_manager.reset(new_session)
1179 # Reset counter used to index all histories
1179 # Reset counter used to index all histories
1180 if new_session:
1180 if new_session:
1181 self.execution_count = 1
1181 self.execution_count = 1
1182
1182
1183 # Flush cached output items
1183 # Flush cached output items
1184 if self.displayhook.do_full_cache:
1184 if self.displayhook.do_full_cache:
1185 self.displayhook.flush()
1185 self.displayhook.flush()
1186
1186
1187 # The main execution namespaces must be cleared very carefully,
1187 # The main execution namespaces must be cleared very carefully,
1188 # skipping the deletion of the builtin-related keys, because doing so
1188 # skipping the deletion of the builtin-related keys, because doing so
1189 # would cause errors in many object's __del__ methods.
1189 # would cause errors in many object's __del__ methods.
1190 if self.user_ns is not self.user_global_ns:
1190 if self.user_ns is not self.user_global_ns:
1191 self.user_ns.clear()
1191 self.user_ns.clear()
1192 ns = self.user_global_ns
1192 ns = self.user_global_ns
1193 drop_keys = set(ns.keys())
1193 drop_keys = set(ns.keys())
1194 drop_keys.discard('__builtin__')
1194 drop_keys.discard('__builtin__')
1195 drop_keys.discard('__builtins__')
1195 drop_keys.discard('__builtins__')
1196 drop_keys.discard('__name__')
1196 drop_keys.discard('__name__')
1197 for k in drop_keys:
1197 for k in drop_keys:
1198 del ns[k]
1198 del ns[k]
1199
1199
1200 self.user_ns_hidden.clear()
1200 self.user_ns_hidden.clear()
1201
1201
1202 # Restore the user namespaces to minimal usability
1202 # Restore the user namespaces to minimal usability
1203 self.init_user_ns()
1203 self.init_user_ns()
1204
1204
1205 # Restore the default and user aliases
1205 # Restore the default and user aliases
1206 self.alias_manager.clear_aliases()
1206 self.alias_manager.clear_aliases()
1207 self.alias_manager.init_aliases()
1207 self.alias_manager.init_aliases()
1208
1208
1209 # Flush the private list of module references kept for script
1209 # Flush the private list of module references kept for script
1210 # execution protection
1210 # execution protection
1211 self.clear_main_mod_cache()
1211 self.clear_main_mod_cache()
1212
1212
1213 def del_var(self, varname, by_name=False):
1213 def del_var(self, varname, by_name=False):
1214 """Delete a variable from the various namespaces, so that, as
1214 """Delete a variable from the various namespaces, so that, as
1215 far as possible, we're not keeping any hidden references to it.
1215 far as possible, we're not keeping any hidden references to it.
1216
1216
1217 Parameters
1217 Parameters
1218 ----------
1218 ----------
1219 varname : str
1219 varname : str
1220 The name of the variable to delete.
1220 The name of the variable to delete.
1221 by_name : bool
1221 by_name : bool
1222 If True, delete variables with the given name in each
1222 If True, delete variables with the given name in each
1223 namespace. If False (default), find the variable in the user
1223 namespace. If False (default), find the variable in the user
1224 namespace, and delete references to it.
1224 namespace, and delete references to it.
1225 """
1225 """
1226 if varname in ('__builtin__', '__builtins__'):
1226 if varname in ('__builtin__', '__builtins__'):
1227 raise ValueError("Refusing to delete %s" % varname)
1227 raise ValueError("Refusing to delete %s" % varname)
1228
1228
1229 ns_refs = self.all_ns_refs
1229 ns_refs = self.all_ns_refs
1230
1230
1231 if by_name: # Delete by name
1231 if by_name: # Delete by name
1232 for ns in ns_refs:
1232 for ns in ns_refs:
1233 try:
1233 try:
1234 del ns[varname]
1234 del ns[varname]
1235 except KeyError:
1235 except KeyError:
1236 pass
1236 pass
1237 else: # Delete by object
1237 else: # Delete by object
1238 try:
1238 try:
1239 obj = self.user_ns[varname]
1239 obj = self.user_ns[varname]
1240 except KeyError:
1240 except KeyError:
1241 raise NameError("name '%s' is not defined" % varname)
1241 raise NameError("name '%s' is not defined" % varname)
1242 # Also check in output history
1242 # Also check in output history
1243 ns_refs.append(self.history_manager.output_hist)
1243 ns_refs.append(self.history_manager.output_hist)
1244 for ns in ns_refs:
1244 for ns in ns_refs:
1245 to_delete = [n for n, o in ns.iteritems() if o is obj]
1245 to_delete = [n for n, o in ns.iteritems() if o is obj]
1246 for name in to_delete:
1246 for name in to_delete:
1247 del ns[name]
1247 del ns[name]
1248
1248
1249 # displayhook keeps extra references, but not in a dictionary
1249 # displayhook keeps extra references, but not in a dictionary
1250 for name in ('_', '__', '___'):
1250 for name in ('_', '__', '___'):
1251 if getattr(self.displayhook, name) is obj:
1251 if getattr(self.displayhook, name) is obj:
1252 setattr(self.displayhook, name, None)
1252 setattr(self.displayhook, name, None)
1253
1253
1254 def reset_selective(self, regex=None):
1254 def reset_selective(self, regex=None):
1255 """Clear selective variables from internal namespaces based on a
1255 """Clear selective variables from internal namespaces based on a
1256 specified regular expression.
1256 specified regular expression.
1257
1257
1258 Parameters
1258 Parameters
1259 ----------
1259 ----------
1260 regex : string or compiled pattern, optional
1260 regex : string or compiled pattern, optional
1261 A regular expression pattern that will be used in searching
1261 A regular expression pattern that will be used in searching
1262 variable names in the users namespaces.
1262 variable names in the users namespaces.
1263 """
1263 """
1264 if regex is not None:
1264 if regex is not None:
1265 try:
1265 try:
1266 m = re.compile(regex)
1266 m = re.compile(regex)
1267 except TypeError:
1267 except TypeError:
1268 raise TypeError('regex must be a string or compiled pattern')
1268 raise TypeError('regex must be a string or compiled pattern')
1269 # Search for keys in each namespace that match the given regex
1269 # Search for keys in each namespace that match the given regex
1270 # If a match is found, delete the key/value pair.
1270 # If a match is found, delete the key/value pair.
1271 for ns in self.all_ns_refs:
1271 for ns in self.all_ns_refs:
1272 for var in ns:
1272 for var in ns:
1273 if m.search(var):
1273 if m.search(var):
1274 del ns[var]
1274 del ns[var]
1275
1275
1276 def push(self, variables, interactive=True):
1276 def push(self, variables, interactive=True):
1277 """Inject a group of variables into the IPython user namespace.
1277 """Inject a group of variables into the IPython user namespace.
1278
1278
1279 Parameters
1279 Parameters
1280 ----------
1280 ----------
1281 variables : dict, str or list/tuple of str
1281 variables : dict, str or list/tuple of str
1282 The variables to inject into the user's namespace. If a dict, a
1282 The variables to inject into the user's namespace. If a dict, a
1283 simple update is done. If a str, the string is assumed to have
1283 simple update is done. If a str, the string is assumed to have
1284 variable names separated by spaces. A list/tuple of str can also
1284 variable names separated by spaces. A list/tuple of str can also
1285 be used to give the variable names. If just the variable names are
1285 be used to give the variable names. If just the variable names are
1286 give (list/tuple/str) then the variable values looked up in the
1286 give (list/tuple/str) then the variable values looked up in the
1287 callers frame.
1287 callers frame.
1288 interactive : bool
1288 interactive : bool
1289 If True (default), the variables will be listed with the ``who``
1289 If True (default), the variables will be listed with the ``who``
1290 magic.
1290 magic.
1291 """
1291 """
1292 vdict = None
1292 vdict = None
1293
1293
1294 # We need a dict of name/value pairs to do namespace updates.
1294 # We need a dict of name/value pairs to do namespace updates.
1295 if isinstance(variables, dict):
1295 if isinstance(variables, dict):
1296 vdict = variables
1296 vdict = variables
1297 elif isinstance(variables, (basestring, list, tuple)):
1297 elif isinstance(variables, (basestring, list, tuple)):
1298 if isinstance(variables, basestring):
1298 if isinstance(variables, basestring):
1299 vlist = variables.split()
1299 vlist = variables.split()
1300 else:
1300 else:
1301 vlist = variables
1301 vlist = variables
1302 vdict = {}
1302 vdict = {}
1303 cf = sys._getframe(1)
1303 cf = sys._getframe(1)
1304 for name in vlist:
1304 for name in vlist:
1305 try:
1305 try:
1306 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1306 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1307 except:
1307 except:
1308 print('Could not get variable %s from %s' %
1308 print('Could not get variable %s from %s' %
1309 (name,cf.f_code.co_name))
1309 (name,cf.f_code.co_name))
1310 else:
1310 else:
1311 raise ValueError('variables must be a dict/str/list/tuple')
1311 raise ValueError('variables must be a dict/str/list/tuple')
1312
1312
1313 # Propagate variables to user namespace
1313 # Propagate variables to user namespace
1314 self.user_ns.update(vdict)
1314 self.user_ns.update(vdict)
1315
1315
1316 # And configure interactive visibility
1316 # And configure interactive visibility
1317 user_ns_hidden = self.user_ns_hidden
1317 user_ns_hidden = self.user_ns_hidden
1318 if interactive:
1318 if interactive:
1319 for name in vdict:
1319 for name in vdict:
1320 user_ns_hidden.pop(name, None)
1320 user_ns_hidden.pop(name, None)
1321 else:
1321 else:
1322 user_ns_hidden.update(vdict)
1322 user_ns_hidden.update(vdict)
1323
1323
1324 def drop_by_id(self, variables):
1324 def drop_by_id(self, variables):
1325 """Remove a dict of variables from the user namespace, if they are the
1325 """Remove a dict of variables from the user namespace, if they are the
1326 same as the values in the dictionary.
1326 same as the values in the dictionary.
1327
1327
1328 This is intended for use by extensions: variables that they've added can
1328 This is intended for use by extensions: variables that they've added can
1329 be taken back out if they are unloaded, without removing any that the
1329 be taken back out if they are unloaded, without removing any that the
1330 user has overwritten.
1330 user has overwritten.
1331
1331
1332 Parameters
1332 Parameters
1333 ----------
1333 ----------
1334 variables : dict
1334 variables : dict
1335 A dictionary mapping object names (as strings) to the objects.
1335 A dictionary mapping object names (as strings) to the objects.
1336 """
1336 """
1337 for name, obj in variables.iteritems():
1337 for name, obj in variables.iteritems():
1338 if name in self.user_ns and self.user_ns[name] is obj:
1338 if name in self.user_ns and self.user_ns[name] is obj:
1339 del self.user_ns[name]
1339 del self.user_ns[name]
1340 self.user_ns_hidden.pop(name, None)
1340 self.user_ns_hidden.pop(name, None)
1341
1341
1342 #-------------------------------------------------------------------------
1342 #-------------------------------------------------------------------------
1343 # Things related to object introspection
1343 # Things related to object introspection
1344 #-------------------------------------------------------------------------
1344 #-------------------------------------------------------------------------
1345
1345
1346 def _ofind(self, oname, namespaces=None):
1346 def _ofind(self, oname, namespaces=None):
1347 """Find an object in the available namespaces.
1347 """Find an object in the available namespaces.
1348
1348
1349 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1349 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1350
1350
1351 Has special code to detect magic functions.
1351 Has special code to detect magic functions.
1352 """
1352 """
1353 oname = oname.strip()
1353 oname = oname.strip()
1354 #print '1- oname: <%r>' % oname # dbg
1354 #print '1- oname: <%r>' % oname # dbg
1355 if not oname.startswith(ESC_MAGIC) and \
1355 if not oname.startswith(ESC_MAGIC) and \
1356 not oname.startswith(ESC_MAGIC2) and \
1356 not oname.startswith(ESC_MAGIC2) and \
1357 not py3compat.isidentifier(oname, dotted=True):
1357 not py3compat.isidentifier(oname, dotted=True):
1358 return dict(found=False)
1358 return dict(found=False)
1359
1359
1360 alias_ns = None
1360 alias_ns = None
1361 if namespaces is None:
1361 if namespaces is None:
1362 # Namespaces to search in:
1362 # Namespaces to search in:
1363 # Put them in a list. The order is important so that we
1363 # Put them in a list. The order is important so that we
1364 # find things in the same order that Python finds them.
1364 # find things in the same order that Python finds them.
1365 namespaces = [ ('Interactive', self.user_ns),
1365 namespaces = [ ('Interactive', self.user_ns),
1366 ('Interactive (global)', self.user_global_ns),
1366 ('Interactive (global)', self.user_global_ns),
1367 ('Python builtin', builtin_mod.__dict__),
1367 ('Python builtin', builtin_mod.__dict__),
1368 ]
1368 ]
1369
1369
1370 # initialize results to 'null'
1370 # initialize results to 'null'
1371 found = False; obj = None; ospace = None; ds = None;
1371 found = False; obj = None; ospace = None; ds = None;
1372 ismagic = False; isalias = False; parent = None
1372 ismagic = False; isalias = False; parent = None
1373
1373
1374 # We need to special-case 'print', which as of python2.6 registers as a
1374 # We need to special-case 'print', which as of python2.6 registers as a
1375 # function but should only be treated as one if print_function was
1375 # function but should only be treated as one if print_function was
1376 # loaded with a future import. In this case, just bail.
1376 # loaded with a future import. In this case, just bail.
1377 if (oname == 'print' and not py3compat.PY3 and not \
1377 if (oname == 'print' and not py3compat.PY3 and not \
1378 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1378 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1379 return {'found':found, 'obj':obj, 'namespace':ospace,
1379 return {'found':found, 'obj':obj, 'namespace':ospace,
1380 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1380 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1381
1381
1382 # Look for the given name by splitting it in parts. If the head is
1382 # Look for the given name by splitting it in parts. If the head is
1383 # found, then we look for all the remaining parts as members, and only
1383 # found, then we look for all the remaining parts as members, and only
1384 # declare success if we can find them all.
1384 # declare success if we can find them all.
1385 oname_parts = oname.split('.')
1385 oname_parts = oname.split('.')
1386 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1386 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1387 for nsname,ns in namespaces:
1387 for nsname,ns in namespaces:
1388 try:
1388 try:
1389 obj = ns[oname_head]
1389 obj = ns[oname_head]
1390 except KeyError:
1390 except KeyError:
1391 continue
1391 continue
1392 else:
1392 else:
1393 #print 'oname_rest:', oname_rest # dbg
1393 #print 'oname_rest:', oname_rest # dbg
1394 for part in oname_rest:
1394 for part in oname_rest:
1395 try:
1395 try:
1396 parent = obj
1396 parent = obj
1397 obj = getattr(obj,part)
1397 obj = getattr(obj,part)
1398 except:
1398 except:
1399 # Blanket except b/c some badly implemented objects
1399 # Blanket except b/c some badly implemented objects
1400 # allow __getattr__ to raise exceptions other than
1400 # allow __getattr__ to raise exceptions other than
1401 # AttributeError, which then crashes IPython.
1401 # AttributeError, which then crashes IPython.
1402 break
1402 break
1403 else:
1403 else:
1404 # If we finish the for loop (no break), we got all members
1404 # If we finish the for loop (no break), we got all members
1405 found = True
1405 found = True
1406 ospace = nsname
1406 ospace = nsname
1407 break # namespace loop
1407 break # namespace loop
1408
1408
1409 # Try to see if it's magic
1409 # Try to see if it's magic
1410 if not found:
1410 if not found:
1411 obj = None
1411 obj = None
1412 if oname.startswith(ESC_MAGIC2):
1412 if oname.startswith(ESC_MAGIC2):
1413 oname = oname.lstrip(ESC_MAGIC2)
1413 oname = oname.lstrip(ESC_MAGIC2)
1414 obj = self.find_cell_magic(oname)
1414 obj = self.find_cell_magic(oname)
1415 elif oname.startswith(ESC_MAGIC):
1415 elif oname.startswith(ESC_MAGIC):
1416 oname = oname.lstrip(ESC_MAGIC)
1416 oname = oname.lstrip(ESC_MAGIC)
1417 obj = self.find_line_magic(oname)
1417 obj = self.find_line_magic(oname)
1418 else:
1418 else:
1419 # search without prefix, so run? will find %run?
1419 # search without prefix, so run? will find %run?
1420 obj = self.find_line_magic(oname)
1420 obj = self.find_line_magic(oname)
1421 if obj is None:
1421 if obj is None:
1422 obj = self.find_cell_magic(oname)
1422 obj = self.find_cell_magic(oname)
1423 if obj is not None:
1423 if obj is not None:
1424 found = True
1424 found = True
1425 ospace = 'IPython internal'
1425 ospace = 'IPython internal'
1426 ismagic = True
1426 ismagic = True
1427
1427
1428 # Last try: special-case some literals like '', [], {}, etc:
1428 # Last try: special-case some literals like '', [], {}, etc:
1429 if not found and oname_head in ["''",'""','[]','{}','()']:
1429 if not found and oname_head in ["''",'""','[]','{}','()']:
1430 obj = eval(oname_head)
1430 obj = eval(oname_head)
1431 found = True
1431 found = True
1432 ospace = 'Interactive'
1432 ospace = 'Interactive'
1433
1433
1434 return {'found':found, 'obj':obj, 'namespace':ospace,
1434 return {'found':found, 'obj':obj, 'namespace':ospace,
1435 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1435 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1436
1436
1437 def _ofind_property(self, oname, info):
1437 def _ofind_property(self, oname, info):
1438 """Second part of object finding, to look for property details."""
1438 """Second part of object finding, to look for property details."""
1439 if info.found:
1439 if info.found:
1440 # Get the docstring of the class property if it exists.
1440 # Get the docstring of the class property if it exists.
1441 path = oname.split('.')
1441 path = oname.split('.')
1442 root = '.'.join(path[:-1])
1442 root = '.'.join(path[:-1])
1443 if info.parent is not None:
1443 if info.parent is not None:
1444 try:
1444 try:
1445 target = getattr(info.parent, '__class__')
1445 target = getattr(info.parent, '__class__')
1446 # The object belongs to a class instance.
1446 # The object belongs to a class instance.
1447 try:
1447 try:
1448 target = getattr(target, path[-1])
1448 target = getattr(target, path[-1])
1449 # The class defines the object.
1449 # The class defines the object.
1450 if isinstance(target, property):
1450 if isinstance(target, property):
1451 oname = root + '.__class__.' + path[-1]
1451 oname = root + '.__class__.' + path[-1]
1452 info = Struct(self._ofind(oname))
1452 info = Struct(self._ofind(oname))
1453 except AttributeError: pass
1453 except AttributeError: pass
1454 except AttributeError: pass
1454 except AttributeError: pass
1455
1455
1456 # We return either the new info or the unmodified input if the object
1456 # We return either the new info or the unmodified input if the object
1457 # hadn't been found
1457 # hadn't been found
1458 return info
1458 return info
1459
1459
1460 def _object_find(self, oname, namespaces=None):
1460 def _object_find(self, oname, namespaces=None):
1461 """Find an object and return a struct with info about it."""
1461 """Find an object and return a struct with info about it."""
1462 inf = Struct(self._ofind(oname, namespaces))
1462 inf = Struct(self._ofind(oname, namespaces))
1463 return Struct(self._ofind_property(oname, inf))
1463 return Struct(self._ofind_property(oname, inf))
1464
1464
1465 def _inspect(self, meth, oname, namespaces=None, **kw):
1465 def _inspect(self, meth, oname, namespaces=None, **kw):
1466 """Generic interface to the inspector system.
1466 """Generic interface to the inspector system.
1467
1467
1468 This function is meant to be called by pdef, pdoc & friends."""
1468 This function is meant to be called by pdef, pdoc & friends."""
1469 info = self._object_find(oname, namespaces)
1469 info = self._object_find(oname, namespaces)
1470 if info.found:
1470 if info.found:
1471 pmethod = getattr(self.inspector, meth)
1471 pmethod = getattr(self.inspector, meth)
1472 formatter = format_screen if info.ismagic else None
1472 formatter = format_screen if info.ismagic else None
1473 if meth == 'pdoc':
1473 if meth == 'pdoc':
1474 pmethod(info.obj, oname, formatter)
1474 pmethod(info.obj, oname, formatter)
1475 elif meth == 'pinfo':
1475 elif meth == 'pinfo':
1476 pmethod(info.obj, oname, formatter, info, **kw)
1476 pmethod(info.obj, oname, formatter, info, **kw)
1477 else:
1477 else:
1478 pmethod(info.obj, oname)
1478 pmethod(info.obj, oname)
1479 else:
1479 else:
1480 print('Object `%s` not found.' % oname)
1480 print('Object `%s` not found.' % oname)
1481 return 'not found' # so callers can take other action
1481 return 'not found' # so callers can take other action
1482
1482
1483 def object_inspect(self, oname, detail_level=0):
1483 def object_inspect(self, oname, detail_level=0):
1484 with self.builtin_trap:
1484 with self.builtin_trap:
1485 info = self._object_find(oname)
1485 info = self._object_find(oname)
1486 if info.found:
1486 if info.found:
1487 return self.inspector.info(info.obj, oname, info=info,
1487 return self.inspector.info(info.obj, oname, info=info,
1488 detail_level=detail_level
1488 detail_level=detail_level
1489 )
1489 )
1490 else:
1490 else:
1491 return oinspect.object_info(name=oname, found=False)
1491 return oinspect.object_info(name=oname, found=False)
1492
1492
1493 #-------------------------------------------------------------------------
1493 #-------------------------------------------------------------------------
1494 # Things related to history management
1494 # Things related to history management
1495 #-------------------------------------------------------------------------
1495 #-------------------------------------------------------------------------
1496
1496
1497 def init_history(self):
1497 def init_history(self):
1498 """Sets up the command history, and starts regular autosaves."""
1498 """Sets up the command history, and starts regular autosaves."""
1499 self.history_manager = HistoryManager(shell=self, parent=self)
1499 self.history_manager = HistoryManager(shell=self, parent=self)
1500 self.configurables.append(self.history_manager)
1500 self.configurables.append(self.history_manager)
1501
1501
1502 #-------------------------------------------------------------------------
1502 #-------------------------------------------------------------------------
1503 # Things related to exception handling and tracebacks (not debugging)
1503 # Things related to exception handling and tracebacks (not debugging)
1504 #-------------------------------------------------------------------------
1504 #-------------------------------------------------------------------------
1505
1505
1506 def init_traceback_handlers(self, custom_exceptions):
1506 def init_traceback_handlers(self, custom_exceptions):
1507 # Syntax error handler.
1507 # Syntax error handler.
1508 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1508 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1509
1509
1510 # The interactive one is initialized with an offset, meaning we always
1510 # The interactive one is initialized with an offset, meaning we always
1511 # want to remove the topmost item in the traceback, which is our own
1511 # want to remove the topmost item in the traceback, which is our own
1512 # internal code. Valid modes: ['Plain','Context','Verbose']
1512 # internal code. Valid modes: ['Plain','Context','Verbose']
1513 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1513 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1514 color_scheme='NoColor',
1514 color_scheme='NoColor',
1515 tb_offset = 1,
1515 tb_offset = 1,
1516 check_cache=check_linecache_ipython)
1516 check_cache=check_linecache_ipython)
1517
1517
1518 # The instance will store a pointer to the system-wide exception hook,
1518 # The instance will store a pointer to the system-wide exception hook,
1519 # so that runtime code (such as magics) can access it. This is because
1519 # so that runtime code (such as magics) can access it. This is because
1520 # during the read-eval loop, it may get temporarily overwritten.
1520 # during the read-eval loop, it may get temporarily overwritten.
1521 self.sys_excepthook = sys.excepthook
1521 self.sys_excepthook = sys.excepthook
1522
1522
1523 # and add any custom exception handlers the user may have specified
1523 # and add any custom exception handlers the user may have specified
1524 self.set_custom_exc(*custom_exceptions)
1524 self.set_custom_exc(*custom_exceptions)
1525
1525
1526 # Set the exception mode
1526 # Set the exception mode
1527 self.InteractiveTB.set_mode(mode=self.xmode)
1527 self.InteractiveTB.set_mode(mode=self.xmode)
1528
1528
1529 def set_custom_exc(self, exc_tuple, handler):
1529 def set_custom_exc(self, exc_tuple, handler):
1530 """set_custom_exc(exc_tuple,handler)
1530 """set_custom_exc(exc_tuple,handler)
1531
1531
1532 Set a custom exception handler, which will be called if any of the
1532 Set a custom exception handler, which will be called if any of the
1533 exceptions in exc_tuple occur in the mainloop (specifically, in the
1533 exceptions in exc_tuple occur in the mainloop (specifically, in the
1534 run_code() method).
1534 run_code() method).
1535
1535
1536 Parameters
1536 Parameters
1537 ----------
1537 ----------
1538
1538
1539 exc_tuple : tuple of exception classes
1539 exc_tuple : tuple of exception classes
1540 A *tuple* of exception classes, for which to call the defined
1540 A *tuple* of exception classes, for which to call the defined
1541 handler. It is very important that you use a tuple, and NOT A
1541 handler. It is very important that you use a tuple, and NOT A
1542 LIST here, because of the way Python's except statement works. If
1542 LIST here, because of the way Python's except statement works. If
1543 you only want to trap a single exception, use a singleton tuple::
1543 you only want to trap a single exception, use a singleton tuple::
1544
1544
1545 exc_tuple == (MyCustomException,)
1545 exc_tuple == (MyCustomException,)
1546
1546
1547 handler : callable
1547 handler : callable
1548 handler must have the following signature::
1548 handler must have the following signature::
1549
1549
1550 def my_handler(self, etype, value, tb, tb_offset=None):
1550 def my_handler(self, etype, value, tb, tb_offset=None):
1551 ...
1551 ...
1552 return structured_traceback
1552 return structured_traceback
1553
1553
1554 Your handler must return a structured traceback (a list of strings),
1554 Your handler must return a structured traceback (a list of strings),
1555 or None.
1555 or None.
1556
1556
1557 This will be made into an instance method (via types.MethodType)
1557 This will be made into an instance method (via types.MethodType)
1558 of IPython itself, and it will be called if any of the exceptions
1558 of IPython itself, and it will be called if any of the exceptions
1559 listed in the exc_tuple are caught. If the handler is None, an
1559 listed in the exc_tuple are caught. If the handler is None, an
1560 internal basic one is used, which just prints basic info.
1560 internal basic one is used, which just prints basic info.
1561
1561
1562 To protect IPython from crashes, if your handler ever raises an
1562 To protect IPython from crashes, if your handler ever raises an
1563 exception or returns an invalid result, it will be immediately
1563 exception or returns an invalid result, it will be immediately
1564 disabled.
1564 disabled.
1565
1565
1566 WARNING: by putting in your own exception handler into IPython's main
1566 WARNING: by putting in your own exception handler into IPython's main
1567 execution loop, you run a very good chance of nasty crashes. This
1567 execution loop, you run a very good chance of nasty crashes. This
1568 facility should only be used if you really know what you are doing."""
1568 facility should only be used if you really know what you are doing."""
1569
1569
1570 assert type(exc_tuple)==type(()) , \
1570 assert type(exc_tuple)==type(()) , \
1571 "The custom exceptions must be given AS A TUPLE."
1571 "The custom exceptions must be given AS A TUPLE."
1572
1572
1573 def dummy_handler(self,etype,value,tb,tb_offset=None):
1573 def dummy_handler(self,etype,value,tb,tb_offset=None):
1574 print('*** Simple custom exception handler ***')
1574 print('*** Simple custom exception handler ***')
1575 print('Exception type :',etype)
1575 print('Exception type :',etype)
1576 print('Exception value:',value)
1576 print('Exception value:',value)
1577 print('Traceback :',tb)
1577 print('Traceback :',tb)
1578 #print 'Source code :','\n'.join(self.buffer)
1578 #print 'Source code :','\n'.join(self.buffer)
1579
1579
1580 def validate_stb(stb):
1580 def validate_stb(stb):
1581 """validate structured traceback return type
1581 """validate structured traceback return type
1582
1582
1583 return type of CustomTB *should* be a list of strings, but allow
1583 return type of CustomTB *should* be a list of strings, but allow
1584 single strings or None, which are harmless.
1584 single strings or None, which are harmless.
1585
1585
1586 This function will *always* return a list of strings,
1586 This function will *always* return a list of strings,
1587 and will raise a TypeError if stb is inappropriate.
1587 and will raise a TypeError if stb is inappropriate.
1588 """
1588 """
1589 msg = "CustomTB must return list of strings, not %r" % stb
1589 msg = "CustomTB must return list of strings, not %r" % stb
1590 if stb is None:
1590 if stb is None:
1591 return []
1591 return []
1592 elif isinstance(stb, basestring):
1592 elif isinstance(stb, basestring):
1593 return [stb]
1593 return [stb]
1594 elif not isinstance(stb, list):
1594 elif not isinstance(stb, list):
1595 raise TypeError(msg)
1595 raise TypeError(msg)
1596 # it's a list
1596 # it's a list
1597 for line in stb:
1597 for line in stb:
1598 # check every element
1598 # check every element
1599 if not isinstance(line, basestring):
1599 if not isinstance(line, basestring):
1600 raise TypeError(msg)
1600 raise TypeError(msg)
1601 return stb
1601 return stb
1602
1602
1603 if handler is None:
1603 if handler is None:
1604 wrapped = dummy_handler
1604 wrapped = dummy_handler
1605 else:
1605 else:
1606 def wrapped(self,etype,value,tb,tb_offset=None):
1606 def wrapped(self,etype,value,tb,tb_offset=None):
1607 """wrap CustomTB handler, to protect IPython from user code
1607 """wrap CustomTB handler, to protect IPython from user code
1608
1608
1609 This makes it harder (but not impossible) for custom exception
1609 This makes it harder (but not impossible) for custom exception
1610 handlers to crash IPython.
1610 handlers to crash IPython.
1611 """
1611 """
1612 try:
1612 try:
1613 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1613 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1614 return validate_stb(stb)
1614 return validate_stb(stb)
1615 except:
1615 except:
1616 # clear custom handler immediately
1616 # clear custom handler immediately
1617 self.set_custom_exc((), None)
1617 self.set_custom_exc((), None)
1618 print("Custom TB Handler failed, unregistering", file=io.stderr)
1618 print("Custom TB Handler failed, unregistering", file=io.stderr)
1619 # show the exception in handler first
1619 # show the exception in handler first
1620 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1620 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1621 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1621 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1622 print("The original exception:", file=io.stdout)
1622 print("The original exception:", file=io.stdout)
1623 stb = self.InteractiveTB.structured_traceback(
1623 stb = self.InteractiveTB.structured_traceback(
1624 (etype,value,tb), tb_offset=tb_offset
1624 (etype,value,tb), tb_offset=tb_offset
1625 )
1625 )
1626 return stb
1626 return stb
1627
1627
1628 self.CustomTB = types.MethodType(wrapped,self)
1628 self.CustomTB = types.MethodType(wrapped,self)
1629 self.custom_exceptions = exc_tuple
1629 self.custom_exceptions = exc_tuple
1630
1630
1631 def excepthook(self, etype, value, tb):
1631 def excepthook(self, etype, value, tb):
1632 """One more defense for GUI apps that call sys.excepthook.
1632 """One more defense for GUI apps that call sys.excepthook.
1633
1633
1634 GUI frameworks like wxPython trap exceptions and call
1634 GUI frameworks like wxPython trap exceptions and call
1635 sys.excepthook themselves. I guess this is a feature that
1635 sys.excepthook themselves. I guess this is a feature that
1636 enables them to keep running after exceptions that would
1636 enables them to keep running after exceptions that would
1637 otherwise kill their mainloop. This is a bother for IPython
1637 otherwise kill their mainloop. This is a bother for IPython
1638 which excepts to catch all of the program exceptions with a try:
1638 which excepts to catch all of the program exceptions with a try:
1639 except: statement.
1639 except: statement.
1640
1640
1641 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1641 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1642 any app directly invokes sys.excepthook, it will look to the user like
1642 any app directly invokes sys.excepthook, it will look to the user like
1643 IPython crashed. In order to work around this, we can disable the
1643 IPython crashed. In order to work around this, we can disable the
1644 CrashHandler and replace it with this excepthook instead, which prints a
1644 CrashHandler and replace it with this excepthook instead, which prints a
1645 regular traceback using our InteractiveTB. In this fashion, apps which
1645 regular traceback using our InteractiveTB. In this fashion, apps which
1646 call sys.excepthook will generate a regular-looking exception from
1646 call sys.excepthook will generate a regular-looking exception from
1647 IPython, and the CrashHandler will only be triggered by real IPython
1647 IPython, and the CrashHandler will only be triggered by real IPython
1648 crashes.
1648 crashes.
1649
1649
1650 This hook should be used sparingly, only in places which are not likely
1650 This hook should be used sparingly, only in places which are not likely
1651 to be true IPython errors.
1651 to be true IPython errors.
1652 """
1652 """
1653 self.showtraceback((etype,value,tb),tb_offset=0)
1653 self.showtraceback((etype,value,tb),tb_offset=0)
1654
1654
1655 def _get_exc_info(self, exc_tuple=None):
1655 def _get_exc_info(self, exc_tuple=None):
1656 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1656 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1657
1657
1658 Ensures sys.last_type,value,traceback hold the exc_info we found,
1658 Ensures sys.last_type,value,traceback hold the exc_info we found,
1659 from whichever source.
1659 from whichever source.
1660
1660
1661 raises ValueError if none of these contain any information
1661 raises ValueError if none of these contain any information
1662 """
1662 """
1663 if exc_tuple is None:
1663 if exc_tuple is None:
1664 etype, value, tb = sys.exc_info()
1664 etype, value, tb = sys.exc_info()
1665 else:
1665 else:
1666 etype, value, tb = exc_tuple
1666 etype, value, tb = exc_tuple
1667
1667
1668 if etype is None:
1668 if etype is None:
1669 if hasattr(sys, 'last_type'):
1669 if hasattr(sys, 'last_type'):
1670 etype, value, tb = sys.last_type, sys.last_value, \
1670 etype, value, tb = sys.last_type, sys.last_value, \
1671 sys.last_traceback
1671 sys.last_traceback
1672
1672
1673 if etype is None:
1673 if etype is None:
1674 raise ValueError("No exception to find")
1674 raise ValueError("No exception to find")
1675
1675
1676 # Now store the exception info in sys.last_type etc.
1676 # Now store the exception info in sys.last_type etc.
1677 # WARNING: these variables are somewhat deprecated and not
1677 # WARNING: these variables are somewhat deprecated and not
1678 # necessarily safe to use in a threaded environment, but tools
1678 # necessarily safe to use in a threaded environment, but tools
1679 # like pdb depend on their existence, so let's set them. If we
1679 # like pdb depend on their existence, so let's set them. If we
1680 # find problems in the field, we'll need to revisit their use.
1680 # find problems in the field, we'll need to revisit their use.
1681 sys.last_type = etype
1681 sys.last_type = etype
1682 sys.last_value = value
1682 sys.last_value = value
1683 sys.last_traceback = tb
1683 sys.last_traceback = tb
1684
1684
1685 return etype, value, tb
1685 return etype, value, tb
1686
1686
1687 def show_usage_error(self, exc):
1687 def show_usage_error(self, exc):
1688 """Show a short message for UsageErrors
1688 """Show a short message for UsageErrors
1689
1689
1690 These are special exceptions that shouldn't show a traceback.
1690 These are special exceptions that shouldn't show a traceback.
1691 """
1691 """
1692 self.write_err("UsageError: %s" % exc)
1692 self.write_err("UsageError: %s" % exc)
1693
1693
1694 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1694 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1695 exception_only=False):
1695 exception_only=False):
1696 """Display the exception that just occurred.
1696 """Display the exception that just occurred.
1697
1697
1698 If nothing is known about the exception, this is the method which
1698 If nothing is known about the exception, this is the method which
1699 should be used throughout the code for presenting user tracebacks,
1699 should be used throughout the code for presenting user tracebacks,
1700 rather than directly invoking the InteractiveTB object.
1700 rather than directly invoking the InteractiveTB object.
1701
1701
1702 A specific showsyntaxerror() also exists, but this method can take
1702 A specific showsyntaxerror() also exists, but this method can take
1703 care of calling it if needed, so unless you are explicitly catching a
1703 care of calling it if needed, so unless you are explicitly catching a
1704 SyntaxError exception, don't try to analyze the stack manually and
1704 SyntaxError exception, don't try to analyze the stack manually and
1705 simply call this method."""
1705 simply call this method."""
1706
1706
1707 try:
1707 try:
1708 try:
1708 try:
1709 etype, value, tb = self._get_exc_info(exc_tuple)
1709 etype, value, tb = self._get_exc_info(exc_tuple)
1710 except ValueError:
1710 except ValueError:
1711 self.write_err('No traceback available to show.\n')
1711 self.write_err('No traceback available to show.\n')
1712 return
1712 return
1713
1713
1714 if issubclass(etype, SyntaxError):
1714 if issubclass(etype, SyntaxError):
1715 # Though this won't be called by syntax errors in the input
1715 # Though this won't be called by syntax errors in the input
1716 # line, there may be SyntaxError cases with imported code.
1716 # line, there may be SyntaxError cases with imported code.
1717 self.showsyntaxerror(filename)
1717 self.showsyntaxerror(filename)
1718 elif etype is UsageError:
1718 elif etype is UsageError:
1719 self.show_usage_error(value)
1719 self.show_usage_error(value)
1720 else:
1720 else:
1721 if exception_only:
1721 if exception_only:
1722 stb = ['An exception has occurred, use %tb to see '
1722 stb = ['An exception has occurred, use %tb to see '
1723 'the full traceback.\n']
1723 'the full traceback.\n']
1724 stb.extend(self.InteractiveTB.get_exception_only(etype,
1724 stb.extend(self.InteractiveTB.get_exception_only(etype,
1725 value))
1725 value))
1726 else:
1726 else:
1727 try:
1727 try:
1728 # Exception classes can customise their traceback - we
1728 # Exception classes can customise their traceback - we
1729 # use this in IPython.parallel for exceptions occurring
1729 # use this in IPython.parallel for exceptions occurring
1730 # in the engines. This should return a list of strings.
1730 # in the engines. This should return a list of strings.
1731 stb = value._render_traceback_()
1731 stb = value._render_traceback_()
1732 except Exception:
1732 except Exception:
1733 stb = self.InteractiveTB.structured_traceback(etype,
1733 stb = self.InteractiveTB.structured_traceback(etype,
1734 value, tb, tb_offset=tb_offset)
1734 value, tb, tb_offset=tb_offset)
1735
1735
1736 self._showtraceback(etype, value, stb)
1736 self._showtraceback(etype, value, stb)
1737 if self.call_pdb:
1737 if self.call_pdb:
1738 # drop into debugger
1738 # drop into debugger
1739 self.debugger(force=True)
1739 self.debugger(force=True)
1740 return
1740 return
1741
1741
1742 # Actually show the traceback
1742 # Actually show the traceback
1743 self._showtraceback(etype, value, stb)
1743 self._showtraceback(etype, value, stb)
1744
1744
1745 except KeyboardInterrupt:
1745 except KeyboardInterrupt:
1746 self.write_err("\nKeyboardInterrupt\n")
1746 self.write_err("\nKeyboardInterrupt\n")
1747
1747
1748 def _showtraceback(self, etype, evalue, stb):
1748 def _showtraceback(self, etype, evalue, stb):
1749 """Actually show a traceback.
1749 """Actually show a traceback.
1750
1750
1751 Subclasses may override this method to put the traceback on a different
1751 Subclasses may override this method to put the traceback on a different
1752 place, like a side channel.
1752 place, like a side channel.
1753 """
1753 """
1754 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1754 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1755
1755
1756 def showsyntaxerror(self, filename=None):
1756 def showsyntaxerror(self, filename=None):
1757 """Display the syntax error that just occurred.
1757 """Display the syntax error that just occurred.
1758
1758
1759 This doesn't display a stack trace because there isn't one.
1759 This doesn't display a stack trace because there isn't one.
1760
1760
1761 If a filename is given, it is stuffed in the exception instead
1761 If a filename is given, it is stuffed in the exception instead
1762 of what was there before (because Python's parser always uses
1762 of what was there before (because Python's parser always uses
1763 "<string>" when reading from a string).
1763 "<string>" when reading from a string).
1764 """
1764 """
1765 etype, value, last_traceback = self._get_exc_info()
1765 etype, value, last_traceback = self._get_exc_info()
1766
1766
1767 if filename and issubclass(etype, SyntaxError):
1767 if filename and issubclass(etype, SyntaxError):
1768 try:
1768 try:
1769 value.filename = filename
1769 value.filename = filename
1770 except:
1770 except:
1771 # Not the format we expect; leave it alone
1771 # Not the format we expect; leave it alone
1772 pass
1772 pass
1773
1773
1774 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1774 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1775 self._showtraceback(etype, value, stb)
1775 self._showtraceback(etype, value, stb)
1776
1776
1777 # This is overridden in TerminalInteractiveShell to show a message about
1777 # This is overridden in TerminalInteractiveShell to show a message about
1778 # the %paste magic.
1778 # the %paste magic.
1779 def showindentationerror(self):
1779 def showindentationerror(self):
1780 """Called by run_cell when there's an IndentationError in code entered
1780 """Called by run_cell when there's an IndentationError in code entered
1781 at the prompt.
1781 at the prompt.
1782
1782
1783 This is overridden in TerminalInteractiveShell to show a message about
1783 This is overridden in TerminalInteractiveShell to show a message about
1784 the %paste magic."""
1784 the %paste magic."""
1785 self.showsyntaxerror()
1785 self.showsyntaxerror()
1786
1786
1787 #-------------------------------------------------------------------------
1787 #-------------------------------------------------------------------------
1788 # Things related to readline
1788 # Things related to readline
1789 #-------------------------------------------------------------------------
1789 #-------------------------------------------------------------------------
1790
1790
1791 def init_readline(self):
1791 def init_readline(self):
1792 """Command history completion/saving/reloading."""
1792 """Command history completion/saving/reloading."""
1793
1793
1794 if self.readline_use:
1794 if self.readline_use:
1795 import IPython.utils.rlineimpl as readline
1795 import IPython.utils.rlineimpl as readline
1796
1796
1797 self.rl_next_input = None
1797 self.rl_next_input = None
1798 self.rl_do_indent = False
1798 self.rl_do_indent = False
1799
1799
1800 if not self.readline_use or not readline.have_readline:
1800 if not self.readline_use or not readline.have_readline:
1801 self.has_readline = False
1801 self.has_readline = False
1802 self.readline = None
1802 self.readline = None
1803 # Set a number of methods that depend on readline to be no-op
1803 # Set a number of methods that depend on readline to be no-op
1804 self.readline_no_record = no_op_context
1804 self.readline_no_record = no_op_context
1805 self.set_readline_completer = no_op
1805 self.set_readline_completer = no_op
1806 self.set_custom_completer = no_op
1806 self.set_custom_completer = no_op
1807 if self.readline_use:
1807 if self.readline_use:
1808 warn('Readline services not available or not loaded.')
1808 warn('Readline services not available or not loaded.')
1809 else:
1809 else:
1810 self.has_readline = True
1810 self.has_readline = True
1811 self.readline = readline
1811 self.readline = readline
1812 sys.modules['readline'] = readline
1812 sys.modules['readline'] = readline
1813
1813
1814 # Platform-specific configuration
1814 # Platform-specific configuration
1815 if os.name == 'nt':
1815 if os.name == 'nt':
1816 # FIXME - check with Frederick to see if we can harmonize
1816 # FIXME - check with Frederick to see if we can harmonize
1817 # naming conventions with pyreadline to avoid this
1817 # naming conventions with pyreadline to avoid this
1818 # platform-dependent check
1818 # platform-dependent check
1819 self.readline_startup_hook = readline.set_pre_input_hook
1819 self.readline_startup_hook = readline.set_pre_input_hook
1820 else:
1820 else:
1821 self.readline_startup_hook = readline.set_startup_hook
1821 self.readline_startup_hook = readline.set_startup_hook
1822
1822
1823 # Load user's initrc file (readline config)
1823 # Load user's initrc file (readline config)
1824 # Or if libedit is used, load editrc.
1824 # Or if libedit is used, load editrc.
1825 inputrc_name = os.environ.get('INPUTRC')
1825 inputrc_name = os.environ.get('INPUTRC')
1826 if inputrc_name is None:
1826 if inputrc_name is None:
1827 inputrc_name = '.inputrc'
1827 inputrc_name = '.inputrc'
1828 if readline.uses_libedit:
1828 if readline.uses_libedit:
1829 inputrc_name = '.editrc'
1829 inputrc_name = '.editrc'
1830 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1830 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1831 if os.path.isfile(inputrc_name):
1831 if os.path.isfile(inputrc_name):
1832 try:
1832 try:
1833 readline.read_init_file(inputrc_name)
1833 readline.read_init_file(inputrc_name)
1834 except:
1834 except:
1835 warn('Problems reading readline initialization file <%s>'
1835 warn('Problems reading readline initialization file <%s>'
1836 % inputrc_name)
1836 % inputrc_name)
1837
1837
1838 # Configure readline according to user's prefs
1838 # Configure readline according to user's prefs
1839 # This is only done if GNU readline is being used. If libedit
1839 # This is only done if GNU readline is being used. If libedit
1840 # is being used (as on Leopard) the readline config is
1840 # is being used (as on Leopard) the readline config is
1841 # not run as the syntax for libedit is different.
1841 # not run as the syntax for libedit is different.
1842 if not readline.uses_libedit:
1842 if not readline.uses_libedit:
1843 for rlcommand in self.readline_parse_and_bind:
1843 for rlcommand in self.readline_parse_and_bind:
1844 #print "loading rl:",rlcommand # dbg
1844 #print "loading rl:",rlcommand # dbg
1845 readline.parse_and_bind(rlcommand)
1845 readline.parse_and_bind(rlcommand)
1846
1846
1847 # Remove some chars from the delimiters list. If we encounter
1847 # Remove some chars from the delimiters list. If we encounter
1848 # unicode chars, discard them.
1848 # unicode chars, discard them.
1849 delims = readline.get_completer_delims()
1849 delims = readline.get_completer_delims()
1850 if not py3compat.PY3:
1850 if not py3compat.PY3:
1851 delims = delims.encode("ascii", "ignore")
1851 delims = delims.encode("ascii", "ignore")
1852 for d in self.readline_remove_delims:
1852 for d in self.readline_remove_delims:
1853 delims = delims.replace(d, "")
1853 delims = delims.replace(d, "")
1854 delims = delims.replace(ESC_MAGIC, '')
1854 delims = delims.replace(ESC_MAGIC, '')
1855 readline.set_completer_delims(delims)
1855 readline.set_completer_delims(delims)
1856 # Store these so we can restore them if something like rpy2 modifies
1856 # Store these so we can restore them if something like rpy2 modifies
1857 # them.
1857 # them.
1858 self.readline_delims = delims
1858 self.readline_delims = delims
1859 # otherwise we end up with a monster history after a while:
1859 # otherwise we end up with a monster history after a while:
1860 readline.set_history_length(self.history_length)
1860 readline.set_history_length(self.history_length)
1861
1861
1862 self.refill_readline_hist()
1862 self.refill_readline_hist()
1863 self.readline_no_record = ReadlineNoRecord(self)
1863 self.readline_no_record = ReadlineNoRecord(self)
1864
1864
1865 # Configure auto-indent for all platforms
1865 # Configure auto-indent for all platforms
1866 self.set_autoindent(self.autoindent)
1866 self.set_autoindent(self.autoindent)
1867
1867
1868 def refill_readline_hist(self):
1868 def refill_readline_hist(self):
1869 # Load the last 1000 lines from history
1869 # Load the last 1000 lines from history
1870 self.readline.clear_history()
1870 self.readline.clear_history()
1871 stdin_encoding = sys.stdin.encoding or "utf-8"
1871 stdin_encoding = sys.stdin.encoding or "utf-8"
1872 last_cell = u""
1872 last_cell = u""
1873 for _, _, cell in self.history_manager.get_tail(1000,
1873 for _, _, cell in self.history_manager.get_tail(1000,
1874 include_latest=True):
1874 include_latest=True):
1875 # Ignore blank lines and consecutive duplicates
1875 # Ignore blank lines and consecutive duplicates
1876 cell = cell.rstrip()
1876 cell = cell.rstrip()
1877 if cell and (cell != last_cell):
1877 if cell and (cell != last_cell):
1878 try:
1878 try:
1879 if self.multiline_history:
1879 if self.multiline_history:
1880 self.readline.add_history(py3compat.unicode_to_str(cell,
1880 self.readline.add_history(py3compat.unicode_to_str(cell,
1881 stdin_encoding))
1881 stdin_encoding))
1882 else:
1882 else:
1883 for line in cell.splitlines():
1883 for line in cell.splitlines():
1884 self.readline.add_history(py3compat.unicode_to_str(line,
1884 self.readline.add_history(py3compat.unicode_to_str(line,
1885 stdin_encoding))
1885 stdin_encoding))
1886 last_cell = cell
1886 last_cell = cell
1887
1887
1888 except TypeError:
1888 except TypeError:
1889 # The history DB can get corrupted so it returns strings
1889 # The history DB can get corrupted so it returns strings
1890 # containing null bytes, which readline objects to.
1890 # containing null bytes, which readline objects to.
1891 continue
1891 continue
1892
1892
1893 @skip_doctest
1893 @skip_doctest
1894 def set_next_input(self, s):
1894 def set_next_input(self, s):
1895 """ Sets the 'default' input string for the next command line.
1895 """ Sets the 'default' input string for the next command line.
1896
1896
1897 Requires readline.
1897 Requires readline.
1898
1898
1899 Example::
1899 Example::
1900
1900
1901 In [1]: _ip.set_next_input("Hello Word")
1901 In [1]: _ip.set_next_input("Hello Word")
1902 In [2]: Hello Word_ # cursor is here
1902 In [2]: Hello Word_ # cursor is here
1903 """
1903 """
1904 self.rl_next_input = py3compat.cast_bytes_py2(s)
1904 self.rl_next_input = py3compat.cast_bytes_py2(s)
1905
1905
1906 # Maybe move this to the terminal subclass?
1906 # Maybe move this to the terminal subclass?
1907 def pre_readline(self):
1907 def pre_readline(self):
1908 """readline hook to be used at the start of each line.
1908 """readline hook to be used at the start of each line.
1909
1909
1910 Currently it handles auto-indent only."""
1910 Currently it handles auto-indent only."""
1911
1911
1912 if self.rl_do_indent:
1912 if self.rl_do_indent:
1913 self.readline.insert_text(self._indent_current_str())
1913 self.readline.insert_text(self._indent_current_str())
1914 if self.rl_next_input is not None:
1914 if self.rl_next_input is not None:
1915 self.readline.insert_text(self.rl_next_input)
1915 self.readline.insert_text(self.rl_next_input)
1916 self.rl_next_input = None
1916 self.rl_next_input = None
1917
1917
1918 def _indent_current_str(self):
1918 def _indent_current_str(self):
1919 """return the current level of indentation as a string"""
1919 """return the current level of indentation as a string"""
1920 return self.input_splitter.indent_spaces * ' '
1920 return self.input_splitter.indent_spaces * ' '
1921
1921
1922 #-------------------------------------------------------------------------
1922 #-------------------------------------------------------------------------
1923 # Things related to text completion
1923 # Things related to text completion
1924 #-------------------------------------------------------------------------
1924 #-------------------------------------------------------------------------
1925
1925
1926 def init_completer(self):
1926 def init_completer(self):
1927 """Initialize the completion machinery.
1927 """Initialize the completion machinery.
1928
1928
1929 This creates completion machinery that can be used by client code,
1929 This creates completion machinery that can be used by client code,
1930 either interactively in-process (typically triggered by the readline
1930 either interactively in-process (typically triggered by the readline
1931 library), programatically (such as in test suites) or out-of-prcess
1931 library), programatically (such as in test suites) or out-of-prcess
1932 (typically over the network by remote frontends).
1932 (typically over the network by remote frontends).
1933 """
1933 """
1934 from IPython.core.completer import IPCompleter
1934 from IPython.core.completer import IPCompleter
1935 from IPython.core.completerlib import (module_completer,
1935 from IPython.core.completerlib import (module_completer,
1936 magic_run_completer, cd_completer, reset_completer)
1936 magic_run_completer, cd_completer, reset_completer)
1937
1937
1938 self.Completer = IPCompleter(shell=self,
1938 self.Completer = IPCompleter(shell=self,
1939 namespace=self.user_ns,
1939 namespace=self.user_ns,
1940 global_namespace=self.user_global_ns,
1940 global_namespace=self.user_global_ns,
1941 use_readline=self.has_readline,
1941 use_readline=self.has_readline,
1942 parent=self,
1942 parent=self,
1943 )
1943 )
1944 self.configurables.append(self.Completer)
1944 self.configurables.append(self.Completer)
1945
1945
1946 # Add custom completers to the basic ones built into IPCompleter
1946 # Add custom completers to the basic ones built into IPCompleter
1947 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1947 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1948 self.strdispatchers['complete_command'] = sdisp
1948 self.strdispatchers['complete_command'] = sdisp
1949 self.Completer.custom_completers = sdisp
1949 self.Completer.custom_completers = sdisp
1950
1950
1951 self.set_hook('complete_command', module_completer, str_key = 'import')
1951 self.set_hook('complete_command', module_completer, str_key = 'import')
1952 self.set_hook('complete_command', module_completer, str_key = 'from')
1952 self.set_hook('complete_command', module_completer, str_key = 'from')
1953 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1953 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1954 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1954 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1955 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1955 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1956
1956
1957 # Only configure readline if we truly are using readline. IPython can
1957 # Only configure readline if we truly are using readline. IPython can
1958 # do tab-completion over the network, in GUIs, etc, where readline
1958 # do tab-completion over the network, in GUIs, etc, where readline
1959 # itself may be absent
1959 # itself may be absent
1960 if self.has_readline:
1960 if self.has_readline:
1961 self.set_readline_completer()
1961 self.set_readline_completer()
1962
1962
1963 def complete(self, text, line=None, cursor_pos=None):
1963 def complete(self, text, line=None, cursor_pos=None):
1964 """Return the completed text and a list of completions.
1964 """Return the completed text and a list of completions.
1965
1965
1966 Parameters
1966 Parameters
1967 ----------
1967 ----------
1968
1968
1969 text : string
1969 text : string
1970 A string of text to be completed on. It can be given as empty and
1970 A string of text to be completed on. It can be given as empty and
1971 instead a line/position pair are given. In this case, the
1971 instead a line/position pair are given. In this case, the
1972 completer itself will split the line like readline does.
1972 completer itself will split the line like readline does.
1973
1973
1974 line : string, optional
1974 line : string, optional
1975 The complete line that text is part of.
1975 The complete line that text is part of.
1976
1976
1977 cursor_pos : int, optional
1977 cursor_pos : int, optional
1978 The position of the cursor on the input line.
1978 The position of the cursor on the input line.
1979
1979
1980 Returns
1980 Returns
1981 -------
1981 -------
1982 text : string
1982 text : string
1983 The actual text that was completed.
1983 The actual text that was completed.
1984
1984
1985 matches : list
1985 matches : list
1986 A sorted list with all possible completions.
1986 A sorted list with all possible completions.
1987
1987
1988 The optional arguments allow the completion to take more context into
1988 The optional arguments allow the completion to take more context into
1989 account, and are part of the low-level completion API.
1989 account, and are part of the low-level completion API.
1990
1990
1991 This is a wrapper around the completion mechanism, similar to what
1991 This is a wrapper around the completion mechanism, similar to what
1992 readline does at the command line when the TAB key is hit. By
1992 readline does at the command line when the TAB key is hit. By
1993 exposing it as a method, it can be used by other non-readline
1993 exposing it as a method, it can be used by other non-readline
1994 environments (such as GUIs) for text completion.
1994 environments (such as GUIs) for text completion.
1995
1995
1996 Simple usage example:
1996 Simple usage example:
1997
1997
1998 In [1]: x = 'hello'
1998 In [1]: x = 'hello'
1999
1999
2000 In [2]: _ip.complete('x.l')
2000 In [2]: _ip.complete('x.l')
2001 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2001 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2002 """
2002 """
2003
2003
2004 # Inject names into __builtin__ so we can complete on the added names.
2004 # Inject names into __builtin__ so we can complete on the added names.
2005 with self.builtin_trap:
2005 with self.builtin_trap:
2006 return self.Completer.complete(text, line, cursor_pos)
2006 return self.Completer.complete(text, line, cursor_pos)
2007
2007
2008 def set_custom_completer(self, completer, pos=0):
2008 def set_custom_completer(self, completer, pos=0):
2009 """Adds a new custom completer function.
2009 """Adds a new custom completer function.
2010
2010
2011 The position argument (defaults to 0) is the index in the completers
2011 The position argument (defaults to 0) is the index in the completers
2012 list where you want the completer to be inserted."""
2012 list where you want the completer to be inserted."""
2013
2013
2014 newcomp = types.MethodType(completer,self.Completer)
2014 newcomp = types.MethodType(completer,self.Completer)
2015 self.Completer.matchers.insert(pos,newcomp)
2015 self.Completer.matchers.insert(pos,newcomp)
2016
2016
2017 def set_readline_completer(self):
2017 def set_readline_completer(self):
2018 """Reset readline's completer to be our own."""
2018 """Reset readline's completer to be our own."""
2019 self.readline.set_completer(self.Completer.rlcomplete)
2019 self.readline.set_completer(self.Completer.rlcomplete)
2020
2020
2021 def set_completer_frame(self, frame=None):
2021 def set_completer_frame(self, frame=None):
2022 """Set the frame of the completer."""
2022 """Set the frame of the completer."""
2023 if frame:
2023 if frame:
2024 self.Completer.namespace = frame.f_locals
2024 self.Completer.namespace = frame.f_locals
2025 self.Completer.global_namespace = frame.f_globals
2025 self.Completer.global_namespace = frame.f_globals
2026 else:
2026 else:
2027 self.Completer.namespace = self.user_ns
2027 self.Completer.namespace = self.user_ns
2028 self.Completer.global_namespace = self.user_global_ns
2028 self.Completer.global_namespace = self.user_global_ns
2029
2029
2030 #-------------------------------------------------------------------------
2030 #-------------------------------------------------------------------------
2031 # Things related to magics
2031 # Things related to magics
2032 #-------------------------------------------------------------------------
2032 #-------------------------------------------------------------------------
2033
2033
2034 def init_magics(self):
2034 def init_magics(self):
2035 from IPython.core import magics as m
2035 from IPython.core import magics as m
2036 self.magics_manager = magic.MagicsManager(shell=self,
2036 self.magics_manager = magic.MagicsManager(shell=self,
2037 parent=self,
2037 parent=self,
2038 user_magics=m.UserMagics(self))
2038 user_magics=m.UserMagics(self))
2039 self.configurables.append(self.magics_manager)
2039 self.configurables.append(self.magics_manager)
2040
2040
2041 # Expose as public API from the magics manager
2041 # Expose as public API from the magics manager
2042 self.register_magics = self.magics_manager.register
2042 self.register_magics = self.magics_manager.register
2043 self.define_magic = self.magics_manager.define_magic
2043 self.define_magic = self.magics_manager.define_magic
2044
2044
2045 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2045 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2046 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2046 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2047 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2047 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2048 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2048 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2049 )
2049 )
2050
2050
2051 # Register Magic Aliases
2051 # Register Magic Aliases
2052 mman = self.magics_manager
2052 mman = self.magics_manager
2053 # FIXME: magic aliases should be defined by the Magics classes
2053 # FIXME: magic aliases should be defined by the Magics classes
2054 # or in MagicsManager, not here
2054 # or in MagicsManager, not here
2055 mman.register_alias('ed', 'edit')
2055 mman.register_alias('ed', 'edit')
2056 mman.register_alias('hist', 'history')
2056 mman.register_alias('hist', 'history')
2057 mman.register_alias('rep', 'recall')
2057 mman.register_alias('rep', 'recall')
2058 mman.register_alias('SVG', 'svg', 'cell')
2058 mman.register_alias('SVG', 'svg', 'cell')
2059 mman.register_alias('HTML', 'html', 'cell')
2059 mman.register_alias('HTML', 'html', 'cell')
2060 mman.register_alias('file', 'writefile', 'cell')
2060 mman.register_alias('file', 'writefile', 'cell')
2061
2061
2062 # FIXME: Move the color initialization to the DisplayHook, which
2062 # FIXME: Move the color initialization to the DisplayHook, which
2063 # should be split into a prompt manager and displayhook. We probably
2063 # should be split into a prompt manager and displayhook. We probably
2064 # even need a centralize colors management object.
2064 # even need a centralize colors management object.
2065 self.magic('colors %s' % self.colors)
2065 self.magic('colors %s' % self.colors)
2066
2066
2067 # Defined here so that it's included in the documentation
2067 # Defined here so that it's included in the documentation
2068 @functools.wraps(magic.MagicsManager.register_function)
2068 @functools.wraps(magic.MagicsManager.register_function)
2069 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2069 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2070 self.magics_manager.register_function(func,
2070 self.magics_manager.register_function(func,
2071 magic_kind=magic_kind, magic_name=magic_name)
2071 magic_kind=magic_kind, magic_name=magic_name)
2072
2072
2073 def run_line_magic(self, magic_name, line):
2073 def run_line_magic(self, magic_name, line):
2074 """Execute the given line magic.
2074 """Execute the given line magic.
2075
2075
2076 Parameters
2076 Parameters
2077 ----------
2077 ----------
2078 magic_name : str
2078 magic_name : str
2079 Name of the desired magic function, without '%' prefix.
2079 Name of the desired magic function, without '%' prefix.
2080
2080
2081 line : str
2081 line : str
2082 The rest of the input line as a single string.
2082 The rest of the input line as a single string.
2083 """
2083 """
2084 fn = self.find_line_magic(magic_name)
2084 fn = self.find_line_magic(magic_name)
2085 if fn is None:
2085 if fn is None:
2086 cm = self.find_cell_magic(magic_name)
2086 cm = self.find_cell_magic(magic_name)
2087 etpl = "Line magic function `%%%s` not found%s."
2087 etpl = "Line magic function `%%%s` not found%s."
2088 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2088 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2089 'did you mean that instead?)' % magic_name )
2089 'did you mean that instead?)' % magic_name )
2090 error(etpl % (magic_name, extra))
2090 error(etpl % (magic_name, extra))
2091 else:
2091 else:
2092 # Note: this is the distance in the stack to the user's frame.
2092 # Note: this is the distance in the stack to the user's frame.
2093 # This will need to be updated if the internal calling logic gets
2093 # This will need to be updated if the internal calling logic gets
2094 # refactored, or else we'll be expanding the wrong variables.
2094 # refactored, or else we'll be expanding the wrong variables.
2095 stack_depth = 2
2095 stack_depth = 2
2096 magic_arg_s = self.var_expand(line, stack_depth)
2096 magic_arg_s = self.var_expand(line, stack_depth)
2097 # Put magic args in a list so we can call with f(*a) syntax
2097 # Put magic args in a list so we can call with f(*a) syntax
2098 args = [magic_arg_s]
2098 args = [magic_arg_s]
2099 kwargs = {}
2099 kwargs = {}
2100 # Grab local namespace if we need it:
2100 # Grab local namespace if we need it:
2101 if getattr(fn, "needs_local_scope", False):
2101 if getattr(fn, "needs_local_scope", False):
2102 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2102 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2103 with self.builtin_trap:
2103 with self.builtin_trap:
2104 result = fn(*args,**kwargs)
2104 result = fn(*args,**kwargs)
2105 return result
2105 return result
2106
2106
2107 def run_cell_magic(self, magic_name, line, cell):
2107 def run_cell_magic(self, magic_name, line, cell):
2108 """Execute the given cell magic.
2108 """Execute the given cell magic.
2109
2109
2110 Parameters
2110 Parameters
2111 ----------
2111 ----------
2112 magic_name : str
2112 magic_name : str
2113 Name of the desired magic function, without '%' prefix.
2113 Name of the desired magic function, without '%' prefix.
2114
2114
2115 line : str
2115 line : str
2116 The rest of the first input line as a single string.
2116 The rest of the first input line as a single string.
2117
2117
2118 cell : str
2118 cell : str
2119 The body of the cell as a (possibly multiline) string.
2119 The body of the cell as a (possibly multiline) string.
2120 """
2120 """
2121 fn = self.find_cell_magic(magic_name)
2121 fn = self.find_cell_magic(magic_name)
2122 if fn is None:
2122 if fn is None:
2123 lm = self.find_line_magic(magic_name)
2123 lm = self.find_line_magic(magic_name)
2124 etpl = "Cell magic `%%{0}` not found{1}."
2124 etpl = "Cell magic `%%{0}` not found{1}."
2125 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2125 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2126 'did you mean that instead?)'.format(magic_name))
2126 'did you mean that instead?)'.format(magic_name))
2127 error(etpl.format(magic_name, extra))
2127 error(etpl.format(magic_name, extra))
2128 elif cell == '':
2128 elif cell == '':
2129 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2129 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2130 if self.find_line_magic(magic_name) is not None:
2130 if self.find_line_magic(magic_name) is not None:
2131 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2131 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2132 raise UsageError(message)
2132 raise UsageError(message)
2133 else:
2133 else:
2134 # Note: this is the distance in the stack to the user's frame.
2134 # Note: this is the distance in the stack to the user's frame.
2135 # This will need to be updated if the internal calling logic gets
2135 # This will need to be updated if the internal calling logic gets
2136 # refactored, or else we'll be expanding the wrong variables.
2136 # refactored, or else we'll be expanding the wrong variables.
2137 stack_depth = 2
2137 stack_depth = 2
2138 magic_arg_s = self.var_expand(line, stack_depth)
2138 magic_arg_s = self.var_expand(line, stack_depth)
2139 with self.builtin_trap:
2139 with self.builtin_trap:
2140 result = fn(magic_arg_s, cell)
2140 result = fn(magic_arg_s, cell)
2141 return result
2141 return result
2142
2142
2143 def find_line_magic(self, magic_name):
2143 def find_line_magic(self, magic_name):
2144 """Find and return a line magic by name.
2144 """Find and return a line magic by name.
2145
2145
2146 Returns None if the magic isn't found."""
2146 Returns None if the magic isn't found."""
2147 return self.magics_manager.magics['line'].get(magic_name)
2147 return self.magics_manager.magics['line'].get(magic_name)
2148
2148
2149 def find_cell_magic(self, magic_name):
2149 def find_cell_magic(self, magic_name):
2150 """Find and return a cell magic by name.
2150 """Find and return a cell magic by name.
2151
2151
2152 Returns None if the magic isn't found."""
2152 Returns None if the magic isn't found."""
2153 return self.magics_manager.magics['cell'].get(magic_name)
2153 return self.magics_manager.magics['cell'].get(magic_name)
2154
2154
2155 def find_magic(self, magic_name, magic_kind='line'):
2155 def find_magic(self, magic_name, magic_kind='line'):
2156 """Find and return a magic of the given type by name.
2156 """Find and return a magic of the given type by name.
2157
2157
2158 Returns None if the magic isn't found."""
2158 Returns None if the magic isn't found."""
2159 return self.magics_manager.magics[magic_kind].get(magic_name)
2159 return self.magics_manager.magics[magic_kind].get(magic_name)
2160
2160
2161 def magic(self, arg_s):
2161 def magic(self, arg_s):
2162 """DEPRECATED. Use run_line_magic() instead.
2162 """DEPRECATED. Use run_line_magic() instead.
2163
2163
2164 Call a magic function by name.
2164 Call a magic function by name.
2165
2165
2166 Input: a string containing the name of the magic function to call and
2166 Input: a string containing the name of the magic function to call and
2167 any additional arguments to be passed to the magic.
2167 any additional arguments to be passed to the magic.
2168
2168
2169 magic('name -opt foo bar') is equivalent to typing at the ipython
2169 magic('name -opt foo bar') is equivalent to typing at the ipython
2170 prompt:
2170 prompt:
2171
2171
2172 In[1]: %name -opt foo bar
2172 In[1]: %name -opt foo bar
2173
2173
2174 To call a magic without arguments, simply use magic('name').
2174 To call a magic without arguments, simply use magic('name').
2175
2175
2176 This provides a proper Python function to call IPython's magics in any
2176 This provides a proper Python function to call IPython's magics in any
2177 valid Python code you can type at the interpreter, including loops and
2177 valid Python code you can type at the interpreter, including loops and
2178 compound statements.
2178 compound statements.
2179 """
2179 """
2180 # TODO: should we issue a loud deprecation warning here?
2180 # TODO: should we issue a loud deprecation warning here?
2181 magic_name, _, magic_arg_s = arg_s.partition(' ')
2181 magic_name, _, magic_arg_s = arg_s.partition(' ')
2182 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2182 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2183 return self.run_line_magic(magic_name, magic_arg_s)
2183 return self.run_line_magic(magic_name, magic_arg_s)
2184
2184
2185 #-------------------------------------------------------------------------
2185 #-------------------------------------------------------------------------
2186 # Things related to macros
2186 # Things related to macros
2187 #-------------------------------------------------------------------------
2187 #-------------------------------------------------------------------------
2188
2188
2189 def define_macro(self, name, themacro):
2189 def define_macro(self, name, themacro):
2190 """Define a new macro
2190 """Define a new macro
2191
2191
2192 Parameters
2192 Parameters
2193 ----------
2193 ----------
2194 name : str
2194 name : str
2195 The name of the macro.
2195 The name of the macro.
2196 themacro : str or Macro
2196 themacro : str or Macro
2197 The action to do upon invoking the macro. If a string, a new
2197 The action to do upon invoking the macro. If a string, a new
2198 Macro object is created by passing the string to it.
2198 Macro object is created by passing the string to it.
2199 """
2199 """
2200
2200
2201 from IPython.core import macro
2201 from IPython.core import macro
2202
2202
2203 if isinstance(themacro, basestring):
2203 if isinstance(themacro, basestring):
2204 themacro = macro.Macro(themacro)
2204 themacro = macro.Macro(themacro)
2205 if not isinstance(themacro, macro.Macro):
2205 if not isinstance(themacro, macro.Macro):
2206 raise ValueError('A macro must be a string or a Macro instance.')
2206 raise ValueError('A macro must be a string or a Macro instance.')
2207 self.user_ns[name] = themacro
2207 self.user_ns[name] = themacro
2208
2208
2209 #-------------------------------------------------------------------------
2209 #-------------------------------------------------------------------------
2210 # Things related to the running of system commands
2210 # Things related to the running of system commands
2211 #-------------------------------------------------------------------------
2211 #-------------------------------------------------------------------------
2212
2212
2213 def system_piped(self, cmd):
2213 def system_piped(self, cmd):
2214 """Call the given cmd in a subprocess, piping stdout/err
2214 """Call the given cmd in a subprocess, piping stdout/err
2215
2215
2216 Parameters
2216 Parameters
2217 ----------
2217 ----------
2218 cmd : str
2218 cmd : str
2219 Command to execute (can not end in '&', as background processes are
2219 Command to execute (can not end in '&', as background processes are
2220 not supported. Should not be a command that expects input
2220 not supported. Should not be a command that expects input
2221 other than simple text.
2221 other than simple text.
2222 """
2222 """
2223 if cmd.rstrip().endswith('&'):
2223 if cmd.rstrip().endswith('&'):
2224 # this is *far* from a rigorous test
2224 # this is *far* from a rigorous test
2225 # We do not support backgrounding processes because we either use
2225 # We do not support backgrounding processes because we either use
2226 # pexpect or pipes to read from. Users can always just call
2226 # pexpect or pipes to read from. Users can always just call
2227 # os.system() or use ip.system=ip.system_raw
2227 # os.system() or use ip.system=ip.system_raw
2228 # if they really want a background process.
2228 # if they really want a background process.
2229 raise OSError("Background processes not supported.")
2229 raise OSError("Background processes not supported.")
2230
2230
2231 # we explicitly do NOT return the subprocess status code, because
2231 # we explicitly do NOT return the subprocess status code, because
2232 # a non-None value would trigger :func:`sys.displayhook` calls.
2232 # a non-None value would trigger :func:`sys.displayhook` calls.
2233 # Instead, we store the exit_code in user_ns.
2233 # Instead, we store the exit_code in user_ns.
2234 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2234 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2235
2235
2236 def system_raw(self, cmd):
2236 def system_raw(self, cmd):
2237 """Call the given cmd in a subprocess using os.system on Windows or
2237 """Call the given cmd in a subprocess using os.system on Windows or
2238 subprocess.call using the system shell on other platforms.
2238 subprocess.call using the system shell on other platforms.
2239
2239
2240 Parameters
2240 Parameters
2241 ----------
2241 ----------
2242 cmd : str
2242 cmd : str
2243 Command to execute.
2243 Command to execute.
2244 """
2244 """
2245 cmd = self.var_expand(cmd, depth=1)
2245 cmd = self.var_expand(cmd, depth=1)
2246 # protect os.system from UNC paths on Windows, which it can't handle:
2246 # protect os.system from UNC paths on Windows, which it can't handle:
2247 if sys.platform == 'win32':
2247 if sys.platform == 'win32':
2248 from IPython.utils._process_win32 import AvoidUNCPath
2248 from IPython.utils._process_win32 import AvoidUNCPath
2249 with AvoidUNCPath() as path:
2249 with AvoidUNCPath() as path:
2250 if path is not None:
2250 if path is not None:
2251 cmd = '"pushd %s &&"%s' % (path, cmd)
2251 cmd = '"pushd %s &&"%s' % (path, cmd)
2252 cmd = py3compat.unicode_to_str(cmd)
2252 cmd = py3compat.unicode_to_str(cmd)
2253 ec = os.system(cmd)
2253 ec = os.system(cmd)
2254 else:
2254 else:
2255 cmd = py3compat.unicode_to_str(cmd)
2255 cmd = py3compat.unicode_to_str(cmd)
2256 # Call the cmd using the OS shell, instead of the default /bin/sh, if set.
2256 # Call the cmd using the OS shell, instead of the default /bin/sh, if set.
2257 ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None))
2257 ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None))
2258 # exit code is positive for program failure, or negative for
2258 # exit code is positive for program failure, or negative for
2259 # terminating signal number.
2259 # terminating signal number.
2260
2260
2261 # We explicitly do NOT return the subprocess status code, because
2261 # We explicitly do NOT return the subprocess status code, because
2262 # a non-None value would trigger :func:`sys.displayhook` calls.
2262 # a non-None value would trigger :func:`sys.displayhook` calls.
2263 # Instead, we store the exit_code in user_ns.
2263 # Instead, we store the exit_code in user_ns.
2264 self.user_ns['_exit_code'] = ec
2264 self.user_ns['_exit_code'] = ec
2265
2265
2266 # use piped system by default, because it is better behaved
2266 # use piped system by default, because it is better behaved
2267 system = system_piped
2267 system = system_piped
2268
2268
2269 def getoutput(self, cmd, split=True, depth=0):
2269 def getoutput(self, cmd, split=True, depth=0):
2270 """Get output (possibly including stderr) from a subprocess.
2270 """Get output (possibly including stderr) from a subprocess.
2271
2271
2272 Parameters
2272 Parameters
2273 ----------
2273 ----------
2274 cmd : str
2274 cmd : str
2275 Command to execute (can not end in '&', as background processes are
2275 Command to execute (can not end in '&', as background processes are
2276 not supported.
2276 not supported.
2277 split : bool, optional
2277 split : bool, optional
2278 If True, split the output into an IPython SList. Otherwise, an
2278 If True, split the output into an IPython SList. Otherwise, an
2279 IPython LSString is returned. These are objects similar to normal
2279 IPython LSString is returned. These are objects similar to normal
2280 lists and strings, with a few convenience attributes for easier
2280 lists and strings, with a few convenience attributes for easier
2281 manipulation of line-based output. You can use '?' on them for
2281 manipulation of line-based output. You can use '?' on them for
2282 details.
2282 details.
2283 depth : int, optional
2283 depth : int, optional
2284 How many frames above the caller are the local variables which should
2284 How many frames above the caller are the local variables which should
2285 be expanded in the command string? The default (0) assumes that the
2285 be expanded in the command string? The default (0) assumes that the
2286 expansion variables are in the stack frame calling this function.
2286 expansion variables are in the stack frame calling this function.
2287 """
2287 """
2288 if cmd.rstrip().endswith('&'):
2288 if cmd.rstrip().endswith('&'):
2289 # this is *far* from a rigorous test
2289 # this is *far* from a rigorous test
2290 raise OSError("Background processes not supported.")
2290 raise OSError("Background processes not supported.")
2291 out = getoutput(self.var_expand(cmd, depth=depth+1))
2291 out = getoutput(self.var_expand(cmd, depth=depth+1))
2292 if split:
2292 if split:
2293 out = SList(out.splitlines())
2293 out = SList(out.splitlines())
2294 else:
2294 else:
2295 out = LSString(out)
2295 out = LSString(out)
2296 return out
2296 return out
2297
2297
2298 #-------------------------------------------------------------------------
2298 #-------------------------------------------------------------------------
2299 # Things related to aliases
2299 # Things related to aliases
2300 #-------------------------------------------------------------------------
2300 #-------------------------------------------------------------------------
2301
2301
2302 def init_alias(self):
2302 def init_alias(self):
2303 self.alias_manager = AliasManager(shell=self, parent=self)
2303 self.alias_manager = AliasManager(shell=self, parent=self)
2304 self.configurables.append(self.alias_manager)
2304 self.configurables.append(self.alias_manager)
2305
2305
2306 #-------------------------------------------------------------------------
2306 #-------------------------------------------------------------------------
2307 # Things related to extensions
2307 # Things related to extensions
2308 #-------------------------------------------------------------------------
2308 #-------------------------------------------------------------------------
2309
2309
2310 def init_extension_manager(self):
2310 def init_extension_manager(self):
2311 self.extension_manager = ExtensionManager(shell=self, parent=self)
2311 self.extension_manager = ExtensionManager(shell=self, parent=self)
2312 self.configurables.append(self.extension_manager)
2312 self.configurables.append(self.extension_manager)
2313
2313
2314 #-------------------------------------------------------------------------
2314 #-------------------------------------------------------------------------
2315 # Things related to payloads
2315 # Things related to payloads
2316 #-------------------------------------------------------------------------
2316 #-------------------------------------------------------------------------
2317
2317
2318 def init_payload(self):
2318 def init_payload(self):
2319 self.payload_manager = PayloadManager(parent=self)
2319 self.payload_manager = PayloadManager(parent=self)
2320 self.configurables.append(self.payload_manager)
2320 self.configurables.append(self.payload_manager)
2321
2321
2322 #-------------------------------------------------------------------------
2322 #-------------------------------------------------------------------------
2323 # Things related to widgets
2323 # Things related to widgets
2324 #-------------------------------------------------------------------------
2324 #-------------------------------------------------------------------------
2325
2325
2326 def init_comms(self):
2326 def init_comms(self):
2327 # not implemented in the base class
2327 # not implemented in the base class
2328 pass
2328 pass
2329
2329
2330 #-------------------------------------------------------------------------
2330 #-------------------------------------------------------------------------
2331 # Things related to the prefilter
2331 # Things related to the prefilter
2332 #-------------------------------------------------------------------------
2332 #-------------------------------------------------------------------------
2333
2333
2334 def init_prefilter(self):
2334 def init_prefilter(self):
2335 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2335 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2336 self.configurables.append(self.prefilter_manager)
2336 self.configurables.append(self.prefilter_manager)
2337 # Ultimately this will be refactored in the new interpreter code, but
2337 # Ultimately this will be refactored in the new interpreter code, but
2338 # for now, we should expose the main prefilter method (there's legacy
2338 # for now, we should expose the main prefilter method (there's legacy
2339 # code out there that may rely on this).
2339 # code out there that may rely on this).
2340 self.prefilter = self.prefilter_manager.prefilter_lines
2340 self.prefilter = self.prefilter_manager.prefilter_lines
2341
2341
2342 def auto_rewrite_input(self, cmd):
2342 def auto_rewrite_input(self, cmd):
2343 """Print to the screen the rewritten form of the user's command.
2343 """Print to the screen the rewritten form of the user's command.
2344
2344
2345 This shows visual feedback by rewriting input lines that cause
2345 This shows visual feedback by rewriting input lines that cause
2346 automatic calling to kick in, like::
2346 automatic calling to kick in, like::
2347
2347
2348 /f x
2348 /f x
2349
2349
2350 into::
2350 into::
2351
2351
2352 ------> f(x)
2352 ------> f(x)
2353
2353
2354 after the user's input prompt. This helps the user understand that the
2354 after the user's input prompt. This helps the user understand that the
2355 input line was transformed automatically by IPython.
2355 input line was transformed automatically by IPython.
2356 """
2356 """
2357 if not self.show_rewritten_input:
2357 if not self.show_rewritten_input:
2358 return
2358 return
2359
2359
2360 rw = self.prompt_manager.render('rewrite') + cmd
2360 rw = self.prompt_manager.render('rewrite') + cmd
2361
2361
2362 try:
2362 try:
2363 # plain ascii works better w/ pyreadline, on some machines, so
2363 # plain ascii works better w/ pyreadline, on some machines, so
2364 # we use it and only print uncolored rewrite if we have unicode
2364 # we use it and only print uncolored rewrite if we have unicode
2365 rw = str(rw)
2365 rw = str(rw)
2366 print(rw, file=io.stdout)
2366 print(rw, file=io.stdout)
2367 except UnicodeEncodeError:
2367 except UnicodeEncodeError:
2368 print("------> " + cmd)
2368 print("------> " + cmd)
2369
2369
2370 #-------------------------------------------------------------------------
2370 #-------------------------------------------------------------------------
2371 # Things related to extracting values/expressions from kernel and user_ns
2371 # Things related to extracting values/expressions from kernel and user_ns
2372 #-------------------------------------------------------------------------
2372 #-------------------------------------------------------------------------
2373
2373
2374 def _user_obj_error(self):
2374 def _user_obj_error(self):
2375 """return simple exception dict
2375 """return simple exception dict
2376
2376
2377 for use in user_variables / expressions
2377 for use in user_variables / expressions
2378 """
2378 """
2379
2379
2380 etype, evalue, tb = self._get_exc_info()
2380 etype, evalue, tb = self._get_exc_info()
2381 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2381 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2382
2382
2383 exc_info = {
2383 exc_info = {
2384 u'status' : 'error',
2384 u'status' : 'error',
2385 u'traceback' : stb,
2385 u'traceback' : stb,
2386 u'ename' : unicode(etype.__name__),
2386 u'ename' : unicode(etype.__name__),
2387 u'evalue' : py3compat.safe_unicode(evalue),
2387 u'evalue' : py3compat.safe_unicode(evalue),
2388 }
2388 }
2389
2389
2390 return exc_info
2390 return exc_info
2391
2391
2392 def _format_user_obj(self, obj):
2392 def _format_user_obj(self, obj):
2393 """format a user object to display dict
2393 """format a user object to display dict
2394
2394
2395 for use in user_expressions / variables
2395 for use in user_expressions / variables
2396 """
2396 """
2397
2397
2398 data, md = self.display_formatter.format(obj)
2398 data, md = self.display_formatter.format(obj)
2399 value = {
2399 value = {
2400 'status' : 'ok',
2400 'status' : 'ok',
2401 'data' : data,
2401 'data' : data,
2402 'metadata' : md,
2402 'metadata' : md,
2403 }
2403 }
2404 return value
2404 return value
2405
2405
2406 def user_variables(self, names):
2406 def user_variables(self, names):
2407 """Get a list of variable names from the user's namespace.
2407 """Get a list of variable names from the user's namespace.
2408
2408
2409 Parameters
2409 Parameters
2410 ----------
2410 ----------
2411 names : list of strings
2411 names : list of strings
2412 A list of names of variables to be read from the user namespace.
2412 A list of names of variables to be read from the user namespace.
2413
2413
2414 Returns
2414 Returns
2415 -------
2415 -------
2416 A dict, keyed by the input names and with the rich mime-type repr(s) of each value.
2416 A dict, keyed by the input names and with the rich mime-type repr(s) of each value.
2417 Each element will be a sub-dict of the same form as a display_data message.
2417 Each element will be a sub-dict of the same form as a display_data message.
2418 """
2418 """
2419 out = {}
2419 out = {}
2420 user_ns = self.user_ns
2420 user_ns = self.user_ns
2421
2421
2422 for varname in names:
2422 for varname in names:
2423 try:
2423 try:
2424 value = self._format_user_obj(user_ns[varname])
2424 value = self._format_user_obj(user_ns[varname])
2425 except:
2425 except:
2426 value = self._user_obj_error()
2426 value = self._user_obj_error()
2427 out[varname] = value
2427 out[varname] = value
2428 return out
2428 return out
2429
2429
2430 def user_expressions(self, expressions):
2430 def user_expressions(self, expressions):
2431 """Evaluate a dict of expressions in the user's namespace.
2431 """Evaluate a dict of expressions in the user's namespace.
2432
2432
2433 Parameters
2433 Parameters
2434 ----------
2434 ----------
2435 expressions : dict
2435 expressions : dict
2436 A dict with string keys and string values. The expression values
2436 A dict with string keys and string values. The expression values
2437 should be valid Python expressions, each of which will be evaluated
2437 should be valid Python expressions, each of which will be evaluated
2438 in the user namespace.
2438 in the user namespace.
2439
2439
2440 Returns
2440 Returns
2441 -------
2441 -------
2442 A dict, keyed like the input expressions dict, with the rich mime-typed
2442 A dict, keyed like the input expressions dict, with the rich mime-typed
2443 display_data of each value.
2443 display_data of each value.
2444 """
2444 """
2445 out = {}
2445 out = {}
2446 user_ns = self.user_ns
2446 user_ns = self.user_ns
2447 global_ns = self.user_global_ns
2447 global_ns = self.user_global_ns
2448
2448
2449 for key, expr in expressions.iteritems():
2449 for key, expr in expressions.iteritems():
2450 try:
2450 try:
2451 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2451 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2452 except:
2452 except:
2453 value = self._user_obj_error()
2453 value = self._user_obj_error()
2454 out[key] = value
2454 out[key] = value
2455 return out
2455 return out
2456
2456
2457 #-------------------------------------------------------------------------
2457 #-------------------------------------------------------------------------
2458 # Things related to the running of code
2458 # Things related to the running of code
2459 #-------------------------------------------------------------------------
2459 #-------------------------------------------------------------------------
2460
2460
2461 def ex(self, cmd):
2461 def ex(self, cmd):
2462 """Execute a normal python statement in user namespace."""
2462 """Execute a normal python statement in user namespace."""
2463 with self.builtin_trap:
2463 with self.builtin_trap:
2464 exec cmd in self.user_global_ns, self.user_ns
2464 exec(cmd, self.user_global_ns, self.user_ns)
2465
2465
2466 def ev(self, expr):
2466 def ev(self, expr):
2467 """Evaluate python expression expr in user namespace.
2467 """Evaluate python expression expr in user namespace.
2468
2468
2469 Returns the result of evaluation
2469 Returns the result of evaluation
2470 """
2470 """
2471 with self.builtin_trap:
2471 with self.builtin_trap:
2472 return eval(expr, self.user_global_ns, self.user_ns)
2472 return eval(expr, self.user_global_ns, self.user_ns)
2473
2473
2474 def safe_execfile(self, fname, *where, **kw):
2474 def safe_execfile(self, fname, *where, **kw):
2475 """A safe version of the builtin execfile().
2475 """A safe version of the builtin execfile().
2476
2476
2477 This version will never throw an exception, but instead print
2477 This version will never throw an exception, but instead print
2478 helpful error messages to the screen. This only works on pure
2478 helpful error messages to the screen. This only works on pure
2479 Python files with the .py extension.
2479 Python files with the .py extension.
2480
2480
2481 Parameters
2481 Parameters
2482 ----------
2482 ----------
2483 fname : string
2483 fname : string
2484 The name of the file to be executed.
2484 The name of the file to be executed.
2485 where : tuple
2485 where : tuple
2486 One or two namespaces, passed to execfile() as (globals,locals).
2486 One or two namespaces, passed to execfile() as (globals,locals).
2487 If only one is given, it is passed as both.
2487 If only one is given, it is passed as both.
2488 exit_ignore : bool (False)
2488 exit_ignore : bool (False)
2489 If True, then silence SystemExit for non-zero status (it is always
2489 If True, then silence SystemExit for non-zero status (it is always
2490 silenced for zero status, as it is so common).
2490 silenced for zero status, as it is so common).
2491 raise_exceptions : bool (False)
2491 raise_exceptions : bool (False)
2492 If True raise exceptions everywhere. Meant for testing.
2492 If True raise exceptions everywhere. Meant for testing.
2493
2493
2494 """
2494 """
2495 kw.setdefault('exit_ignore', False)
2495 kw.setdefault('exit_ignore', False)
2496 kw.setdefault('raise_exceptions', False)
2496 kw.setdefault('raise_exceptions', False)
2497
2497
2498 fname = os.path.abspath(os.path.expanduser(fname))
2498 fname = os.path.abspath(os.path.expanduser(fname))
2499
2499
2500 # Make sure we can open the file
2500 # Make sure we can open the file
2501 try:
2501 try:
2502 with open(fname) as thefile:
2502 with open(fname) as thefile:
2503 pass
2503 pass
2504 except:
2504 except:
2505 warn('Could not open file <%s> for safe execution.' % fname)
2505 warn('Could not open file <%s> for safe execution.' % fname)
2506 return
2506 return
2507
2507
2508 # Find things also in current directory. This is needed to mimic the
2508 # Find things also in current directory. This is needed to mimic the
2509 # behavior of running a script from the system command line, where
2509 # behavior of running a script from the system command line, where
2510 # Python inserts the script's directory into sys.path
2510 # Python inserts the script's directory into sys.path
2511 dname = os.path.dirname(fname)
2511 dname = os.path.dirname(fname)
2512
2512
2513 with prepended_to_syspath(dname):
2513 with prepended_to_syspath(dname):
2514 try:
2514 try:
2515 py3compat.execfile(fname,*where)
2515 py3compat.execfile(fname,*where)
2516 except SystemExit as status:
2516 except SystemExit as status:
2517 # If the call was made with 0 or None exit status (sys.exit(0)
2517 # If the call was made with 0 or None exit status (sys.exit(0)
2518 # or sys.exit() ), don't bother showing a traceback, as both of
2518 # or sys.exit() ), don't bother showing a traceback, as both of
2519 # these are considered normal by the OS:
2519 # these are considered normal by the OS:
2520 # > python -c'import sys;sys.exit(0)'; echo $?
2520 # > python -c'import sys;sys.exit(0)'; echo $?
2521 # 0
2521 # 0
2522 # > python -c'import sys;sys.exit()'; echo $?
2522 # > python -c'import sys;sys.exit()'; echo $?
2523 # 0
2523 # 0
2524 # For other exit status, we show the exception unless
2524 # For other exit status, we show the exception unless
2525 # explicitly silenced, but only in short form.
2525 # explicitly silenced, but only in short form.
2526 if kw['raise_exceptions']:
2526 if kw['raise_exceptions']:
2527 raise
2527 raise
2528 if status.code and not kw['exit_ignore']:
2528 if status.code and not kw['exit_ignore']:
2529 self.showtraceback(exception_only=True)
2529 self.showtraceback(exception_only=True)
2530 except:
2530 except:
2531 if kw['raise_exceptions']:
2531 if kw['raise_exceptions']:
2532 raise
2532 raise
2533 self.showtraceback()
2533 self.showtraceback()
2534
2534
2535 def safe_execfile_ipy(self, fname):
2535 def safe_execfile_ipy(self, fname):
2536 """Like safe_execfile, but for .ipy files with IPython syntax.
2536 """Like safe_execfile, but for .ipy files with IPython syntax.
2537
2537
2538 Parameters
2538 Parameters
2539 ----------
2539 ----------
2540 fname : str
2540 fname : str
2541 The name of the file to execute. The filename must have a
2541 The name of the file to execute. The filename must have a
2542 .ipy extension.
2542 .ipy extension.
2543 """
2543 """
2544 fname = os.path.abspath(os.path.expanduser(fname))
2544 fname = os.path.abspath(os.path.expanduser(fname))
2545
2545
2546 # Make sure we can open the file
2546 # Make sure we can open the file
2547 try:
2547 try:
2548 with open(fname) as thefile:
2548 with open(fname) as thefile:
2549 pass
2549 pass
2550 except:
2550 except:
2551 warn('Could not open file <%s> for safe execution.' % fname)
2551 warn('Could not open file <%s> for safe execution.' % fname)
2552 return
2552 return
2553
2553
2554 # Find things also in current directory. This is needed to mimic the
2554 # Find things also in current directory. This is needed to mimic the
2555 # behavior of running a script from the system command line, where
2555 # behavior of running a script from the system command line, where
2556 # Python inserts the script's directory into sys.path
2556 # Python inserts the script's directory into sys.path
2557 dname = os.path.dirname(fname)
2557 dname = os.path.dirname(fname)
2558
2558
2559 with prepended_to_syspath(dname):
2559 with prepended_to_syspath(dname):
2560 try:
2560 try:
2561 with open(fname) as thefile:
2561 with open(fname) as thefile:
2562 # self.run_cell currently captures all exceptions
2562 # self.run_cell currently captures all exceptions
2563 # raised in user code. It would be nice if there were
2563 # raised in user code. It would be nice if there were
2564 # versions of runlines, execfile that did raise, so
2564 # versions of runlines, execfile that did raise, so
2565 # we could catch the errors.
2565 # we could catch the errors.
2566 self.run_cell(thefile.read(), store_history=False, shell_futures=False)
2566 self.run_cell(thefile.read(), store_history=False, shell_futures=False)
2567 except:
2567 except:
2568 self.showtraceback()
2568 self.showtraceback()
2569 warn('Unknown failure executing file: <%s>' % fname)
2569 warn('Unknown failure executing file: <%s>' % fname)
2570
2570
2571 def safe_run_module(self, mod_name, where):
2571 def safe_run_module(self, mod_name, where):
2572 """A safe version of runpy.run_module().
2572 """A safe version of runpy.run_module().
2573
2573
2574 This version will never throw an exception, but instead print
2574 This version will never throw an exception, but instead print
2575 helpful error messages to the screen.
2575 helpful error messages to the screen.
2576
2576
2577 `SystemExit` exceptions with status code 0 or None are ignored.
2577 `SystemExit` exceptions with status code 0 or None are ignored.
2578
2578
2579 Parameters
2579 Parameters
2580 ----------
2580 ----------
2581 mod_name : string
2581 mod_name : string
2582 The name of the module to be executed.
2582 The name of the module to be executed.
2583 where : dict
2583 where : dict
2584 The globals namespace.
2584 The globals namespace.
2585 """
2585 """
2586 try:
2586 try:
2587 try:
2587 try:
2588 where.update(
2588 where.update(
2589 runpy.run_module(str(mod_name), run_name="__main__",
2589 runpy.run_module(str(mod_name), run_name="__main__",
2590 alter_sys=True)
2590 alter_sys=True)
2591 )
2591 )
2592 except SystemExit as status:
2592 except SystemExit as status:
2593 if status.code:
2593 if status.code:
2594 raise
2594 raise
2595 except:
2595 except:
2596 self.showtraceback()
2596 self.showtraceback()
2597 warn('Unknown failure executing module: <%s>' % mod_name)
2597 warn('Unknown failure executing module: <%s>' % mod_name)
2598
2598
2599 def _run_cached_cell_magic(self, magic_name, line):
2599 def _run_cached_cell_magic(self, magic_name, line):
2600 """Special method to call a cell magic with the data stored in self.
2600 """Special method to call a cell magic with the data stored in self.
2601 """
2601 """
2602 cell = self._current_cell_magic_body
2602 cell = self._current_cell_magic_body
2603 self._current_cell_magic_body = None
2603 self._current_cell_magic_body = None
2604 return self.run_cell_magic(magic_name, line, cell)
2604 return self.run_cell_magic(magic_name, line, cell)
2605
2605
2606 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2606 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2607 """Run a complete IPython cell.
2607 """Run a complete IPython cell.
2608
2608
2609 Parameters
2609 Parameters
2610 ----------
2610 ----------
2611 raw_cell : str
2611 raw_cell : str
2612 The code (including IPython code such as %magic functions) to run.
2612 The code (including IPython code such as %magic functions) to run.
2613 store_history : bool
2613 store_history : bool
2614 If True, the raw and translated cell will be stored in IPython's
2614 If True, the raw and translated cell will be stored in IPython's
2615 history. For user code calling back into IPython's machinery, this
2615 history. For user code calling back into IPython's machinery, this
2616 should be set to False.
2616 should be set to False.
2617 silent : bool
2617 silent : bool
2618 If True, avoid side-effects, such as implicit displayhooks and
2618 If True, avoid side-effects, such as implicit displayhooks and
2619 and logging. silent=True forces store_history=False.
2619 and logging. silent=True forces store_history=False.
2620 shell_futures : bool
2620 shell_futures : bool
2621 If True, the code will share future statements with the interactive
2621 If True, the code will share future statements with the interactive
2622 shell. It will both be affected by previous __future__ imports, and
2622 shell. It will both be affected by previous __future__ imports, and
2623 any __future__ imports in the code will affect the shell. If False,
2623 any __future__ imports in the code will affect the shell. If False,
2624 __future__ imports are not shared in either direction.
2624 __future__ imports are not shared in either direction.
2625 """
2625 """
2626 if (not raw_cell) or raw_cell.isspace():
2626 if (not raw_cell) or raw_cell.isspace():
2627 return
2627 return
2628
2628
2629 if silent:
2629 if silent:
2630 store_history = False
2630 store_history = False
2631
2631
2632 self.input_transformer_manager.push(raw_cell)
2632 self.input_transformer_manager.push(raw_cell)
2633 cell = self.input_transformer_manager.source_reset()
2633 cell = self.input_transformer_manager.source_reset()
2634
2634
2635 # Our own compiler remembers the __future__ environment. If we want to
2635 # Our own compiler remembers the __future__ environment. If we want to
2636 # run code with a separate __future__ environment, use the default
2636 # run code with a separate __future__ environment, use the default
2637 # compiler
2637 # compiler
2638 compiler = self.compile if shell_futures else CachingCompiler()
2638 compiler = self.compile if shell_futures else CachingCompiler()
2639
2639
2640 with self.builtin_trap:
2640 with self.builtin_trap:
2641 prefilter_failed = False
2641 prefilter_failed = False
2642 if len(cell.splitlines()) == 1:
2642 if len(cell.splitlines()) == 1:
2643 try:
2643 try:
2644 # use prefilter_lines to handle trailing newlines
2644 # use prefilter_lines to handle trailing newlines
2645 # restore trailing newline for ast.parse
2645 # restore trailing newline for ast.parse
2646 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2646 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2647 except AliasError as e:
2647 except AliasError as e:
2648 error(e)
2648 error(e)
2649 prefilter_failed = True
2649 prefilter_failed = True
2650 except Exception:
2650 except Exception:
2651 # don't allow prefilter errors to crash IPython
2651 # don't allow prefilter errors to crash IPython
2652 self.showtraceback()
2652 self.showtraceback()
2653 prefilter_failed = True
2653 prefilter_failed = True
2654
2654
2655 # Store raw and processed history
2655 # Store raw and processed history
2656 if store_history:
2656 if store_history:
2657 self.history_manager.store_inputs(self.execution_count,
2657 self.history_manager.store_inputs(self.execution_count,
2658 cell, raw_cell)
2658 cell, raw_cell)
2659 if not silent:
2659 if not silent:
2660 self.logger.log(cell, raw_cell)
2660 self.logger.log(cell, raw_cell)
2661
2661
2662 if not prefilter_failed:
2662 if not prefilter_failed:
2663 # don't run if prefilter failed
2663 # don't run if prefilter failed
2664 cell_name = self.compile.cache(cell, self.execution_count)
2664 cell_name = self.compile.cache(cell, self.execution_count)
2665
2665
2666 with self.display_trap:
2666 with self.display_trap:
2667 try:
2667 try:
2668 code_ast = compiler.ast_parse(cell, filename=cell_name)
2668 code_ast = compiler.ast_parse(cell, filename=cell_name)
2669 except IndentationError:
2669 except IndentationError:
2670 self.showindentationerror()
2670 self.showindentationerror()
2671 if store_history:
2671 if store_history:
2672 self.execution_count += 1
2672 self.execution_count += 1
2673 return None
2673 return None
2674 except (OverflowError, SyntaxError, ValueError, TypeError,
2674 except (OverflowError, SyntaxError, ValueError, TypeError,
2675 MemoryError):
2675 MemoryError):
2676 self.showsyntaxerror()
2676 self.showsyntaxerror()
2677 if store_history:
2677 if store_history:
2678 self.execution_count += 1
2678 self.execution_count += 1
2679 return None
2679 return None
2680
2680
2681 code_ast = self.transform_ast(code_ast)
2681 code_ast = self.transform_ast(code_ast)
2682
2682
2683 interactivity = "none" if silent else self.ast_node_interactivity
2683 interactivity = "none" if silent else self.ast_node_interactivity
2684 self.run_ast_nodes(code_ast.body, cell_name,
2684 self.run_ast_nodes(code_ast.body, cell_name,
2685 interactivity=interactivity, compiler=compiler)
2685 interactivity=interactivity, compiler=compiler)
2686
2686
2687 # Execute any registered post-execution functions.
2687 # Execute any registered post-execution functions.
2688 # unless we are silent
2688 # unless we are silent
2689 post_exec = [] if silent else self._post_execute.iteritems()
2689 post_exec = [] if silent else self._post_execute.iteritems()
2690
2690
2691 for func, status in post_exec:
2691 for func, status in post_exec:
2692 if self.disable_failing_post_execute and not status:
2692 if self.disable_failing_post_execute and not status:
2693 continue
2693 continue
2694 try:
2694 try:
2695 func()
2695 func()
2696 except KeyboardInterrupt:
2696 except KeyboardInterrupt:
2697 print("\nKeyboardInterrupt", file=io.stderr)
2697 print("\nKeyboardInterrupt", file=io.stderr)
2698 except Exception:
2698 except Exception:
2699 # register as failing:
2699 # register as failing:
2700 self._post_execute[func] = False
2700 self._post_execute[func] = False
2701 self.showtraceback()
2701 self.showtraceback()
2702 print('\n'.join([
2702 print('\n'.join([
2703 "post-execution function %r produced an error." % func,
2703 "post-execution function %r produced an error." % func,
2704 "If this problem persists, you can disable failing post-exec functions with:",
2704 "If this problem persists, you can disable failing post-exec functions with:",
2705 "",
2705 "",
2706 " get_ipython().disable_failing_post_execute = True"
2706 " get_ipython().disable_failing_post_execute = True"
2707 ]), file=io.stderr)
2707 ]), file=io.stderr)
2708
2708
2709 if store_history:
2709 if store_history:
2710 # Write output to the database. Does nothing unless
2710 # Write output to the database. Does nothing unless
2711 # history output logging is enabled.
2711 # history output logging is enabled.
2712 self.history_manager.store_output(self.execution_count)
2712 self.history_manager.store_output(self.execution_count)
2713 # Each cell is a *single* input, regardless of how many lines it has
2713 # Each cell is a *single* input, regardless of how many lines it has
2714 self.execution_count += 1
2714 self.execution_count += 1
2715
2715
2716 def transform_ast(self, node):
2716 def transform_ast(self, node):
2717 """Apply the AST transformations from self.ast_transformers
2717 """Apply the AST transformations from self.ast_transformers
2718
2718
2719 Parameters
2719 Parameters
2720 ----------
2720 ----------
2721 node : ast.Node
2721 node : ast.Node
2722 The root node to be transformed. Typically called with the ast.Module
2722 The root node to be transformed. Typically called with the ast.Module
2723 produced by parsing user input.
2723 produced by parsing user input.
2724
2724
2725 Returns
2725 Returns
2726 -------
2726 -------
2727 An ast.Node corresponding to the node it was called with. Note that it
2727 An ast.Node corresponding to the node it was called with. Note that it
2728 may also modify the passed object, so don't rely on references to the
2728 may also modify the passed object, so don't rely on references to the
2729 original AST.
2729 original AST.
2730 """
2730 """
2731 for transformer in self.ast_transformers:
2731 for transformer in self.ast_transformers:
2732 try:
2732 try:
2733 node = transformer.visit(node)
2733 node = transformer.visit(node)
2734 except Exception:
2734 except Exception:
2735 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2735 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2736 self.ast_transformers.remove(transformer)
2736 self.ast_transformers.remove(transformer)
2737
2737
2738 if self.ast_transformers:
2738 if self.ast_transformers:
2739 ast.fix_missing_locations(node)
2739 ast.fix_missing_locations(node)
2740 return node
2740 return node
2741
2741
2742
2742
2743 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2743 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2744 compiler=compile):
2744 compiler=compile):
2745 """Run a sequence of AST nodes. The execution mode depends on the
2745 """Run a sequence of AST nodes. The execution mode depends on the
2746 interactivity parameter.
2746 interactivity parameter.
2747
2747
2748 Parameters
2748 Parameters
2749 ----------
2749 ----------
2750 nodelist : list
2750 nodelist : list
2751 A sequence of AST nodes to run.
2751 A sequence of AST nodes to run.
2752 cell_name : str
2752 cell_name : str
2753 Will be passed to the compiler as the filename of the cell. Typically
2753 Will be passed to the compiler as the filename of the cell. Typically
2754 the value returned by ip.compile.cache(cell).
2754 the value returned by ip.compile.cache(cell).
2755 interactivity : str
2755 interactivity : str
2756 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2756 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2757 run interactively (displaying output from expressions). 'last_expr'
2757 run interactively (displaying output from expressions). 'last_expr'
2758 will run the last node interactively only if it is an expression (i.e.
2758 will run the last node interactively only if it is an expression (i.e.
2759 expressions in loops or other blocks are not displayed. Other values
2759 expressions in loops or other blocks are not displayed. Other values
2760 for this parameter will raise a ValueError.
2760 for this parameter will raise a ValueError.
2761 compiler : callable
2761 compiler : callable
2762 A function with the same interface as the built-in compile(), to turn
2762 A function with the same interface as the built-in compile(), to turn
2763 the AST nodes into code objects. Default is the built-in compile().
2763 the AST nodes into code objects. Default is the built-in compile().
2764 """
2764 """
2765 if not nodelist:
2765 if not nodelist:
2766 return
2766 return
2767
2767
2768 if interactivity == 'last_expr':
2768 if interactivity == 'last_expr':
2769 if isinstance(nodelist[-1], ast.Expr):
2769 if isinstance(nodelist[-1], ast.Expr):
2770 interactivity = "last"
2770 interactivity = "last"
2771 else:
2771 else:
2772 interactivity = "none"
2772 interactivity = "none"
2773
2773
2774 if interactivity == 'none':
2774 if interactivity == 'none':
2775 to_run_exec, to_run_interactive = nodelist, []
2775 to_run_exec, to_run_interactive = nodelist, []
2776 elif interactivity == 'last':
2776 elif interactivity == 'last':
2777 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2777 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2778 elif interactivity == 'all':
2778 elif interactivity == 'all':
2779 to_run_exec, to_run_interactive = [], nodelist
2779 to_run_exec, to_run_interactive = [], nodelist
2780 else:
2780 else:
2781 raise ValueError("Interactivity was %r" % interactivity)
2781 raise ValueError("Interactivity was %r" % interactivity)
2782
2782
2783 exec_count = self.execution_count
2783 exec_count = self.execution_count
2784
2784
2785 try:
2785 try:
2786 for i, node in enumerate(to_run_exec):
2786 for i, node in enumerate(to_run_exec):
2787 mod = ast.Module([node])
2787 mod = ast.Module([node])
2788 code = compiler(mod, cell_name, "exec")
2788 code = compiler(mod, cell_name, "exec")
2789 if self.run_code(code):
2789 if self.run_code(code):
2790 return True
2790 return True
2791
2791
2792 for i, node in enumerate(to_run_interactive):
2792 for i, node in enumerate(to_run_interactive):
2793 mod = ast.Interactive([node])
2793 mod = ast.Interactive([node])
2794 code = compiler(mod, cell_name, "single")
2794 code = compiler(mod, cell_name, "single")
2795 if self.run_code(code):
2795 if self.run_code(code):
2796 return True
2796 return True
2797
2797
2798 # Flush softspace
2798 # Flush softspace
2799 if softspace(sys.stdout, 0):
2799 if softspace(sys.stdout, 0):
2800 print()
2800 print()
2801
2801
2802 except:
2802 except:
2803 # It's possible to have exceptions raised here, typically by
2803 # It's possible to have exceptions raised here, typically by
2804 # compilation of odd code (such as a naked 'return' outside a
2804 # compilation of odd code (such as a naked 'return' outside a
2805 # function) that did parse but isn't valid. Typically the exception
2805 # function) that did parse but isn't valid. Typically the exception
2806 # is a SyntaxError, but it's safest just to catch anything and show
2806 # is a SyntaxError, but it's safest just to catch anything and show
2807 # the user a traceback.
2807 # the user a traceback.
2808
2808
2809 # We do only one try/except outside the loop to minimize the impact
2809 # We do only one try/except outside the loop to minimize the impact
2810 # on runtime, and also because if any node in the node list is
2810 # on runtime, and also because if any node in the node list is
2811 # broken, we should stop execution completely.
2811 # broken, we should stop execution completely.
2812 self.showtraceback()
2812 self.showtraceback()
2813
2813
2814 return False
2814 return False
2815
2815
2816 def run_code(self, code_obj):
2816 def run_code(self, code_obj):
2817 """Execute a code object.
2817 """Execute a code object.
2818
2818
2819 When an exception occurs, self.showtraceback() is called to display a
2819 When an exception occurs, self.showtraceback() is called to display a
2820 traceback.
2820 traceback.
2821
2821
2822 Parameters
2822 Parameters
2823 ----------
2823 ----------
2824 code_obj : code object
2824 code_obj : code object
2825 A compiled code object, to be executed
2825 A compiled code object, to be executed
2826
2826
2827 Returns
2827 Returns
2828 -------
2828 -------
2829 False : successful execution.
2829 False : successful execution.
2830 True : an error occurred.
2830 True : an error occurred.
2831 """
2831 """
2832
2832
2833 # Set our own excepthook in case the user code tries to call it
2833 # Set our own excepthook in case the user code tries to call it
2834 # directly, so that the IPython crash handler doesn't get triggered
2834 # directly, so that the IPython crash handler doesn't get triggered
2835 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2835 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2836
2836
2837 # we save the original sys.excepthook in the instance, in case config
2837 # we save the original sys.excepthook in the instance, in case config
2838 # code (such as magics) needs access to it.
2838 # code (such as magics) needs access to it.
2839 self.sys_excepthook = old_excepthook
2839 self.sys_excepthook = old_excepthook
2840 outflag = 1 # happens in more places, so it's easier as default
2840 outflag = 1 # happens in more places, so it's easier as default
2841 try:
2841 try:
2842 try:
2842 try:
2843 self.hooks.pre_run_code_hook()
2843 self.hooks.pre_run_code_hook()
2844 #rprint('Running code', repr(code_obj)) # dbg
2844 #rprint('Running code', repr(code_obj)) # dbg
2845 exec code_obj in self.user_global_ns, self.user_ns
2845 exec(code_obj, self.user_global_ns, self.user_ns)
2846 finally:
2846 finally:
2847 # Reset our crash handler in place
2847 # Reset our crash handler in place
2848 sys.excepthook = old_excepthook
2848 sys.excepthook = old_excepthook
2849 except SystemExit:
2849 except SystemExit:
2850 self.showtraceback(exception_only=True)
2850 self.showtraceback(exception_only=True)
2851 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2851 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2852 except self.custom_exceptions:
2852 except self.custom_exceptions:
2853 etype,value,tb = sys.exc_info()
2853 etype,value,tb = sys.exc_info()
2854 self.CustomTB(etype,value,tb)
2854 self.CustomTB(etype,value,tb)
2855 except:
2855 except:
2856 self.showtraceback()
2856 self.showtraceback()
2857 else:
2857 else:
2858 outflag = 0
2858 outflag = 0
2859 return outflag
2859 return outflag
2860
2860
2861 # For backwards compatibility
2861 # For backwards compatibility
2862 runcode = run_code
2862 runcode = run_code
2863
2863
2864 #-------------------------------------------------------------------------
2864 #-------------------------------------------------------------------------
2865 # Things related to GUI support and pylab
2865 # Things related to GUI support and pylab
2866 #-------------------------------------------------------------------------
2866 #-------------------------------------------------------------------------
2867
2867
2868 def enable_gui(self, gui=None):
2868 def enable_gui(self, gui=None):
2869 raise NotImplementedError('Implement enable_gui in a subclass')
2869 raise NotImplementedError('Implement enable_gui in a subclass')
2870
2870
2871 def enable_matplotlib(self, gui=None):
2871 def enable_matplotlib(self, gui=None):
2872 """Enable interactive matplotlib and inline figure support.
2872 """Enable interactive matplotlib and inline figure support.
2873
2873
2874 This takes the following steps:
2874 This takes the following steps:
2875
2875
2876 1. select the appropriate eventloop and matplotlib backend
2876 1. select the appropriate eventloop and matplotlib backend
2877 2. set up matplotlib for interactive use with that backend
2877 2. set up matplotlib for interactive use with that backend
2878 3. configure formatters for inline figure display
2878 3. configure formatters for inline figure display
2879 4. enable the selected gui eventloop
2879 4. enable the selected gui eventloop
2880
2880
2881 Parameters
2881 Parameters
2882 ----------
2882 ----------
2883 gui : optional, string
2883 gui : optional, string
2884 If given, dictates the choice of matplotlib GUI backend to use
2884 If given, dictates the choice of matplotlib GUI backend to use
2885 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2885 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2886 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2886 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2887 matplotlib (as dictated by the matplotlib build-time options plus the
2887 matplotlib (as dictated by the matplotlib build-time options plus the
2888 user's matplotlibrc configuration file). Note that not all backends
2888 user's matplotlibrc configuration file). Note that not all backends
2889 make sense in all contexts, for example a terminal ipython can't
2889 make sense in all contexts, for example a terminal ipython can't
2890 display figures inline.
2890 display figures inline.
2891 """
2891 """
2892 from IPython.core import pylabtools as pt
2892 from IPython.core import pylabtools as pt
2893 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2893 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2894
2894
2895 if gui != 'inline':
2895 if gui != 'inline':
2896 # If we have our first gui selection, store it
2896 # If we have our first gui selection, store it
2897 if self.pylab_gui_select is None:
2897 if self.pylab_gui_select is None:
2898 self.pylab_gui_select = gui
2898 self.pylab_gui_select = gui
2899 # Otherwise if they are different
2899 # Otherwise if they are different
2900 elif gui != self.pylab_gui_select:
2900 elif gui != self.pylab_gui_select:
2901 print ('Warning: Cannot change to a different GUI toolkit: %s.'
2901 print ('Warning: Cannot change to a different GUI toolkit: %s.'
2902 ' Using %s instead.' % (gui, self.pylab_gui_select))
2902 ' Using %s instead.' % (gui, self.pylab_gui_select))
2903 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
2903 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
2904
2904
2905 pt.activate_matplotlib(backend)
2905 pt.activate_matplotlib(backend)
2906 pt.configure_inline_support(self, backend)
2906 pt.configure_inline_support(self, backend)
2907
2907
2908 # Now we must activate the gui pylab wants to use, and fix %run to take
2908 # Now we must activate the gui pylab wants to use, and fix %run to take
2909 # plot updates into account
2909 # plot updates into account
2910 self.enable_gui(gui)
2910 self.enable_gui(gui)
2911 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2911 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2912 pt.mpl_runner(self.safe_execfile)
2912 pt.mpl_runner(self.safe_execfile)
2913
2913
2914 return gui, backend
2914 return gui, backend
2915
2915
2916 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2916 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2917 """Activate pylab support at runtime.
2917 """Activate pylab support at runtime.
2918
2918
2919 This turns on support for matplotlib, preloads into the interactive
2919 This turns on support for matplotlib, preloads into the interactive
2920 namespace all of numpy and pylab, and configures IPython to correctly
2920 namespace all of numpy and pylab, and configures IPython to correctly
2921 interact with the GUI event loop. The GUI backend to be used can be
2921 interact with the GUI event loop. The GUI backend to be used can be
2922 optionally selected with the optional ``gui`` argument.
2922 optionally selected with the optional ``gui`` argument.
2923
2923
2924 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
2924 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
2925
2925
2926 Parameters
2926 Parameters
2927 ----------
2927 ----------
2928 gui : optional, string
2928 gui : optional, string
2929 If given, dictates the choice of matplotlib GUI backend to use
2929 If given, dictates the choice of matplotlib GUI backend to use
2930 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2930 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2931 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2931 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2932 matplotlib (as dictated by the matplotlib build-time options plus the
2932 matplotlib (as dictated by the matplotlib build-time options plus the
2933 user's matplotlibrc configuration file). Note that not all backends
2933 user's matplotlibrc configuration file). Note that not all backends
2934 make sense in all contexts, for example a terminal ipython can't
2934 make sense in all contexts, for example a terminal ipython can't
2935 display figures inline.
2935 display figures inline.
2936 import_all : optional, bool, default: True
2936 import_all : optional, bool, default: True
2937 Whether to do `from numpy import *` and `from pylab import *`
2937 Whether to do `from numpy import *` and `from pylab import *`
2938 in addition to module imports.
2938 in addition to module imports.
2939 welcome_message : deprecated
2939 welcome_message : deprecated
2940 This argument is ignored, no welcome message will be displayed.
2940 This argument is ignored, no welcome message will be displayed.
2941 """
2941 """
2942 from IPython.core.pylabtools import import_pylab
2942 from IPython.core.pylabtools import import_pylab
2943
2943
2944 gui, backend = self.enable_matplotlib(gui)
2944 gui, backend = self.enable_matplotlib(gui)
2945
2945
2946 # We want to prevent the loading of pylab to pollute the user's
2946 # We want to prevent the loading of pylab to pollute the user's
2947 # namespace as shown by the %who* magics, so we execute the activation
2947 # namespace as shown by the %who* magics, so we execute the activation
2948 # code in an empty namespace, and we update *both* user_ns and
2948 # code in an empty namespace, and we update *both* user_ns and
2949 # user_ns_hidden with this information.
2949 # user_ns_hidden with this information.
2950 ns = {}
2950 ns = {}
2951 import_pylab(ns, import_all)
2951 import_pylab(ns, import_all)
2952 # warn about clobbered names
2952 # warn about clobbered names
2953 ignored = set(["__builtins__"])
2953 ignored = set(["__builtins__"])
2954 both = set(ns).intersection(self.user_ns).difference(ignored)
2954 both = set(ns).intersection(self.user_ns).difference(ignored)
2955 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
2955 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
2956 self.user_ns.update(ns)
2956 self.user_ns.update(ns)
2957 self.user_ns_hidden.update(ns)
2957 self.user_ns_hidden.update(ns)
2958 return gui, backend, clobbered
2958 return gui, backend, clobbered
2959
2959
2960 #-------------------------------------------------------------------------
2960 #-------------------------------------------------------------------------
2961 # Utilities
2961 # Utilities
2962 #-------------------------------------------------------------------------
2962 #-------------------------------------------------------------------------
2963
2963
2964 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2964 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2965 """Expand python variables in a string.
2965 """Expand python variables in a string.
2966
2966
2967 The depth argument indicates how many frames above the caller should
2967 The depth argument indicates how many frames above the caller should
2968 be walked to look for the local namespace where to expand variables.
2968 be walked to look for the local namespace where to expand variables.
2969
2969
2970 The global namespace for expansion is always the user's interactive
2970 The global namespace for expansion is always the user's interactive
2971 namespace.
2971 namespace.
2972 """
2972 """
2973 ns = self.user_ns.copy()
2973 ns = self.user_ns.copy()
2974 ns.update(sys._getframe(depth+1).f_locals)
2974 ns.update(sys._getframe(depth+1).f_locals)
2975 try:
2975 try:
2976 # We have to use .vformat() here, because 'self' is a valid and common
2976 # We have to use .vformat() here, because 'self' is a valid and common
2977 # name, and expanding **ns for .format() would make it collide with
2977 # name, and expanding **ns for .format() would make it collide with
2978 # the 'self' argument of the method.
2978 # the 'self' argument of the method.
2979 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
2979 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
2980 except Exception:
2980 except Exception:
2981 # if formatter couldn't format, just let it go untransformed
2981 # if formatter couldn't format, just let it go untransformed
2982 pass
2982 pass
2983 return cmd
2983 return cmd
2984
2984
2985 def mktempfile(self, data=None, prefix='ipython_edit_'):
2985 def mktempfile(self, data=None, prefix='ipython_edit_'):
2986 """Make a new tempfile and return its filename.
2986 """Make a new tempfile and return its filename.
2987
2987
2988 This makes a call to tempfile.mktemp, but it registers the created
2988 This makes a call to tempfile.mktemp, but it registers the created
2989 filename internally so ipython cleans it up at exit time.
2989 filename internally so ipython cleans it up at exit time.
2990
2990
2991 Optional inputs:
2991 Optional inputs:
2992
2992
2993 - data(None): if data is given, it gets written out to the temp file
2993 - data(None): if data is given, it gets written out to the temp file
2994 immediately, and the file is closed again."""
2994 immediately, and the file is closed again."""
2995
2995
2996 filename = tempfile.mktemp('.py', prefix)
2996 filename = tempfile.mktemp('.py', prefix)
2997 self.tempfiles.append(filename)
2997 self.tempfiles.append(filename)
2998
2998
2999 if data:
2999 if data:
3000 tmp_file = open(filename,'w')
3000 tmp_file = open(filename,'w')
3001 tmp_file.write(data)
3001 tmp_file.write(data)
3002 tmp_file.close()
3002 tmp_file.close()
3003 return filename
3003 return filename
3004
3004
3005 # TODO: This should be removed when Term is refactored.
3005 # TODO: This should be removed when Term is refactored.
3006 def write(self,data):
3006 def write(self,data):
3007 """Write a string to the default output"""
3007 """Write a string to the default output"""
3008 io.stdout.write(data)
3008 io.stdout.write(data)
3009
3009
3010 # TODO: This should be removed when Term is refactored.
3010 # TODO: This should be removed when Term is refactored.
3011 def write_err(self,data):
3011 def write_err(self,data):
3012 """Write a string to the default error output"""
3012 """Write a string to the default error output"""
3013 io.stderr.write(data)
3013 io.stderr.write(data)
3014
3014
3015 def ask_yes_no(self, prompt, default=None):
3015 def ask_yes_no(self, prompt, default=None):
3016 if self.quiet:
3016 if self.quiet:
3017 return True
3017 return True
3018 return ask_yes_no(prompt,default)
3018 return ask_yes_no(prompt,default)
3019
3019
3020 def show_usage(self):
3020 def show_usage(self):
3021 """Show a usage message"""
3021 """Show a usage message"""
3022 page.page(IPython.core.usage.interactive_usage)
3022 page.page(IPython.core.usage.interactive_usage)
3023
3023
3024 def extract_input_lines(self, range_str, raw=False):
3024 def extract_input_lines(self, range_str, raw=False):
3025 """Return as a string a set of input history slices.
3025 """Return as a string a set of input history slices.
3026
3026
3027 Parameters
3027 Parameters
3028 ----------
3028 ----------
3029 range_str : string
3029 range_str : string
3030 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3030 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3031 since this function is for use by magic functions which get their
3031 since this function is for use by magic functions which get their
3032 arguments as strings. The number before the / is the session
3032 arguments as strings. The number before the / is the session
3033 number: ~n goes n back from the current session.
3033 number: ~n goes n back from the current session.
3034
3034
3035 Optional Parameters:
3035 Optional Parameters:
3036 - raw(False): by default, the processed input is used. If this is
3036 - raw(False): by default, the processed input is used. If this is
3037 true, the raw input history is used instead.
3037 true, the raw input history is used instead.
3038
3038
3039 Note that slices can be called with two notations:
3039 Note that slices can be called with two notations:
3040
3040
3041 N:M -> standard python form, means including items N...(M-1).
3041 N:M -> standard python form, means including items N...(M-1).
3042
3042
3043 N-M -> include items N..M (closed endpoint).
3043 N-M -> include items N..M (closed endpoint).
3044 """
3044 """
3045 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3045 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3046 return "\n".join(x for _, _, x in lines)
3046 return "\n".join(x for _, _, x in lines)
3047
3047
3048 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
3048 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
3049 """Get a code string from history, file, url, or a string or macro.
3049 """Get a code string from history, file, url, or a string or macro.
3050
3050
3051 This is mainly used by magic functions.
3051 This is mainly used by magic functions.
3052
3052
3053 Parameters
3053 Parameters
3054 ----------
3054 ----------
3055
3055
3056 target : str
3056 target : str
3057
3057
3058 A string specifying code to retrieve. This will be tried respectively
3058 A string specifying code to retrieve. This will be tried respectively
3059 as: ranges of input history (see %history for syntax), url,
3059 as: ranges of input history (see %history for syntax), url,
3060 correspnding .py file, filename, or an expression evaluating to a
3060 correspnding .py file, filename, or an expression evaluating to a
3061 string or Macro in the user namespace.
3061 string or Macro in the user namespace.
3062
3062
3063 raw : bool
3063 raw : bool
3064 If true (default), retrieve raw history. Has no effect on the other
3064 If true (default), retrieve raw history. Has no effect on the other
3065 retrieval mechanisms.
3065 retrieval mechanisms.
3066
3066
3067 py_only : bool (default False)
3067 py_only : bool (default False)
3068 Only try to fetch python code, do not try alternative methods to decode file
3068 Only try to fetch python code, do not try alternative methods to decode file
3069 if unicode fails.
3069 if unicode fails.
3070
3070
3071 Returns
3071 Returns
3072 -------
3072 -------
3073 A string of code.
3073 A string of code.
3074
3074
3075 ValueError is raised if nothing is found, and TypeError if it evaluates
3075 ValueError is raised if nothing is found, and TypeError if it evaluates
3076 to an object of another type. In each case, .args[0] is a printable
3076 to an object of another type. In each case, .args[0] is a printable
3077 message.
3077 message.
3078 """
3078 """
3079 code = self.extract_input_lines(target, raw=raw) # Grab history
3079 code = self.extract_input_lines(target, raw=raw) # Grab history
3080 if code:
3080 if code:
3081 return code
3081 return code
3082 utarget = unquote_filename(target)
3082 utarget = unquote_filename(target)
3083 try:
3083 try:
3084 if utarget.startswith(('http://', 'https://')):
3084 if utarget.startswith(('http://', 'https://')):
3085 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3085 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3086 except UnicodeDecodeError:
3086 except UnicodeDecodeError:
3087 if not py_only :
3087 if not py_only :
3088 from urllib import urlopen # Deferred import
3088 from urllib import urlopen # Deferred import
3089 response = urlopen(target)
3089 response = urlopen(target)
3090 return response.read().decode('latin1')
3090 return response.read().decode('latin1')
3091 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3091 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3092
3092
3093 potential_target = [target]
3093 potential_target = [target]
3094 try :
3094 try :
3095 potential_target.insert(0,get_py_filename(target))
3095 potential_target.insert(0,get_py_filename(target))
3096 except IOError:
3096 except IOError:
3097 pass
3097 pass
3098
3098
3099 for tgt in potential_target :
3099 for tgt in potential_target :
3100 if os.path.isfile(tgt): # Read file
3100 if os.path.isfile(tgt): # Read file
3101 try :
3101 try :
3102 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3102 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3103 except UnicodeDecodeError :
3103 except UnicodeDecodeError :
3104 if not py_only :
3104 if not py_only :
3105 with io_open(tgt,'r', encoding='latin1') as f :
3105 with io_open(tgt,'r', encoding='latin1') as f :
3106 return f.read()
3106 return f.read()
3107 raise ValueError(("'%s' seem to be unreadable.") % target)
3107 raise ValueError(("'%s' seem to be unreadable.") % target)
3108 elif os.path.isdir(os.path.expanduser(tgt)):
3108 elif os.path.isdir(os.path.expanduser(tgt)):
3109 raise ValueError("'%s' is a directory, not a regular file." % target)
3109 raise ValueError("'%s' is a directory, not a regular file." % target)
3110
3110
3111 try: # User namespace
3111 try: # User namespace
3112 codeobj = eval(target, self.user_ns)
3112 codeobj = eval(target, self.user_ns)
3113 except Exception:
3113 except Exception:
3114 raise ValueError(("'%s' was not found in history, as a file, url, "
3114 raise ValueError(("'%s' was not found in history, as a file, url, "
3115 "nor in the user namespace.") % target)
3115 "nor in the user namespace.") % target)
3116 if isinstance(codeobj, basestring):
3116 if isinstance(codeobj, basestring):
3117 return codeobj
3117 return codeobj
3118 elif isinstance(codeobj, Macro):
3118 elif isinstance(codeobj, Macro):
3119 return codeobj.value
3119 return codeobj.value
3120
3120
3121 raise TypeError("%s is neither a string nor a macro." % target,
3121 raise TypeError("%s is neither a string nor a macro." % target,
3122 codeobj)
3122 codeobj)
3123
3123
3124 #-------------------------------------------------------------------------
3124 #-------------------------------------------------------------------------
3125 # Things related to IPython exiting
3125 # Things related to IPython exiting
3126 #-------------------------------------------------------------------------
3126 #-------------------------------------------------------------------------
3127 def atexit_operations(self):
3127 def atexit_operations(self):
3128 """This will be executed at the time of exit.
3128 """This will be executed at the time of exit.
3129
3129
3130 Cleanup operations and saving of persistent data that is done
3130 Cleanup operations and saving of persistent data that is done
3131 unconditionally by IPython should be performed here.
3131 unconditionally by IPython should be performed here.
3132
3132
3133 For things that may depend on startup flags or platform specifics (such
3133 For things that may depend on startup flags or platform specifics (such
3134 as having readline or not), register a separate atexit function in the
3134 as having readline or not), register a separate atexit function in the
3135 code that has the appropriate information, rather than trying to
3135 code that has the appropriate information, rather than trying to
3136 clutter
3136 clutter
3137 """
3137 """
3138 # Close the history session (this stores the end time and line count)
3138 # Close the history session (this stores the end time and line count)
3139 # this must be *before* the tempfile cleanup, in case of temporary
3139 # this must be *before* the tempfile cleanup, in case of temporary
3140 # history db
3140 # history db
3141 self.history_manager.end_session()
3141 self.history_manager.end_session()
3142
3142
3143 # Cleanup all tempfiles left around
3143 # Cleanup all tempfiles left around
3144 for tfile in self.tempfiles:
3144 for tfile in self.tempfiles:
3145 try:
3145 try:
3146 os.unlink(tfile)
3146 os.unlink(tfile)
3147 except OSError:
3147 except OSError:
3148 pass
3148 pass
3149
3149
3150 # Clear all user namespaces to release all references cleanly.
3150 # Clear all user namespaces to release all references cleanly.
3151 self.reset(new_session=False)
3151 self.reset(new_session=False)
3152
3152
3153 # Run user hooks
3153 # Run user hooks
3154 self.hooks.shutdown_hook()
3154 self.hooks.shutdown_hook()
3155
3155
3156 def cleanup(self):
3156 def cleanup(self):
3157 self.restore_sys_module_state()
3157 self.restore_sys_module_state()
3158
3158
3159
3159
3160 class InteractiveShellABC(object):
3160 class InteractiveShellABC(object):
3161 """An abstract base class for InteractiveShell."""
3161 """An abstract base class for InteractiveShell."""
3162 __metaclass__ = abc.ABCMeta
3162 __metaclass__ = abc.ABCMeta
3163
3163
3164 InteractiveShellABC.register(InteractiveShell)
3164 InteractiveShellABC.register(InteractiveShell)
@@ -1,159 +1,159 b''
1 """Implementation of configuration-related magic functions.
1 """Implementation of configuration-related magic functions.
2 """
2 """
3 from __future__ import print_function
3 from __future__ import print_function
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2012 The IPython Development Team.
5 # Copyright (c) 2012 The IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 # Stdlib
16 # Stdlib
17 import re
17 import re
18
18
19 # Our own packages
19 # Our own packages
20 from IPython.core.error import UsageError
20 from IPython.core.error import UsageError
21 from IPython.core.magic import Magics, magics_class, line_magic
21 from IPython.core.magic import Magics, magics_class, line_magic
22 from IPython.utils.warn import error
22 from IPython.utils.warn import error
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Magic implementation classes
25 # Magic implementation classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 reg = re.compile('^\w+\.\w+$')
28 reg = re.compile('^\w+\.\w+$')
29 @magics_class
29 @magics_class
30 class ConfigMagics(Magics):
30 class ConfigMagics(Magics):
31
31
32 def __init__(self, shell):
32 def __init__(self, shell):
33 super(ConfigMagics, self).__init__(shell)
33 super(ConfigMagics, self).__init__(shell)
34 self.configurables = []
34 self.configurables = []
35
35
36 @line_magic
36 @line_magic
37 def config(self, s):
37 def config(self, s):
38 """configure IPython
38 """configure IPython
39
39
40 %config Class[.trait=value]
40 %config Class[.trait=value]
41
41
42 This magic exposes most of the IPython config system. Any
42 This magic exposes most of the IPython config system. Any
43 Configurable class should be able to be configured with the simple
43 Configurable class should be able to be configured with the simple
44 line::
44 line::
45
45
46 %config Class.trait=value
46 %config Class.trait=value
47
47
48 Where `value` will be resolved in the user's namespace, if it is an
48 Where `value` will be resolved in the user's namespace, if it is an
49 expression or variable name.
49 expression or variable name.
50
50
51 Examples
51 Examples
52 --------
52 --------
53
53
54 To see what classes are available for config, pass no arguments::
54 To see what classes are available for config, pass no arguments::
55
55
56 In [1]: %config
56 In [1]: %config
57 Available objects for config:
57 Available objects for config:
58 TerminalInteractiveShell
58 TerminalInteractiveShell
59 HistoryManager
59 HistoryManager
60 PrefilterManager
60 PrefilterManager
61 AliasManager
61 AliasManager
62 IPCompleter
62 IPCompleter
63 PromptManager
63 PromptManager
64 DisplayFormatter
64 DisplayFormatter
65
65
66 To view what is configurable on a given class, just pass the class
66 To view what is configurable on a given class, just pass the class
67 name::
67 name::
68
68
69 In [2]: %config IPCompleter
69 In [2]: %config IPCompleter
70 IPCompleter options
70 IPCompleter options
71 -----------------
71 -----------------
72 IPCompleter.omit__names=<Enum>
72 IPCompleter.omit__names=<Enum>
73 Current: 2
73 Current: 2
74 Choices: (0, 1, 2)
74 Choices: (0, 1, 2)
75 Instruct the completer to omit private method names
75 Instruct the completer to omit private method names
76 Specifically, when completing on ``object.<tab>``.
76 Specifically, when completing on ``object.<tab>``.
77 When 2 [default]: all names that start with '_' will be excluded.
77 When 2 [default]: all names that start with '_' will be excluded.
78 When 1: all 'magic' names (``__foo__``) will be excluded.
78 When 1: all 'magic' names (``__foo__``) will be excluded.
79 When 0: nothing will be excluded.
79 When 0: nothing will be excluded.
80 IPCompleter.merge_completions=<CBool>
80 IPCompleter.merge_completions=<CBool>
81 Current: True
81 Current: True
82 Whether to merge completion results into a single list
82 Whether to merge completion results into a single list
83 If False, only the completion results from the first non-empty
83 If False, only the completion results from the first non-empty
84 completer will be returned.
84 completer will be returned.
85 IPCompleter.limit_to__all__=<CBool>
85 IPCompleter.limit_to__all__=<CBool>
86 Current: False
86 Current: False
87 Instruct the completer to use __all__ for the completion
87 Instruct the completer to use __all__ for the completion
88 Specifically, when completing on ``object.<tab>``.
88 Specifically, when completing on ``object.<tab>``.
89 When True: only those names in obj.__all__ will be included.
89 When True: only those names in obj.__all__ will be included.
90 When False [default]: the __all__ attribute is ignored
90 When False [default]: the __all__ attribute is ignored
91 IPCompleter.greedy=<CBool>
91 IPCompleter.greedy=<CBool>
92 Current: False
92 Current: False
93 Activate greedy completion
93 Activate greedy completion
94 This will enable completion on elements of lists, results of
94 This will enable completion on elements of lists, results of
95 function calls, etc., but can be unsafe because the code is
95 function calls, etc., but can be unsafe because the code is
96 actually evaluated on TAB.
96 actually evaluated on TAB.
97
97
98 but the real use is in setting values::
98 but the real use is in setting values::
99
99
100 In [3]: %config IPCompleter.greedy = True
100 In [3]: %config IPCompleter.greedy = True
101
101
102 and these values are read from the user_ns if they are variables::
102 and these values are read from the user_ns if they are variables::
103
103
104 In [4]: feeling_greedy=False
104 In [4]: feeling_greedy=False
105
105
106 In [5]: %config IPCompleter.greedy = feeling_greedy
106 In [5]: %config IPCompleter.greedy = feeling_greedy
107
107
108 """
108 """
109 from IPython.config.loader import Config
109 from IPython.config.loader import Config
110 # some IPython objects are Configurable, but do not yet have
110 # some IPython objects are Configurable, but do not yet have
111 # any configurable traits. Exclude them from the effects of
111 # any configurable traits. Exclude them from the effects of
112 # this magic, as their presence is just noise:
112 # this magic, as their presence is just noise:
113 configurables = [ c for c in self.shell.configurables
113 configurables = [ c for c in self.shell.configurables
114 if c.__class__.class_traits(config=True) ]
114 if c.__class__.class_traits(config=True) ]
115 classnames = [ c.__class__.__name__ for c in configurables ]
115 classnames = [ c.__class__.__name__ for c in configurables ]
116
116
117 line = s.strip()
117 line = s.strip()
118 if not line:
118 if not line:
119 # print available configurable names
119 # print available configurable names
120 print("Available objects for config:")
120 print("Available objects for config:")
121 for name in classnames:
121 for name in classnames:
122 print(" ", name)
122 print(" ", name)
123 return
123 return
124 elif line in classnames:
124 elif line in classnames:
125 # `%config TerminalInteractiveShell` will print trait info for
125 # `%config TerminalInteractiveShell` will print trait info for
126 # TerminalInteractiveShell
126 # TerminalInteractiveShell
127 c = configurables[classnames.index(line)]
127 c = configurables[classnames.index(line)]
128 cls = c.__class__
128 cls = c.__class__
129 help = cls.class_get_help(c)
129 help = cls.class_get_help(c)
130 # strip leading '--' from cl-args:
130 # strip leading '--' from cl-args:
131 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
131 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
132 print(help)
132 print(help)
133 return
133 return
134 elif reg.match(line):
134 elif reg.match(line):
135 cls, attr = line.split('.')
135 cls, attr = line.split('.')
136 return getattr(configurables[classnames.index(cls)],attr)
136 return getattr(configurables[classnames.index(cls)],attr)
137 elif '=' not in line:
137 elif '=' not in line:
138 msg = "Invalid config statement: %r, "\
138 msg = "Invalid config statement: %r, "\
139 "should be `Class.trait = value`."
139 "should be `Class.trait = value`."
140
140
141 ll = line.lower()
141 ll = line.lower()
142 for classname in classnames:
142 for classname in classnames:
143 if ll == classname.lower():
143 if ll == classname.lower():
144 msg = msg + '\nDid you mean %s (note the case)?' % classname
144 msg = msg + '\nDid you mean %s (note the case)?' % classname
145 break
145 break
146
146
147 raise UsageError( msg % line)
147 raise UsageError( msg % line)
148
148
149 # otherwise, assume we are setting configurables.
149 # otherwise, assume we are setting configurables.
150 # leave quotes on args when splitting, because we want
150 # leave quotes on args when splitting, because we want
151 # unquoted args to eval in user_ns
151 # unquoted args to eval in user_ns
152 cfg = Config()
152 cfg = Config()
153 exec "cfg."+line in locals(), self.shell.user_ns
153 exec("cfg."+line, locals(), self.shell.user_ns)
154
154
155 for configurable in configurables:
155 for configurable in configurables:
156 try:
156 try:
157 configurable.update_config(cfg)
157 configurable.update_config(cfg)
158 except Exception as e:
158 except Exception as e:
159 error(e)
159 error(e)
@@ -1,1288 +1,1288 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Implementation of execution-related magic functions.
2 """Implementation of execution-related magic functions.
3 """
3 """
4 from __future__ import print_function
4 from __future__ import print_function
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2012 The IPython Development Team.
6 # Copyright (c) 2012 The IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 # Stdlib
17 # Stdlib
18 import __builtin__ as builtin_mod
18 import __builtin__ as builtin_mod
19 import ast
19 import ast
20 import bdb
20 import bdb
21 import os
21 import os
22 import sys
22 import sys
23 import time
23 import time
24 from StringIO import StringIO
24 from StringIO import StringIO
25
25
26 # cProfile was added in Python2.5
26 # cProfile was added in Python2.5
27 try:
27 try:
28 import cProfile as profile
28 import cProfile as profile
29 import pstats
29 import pstats
30 except ImportError:
30 except ImportError:
31 # profile isn't bundled by default in Debian for license reasons
31 # profile isn't bundled by default in Debian for license reasons
32 try:
32 try:
33 import profile, pstats
33 import profile, pstats
34 except ImportError:
34 except ImportError:
35 profile = pstats = None
35 profile = pstats = None
36
36
37 # Our own packages
37 # Our own packages
38 from IPython.core import debugger, oinspect
38 from IPython.core import debugger, oinspect
39 from IPython.core import magic_arguments
39 from IPython.core import magic_arguments
40 from IPython.core import page
40 from IPython.core import page
41 from IPython.core.error import UsageError
41 from IPython.core.error import UsageError
42 from IPython.core.macro import Macro
42 from IPython.core.macro import Macro
43 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
43 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
44 line_cell_magic, on_off, needs_local_scope)
44 line_cell_magic, on_off, needs_local_scope)
45 from IPython.testing.skipdoctest import skip_doctest
45 from IPython.testing.skipdoctest import skip_doctest
46 from IPython.utils import py3compat
46 from IPython.utils import py3compat
47 from IPython.utils.contexts import preserve_keys
47 from IPython.utils.contexts import preserve_keys
48 from IPython.utils.io import capture_output
48 from IPython.utils.io import capture_output
49 from IPython.utils.ipstruct import Struct
49 from IPython.utils.ipstruct import Struct
50 from IPython.utils.module_paths import find_mod
50 from IPython.utils.module_paths import find_mod
51 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
51 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
52 from IPython.utils.timing import clock, clock2
52 from IPython.utils.timing import clock, clock2
53 from IPython.utils.warn import warn, error
53 from IPython.utils.warn import warn, error
54
54
55
55
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57 # Magic implementation classes
57 # Magic implementation classes
58 #-----------------------------------------------------------------------------
58 #-----------------------------------------------------------------------------
59
59
60
60
61 class TimeitResult(object):
61 class TimeitResult(object):
62 """
62 """
63 Object returned by the timeit magic with info about the run.
63 Object returned by the timeit magic with info about the run.
64
64
65 Contain the following attributes :
65 Contain the following attributes :
66
66
67 loops: (int) number of loop done per measurement
67 loops: (int) number of loop done per measurement
68 repeat: (int) number of time the mesurement has been repeated
68 repeat: (int) number of time the mesurement has been repeated
69 best: (float) best execusion time / number
69 best: (float) best execusion time / number
70 all_runs: (list of float) execusion time of each run (in s)
70 all_runs: (list of float) execusion time of each run (in s)
71 compile_time: (float) time of statement compilation (s)
71 compile_time: (float) time of statement compilation (s)
72
72
73 """
73 """
74
74
75 def __init__(self, loops, repeat, best, all_runs, compile_time, precision):
75 def __init__(self, loops, repeat, best, all_runs, compile_time, precision):
76 self.loops = loops
76 self.loops = loops
77 self.repeat = repeat
77 self.repeat = repeat
78 self.best = best
78 self.best = best
79 self.all_runs = all_runs
79 self.all_runs = all_runs
80 self.compile_time = compile_time
80 self.compile_time = compile_time
81 self._precision = precision
81 self._precision = precision
82
82
83 def _repr_pretty_(self, p , cycle):
83 def _repr_pretty_(self, p , cycle):
84 unic = u"%d loops, best of %d: %s per loop" % (self.loops, self.repeat,
84 unic = u"%d loops, best of %d: %s per loop" % (self.loops, self.repeat,
85 _format_time(self.best, self._precision))
85 _format_time(self.best, self._precision))
86 p.text(u'<TimeitResult : '+unic+u'>')
86 p.text(u'<TimeitResult : '+unic+u'>')
87
87
88
88
89
89
90
90
91 @magics_class
91 @magics_class
92 class ExecutionMagics(Magics):
92 class ExecutionMagics(Magics):
93 """Magics related to code execution, debugging, profiling, etc.
93 """Magics related to code execution, debugging, profiling, etc.
94
94
95 """
95 """
96
96
97 def __init__(self, shell):
97 def __init__(self, shell):
98 super(ExecutionMagics, self).__init__(shell)
98 super(ExecutionMagics, self).__init__(shell)
99 if profile is None:
99 if profile is None:
100 self.prun = self.profile_missing_notice
100 self.prun = self.profile_missing_notice
101 # Default execution function used to actually run user code.
101 # Default execution function used to actually run user code.
102 self.default_runner = None
102 self.default_runner = None
103
103
104 def profile_missing_notice(self, *args, **kwargs):
104 def profile_missing_notice(self, *args, **kwargs):
105 error("""\
105 error("""\
106 The profile module could not be found. It has been removed from the standard
106 The profile module could not be found. It has been removed from the standard
107 python packages because of its non-free license. To use profiling, install the
107 python packages because of its non-free license. To use profiling, install the
108 python-profiler package from non-free.""")
108 python-profiler package from non-free.""")
109
109
110 @skip_doctest
110 @skip_doctest
111 @line_cell_magic
111 @line_cell_magic
112 def prun(self, parameter_s='', cell=None):
112 def prun(self, parameter_s='', cell=None):
113
113
114 """Run a statement through the python code profiler.
114 """Run a statement through the python code profiler.
115
115
116 Usage, in line mode:
116 Usage, in line mode:
117 %prun [options] statement
117 %prun [options] statement
118
118
119 Usage, in cell mode:
119 Usage, in cell mode:
120 %%prun [options] [statement]
120 %%prun [options] [statement]
121 code...
121 code...
122 code...
122 code...
123
123
124 In cell mode, the additional code lines are appended to the (possibly
124 In cell mode, the additional code lines are appended to the (possibly
125 empty) statement in the first line. Cell mode allows you to easily
125 empty) statement in the first line. Cell mode allows you to easily
126 profile multiline blocks without having to put them in a separate
126 profile multiline blocks without having to put them in a separate
127 function.
127 function.
128
128
129 The given statement (which doesn't require quote marks) is run via the
129 The given statement (which doesn't require quote marks) is run via the
130 python profiler in a manner similar to the profile.run() function.
130 python profiler in a manner similar to the profile.run() function.
131 Namespaces are internally managed to work correctly; profile.run
131 Namespaces are internally managed to work correctly; profile.run
132 cannot be used in IPython because it makes certain assumptions about
132 cannot be used in IPython because it makes certain assumptions about
133 namespaces which do not hold under IPython.
133 namespaces which do not hold under IPython.
134
134
135 Options:
135 Options:
136
136
137 -l <limit>
137 -l <limit>
138 you can place restrictions on what or how much of the
138 you can place restrictions on what or how much of the
139 profile gets printed. The limit value can be:
139 profile gets printed. The limit value can be:
140
140
141 * A string: only information for function names containing this string
141 * A string: only information for function names containing this string
142 is printed.
142 is printed.
143
143
144 * An integer: only these many lines are printed.
144 * An integer: only these many lines are printed.
145
145
146 * A float (between 0 and 1): this fraction of the report is printed
146 * A float (between 0 and 1): this fraction of the report is printed
147 (for example, use a limit of 0.4 to see the topmost 40% only).
147 (for example, use a limit of 0.4 to see the topmost 40% only).
148
148
149 You can combine several limits with repeated use of the option. For
149 You can combine several limits with repeated use of the option. For
150 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
150 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
151 information about class constructors.
151 information about class constructors.
152
152
153 -r
153 -r
154 return the pstats.Stats object generated by the profiling. This
154 return the pstats.Stats object generated by the profiling. This
155 object has all the information about the profile in it, and you can
155 object has all the information about the profile in it, and you can
156 later use it for further analysis or in other functions.
156 later use it for further analysis or in other functions.
157
157
158 -s <key>
158 -s <key>
159 sort profile by given key. You can provide more than one key
159 sort profile by given key. You can provide more than one key
160 by using the option several times: '-s key1 -s key2 -s key3...'. The
160 by using the option several times: '-s key1 -s key2 -s key3...'. The
161 default sorting key is 'time'.
161 default sorting key is 'time'.
162
162
163 The following is copied verbatim from the profile documentation
163 The following is copied verbatim from the profile documentation
164 referenced below:
164 referenced below:
165
165
166 When more than one key is provided, additional keys are used as
166 When more than one key is provided, additional keys are used as
167 secondary criteria when the there is equality in all keys selected
167 secondary criteria when the there is equality in all keys selected
168 before them.
168 before them.
169
169
170 Abbreviations can be used for any key names, as long as the
170 Abbreviations can be used for any key names, as long as the
171 abbreviation is unambiguous. The following are the keys currently
171 abbreviation is unambiguous. The following are the keys currently
172 defined:
172 defined:
173
173
174 ============ =====================
174 ============ =====================
175 Valid Arg Meaning
175 Valid Arg Meaning
176 ============ =====================
176 ============ =====================
177 "calls" call count
177 "calls" call count
178 "cumulative" cumulative time
178 "cumulative" cumulative time
179 "file" file name
179 "file" file name
180 "module" file name
180 "module" file name
181 "pcalls" primitive call count
181 "pcalls" primitive call count
182 "line" line number
182 "line" line number
183 "name" function name
183 "name" function name
184 "nfl" name/file/line
184 "nfl" name/file/line
185 "stdname" standard name
185 "stdname" standard name
186 "time" internal time
186 "time" internal time
187 ============ =====================
187 ============ =====================
188
188
189 Note that all sorts on statistics are in descending order (placing
189 Note that all sorts on statistics are in descending order (placing
190 most time consuming items first), where as name, file, and line number
190 most time consuming items first), where as name, file, and line number
191 searches are in ascending order (i.e., alphabetical). The subtle
191 searches are in ascending order (i.e., alphabetical). The subtle
192 distinction between "nfl" and "stdname" is that the standard name is a
192 distinction between "nfl" and "stdname" is that the standard name is a
193 sort of the name as printed, which means that the embedded line
193 sort of the name as printed, which means that the embedded line
194 numbers get compared in an odd way. For example, lines 3, 20, and 40
194 numbers get compared in an odd way. For example, lines 3, 20, and 40
195 would (if the file names were the same) appear in the string order
195 would (if the file names were the same) appear in the string order
196 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
196 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
197 line numbers. In fact, sort_stats("nfl") is the same as
197 line numbers. In fact, sort_stats("nfl") is the same as
198 sort_stats("name", "file", "line").
198 sort_stats("name", "file", "line").
199
199
200 -T <filename>
200 -T <filename>
201 save profile results as shown on screen to a text
201 save profile results as shown on screen to a text
202 file. The profile is still shown on screen.
202 file. The profile is still shown on screen.
203
203
204 -D <filename>
204 -D <filename>
205 save (via dump_stats) profile statistics to given
205 save (via dump_stats) profile statistics to given
206 filename. This data is in a format understood by the pstats module, and
206 filename. This data is in a format understood by the pstats module, and
207 is generated by a call to the dump_stats() method of profile
207 is generated by a call to the dump_stats() method of profile
208 objects. The profile is still shown on screen.
208 objects. The profile is still shown on screen.
209
209
210 -q
210 -q
211 suppress output to the pager. Best used with -T and/or -D above.
211 suppress output to the pager. Best used with -T and/or -D above.
212
212
213 If you want to run complete programs under the profiler's control, use
213 If you want to run complete programs under the profiler's control, use
214 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
214 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
215 contains profiler specific options as described here.
215 contains profiler specific options as described here.
216
216
217 You can read the complete documentation for the profile module with::
217 You can read the complete documentation for the profile module with::
218
218
219 In [1]: import profile; profile.help()
219 In [1]: import profile; profile.help()
220 """
220 """
221 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
221 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
222 list_all=True, posix=False)
222 list_all=True, posix=False)
223 if cell is not None:
223 if cell is not None:
224 arg_str += '\n' + cell
224 arg_str += '\n' + cell
225 arg_str = self.shell.input_splitter.transform_cell(arg_str)
225 arg_str = self.shell.input_splitter.transform_cell(arg_str)
226 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
226 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
227
227
228 def _run_with_profiler(self, code, opts, namespace):
228 def _run_with_profiler(self, code, opts, namespace):
229 """
229 """
230 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
230 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
231
231
232 Parameters
232 Parameters
233 ----------
233 ----------
234 code : str
234 code : str
235 Code to be executed.
235 Code to be executed.
236 opts : Struct
236 opts : Struct
237 Options parsed by `self.parse_options`.
237 Options parsed by `self.parse_options`.
238 namespace : dict
238 namespace : dict
239 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
239 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
240
240
241 """
241 """
242
242
243 # Fill default values for unspecified options:
243 # Fill default values for unspecified options:
244 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
244 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
245
245
246 prof = profile.Profile()
246 prof = profile.Profile()
247 try:
247 try:
248 prof = prof.runctx(code, namespace, namespace)
248 prof = prof.runctx(code, namespace, namespace)
249 sys_exit = ''
249 sys_exit = ''
250 except SystemExit:
250 except SystemExit:
251 sys_exit = """*** SystemExit exception caught in code being profiled."""
251 sys_exit = """*** SystemExit exception caught in code being profiled."""
252
252
253 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
253 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
254
254
255 lims = opts.l
255 lims = opts.l
256 if lims:
256 if lims:
257 lims = [] # rebuild lims with ints/floats/strings
257 lims = [] # rebuild lims with ints/floats/strings
258 for lim in opts.l:
258 for lim in opts.l:
259 try:
259 try:
260 lims.append(int(lim))
260 lims.append(int(lim))
261 except ValueError:
261 except ValueError:
262 try:
262 try:
263 lims.append(float(lim))
263 lims.append(float(lim))
264 except ValueError:
264 except ValueError:
265 lims.append(lim)
265 lims.append(lim)
266
266
267 # Trap output.
267 # Trap output.
268 stdout_trap = StringIO()
268 stdout_trap = StringIO()
269 stats_stream = stats.stream
269 stats_stream = stats.stream
270 try:
270 try:
271 stats.stream = stdout_trap
271 stats.stream = stdout_trap
272 stats.print_stats(*lims)
272 stats.print_stats(*lims)
273 finally:
273 finally:
274 stats.stream = stats_stream
274 stats.stream = stats_stream
275
275
276 output = stdout_trap.getvalue()
276 output = stdout_trap.getvalue()
277 output = output.rstrip()
277 output = output.rstrip()
278
278
279 if 'q' not in opts:
279 if 'q' not in opts:
280 page.page(output)
280 page.page(output)
281 print(sys_exit, end=' ')
281 print(sys_exit, end=' ')
282
282
283 dump_file = opts.D[0]
283 dump_file = opts.D[0]
284 text_file = opts.T[0]
284 text_file = opts.T[0]
285 if dump_file:
285 if dump_file:
286 dump_file = unquote_filename(dump_file)
286 dump_file = unquote_filename(dump_file)
287 prof.dump_stats(dump_file)
287 prof.dump_stats(dump_file)
288 print('\n*** Profile stats marshalled to file',\
288 print('\n*** Profile stats marshalled to file',\
289 repr(dump_file)+'.',sys_exit)
289 repr(dump_file)+'.',sys_exit)
290 if text_file:
290 if text_file:
291 text_file = unquote_filename(text_file)
291 text_file = unquote_filename(text_file)
292 pfile = open(text_file,'w')
292 pfile = open(text_file,'w')
293 pfile.write(output)
293 pfile.write(output)
294 pfile.close()
294 pfile.close()
295 print('\n*** Profile printout saved to text file',\
295 print('\n*** Profile printout saved to text file',\
296 repr(text_file)+'.',sys_exit)
296 repr(text_file)+'.',sys_exit)
297
297
298 if 'r' in opts:
298 if 'r' in opts:
299 return stats
299 return stats
300 else:
300 else:
301 return None
301 return None
302
302
303 @line_magic
303 @line_magic
304 def pdb(self, parameter_s=''):
304 def pdb(self, parameter_s=''):
305 """Control the automatic calling of the pdb interactive debugger.
305 """Control the automatic calling of the pdb interactive debugger.
306
306
307 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
307 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
308 argument it works as a toggle.
308 argument it works as a toggle.
309
309
310 When an exception is triggered, IPython can optionally call the
310 When an exception is triggered, IPython can optionally call the
311 interactive pdb debugger after the traceback printout. %pdb toggles
311 interactive pdb debugger after the traceback printout. %pdb toggles
312 this feature on and off.
312 this feature on and off.
313
313
314 The initial state of this feature is set in your configuration
314 The initial state of this feature is set in your configuration
315 file (the option is ``InteractiveShell.pdb``).
315 file (the option is ``InteractiveShell.pdb``).
316
316
317 If you want to just activate the debugger AFTER an exception has fired,
317 If you want to just activate the debugger AFTER an exception has fired,
318 without having to type '%pdb on' and rerunning your code, you can use
318 without having to type '%pdb on' and rerunning your code, you can use
319 the %debug magic."""
319 the %debug magic."""
320
320
321 par = parameter_s.strip().lower()
321 par = parameter_s.strip().lower()
322
322
323 if par:
323 if par:
324 try:
324 try:
325 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
325 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
326 except KeyError:
326 except KeyError:
327 print ('Incorrect argument. Use on/1, off/0, '
327 print ('Incorrect argument. Use on/1, off/0, '
328 'or nothing for a toggle.')
328 'or nothing for a toggle.')
329 return
329 return
330 else:
330 else:
331 # toggle
331 # toggle
332 new_pdb = not self.shell.call_pdb
332 new_pdb = not self.shell.call_pdb
333
333
334 # set on the shell
334 # set on the shell
335 self.shell.call_pdb = new_pdb
335 self.shell.call_pdb = new_pdb
336 print('Automatic pdb calling has been turned',on_off(new_pdb))
336 print('Automatic pdb calling has been turned',on_off(new_pdb))
337
337
338 @skip_doctest
338 @skip_doctest
339 @magic_arguments.magic_arguments()
339 @magic_arguments.magic_arguments()
340 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
340 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
341 help="""
341 help="""
342 Set break point at LINE in FILE.
342 Set break point at LINE in FILE.
343 """
343 """
344 )
344 )
345 @magic_arguments.argument('statement', nargs='*',
345 @magic_arguments.argument('statement', nargs='*',
346 help="""
346 help="""
347 Code to run in debugger.
347 Code to run in debugger.
348 You can omit this in cell magic mode.
348 You can omit this in cell magic mode.
349 """
349 """
350 )
350 )
351 @line_cell_magic
351 @line_cell_magic
352 def debug(self, line='', cell=None):
352 def debug(self, line='', cell=None):
353 """Activate the interactive debugger.
353 """Activate the interactive debugger.
354
354
355 This magic command support two ways of activating debugger.
355 This magic command support two ways of activating debugger.
356 One is to activate debugger before executing code. This way, you
356 One is to activate debugger before executing code. This way, you
357 can set a break point, to step through the code from the point.
357 can set a break point, to step through the code from the point.
358 You can use this mode by giving statements to execute and optionally
358 You can use this mode by giving statements to execute and optionally
359 a breakpoint.
359 a breakpoint.
360
360
361 The other one is to activate debugger in post-mortem mode. You can
361 The other one is to activate debugger in post-mortem mode. You can
362 activate this mode simply running %debug without any argument.
362 activate this mode simply running %debug without any argument.
363 If an exception has just occurred, this lets you inspect its stack
363 If an exception has just occurred, this lets you inspect its stack
364 frames interactively. Note that this will always work only on the last
364 frames interactively. Note that this will always work only on the last
365 traceback that occurred, so you must call this quickly after an
365 traceback that occurred, so you must call this quickly after an
366 exception that you wish to inspect has fired, because if another one
366 exception that you wish to inspect has fired, because if another one
367 occurs, it clobbers the previous one.
367 occurs, it clobbers the previous one.
368
368
369 If you want IPython to automatically do this on every exception, see
369 If you want IPython to automatically do this on every exception, see
370 the %pdb magic for more details.
370 the %pdb magic for more details.
371 """
371 """
372 args = magic_arguments.parse_argstring(self.debug, line)
372 args = magic_arguments.parse_argstring(self.debug, line)
373
373
374 if not (args.breakpoint or args.statement or cell):
374 if not (args.breakpoint or args.statement or cell):
375 self._debug_post_mortem()
375 self._debug_post_mortem()
376 else:
376 else:
377 code = "\n".join(args.statement)
377 code = "\n".join(args.statement)
378 if cell:
378 if cell:
379 code += "\n" + cell
379 code += "\n" + cell
380 self._debug_exec(code, args.breakpoint)
380 self._debug_exec(code, args.breakpoint)
381
381
382 def _debug_post_mortem(self):
382 def _debug_post_mortem(self):
383 self.shell.debugger(force=True)
383 self.shell.debugger(force=True)
384
384
385 def _debug_exec(self, code, breakpoint):
385 def _debug_exec(self, code, breakpoint):
386 if breakpoint:
386 if breakpoint:
387 (filename, bp_line) = breakpoint.split(':', 1)
387 (filename, bp_line) = breakpoint.split(':', 1)
388 bp_line = int(bp_line)
388 bp_line = int(bp_line)
389 else:
389 else:
390 (filename, bp_line) = (None, None)
390 (filename, bp_line) = (None, None)
391 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
391 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
392
392
393 @line_magic
393 @line_magic
394 def tb(self, s):
394 def tb(self, s):
395 """Print the last traceback with the currently active exception mode.
395 """Print the last traceback with the currently active exception mode.
396
396
397 See %xmode for changing exception reporting modes."""
397 See %xmode for changing exception reporting modes."""
398 self.shell.showtraceback()
398 self.shell.showtraceback()
399
399
400 @skip_doctest
400 @skip_doctest
401 @line_magic
401 @line_magic
402 def run(self, parameter_s='', runner=None,
402 def run(self, parameter_s='', runner=None,
403 file_finder=get_py_filename):
403 file_finder=get_py_filename):
404 """Run the named file inside IPython as a program.
404 """Run the named file inside IPython as a program.
405
405
406 Usage::
406 Usage::
407
407
408 %run [-n -i -e -G]
408 %run [-n -i -e -G]
409 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
409 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
410 ( -m mod | file ) [args]
410 ( -m mod | file ) [args]
411
411
412 Parameters after the filename are passed as command-line arguments to
412 Parameters after the filename are passed as command-line arguments to
413 the program (put in sys.argv). Then, control returns to IPython's
413 the program (put in sys.argv). Then, control returns to IPython's
414 prompt.
414 prompt.
415
415
416 This is similar to running at a system prompt ``python file args``,
416 This is similar to running at a system prompt ``python file args``,
417 but with the advantage of giving you IPython's tracebacks, and of
417 but with the advantage of giving you IPython's tracebacks, and of
418 loading all variables into your interactive namespace for further use
418 loading all variables into your interactive namespace for further use
419 (unless -p is used, see below).
419 (unless -p is used, see below).
420
420
421 The file is executed in a namespace initially consisting only of
421 The file is executed in a namespace initially consisting only of
422 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
422 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
423 sees its environment as if it were being run as a stand-alone program
423 sees its environment as if it were being run as a stand-alone program
424 (except for sharing global objects such as previously imported
424 (except for sharing global objects such as previously imported
425 modules). But after execution, the IPython interactive namespace gets
425 modules). But after execution, the IPython interactive namespace gets
426 updated with all variables defined in the program (except for __name__
426 updated with all variables defined in the program (except for __name__
427 and sys.argv). This allows for very convenient loading of code for
427 and sys.argv). This allows for very convenient loading of code for
428 interactive work, while giving each program a 'clean sheet' to run in.
428 interactive work, while giving each program a 'clean sheet' to run in.
429
429
430 Arguments are expanded using shell-like glob match. Patterns
430 Arguments are expanded using shell-like glob match. Patterns
431 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
431 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
432 tilde '~' will be expanded into user's home directory. Unlike
432 tilde '~' will be expanded into user's home directory. Unlike
433 real shells, quotation does not suppress expansions. Use
433 real shells, quotation does not suppress expansions. Use
434 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
434 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
435 To completely disable these expansions, you can use -G flag.
435 To completely disable these expansions, you can use -G flag.
436
436
437 Options:
437 Options:
438
438
439 -n
439 -n
440 __name__ is NOT set to '__main__', but to the running file's name
440 __name__ is NOT set to '__main__', but to the running file's name
441 without extension (as python does under import). This allows running
441 without extension (as python does under import). This allows running
442 scripts and reloading the definitions in them without calling code
442 scripts and reloading the definitions in them without calling code
443 protected by an ``if __name__ == "__main__"`` clause.
443 protected by an ``if __name__ == "__main__"`` clause.
444
444
445 -i
445 -i
446 run the file in IPython's namespace instead of an empty one. This
446 run the file in IPython's namespace instead of an empty one. This
447 is useful if you are experimenting with code written in a text editor
447 is useful if you are experimenting with code written in a text editor
448 which depends on variables defined interactively.
448 which depends on variables defined interactively.
449
449
450 -e
450 -e
451 ignore sys.exit() calls or SystemExit exceptions in the script
451 ignore sys.exit() calls or SystemExit exceptions in the script
452 being run. This is particularly useful if IPython is being used to
452 being run. This is particularly useful if IPython is being used to
453 run unittests, which always exit with a sys.exit() call. In such
453 run unittests, which always exit with a sys.exit() call. In such
454 cases you are interested in the output of the test results, not in
454 cases you are interested in the output of the test results, not in
455 seeing a traceback of the unittest module.
455 seeing a traceback of the unittest module.
456
456
457 -t
457 -t
458 print timing information at the end of the run. IPython will give
458 print timing information at the end of the run. IPython will give
459 you an estimated CPU time consumption for your script, which under
459 you an estimated CPU time consumption for your script, which under
460 Unix uses the resource module to avoid the wraparound problems of
460 Unix uses the resource module to avoid the wraparound problems of
461 time.clock(). Under Unix, an estimate of time spent on system tasks
461 time.clock(). Under Unix, an estimate of time spent on system tasks
462 is also given (for Windows platforms this is reported as 0.0).
462 is also given (for Windows platforms this is reported as 0.0).
463
463
464 If -t is given, an additional ``-N<N>`` option can be given, where <N>
464 If -t is given, an additional ``-N<N>`` option can be given, where <N>
465 must be an integer indicating how many times you want the script to
465 must be an integer indicating how many times you want the script to
466 run. The final timing report will include total and per run results.
466 run. The final timing report will include total and per run results.
467
467
468 For example (testing the script uniq_stable.py)::
468 For example (testing the script uniq_stable.py)::
469
469
470 In [1]: run -t uniq_stable
470 In [1]: run -t uniq_stable
471
471
472 IPython CPU timings (estimated):
472 IPython CPU timings (estimated):
473 User : 0.19597 s.
473 User : 0.19597 s.
474 System: 0.0 s.
474 System: 0.0 s.
475
475
476 In [2]: run -t -N5 uniq_stable
476 In [2]: run -t -N5 uniq_stable
477
477
478 IPython CPU timings (estimated):
478 IPython CPU timings (estimated):
479 Total runs performed: 5
479 Total runs performed: 5
480 Times : Total Per run
480 Times : Total Per run
481 User : 0.910862 s, 0.1821724 s.
481 User : 0.910862 s, 0.1821724 s.
482 System: 0.0 s, 0.0 s.
482 System: 0.0 s, 0.0 s.
483
483
484 -d
484 -d
485 run your program under the control of pdb, the Python debugger.
485 run your program under the control of pdb, the Python debugger.
486 This allows you to execute your program step by step, watch variables,
486 This allows you to execute your program step by step, watch variables,
487 etc. Internally, what IPython does is similar to calling::
487 etc. Internally, what IPython does is similar to calling::
488
488
489 pdb.run('execfile("YOURFILENAME")')
489 pdb.run('execfile("YOURFILENAME")')
490
490
491 with a breakpoint set on line 1 of your file. You can change the line
491 with a breakpoint set on line 1 of your file. You can change the line
492 number for this automatic breakpoint to be <N> by using the -bN option
492 number for this automatic breakpoint to be <N> by using the -bN option
493 (where N must be an integer). For example::
493 (where N must be an integer). For example::
494
494
495 %run -d -b40 myscript
495 %run -d -b40 myscript
496
496
497 will set the first breakpoint at line 40 in myscript.py. Note that
497 will set the first breakpoint at line 40 in myscript.py. Note that
498 the first breakpoint must be set on a line which actually does
498 the first breakpoint must be set on a line which actually does
499 something (not a comment or docstring) for it to stop execution.
499 something (not a comment or docstring) for it to stop execution.
500
500
501 Or you can specify a breakpoint in a different file::
501 Or you can specify a breakpoint in a different file::
502
502
503 %run -d -b myotherfile.py:20 myscript
503 %run -d -b myotherfile.py:20 myscript
504
504
505 When the pdb debugger starts, you will see a (Pdb) prompt. You must
505 When the pdb debugger starts, you will see a (Pdb) prompt. You must
506 first enter 'c' (without quotes) to start execution up to the first
506 first enter 'c' (without quotes) to start execution up to the first
507 breakpoint.
507 breakpoint.
508
508
509 Entering 'help' gives information about the use of the debugger. You
509 Entering 'help' gives information about the use of the debugger. You
510 can easily see pdb's full documentation with "import pdb;pdb.help()"
510 can easily see pdb's full documentation with "import pdb;pdb.help()"
511 at a prompt.
511 at a prompt.
512
512
513 -p
513 -p
514 run program under the control of the Python profiler module (which
514 run program under the control of the Python profiler module (which
515 prints a detailed report of execution times, function calls, etc).
515 prints a detailed report of execution times, function calls, etc).
516
516
517 You can pass other options after -p which affect the behavior of the
517 You can pass other options after -p which affect the behavior of the
518 profiler itself. See the docs for %prun for details.
518 profiler itself. See the docs for %prun for details.
519
519
520 In this mode, the program's variables do NOT propagate back to the
520 In this mode, the program's variables do NOT propagate back to the
521 IPython interactive namespace (because they remain in the namespace
521 IPython interactive namespace (because they remain in the namespace
522 where the profiler executes them).
522 where the profiler executes them).
523
523
524 Internally this triggers a call to %prun, see its documentation for
524 Internally this triggers a call to %prun, see its documentation for
525 details on the options available specifically for profiling.
525 details on the options available specifically for profiling.
526
526
527 There is one special usage for which the text above doesn't apply:
527 There is one special usage for which the text above doesn't apply:
528 if the filename ends with .ipy, the file is run as ipython script,
528 if the filename ends with .ipy, the file is run as ipython script,
529 just as if the commands were written on IPython prompt.
529 just as if the commands were written on IPython prompt.
530
530
531 -m
531 -m
532 specify module name to load instead of script path. Similar to
532 specify module name to load instead of script path. Similar to
533 the -m option for the python interpreter. Use this option last if you
533 the -m option for the python interpreter. Use this option last if you
534 want to combine with other %run options. Unlike the python interpreter
534 want to combine with other %run options. Unlike the python interpreter
535 only source modules are allowed no .pyc or .pyo files.
535 only source modules are allowed no .pyc or .pyo files.
536 For example::
536 For example::
537
537
538 %run -m example
538 %run -m example
539
539
540 will run the example module.
540 will run the example module.
541
541
542 -G
542 -G
543 disable shell-like glob expansion of arguments.
543 disable shell-like glob expansion of arguments.
544
544
545 """
545 """
546
546
547 # get arguments and set sys.argv for program to be run.
547 # get arguments and set sys.argv for program to be run.
548 opts, arg_lst = self.parse_options(parameter_s,
548 opts, arg_lst = self.parse_options(parameter_s,
549 'nidtN:b:pD:l:rs:T:em:G',
549 'nidtN:b:pD:l:rs:T:em:G',
550 mode='list', list_all=1)
550 mode='list', list_all=1)
551 if "m" in opts:
551 if "m" in opts:
552 modulename = opts["m"][0]
552 modulename = opts["m"][0]
553 modpath = find_mod(modulename)
553 modpath = find_mod(modulename)
554 if modpath is None:
554 if modpath is None:
555 warn('%r is not a valid modulename on sys.path'%modulename)
555 warn('%r is not a valid modulename on sys.path'%modulename)
556 return
556 return
557 arg_lst = [modpath] + arg_lst
557 arg_lst = [modpath] + arg_lst
558 try:
558 try:
559 filename = file_finder(arg_lst[0])
559 filename = file_finder(arg_lst[0])
560 except IndexError:
560 except IndexError:
561 warn('you must provide at least a filename.')
561 warn('you must provide at least a filename.')
562 print('\n%run:\n', oinspect.getdoc(self.run))
562 print('\n%run:\n', oinspect.getdoc(self.run))
563 return
563 return
564 except IOError as e:
564 except IOError as e:
565 try:
565 try:
566 msg = str(e)
566 msg = str(e)
567 except UnicodeError:
567 except UnicodeError:
568 msg = e.message
568 msg = e.message
569 error(msg)
569 error(msg)
570 return
570 return
571
571
572 if filename.lower().endswith('.ipy'):
572 if filename.lower().endswith('.ipy'):
573 with preserve_keys(self.shell.user_ns, '__file__'):
573 with preserve_keys(self.shell.user_ns, '__file__'):
574 self.shell.user_ns['__file__'] = filename
574 self.shell.user_ns['__file__'] = filename
575 self.shell.safe_execfile_ipy(filename)
575 self.shell.safe_execfile_ipy(filename)
576 return
576 return
577
577
578 # Control the response to exit() calls made by the script being run
578 # Control the response to exit() calls made by the script being run
579 exit_ignore = 'e' in opts
579 exit_ignore = 'e' in opts
580
580
581 # Make sure that the running script gets a proper sys.argv as if it
581 # Make sure that the running script gets a proper sys.argv as if it
582 # were run from a system shell.
582 # were run from a system shell.
583 save_argv = sys.argv # save it for later restoring
583 save_argv = sys.argv # save it for later restoring
584
584
585 if 'G' in opts:
585 if 'G' in opts:
586 args = arg_lst[1:]
586 args = arg_lst[1:]
587 else:
587 else:
588 # tilde and glob expansion
588 # tilde and glob expansion
589 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
589 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
590
590
591 sys.argv = [filename] + args # put in the proper filename
591 sys.argv = [filename] + args # put in the proper filename
592 # protect sys.argv from potential unicode strings on Python 2:
592 # protect sys.argv from potential unicode strings on Python 2:
593 if not py3compat.PY3:
593 if not py3compat.PY3:
594 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
594 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
595
595
596 if 'i' in opts:
596 if 'i' in opts:
597 # Run in user's interactive namespace
597 # Run in user's interactive namespace
598 prog_ns = self.shell.user_ns
598 prog_ns = self.shell.user_ns
599 __name__save = self.shell.user_ns['__name__']
599 __name__save = self.shell.user_ns['__name__']
600 prog_ns['__name__'] = '__main__'
600 prog_ns['__name__'] = '__main__'
601 main_mod = self.shell.user_module
601 main_mod = self.shell.user_module
602
602
603 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
603 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
604 # set the __file__ global in the script's namespace
604 # set the __file__ global in the script's namespace
605 # TK: Is this necessary in interactive mode?
605 # TK: Is this necessary in interactive mode?
606 prog_ns['__file__'] = filename
606 prog_ns['__file__'] = filename
607 else:
607 else:
608 # Run in a fresh, empty namespace
608 # Run in a fresh, empty namespace
609 if 'n' in opts:
609 if 'n' in opts:
610 name = os.path.splitext(os.path.basename(filename))[0]
610 name = os.path.splitext(os.path.basename(filename))[0]
611 else:
611 else:
612 name = '__main__'
612 name = '__main__'
613
613
614 # The shell MUST hold a reference to prog_ns so after %run
614 # The shell MUST hold a reference to prog_ns so after %run
615 # exits, the python deletion mechanism doesn't zero it out
615 # exits, the python deletion mechanism doesn't zero it out
616 # (leaving dangling references). See interactiveshell for details
616 # (leaving dangling references). See interactiveshell for details
617 main_mod = self.shell.new_main_mod(filename, name)
617 main_mod = self.shell.new_main_mod(filename, name)
618 prog_ns = main_mod.__dict__
618 prog_ns = main_mod.__dict__
619
619
620 # pickle fix. See interactiveshell for an explanation. But we need to
620 # pickle fix. See interactiveshell for an explanation. But we need to
621 # make sure that, if we overwrite __main__, we replace it at the end
621 # make sure that, if we overwrite __main__, we replace it at the end
622 main_mod_name = prog_ns['__name__']
622 main_mod_name = prog_ns['__name__']
623
623
624 if main_mod_name == '__main__':
624 if main_mod_name == '__main__':
625 restore_main = sys.modules['__main__']
625 restore_main = sys.modules['__main__']
626 else:
626 else:
627 restore_main = False
627 restore_main = False
628
628
629 # This needs to be undone at the end to prevent holding references to
629 # This needs to be undone at the end to prevent holding references to
630 # every single object ever created.
630 # every single object ever created.
631 sys.modules[main_mod_name] = main_mod
631 sys.modules[main_mod_name] = main_mod
632
632
633 if 'p' in opts or 'd' in opts:
633 if 'p' in opts or 'd' in opts:
634 if 'm' in opts:
634 if 'm' in opts:
635 code = 'run_module(modulename, prog_ns)'
635 code = 'run_module(modulename, prog_ns)'
636 code_ns = {
636 code_ns = {
637 'run_module': self.shell.safe_run_module,
637 'run_module': self.shell.safe_run_module,
638 'prog_ns': prog_ns,
638 'prog_ns': prog_ns,
639 'modulename': modulename,
639 'modulename': modulename,
640 }
640 }
641 else:
641 else:
642 code = 'execfile(filename, prog_ns)'
642 code = 'execfile(filename, prog_ns)'
643 code_ns = {
643 code_ns = {
644 'execfile': self.shell.safe_execfile,
644 'execfile': self.shell.safe_execfile,
645 'prog_ns': prog_ns,
645 'prog_ns': prog_ns,
646 'filename': get_py_filename(filename),
646 'filename': get_py_filename(filename),
647 }
647 }
648
648
649 try:
649 try:
650 stats = None
650 stats = None
651 with self.shell.readline_no_record:
651 with self.shell.readline_no_record:
652 if 'p' in opts:
652 if 'p' in opts:
653 stats = self._run_with_profiler(code, opts, code_ns)
653 stats = self._run_with_profiler(code, opts, code_ns)
654 else:
654 else:
655 if 'd' in opts:
655 if 'd' in opts:
656 bp_file, bp_line = parse_breakpoint(
656 bp_file, bp_line = parse_breakpoint(
657 opts.get('b', ['1'])[0], filename)
657 opts.get('b', ['1'])[0], filename)
658 self._run_with_debugger(
658 self._run_with_debugger(
659 code, code_ns, filename, bp_line, bp_file)
659 code, code_ns, filename, bp_line, bp_file)
660 else:
660 else:
661 if 'm' in opts:
661 if 'm' in opts:
662 def run():
662 def run():
663 self.shell.safe_run_module(modulename, prog_ns)
663 self.shell.safe_run_module(modulename, prog_ns)
664 else:
664 else:
665 if runner is None:
665 if runner is None:
666 runner = self.default_runner
666 runner = self.default_runner
667 if runner is None:
667 if runner is None:
668 runner = self.shell.safe_execfile
668 runner = self.shell.safe_execfile
669
669
670 def run():
670 def run():
671 runner(filename, prog_ns, prog_ns,
671 runner(filename, prog_ns, prog_ns,
672 exit_ignore=exit_ignore)
672 exit_ignore=exit_ignore)
673
673
674 if 't' in opts:
674 if 't' in opts:
675 # timed execution
675 # timed execution
676 try:
676 try:
677 nruns = int(opts['N'][0])
677 nruns = int(opts['N'][0])
678 if nruns < 1:
678 if nruns < 1:
679 error('Number of runs must be >=1')
679 error('Number of runs must be >=1')
680 return
680 return
681 except (KeyError):
681 except (KeyError):
682 nruns = 1
682 nruns = 1
683 self._run_with_timing(run, nruns)
683 self._run_with_timing(run, nruns)
684 else:
684 else:
685 # regular execution
685 # regular execution
686 run()
686 run()
687
687
688 if 'i' in opts:
688 if 'i' in opts:
689 self.shell.user_ns['__name__'] = __name__save
689 self.shell.user_ns['__name__'] = __name__save
690 else:
690 else:
691 # update IPython interactive namespace
691 # update IPython interactive namespace
692
692
693 # Some forms of read errors on the file may mean the
693 # Some forms of read errors on the file may mean the
694 # __name__ key was never set; using pop we don't have to
694 # __name__ key was never set; using pop we don't have to
695 # worry about a possible KeyError.
695 # worry about a possible KeyError.
696 prog_ns.pop('__name__', None)
696 prog_ns.pop('__name__', None)
697
697
698 with preserve_keys(self.shell.user_ns, '__file__'):
698 with preserve_keys(self.shell.user_ns, '__file__'):
699 self.shell.user_ns.update(prog_ns)
699 self.shell.user_ns.update(prog_ns)
700 finally:
700 finally:
701 # It's a bit of a mystery why, but __builtins__ can change from
701 # It's a bit of a mystery why, but __builtins__ can change from
702 # being a module to becoming a dict missing some key data after
702 # being a module to becoming a dict missing some key data after
703 # %run. As best I can see, this is NOT something IPython is doing
703 # %run. As best I can see, this is NOT something IPython is doing
704 # at all, and similar problems have been reported before:
704 # at all, and similar problems have been reported before:
705 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
705 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
706 # Since this seems to be done by the interpreter itself, the best
706 # Since this seems to be done by the interpreter itself, the best
707 # we can do is to at least restore __builtins__ for the user on
707 # we can do is to at least restore __builtins__ for the user on
708 # exit.
708 # exit.
709 self.shell.user_ns['__builtins__'] = builtin_mod
709 self.shell.user_ns['__builtins__'] = builtin_mod
710
710
711 # Ensure key global structures are restored
711 # Ensure key global structures are restored
712 sys.argv = save_argv
712 sys.argv = save_argv
713 if restore_main:
713 if restore_main:
714 sys.modules['__main__'] = restore_main
714 sys.modules['__main__'] = restore_main
715 else:
715 else:
716 # Remove from sys.modules the reference to main_mod we'd
716 # Remove from sys.modules the reference to main_mod we'd
717 # added. Otherwise it will trap references to objects
717 # added. Otherwise it will trap references to objects
718 # contained therein.
718 # contained therein.
719 del sys.modules[main_mod_name]
719 del sys.modules[main_mod_name]
720
720
721 return stats
721 return stats
722
722
723 def _run_with_debugger(self, code, code_ns, filename=None,
723 def _run_with_debugger(self, code, code_ns, filename=None,
724 bp_line=None, bp_file=None):
724 bp_line=None, bp_file=None):
725 """
725 """
726 Run `code` in debugger with a break point.
726 Run `code` in debugger with a break point.
727
727
728 Parameters
728 Parameters
729 ----------
729 ----------
730 code : str
730 code : str
731 Code to execute.
731 Code to execute.
732 code_ns : dict
732 code_ns : dict
733 A namespace in which `code` is executed.
733 A namespace in which `code` is executed.
734 filename : str
734 filename : str
735 `code` is ran as if it is in `filename`.
735 `code` is ran as if it is in `filename`.
736 bp_line : int, optional
736 bp_line : int, optional
737 Line number of the break point.
737 Line number of the break point.
738 bp_file : str, optional
738 bp_file : str, optional
739 Path to the file in which break point is specified.
739 Path to the file in which break point is specified.
740 `filename` is used if not given.
740 `filename` is used if not given.
741
741
742 Raises
742 Raises
743 ------
743 ------
744 UsageError
744 UsageError
745 If the break point given by `bp_line` is not valid.
745 If the break point given by `bp_line` is not valid.
746
746
747 """
747 """
748 deb = debugger.Pdb(self.shell.colors)
748 deb = debugger.Pdb(self.shell.colors)
749 # reset Breakpoint state, which is moronically kept
749 # reset Breakpoint state, which is moronically kept
750 # in a class
750 # in a class
751 bdb.Breakpoint.next = 1
751 bdb.Breakpoint.next = 1
752 bdb.Breakpoint.bplist = {}
752 bdb.Breakpoint.bplist = {}
753 bdb.Breakpoint.bpbynumber = [None]
753 bdb.Breakpoint.bpbynumber = [None]
754 if bp_line is not None:
754 if bp_line is not None:
755 # Set an initial breakpoint to stop execution
755 # Set an initial breakpoint to stop execution
756 maxtries = 10
756 maxtries = 10
757 bp_file = bp_file or filename
757 bp_file = bp_file or filename
758 checkline = deb.checkline(bp_file, bp_line)
758 checkline = deb.checkline(bp_file, bp_line)
759 if not checkline:
759 if not checkline:
760 for bp in range(bp_line + 1, bp_line + maxtries + 1):
760 for bp in range(bp_line + 1, bp_line + maxtries + 1):
761 if deb.checkline(bp_file, bp):
761 if deb.checkline(bp_file, bp):
762 break
762 break
763 else:
763 else:
764 msg = ("\nI failed to find a valid line to set "
764 msg = ("\nI failed to find a valid line to set "
765 "a breakpoint\n"
765 "a breakpoint\n"
766 "after trying up to line: %s.\n"
766 "after trying up to line: %s.\n"
767 "Please set a valid breakpoint manually "
767 "Please set a valid breakpoint manually "
768 "with the -b option." % bp)
768 "with the -b option." % bp)
769 raise UsageError(msg)
769 raise UsageError(msg)
770 # if we find a good linenumber, set the breakpoint
770 # if we find a good linenumber, set the breakpoint
771 deb.do_break('%s:%s' % (bp_file, bp_line))
771 deb.do_break('%s:%s' % (bp_file, bp_line))
772
772
773 if filename:
773 if filename:
774 # Mimic Pdb._runscript(...)
774 # Mimic Pdb._runscript(...)
775 deb._wait_for_mainpyfile = True
775 deb._wait_for_mainpyfile = True
776 deb.mainpyfile = deb.canonic(filename)
776 deb.mainpyfile = deb.canonic(filename)
777
777
778 # Start file run
778 # Start file run
779 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
779 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
780 try:
780 try:
781 if filename:
781 if filename:
782 # save filename so it can be used by methods on the deb object
782 # save filename so it can be used by methods on the deb object
783 deb._exec_filename = filename
783 deb._exec_filename = filename
784 deb.run(code, code_ns)
784 deb.run(code, code_ns)
785
785
786 except:
786 except:
787 etype, value, tb = sys.exc_info()
787 etype, value, tb = sys.exc_info()
788 # Skip three frames in the traceback: the %run one,
788 # Skip three frames in the traceback: the %run one,
789 # one inside bdb.py, and the command-line typed by the
789 # one inside bdb.py, and the command-line typed by the
790 # user (run by exec in pdb itself).
790 # user (run by exec in pdb itself).
791 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
791 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
792
792
793 @staticmethod
793 @staticmethod
794 def _run_with_timing(run, nruns):
794 def _run_with_timing(run, nruns):
795 """
795 """
796 Run function `run` and print timing information.
796 Run function `run` and print timing information.
797
797
798 Parameters
798 Parameters
799 ----------
799 ----------
800 run : callable
800 run : callable
801 Any callable object which takes no argument.
801 Any callable object which takes no argument.
802 nruns : int
802 nruns : int
803 Number of times to execute `run`.
803 Number of times to execute `run`.
804
804
805 """
805 """
806 twall0 = time.time()
806 twall0 = time.time()
807 if nruns == 1:
807 if nruns == 1:
808 t0 = clock2()
808 t0 = clock2()
809 run()
809 run()
810 t1 = clock2()
810 t1 = clock2()
811 t_usr = t1[0] - t0[0]
811 t_usr = t1[0] - t0[0]
812 t_sys = t1[1] - t0[1]
812 t_sys = t1[1] - t0[1]
813 print("\nIPython CPU timings (estimated):")
813 print("\nIPython CPU timings (estimated):")
814 print(" User : %10.2f s." % t_usr)
814 print(" User : %10.2f s." % t_usr)
815 print(" System : %10.2f s." % t_sys)
815 print(" System : %10.2f s." % t_sys)
816 else:
816 else:
817 runs = range(nruns)
817 runs = range(nruns)
818 t0 = clock2()
818 t0 = clock2()
819 for nr in runs:
819 for nr in runs:
820 run()
820 run()
821 t1 = clock2()
821 t1 = clock2()
822 t_usr = t1[0] - t0[0]
822 t_usr = t1[0] - t0[0]
823 t_sys = t1[1] - t0[1]
823 t_sys = t1[1] - t0[1]
824 print("\nIPython CPU timings (estimated):")
824 print("\nIPython CPU timings (estimated):")
825 print("Total runs performed:", nruns)
825 print("Total runs performed:", nruns)
826 print(" Times : %10s %10s" % ('Total', 'Per run'))
826 print(" Times : %10s %10s" % ('Total', 'Per run'))
827 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
827 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
828 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
828 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
829 twall1 = time.time()
829 twall1 = time.time()
830 print("Wall time: %10.2f s." % (twall1 - twall0))
830 print("Wall time: %10.2f s." % (twall1 - twall0))
831
831
832 @skip_doctest
832 @skip_doctest
833 @line_cell_magic
833 @line_cell_magic
834 def timeit(self, line='', cell=None):
834 def timeit(self, line='', cell=None):
835 """Time execution of a Python statement or expression
835 """Time execution of a Python statement or expression
836
836
837 Usage, in line mode:
837 Usage, in line mode:
838 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
838 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
839 or in cell mode:
839 or in cell mode:
840 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
840 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
841 code
841 code
842 code...
842 code...
843
843
844 Time execution of a Python statement or expression using the timeit
844 Time execution of a Python statement or expression using the timeit
845 module. This function can be used both as a line and cell magic:
845 module. This function can be used both as a line and cell magic:
846
846
847 - In line mode you can time a single-line statement (though multiple
847 - In line mode you can time a single-line statement (though multiple
848 ones can be chained with using semicolons).
848 ones can be chained with using semicolons).
849
849
850 - In cell mode, the statement in the first line is used as setup code
850 - In cell mode, the statement in the first line is used as setup code
851 (executed but not timed) and the body of the cell is timed. The cell
851 (executed but not timed) and the body of the cell is timed. The cell
852 body has access to any variables created in the setup code.
852 body has access to any variables created in the setup code.
853
853
854 Options:
854 Options:
855 -n<N>: execute the given statement <N> times in a loop. If this value
855 -n<N>: execute the given statement <N> times in a loop. If this value
856 is not given, a fitting value is chosen.
856 is not given, a fitting value is chosen.
857
857
858 -r<R>: repeat the loop iteration <R> times and take the best result.
858 -r<R>: repeat the loop iteration <R> times and take the best result.
859 Default: 3
859 Default: 3
860
860
861 -t: use time.time to measure the time, which is the default on Unix.
861 -t: use time.time to measure the time, which is the default on Unix.
862 This function measures wall time.
862 This function measures wall time.
863
863
864 -c: use time.clock to measure the time, which is the default on
864 -c: use time.clock to measure the time, which is the default on
865 Windows and measures wall time. On Unix, resource.getrusage is used
865 Windows and measures wall time. On Unix, resource.getrusage is used
866 instead and returns the CPU user time.
866 instead and returns the CPU user time.
867
867
868 -p<P>: use a precision of <P> digits to display the timing result.
868 -p<P>: use a precision of <P> digits to display the timing result.
869 Default: 3
869 Default: 3
870
870
871 -q: Quiet, do not print result.
871 -q: Quiet, do not print result.
872
872
873 -o: return a TimeitResult that can be stored in a variable to inspect
873 -o: return a TimeitResult that can be stored in a variable to inspect
874 the result in more details.
874 the result in more details.
875
875
876
876
877 Examples
877 Examples
878 --------
878 --------
879 ::
879 ::
880
880
881 In [1]: %timeit pass
881 In [1]: %timeit pass
882 10000000 loops, best of 3: 53.3 ns per loop
882 10000000 loops, best of 3: 53.3 ns per loop
883
883
884 In [2]: u = None
884 In [2]: u = None
885
885
886 In [3]: %timeit u is None
886 In [3]: %timeit u is None
887 10000000 loops, best of 3: 184 ns per loop
887 10000000 loops, best of 3: 184 ns per loop
888
888
889 In [4]: %timeit -r 4 u == None
889 In [4]: %timeit -r 4 u == None
890 1000000 loops, best of 4: 242 ns per loop
890 1000000 loops, best of 4: 242 ns per loop
891
891
892 In [5]: import time
892 In [5]: import time
893
893
894 In [6]: %timeit -n1 time.sleep(2)
894 In [6]: %timeit -n1 time.sleep(2)
895 1 loops, best of 3: 2 s per loop
895 1 loops, best of 3: 2 s per loop
896
896
897
897
898 The times reported by %timeit will be slightly higher than those
898 The times reported by %timeit will be slightly higher than those
899 reported by the timeit.py script when variables are accessed. This is
899 reported by the timeit.py script when variables are accessed. This is
900 due to the fact that %timeit executes the statement in the namespace
900 due to the fact that %timeit executes the statement in the namespace
901 of the shell, compared with timeit.py, which uses a single setup
901 of the shell, compared with timeit.py, which uses a single setup
902 statement to import function or create variables. Generally, the bias
902 statement to import function or create variables. Generally, the bias
903 does not matter as long as results from timeit.py are not mixed with
903 does not matter as long as results from timeit.py are not mixed with
904 those from %timeit."""
904 those from %timeit."""
905
905
906 import timeit
906 import timeit
907
907
908 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
908 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
909 posix=False, strict=False)
909 posix=False, strict=False)
910 if stmt == "" and cell is None:
910 if stmt == "" and cell is None:
911 return
911 return
912
912
913 timefunc = timeit.default_timer
913 timefunc = timeit.default_timer
914 number = int(getattr(opts, "n", 0))
914 number = int(getattr(opts, "n", 0))
915 repeat = int(getattr(opts, "r", timeit.default_repeat))
915 repeat = int(getattr(opts, "r", timeit.default_repeat))
916 precision = int(getattr(opts, "p", 3))
916 precision = int(getattr(opts, "p", 3))
917 quiet = 'q' in opts
917 quiet = 'q' in opts
918 return_result = 'o' in opts
918 return_result = 'o' in opts
919 if hasattr(opts, "t"):
919 if hasattr(opts, "t"):
920 timefunc = time.time
920 timefunc = time.time
921 if hasattr(opts, "c"):
921 if hasattr(opts, "c"):
922 timefunc = clock
922 timefunc = clock
923
923
924 timer = timeit.Timer(timer=timefunc)
924 timer = timeit.Timer(timer=timefunc)
925 # this code has tight coupling to the inner workings of timeit.Timer,
925 # this code has tight coupling to the inner workings of timeit.Timer,
926 # but is there a better way to achieve that the code stmt has access
926 # but is there a better way to achieve that the code stmt has access
927 # to the shell namespace?
927 # to the shell namespace?
928 transform = self.shell.input_splitter.transform_cell
928 transform = self.shell.input_splitter.transform_cell
929
929
930 if cell is None:
930 if cell is None:
931 # called as line magic
931 # called as line magic
932 ast_setup = ast.parse("pass")
932 ast_setup = ast.parse("pass")
933 ast_stmt = ast.parse(transform(stmt))
933 ast_stmt = ast.parse(transform(stmt))
934 else:
934 else:
935 ast_setup = ast.parse(transform(stmt))
935 ast_setup = ast.parse(transform(stmt))
936 ast_stmt = ast.parse(transform(cell))
936 ast_stmt = ast.parse(transform(cell))
937
937
938 ast_setup = self.shell.transform_ast(ast_setup)
938 ast_setup = self.shell.transform_ast(ast_setup)
939 ast_stmt = self.shell.transform_ast(ast_stmt)
939 ast_stmt = self.shell.transform_ast(ast_stmt)
940
940
941 # This codestring is taken from timeit.template - we fill it in as an
941 # This codestring is taken from timeit.template - we fill it in as an
942 # AST, so that we can apply our AST transformations to the user code
942 # AST, so that we can apply our AST transformations to the user code
943 # without affecting the timing code.
943 # without affecting the timing code.
944 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
944 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
945 ' setup\n'
945 ' setup\n'
946 ' _t0 = _timer()\n'
946 ' _t0 = _timer()\n'
947 ' for _i in _it:\n'
947 ' for _i in _it:\n'
948 ' stmt\n'
948 ' stmt\n'
949 ' _t1 = _timer()\n'
949 ' _t1 = _timer()\n'
950 ' return _t1 - _t0\n')
950 ' return _t1 - _t0\n')
951
951
952 class TimeitTemplateFiller(ast.NodeTransformer):
952 class TimeitTemplateFiller(ast.NodeTransformer):
953 "This is quite tightly tied to the template definition above."
953 "This is quite tightly tied to the template definition above."
954 def visit_FunctionDef(self, node):
954 def visit_FunctionDef(self, node):
955 "Fill in the setup statement"
955 "Fill in the setup statement"
956 self.generic_visit(node)
956 self.generic_visit(node)
957 if node.name == "inner":
957 if node.name == "inner":
958 node.body[:1] = ast_setup.body
958 node.body[:1] = ast_setup.body
959
959
960 return node
960 return node
961
961
962 def visit_For(self, node):
962 def visit_For(self, node):
963 "Fill in the statement to be timed"
963 "Fill in the statement to be timed"
964 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
964 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
965 node.body = ast_stmt.body
965 node.body = ast_stmt.body
966 return node
966 return node
967
967
968 timeit_ast = TimeitTemplateFiller().visit(timeit_ast_template)
968 timeit_ast = TimeitTemplateFiller().visit(timeit_ast_template)
969 timeit_ast = ast.fix_missing_locations(timeit_ast)
969 timeit_ast = ast.fix_missing_locations(timeit_ast)
970
970
971 # Track compilation time so it can be reported if too long
971 # Track compilation time so it can be reported if too long
972 # Minimum time above which compilation time will be reported
972 # Minimum time above which compilation time will be reported
973 tc_min = 0.1
973 tc_min = 0.1
974
974
975 t0 = clock()
975 t0 = clock()
976 code = compile(timeit_ast, "<magic-timeit>", "exec")
976 code = compile(timeit_ast, "<magic-timeit>", "exec")
977 tc = clock()-t0
977 tc = clock()-t0
978
978
979 ns = {}
979 ns = {}
980 exec code in self.shell.user_ns, ns
980 exec(code, self.shell.user_ns, ns)
981 timer.inner = ns["inner"]
981 timer.inner = ns["inner"]
982
982
983 if number == 0:
983 if number == 0:
984 # determine number so that 0.2 <= total time < 2.0
984 # determine number so that 0.2 <= total time < 2.0
985 number = 1
985 number = 1
986 for _ in range(1, 10):
986 for _ in range(1, 10):
987 if timer.timeit(number) >= 0.2:
987 if timer.timeit(number) >= 0.2:
988 break
988 break
989 number *= 10
989 number *= 10
990 all_runs = timer.repeat(repeat, number)
990 all_runs = timer.repeat(repeat, number)
991 best = min(all_runs) / number
991 best = min(all_runs) / number
992 if not quiet :
992 if not quiet :
993 print(u"%d loops, best of %d: %s per loop" % (number, repeat,
993 print(u"%d loops, best of %d: %s per loop" % (number, repeat,
994 _format_time(best, precision)))
994 _format_time(best, precision)))
995 if tc > tc_min:
995 if tc > tc_min:
996 print("Compiler time: %.2f s" % tc)
996 print("Compiler time: %.2f s" % tc)
997 if return_result:
997 if return_result:
998 return TimeitResult(number, repeat, best, all_runs, tc, precision)
998 return TimeitResult(number, repeat, best, all_runs, tc, precision)
999
999
1000 @skip_doctest
1000 @skip_doctest
1001 @needs_local_scope
1001 @needs_local_scope
1002 @line_cell_magic
1002 @line_cell_magic
1003 def time(self,line='', cell=None, local_ns=None):
1003 def time(self,line='', cell=None, local_ns=None):
1004 """Time execution of a Python statement or expression.
1004 """Time execution of a Python statement or expression.
1005
1005
1006 The CPU and wall clock times are printed, and the value of the
1006 The CPU and wall clock times are printed, and the value of the
1007 expression (if any) is returned. Note that under Win32, system time
1007 expression (if any) is returned. Note that under Win32, system time
1008 is always reported as 0, since it can not be measured.
1008 is always reported as 0, since it can not be measured.
1009
1009
1010 This function can be used both as a line and cell magic:
1010 This function can be used both as a line and cell magic:
1011
1011
1012 - In line mode you can time a single-line statement (though multiple
1012 - In line mode you can time a single-line statement (though multiple
1013 ones can be chained with using semicolons).
1013 ones can be chained with using semicolons).
1014
1014
1015 - In cell mode, you can time the cell body (a directly
1015 - In cell mode, you can time the cell body (a directly
1016 following statement raises an error).
1016 following statement raises an error).
1017
1017
1018 This function provides very basic timing functionality. Use the timeit
1018 This function provides very basic timing functionality. Use the timeit
1019 magic for more controll over the measurement.
1019 magic for more controll over the measurement.
1020
1020
1021 Examples
1021 Examples
1022 --------
1022 --------
1023 ::
1023 ::
1024
1024
1025 In [1]: %time 2**128
1025 In [1]: %time 2**128
1026 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1026 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1027 Wall time: 0.00
1027 Wall time: 0.00
1028 Out[1]: 340282366920938463463374607431768211456L
1028 Out[1]: 340282366920938463463374607431768211456L
1029
1029
1030 In [2]: n = 1000000
1030 In [2]: n = 1000000
1031
1031
1032 In [3]: %time sum(range(n))
1032 In [3]: %time sum(range(n))
1033 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1033 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1034 Wall time: 1.37
1034 Wall time: 1.37
1035 Out[3]: 499999500000L
1035 Out[3]: 499999500000L
1036
1036
1037 In [4]: %time print 'hello world'
1037 In [4]: %time print 'hello world'
1038 hello world
1038 hello world
1039 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1039 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1040 Wall time: 0.00
1040 Wall time: 0.00
1041
1041
1042 Note that the time needed by Python to compile the given expression
1042 Note that the time needed by Python to compile the given expression
1043 will be reported if it is more than 0.1s. In this example, the
1043 will be reported if it is more than 0.1s. In this example, the
1044 actual exponentiation is done by Python at compilation time, so while
1044 actual exponentiation is done by Python at compilation time, so while
1045 the expression can take a noticeable amount of time to compute, that
1045 the expression can take a noticeable amount of time to compute, that
1046 time is purely due to the compilation:
1046 time is purely due to the compilation:
1047
1047
1048 In [5]: %time 3**9999;
1048 In [5]: %time 3**9999;
1049 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1049 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1050 Wall time: 0.00 s
1050 Wall time: 0.00 s
1051
1051
1052 In [6]: %time 3**999999;
1052 In [6]: %time 3**999999;
1053 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1053 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1054 Wall time: 0.00 s
1054 Wall time: 0.00 s
1055 Compiler : 0.78 s
1055 Compiler : 0.78 s
1056 """
1056 """
1057
1057
1058 # fail immediately if the given expression can't be compiled
1058 # fail immediately if the given expression can't be compiled
1059
1059
1060 if line and cell:
1060 if line and cell:
1061 raise UsageError("Can't use statement directly after '%%time'!")
1061 raise UsageError("Can't use statement directly after '%%time'!")
1062
1062
1063 if cell:
1063 if cell:
1064 expr = self.shell.input_transformer_manager.transform_cell(cell)
1064 expr = self.shell.input_transformer_manager.transform_cell(cell)
1065 else:
1065 else:
1066 expr = self.shell.input_transformer_manager.transform_cell(line)
1066 expr = self.shell.input_transformer_manager.transform_cell(line)
1067
1067
1068 # Minimum time above which parse time will be reported
1068 # Minimum time above which parse time will be reported
1069 tp_min = 0.1
1069 tp_min = 0.1
1070
1070
1071 t0 = clock()
1071 t0 = clock()
1072 expr_ast = ast.parse(expr)
1072 expr_ast = ast.parse(expr)
1073 tp = clock()-t0
1073 tp = clock()-t0
1074
1074
1075 # Apply AST transformations
1075 # Apply AST transformations
1076 expr_ast = self.shell.transform_ast(expr_ast)
1076 expr_ast = self.shell.transform_ast(expr_ast)
1077
1077
1078 # Minimum time above which compilation time will be reported
1078 # Minimum time above which compilation time will be reported
1079 tc_min = 0.1
1079 tc_min = 0.1
1080
1080
1081 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1081 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1082 mode = 'eval'
1082 mode = 'eval'
1083 source = '<timed eval>'
1083 source = '<timed eval>'
1084 expr_ast = ast.Expression(expr_ast.body[0].value)
1084 expr_ast = ast.Expression(expr_ast.body[0].value)
1085 else:
1085 else:
1086 mode = 'exec'
1086 mode = 'exec'
1087 source = '<timed exec>'
1087 source = '<timed exec>'
1088 t0 = clock()
1088 t0 = clock()
1089 code = compile(expr_ast, source, mode)
1089 code = compile(expr_ast, source, mode)
1090 tc = clock()-t0
1090 tc = clock()-t0
1091
1091
1092 # skew measurement as little as possible
1092 # skew measurement as little as possible
1093 glob = self.shell.user_ns
1093 glob = self.shell.user_ns
1094 wtime = time.time
1094 wtime = time.time
1095 # time execution
1095 # time execution
1096 wall_st = wtime()
1096 wall_st = wtime()
1097 if mode=='eval':
1097 if mode=='eval':
1098 st = clock2()
1098 st = clock2()
1099 out = eval(code, glob, local_ns)
1099 out = eval(code, glob, local_ns)
1100 end = clock2()
1100 end = clock2()
1101 else:
1101 else:
1102 st = clock2()
1102 st = clock2()
1103 exec code in glob, local_ns
1103 exec(code, glob, local_ns)
1104 end = clock2()
1104 end = clock2()
1105 out = None
1105 out = None
1106 wall_end = wtime()
1106 wall_end = wtime()
1107 # Compute actual times and report
1107 # Compute actual times and report
1108 wall_time = wall_end-wall_st
1108 wall_time = wall_end-wall_st
1109 cpu_user = end[0]-st[0]
1109 cpu_user = end[0]-st[0]
1110 cpu_sys = end[1]-st[1]
1110 cpu_sys = end[1]-st[1]
1111 cpu_tot = cpu_user+cpu_sys
1111 cpu_tot = cpu_user+cpu_sys
1112 # On windows cpu_sys is always zero, so no new information to the next print
1112 # On windows cpu_sys is always zero, so no new information to the next print
1113 if sys.platform != 'win32':
1113 if sys.platform != 'win32':
1114 print("CPU times: user %s, sys: %s, total: %s" % \
1114 print("CPU times: user %s, sys: %s, total: %s" % \
1115 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1115 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1116 print("Wall time: %s" % _format_time(wall_time))
1116 print("Wall time: %s" % _format_time(wall_time))
1117 if tc > tc_min:
1117 if tc > tc_min:
1118 print("Compiler : %s" % _format_time(tc))
1118 print("Compiler : %s" % _format_time(tc))
1119 if tp > tp_min:
1119 if tp > tp_min:
1120 print("Parser : %s" % _format_time(tp))
1120 print("Parser : %s" % _format_time(tp))
1121 return out
1121 return out
1122
1122
1123 @skip_doctest
1123 @skip_doctest
1124 @line_magic
1124 @line_magic
1125 def macro(self, parameter_s=''):
1125 def macro(self, parameter_s=''):
1126 """Define a macro for future re-execution. It accepts ranges of history,
1126 """Define a macro for future re-execution. It accepts ranges of history,
1127 filenames or string objects.
1127 filenames or string objects.
1128
1128
1129 Usage:\\
1129 Usage:\\
1130 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1130 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1131
1131
1132 Options:
1132 Options:
1133
1133
1134 -r: use 'raw' input. By default, the 'processed' history is used,
1134 -r: use 'raw' input. By default, the 'processed' history is used,
1135 so that magics are loaded in their transformed version to valid
1135 so that magics are loaded in their transformed version to valid
1136 Python. If this option is given, the raw input as typed at the
1136 Python. If this option is given, the raw input as typed at the
1137 command line is used instead.
1137 command line is used instead.
1138
1138
1139 -q: quiet macro definition. By default, a tag line is printed
1139 -q: quiet macro definition. By default, a tag line is printed
1140 to indicate the macro has been created, and then the contents of
1140 to indicate the macro has been created, and then the contents of
1141 the macro are printed. If this option is given, then no printout
1141 the macro are printed. If this option is given, then no printout
1142 is produced once the macro is created.
1142 is produced once the macro is created.
1143
1143
1144 This will define a global variable called `name` which is a string
1144 This will define a global variable called `name` which is a string
1145 made of joining the slices and lines you specify (n1,n2,... numbers
1145 made of joining the slices and lines you specify (n1,n2,... numbers
1146 above) from your input history into a single string. This variable
1146 above) from your input history into a single string. This variable
1147 acts like an automatic function which re-executes those lines as if
1147 acts like an automatic function which re-executes those lines as if
1148 you had typed them. You just type 'name' at the prompt and the code
1148 you had typed them. You just type 'name' at the prompt and the code
1149 executes.
1149 executes.
1150
1150
1151 The syntax for indicating input ranges is described in %history.
1151 The syntax for indicating input ranges is described in %history.
1152
1152
1153 Note: as a 'hidden' feature, you can also use traditional python slice
1153 Note: as a 'hidden' feature, you can also use traditional python slice
1154 notation, where N:M means numbers N through M-1.
1154 notation, where N:M means numbers N through M-1.
1155
1155
1156 For example, if your history contains (print using %hist -n )::
1156 For example, if your history contains (print using %hist -n )::
1157
1157
1158 44: x=1
1158 44: x=1
1159 45: y=3
1159 45: y=3
1160 46: z=x+y
1160 46: z=x+y
1161 47: print x
1161 47: print x
1162 48: a=5
1162 48: a=5
1163 49: print 'x',x,'y',y
1163 49: print 'x',x,'y',y
1164
1164
1165 you can create a macro with lines 44 through 47 (included) and line 49
1165 you can create a macro with lines 44 through 47 (included) and line 49
1166 called my_macro with::
1166 called my_macro with::
1167
1167
1168 In [55]: %macro my_macro 44-47 49
1168 In [55]: %macro my_macro 44-47 49
1169
1169
1170 Now, typing `my_macro` (without quotes) will re-execute all this code
1170 Now, typing `my_macro` (without quotes) will re-execute all this code
1171 in one pass.
1171 in one pass.
1172
1172
1173 You don't need to give the line-numbers in order, and any given line
1173 You don't need to give the line-numbers in order, and any given line
1174 number can appear multiple times. You can assemble macros with any
1174 number can appear multiple times. You can assemble macros with any
1175 lines from your input history in any order.
1175 lines from your input history in any order.
1176
1176
1177 The macro is a simple object which holds its value in an attribute,
1177 The macro is a simple object which holds its value in an attribute,
1178 but IPython's display system checks for macros and executes them as
1178 but IPython's display system checks for macros and executes them as
1179 code instead of printing them when you type their name.
1179 code instead of printing them when you type their name.
1180
1180
1181 You can view a macro's contents by explicitly printing it with::
1181 You can view a macro's contents by explicitly printing it with::
1182
1182
1183 print macro_name
1183 print macro_name
1184
1184
1185 """
1185 """
1186 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1186 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1187 if not args: # List existing macros
1187 if not args: # List existing macros
1188 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
1188 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
1189 isinstance(v, Macro))
1189 isinstance(v, Macro))
1190 if len(args) == 1:
1190 if len(args) == 1:
1191 raise UsageError(
1191 raise UsageError(
1192 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1192 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1193 name, codefrom = args[0], " ".join(args[1:])
1193 name, codefrom = args[0], " ".join(args[1:])
1194
1194
1195 #print 'rng',ranges # dbg
1195 #print 'rng',ranges # dbg
1196 try:
1196 try:
1197 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1197 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1198 except (ValueError, TypeError) as e:
1198 except (ValueError, TypeError) as e:
1199 print(e.args[0])
1199 print(e.args[0])
1200 return
1200 return
1201 macro = Macro(lines)
1201 macro = Macro(lines)
1202 self.shell.define_macro(name, macro)
1202 self.shell.define_macro(name, macro)
1203 if not ( 'q' in opts) :
1203 if not ( 'q' in opts) :
1204 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1204 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1205 print('=== Macro contents: ===')
1205 print('=== Macro contents: ===')
1206 print(macro, end=' ')
1206 print(macro, end=' ')
1207
1207
1208 @magic_arguments.magic_arguments()
1208 @magic_arguments.magic_arguments()
1209 @magic_arguments.argument('output', type=str, default='', nargs='?',
1209 @magic_arguments.argument('output', type=str, default='', nargs='?',
1210 help="""The name of the variable in which to store output.
1210 help="""The name of the variable in which to store output.
1211 This is a utils.io.CapturedIO object with stdout/err attributes
1211 This is a utils.io.CapturedIO object with stdout/err attributes
1212 for the text of the captured output.
1212 for the text of the captured output.
1213
1213
1214 CapturedOutput also has a show() method for displaying the output,
1214 CapturedOutput also has a show() method for displaying the output,
1215 and __call__ as well, so you can use that to quickly display the
1215 and __call__ as well, so you can use that to quickly display the
1216 output.
1216 output.
1217
1217
1218 If unspecified, captured output is discarded.
1218 If unspecified, captured output is discarded.
1219 """
1219 """
1220 )
1220 )
1221 @magic_arguments.argument('--no-stderr', action="store_true",
1221 @magic_arguments.argument('--no-stderr', action="store_true",
1222 help="""Don't capture stderr."""
1222 help="""Don't capture stderr."""
1223 )
1223 )
1224 @magic_arguments.argument('--no-stdout', action="store_true",
1224 @magic_arguments.argument('--no-stdout', action="store_true",
1225 help="""Don't capture stdout."""
1225 help="""Don't capture stdout."""
1226 )
1226 )
1227 @magic_arguments.argument('--no-display', action="store_true",
1227 @magic_arguments.argument('--no-display', action="store_true",
1228 help="""Don't capture IPython's rich display."""
1228 help="""Don't capture IPython's rich display."""
1229 )
1229 )
1230 @cell_magic
1230 @cell_magic
1231 def capture(self, line, cell):
1231 def capture(self, line, cell):
1232 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1232 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1233 args = magic_arguments.parse_argstring(self.capture, line)
1233 args = magic_arguments.parse_argstring(self.capture, line)
1234 out = not args.no_stdout
1234 out = not args.no_stdout
1235 err = not args.no_stderr
1235 err = not args.no_stderr
1236 disp = not args.no_display
1236 disp = not args.no_display
1237 with capture_output(out, err, disp) as io:
1237 with capture_output(out, err, disp) as io:
1238 self.shell.run_cell(cell)
1238 self.shell.run_cell(cell)
1239 if args.output:
1239 if args.output:
1240 self.shell.user_ns[args.output] = io
1240 self.shell.user_ns[args.output] = io
1241
1241
1242 def parse_breakpoint(text, current_file):
1242 def parse_breakpoint(text, current_file):
1243 '''Returns (file, line) for file:line and (current_file, line) for line'''
1243 '''Returns (file, line) for file:line and (current_file, line) for line'''
1244 colon = text.find(':')
1244 colon = text.find(':')
1245 if colon == -1:
1245 if colon == -1:
1246 return current_file, int(text)
1246 return current_file, int(text)
1247 else:
1247 else:
1248 return text[:colon], int(text[colon+1:])
1248 return text[:colon], int(text[colon+1:])
1249
1249
1250 def _format_time(timespan, precision=3):
1250 def _format_time(timespan, precision=3):
1251 """Formats the timespan in a human readable form"""
1251 """Formats the timespan in a human readable form"""
1252 import math
1252 import math
1253
1253
1254 if timespan >= 60.0:
1254 if timespan >= 60.0:
1255 # we have more than a minute, format that in a human readable form
1255 # we have more than a minute, format that in a human readable form
1256 # Idea from http://snipplr.com/view/5713/
1256 # Idea from http://snipplr.com/view/5713/
1257 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1257 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1258 time = []
1258 time = []
1259 leftover = timespan
1259 leftover = timespan
1260 for suffix, length in parts:
1260 for suffix, length in parts:
1261 value = int(leftover / length)
1261 value = int(leftover / length)
1262 if value > 0:
1262 if value > 0:
1263 leftover = leftover % length
1263 leftover = leftover % length
1264 time.append(u'%s%s' % (str(value), suffix))
1264 time.append(u'%s%s' % (str(value), suffix))
1265 if leftover < 1:
1265 if leftover < 1:
1266 break
1266 break
1267 return " ".join(time)
1267 return " ".join(time)
1268
1268
1269
1269
1270 # Unfortunately the unicode 'micro' symbol can cause problems in
1270 # Unfortunately the unicode 'micro' symbol can cause problems in
1271 # certain terminals.
1271 # certain terminals.
1272 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1272 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1273 # Try to prevent crashes by being more secure than it needs to
1273 # Try to prevent crashes by being more secure than it needs to
1274 # E.g. eclipse is able to print a µ, but has no sys.stdout.encoding set.
1274 # E.g. eclipse is able to print a µ, but has no sys.stdout.encoding set.
1275 units = [u"s", u"ms",u'us',"ns"] # the save value
1275 units = [u"s", u"ms",u'us',"ns"] # the save value
1276 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1276 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1277 try:
1277 try:
1278 u'\xb5'.encode(sys.stdout.encoding)
1278 u'\xb5'.encode(sys.stdout.encoding)
1279 units = [u"s", u"ms",u'\xb5s',"ns"]
1279 units = [u"s", u"ms",u'\xb5s',"ns"]
1280 except:
1280 except:
1281 pass
1281 pass
1282 scaling = [1, 1e3, 1e6, 1e9]
1282 scaling = [1, 1e3, 1e6, 1e9]
1283
1283
1284 if timespan > 0.0:
1284 if timespan > 0.0:
1285 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1285 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1286 else:
1286 else:
1287 order = 3
1287 order = 3
1288 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1288 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,340 +1,340 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Pylab (matplotlib) support utilities.
2 """Pylab (matplotlib) support utilities.
3
3
4 Authors
4 Authors
5 -------
5 -------
6
6
7 * Fernando Perez.
7 * Fernando Perez.
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10 from __future__ import print_function
10 from __future__ import print_function
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2009 The IPython Development Team
13 # Copyright (C) 2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import sys
23 import sys
24 from io import BytesIO
24 from io import BytesIO
25
25
26 from IPython.core.display import _pngxy
26 from IPython.core.display import _pngxy
27 from IPython.utils.decorators import flag_calls
27 from IPython.utils.decorators import flag_calls
28
28
29 # If user specifies a GUI, that dictates the backend, otherwise we read the
29 # If user specifies a GUI, that dictates the backend, otherwise we read the
30 # user's mpl default from the mpl rc structure
30 # user's mpl default from the mpl rc structure
31 backends = {'tk': 'TkAgg',
31 backends = {'tk': 'TkAgg',
32 'gtk': 'GTKAgg',
32 'gtk': 'GTKAgg',
33 'wx': 'WXAgg',
33 'wx': 'WXAgg',
34 'qt': 'Qt4Agg', # qt3 not supported
34 'qt': 'Qt4Agg', # qt3 not supported
35 'qt4': 'Qt4Agg',
35 'qt4': 'Qt4Agg',
36 'osx': 'MacOSX',
36 'osx': 'MacOSX',
37 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'}
37 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'}
38
38
39 # We also need a reverse backends2guis mapping that will properly choose which
39 # We also need a reverse backends2guis mapping that will properly choose which
40 # GUI support to activate based on the desired matplotlib backend. For the
40 # GUI support to activate based on the desired matplotlib backend. For the
41 # most part it's just a reverse of the above dict, but we also need to add a
41 # most part it's just a reverse of the above dict, but we also need to add a
42 # few others that map to the same GUI manually:
42 # few others that map to the same GUI manually:
43 backend2gui = dict(zip(backends.values(), backends.keys()))
43 backend2gui = dict(zip(backends.values(), backends.keys()))
44 # Our tests expect backend2gui to just return 'qt'
44 # Our tests expect backend2gui to just return 'qt'
45 backend2gui['Qt4Agg'] = 'qt'
45 backend2gui['Qt4Agg'] = 'qt'
46 # In the reverse mapping, there are a few extra valid matplotlib backends that
46 # In the reverse mapping, there are a few extra valid matplotlib backends that
47 # map to the same GUI support
47 # map to the same GUI support
48 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
48 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
49 backend2gui['WX'] = 'wx'
49 backend2gui['WX'] = 'wx'
50 backend2gui['CocoaAgg'] = 'osx'
50 backend2gui['CocoaAgg'] = 'osx'
51
51
52 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
53 # Matplotlib utilities
53 # Matplotlib utilities
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55
55
56
56
57 def getfigs(*fig_nums):
57 def getfigs(*fig_nums):
58 """Get a list of matplotlib figures by figure numbers.
58 """Get a list of matplotlib figures by figure numbers.
59
59
60 If no arguments are given, all available figures are returned. If the
60 If no arguments are given, all available figures are returned. If the
61 argument list contains references to invalid figures, a warning is printed
61 argument list contains references to invalid figures, a warning is printed
62 but the function continues pasting further figures.
62 but the function continues pasting further figures.
63
63
64 Parameters
64 Parameters
65 ----------
65 ----------
66 figs : tuple
66 figs : tuple
67 A tuple of ints giving the figure numbers of the figures to return.
67 A tuple of ints giving the figure numbers of the figures to return.
68 """
68 """
69 from matplotlib._pylab_helpers import Gcf
69 from matplotlib._pylab_helpers import Gcf
70 if not fig_nums:
70 if not fig_nums:
71 fig_managers = Gcf.get_all_fig_managers()
71 fig_managers = Gcf.get_all_fig_managers()
72 return [fm.canvas.figure for fm in fig_managers]
72 return [fm.canvas.figure for fm in fig_managers]
73 else:
73 else:
74 figs = []
74 figs = []
75 for num in fig_nums:
75 for num in fig_nums:
76 f = Gcf.figs.get(num)
76 f = Gcf.figs.get(num)
77 if f is None:
77 if f is None:
78 print(('Warning: figure %s not available.' % num))
78 print(('Warning: figure %s not available.' % num))
79 else:
79 else:
80 figs.append(f.canvas.figure)
80 figs.append(f.canvas.figure)
81 return figs
81 return figs
82
82
83
83
84 def figsize(sizex, sizey):
84 def figsize(sizex, sizey):
85 """Set the default figure size to be [sizex, sizey].
85 """Set the default figure size to be [sizex, sizey].
86
86
87 This is just an easy to remember, convenience wrapper that sets::
87 This is just an easy to remember, convenience wrapper that sets::
88
88
89 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
89 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
90 """
90 """
91 import matplotlib
91 import matplotlib
92 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
92 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
93
93
94
94
95 def print_figure(fig, fmt='png'):
95 def print_figure(fig, fmt='png'):
96 """Convert a figure to svg or png for inline display."""
96 """Convert a figure to svg or png for inline display."""
97 from matplotlib import rcParams
97 from matplotlib import rcParams
98 # When there's an empty figure, we shouldn't return anything, otherwise we
98 # When there's an empty figure, we shouldn't return anything, otherwise we
99 # get big blank areas in the qt console.
99 # get big blank areas in the qt console.
100 if not fig.axes and not fig.lines:
100 if not fig.axes and not fig.lines:
101 return
101 return
102
102
103 fc = fig.get_facecolor()
103 fc = fig.get_facecolor()
104 ec = fig.get_edgecolor()
104 ec = fig.get_edgecolor()
105 bytes_io = BytesIO()
105 bytes_io = BytesIO()
106 dpi = rcParams['savefig.dpi']
106 dpi = rcParams['savefig.dpi']
107 if fmt == 'retina':
107 if fmt == 'retina':
108 dpi = dpi * 2
108 dpi = dpi * 2
109 fmt = 'png'
109 fmt = 'png'
110 fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight',
110 fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight',
111 facecolor=fc, edgecolor=ec, dpi=dpi)
111 facecolor=fc, edgecolor=ec, dpi=dpi)
112 data = bytes_io.getvalue()
112 data = bytes_io.getvalue()
113 return data
113 return data
114
114
115 def retina_figure(fig):
115 def retina_figure(fig):
116 """format a figure as a pixel-doubled (retina) PNG"""
116 """format a figure as a pixel-doubled (retina) PNG"""
117 pngdata = print_figure(fig, fmt='retina')
117 pngdata = print_figure(fig, fmt='retina')
118 w, h = _pngxy(pngdata)
118 w, h = _pngxy(pngdata)
119 metadata = dict(width=w//2, height=h//2)
119 metadata = dict(width=w//2, height=h//2)
120 return pngdata, metadata
120 return pngdata, metadata
121
121
122 # We need a little factory function here to create the closure where
122 # We need a little factory function here to create the closure where
123 # safe_execfile can live.
123 # safe_execfile can live.
124 def mpl_runner(safe_execfile):
124 def mpl_runner(safe_execfile):
125 """Factory to return a matplotlib-enabled runner for %run.
125 """Factory to return a matplotlib-enabled runner for %run.
126
126
127 Parameters
127 Parameters
128 ----------
128 ----------
129 safe_execfile : function
129 safe_execfile : function
130 This must be a function with the same interface as the
130 This must be a function with the same interface as the
131 :meth:`safe_execfile` method of IPython.
131 :meth:`safe_execfile` method of IPython.
132
132
133 Returns
133 Returns
134 -------
134 -------
135 A function suitable for use as the ``runner`` argument of the %run magic
135 A function suitable for use as the ``runner`` argument of the %run magic
136 function.
136 function.
137 """
137 """
138
138
139 def mpl_execfile(fname,*where,**kw):
139 def mpl_execfile(fname,*where,**kw):
140 """matplotlib-aware wrapper around safe_execfile.
140 """matplotlib-aware wrapper around safe_execfile.
141
141
142 Its interface is identical to that of the :func:`execfile` builtin.
142 Its interface is identical to that of the :func:`execfile` builtin.
143
143
144 This is ultimately a call to execfile(), but wrapped in safeties to
144 This is ultimately a call to execfile(), but wrapped in safeties to
145 properly handle interactive rendering."""
145 properly handle interactive rendering."""
146
146
147 import matplotlib
147 import matplotlib
148 import matplotlib.pylab as pylab
148 import matplotlib.pylab as pylab
149
149
150 #print '*** Matplotlib runner ***' # dbg
150 #print '*** Matplotlib runner ***' # dbg
151 # turn off rendering until end of script
151 # turn off rendering until end of script
152 is_interactive = matplotlib.rcParams['interactive']
152 is_interactive = matplotlib.rcParams['interactive']
153 matplotlib.interactive(False)
153 matplotlib.interactive(False)
154 safe_execfile(fname,*where,**kw)
154 safe_execfile(fname,*where,**kw)
155 matplotlib.interactive(is_interactive)
155 matplotlib.interactive(is_interactive)
156 # make rendering call now, if the user tried to do it
156 # make rendering call now, if the user tried to do it
157 if pylab.draw_if_interactive.called:
157 if pylab.draw_if_interactive.called:
158 pylab.draw()
158 pylab.draw()
159 pylab.draw_if_interactive.called = False
159 pylab.draw_if_interactive.called = False
160
160
161 return mpl_execfile
161 return mpl_execfile
162
162
163
163
164 def select_figure_format(shell, fmt):
164 def select_figure_format(shell, fmt):
165 """Select figure format for inline backend, can be 'png', 'retina', or 'svg'.
165 """Select figure format for inline backend, can be 'png', 'retina', or 'svg'.
166
166
167 Using this method ensures only one figure format is active at a time.
167 Using this method ensures only one figure format is active at a time.
168 """
168 """
169 from matplotlib.figure import Figure
169 from matplotlib.figure import Figure
170 from IPython.kernel.zmq.pylab import backend_inline
170 from IPython.kernel.zmq.pylab import backend_inline
171
171
172 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
172 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
173 png_formatter = shell.display_formatter.formatters['image/png']
173 png_formatter = shell.display_formatter.formatters['image/png']
174
174
175 if fmt == 'png':
175 if fmt == 'png':
176 svg_formatter.type_printers.pop(Figure, None)
176 svg_formatter.type_printers.pop(Figure, None)
177 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
177 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
178 elif fmt in ('png2x', 'retina'):
178 elif fmt in ('png2x', 'retina'):
179 svg_formatter.type_printers.pop(Figure, None)
179 svg_formatter.type_printers.pop(Figure, None)
180 png_formatter.for_type(Figure, retina_figure)
180 png_formatter.for_type(Figure, retina_figure)
181 elif fmt == 'svg':
181 elif fmt == 'svg':
182 png_formatter.type_printers.pop(Figure, None)
182 png_formatter.type_printers.pop(Figure, None)
183 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
183 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
184 else:
184 else:
185 raise ValueError("supported formats are: 'png', 'retina', 'svg', not %r" % fmt)
185 raise ValueError("supported formats are: 'png', 'retina', 'svg', not %r" % fmt)
186
186
187 # set the format to be used in the backend()
187 # set the format to be used in the backend()
188 backend_inline._figure_format = fmt
188 backend_inline._figure_format = fmt
189
189
190 #-----------------------------------------------------------------------------
190 #-----------------------------------------------------------------------------
191 # Code for initializing matplotlib and importing pylab
191 # Code for initializing matplotlib and importing pylab
192 #-----------------------------------------------------------------------------
192 #-----------------------------------------------------------------------------
193
193
194
194
195 def find_gui_and_backend(gui=None, gui_select=None):
195 def find_gui_and_backend(gui=None, gui_select=None):
196 """Given a gui string return the gui and mpl backend.
196 """Given a gui string return the gui and mpl backend.
197
197
198 Parameters
198 Parameters
199 ----------
199 ----------
200 gui : str
200 gui : str
201 Can be one of ('tk','gtk','wx','qt','qt4','inline').
201 Can be one of ('tk','gtk','wx','qt','qt4','inline').
202 gui_select : str
202 gui_select : str
203 Can be one of ('tk','gtk','wx','qt','qt4','inline').
203 Can be one of ('tk','gtk','wx','qt','qt4','inline').
204 This is any gui already selected by the shell.
204 This is any gui already selected by the shell.
205
205
206 Returns
206 Returns
207 -------
207 -------
208 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
208 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
209 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline').
209 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline').
210 """
210 """
211
211
212 import matplotlib
212 import matplotlib
213
213
214 if gui and gui != 'auto':
214 if gui and gui != 'auto':
215 # select backend based on requested gui
215 # select backend based on requested gui
216 backend = backends[gui]
216 backend = backends[gui]
217 else:
217 else:
218 # We need to read the backend from the original data structure, *not*
218 # We need to read the backend from the original data structure, *not*
219 # from mpl.rcParams, since a prior invocation of %matplotlib may have
219 # from mpl.rcParams, since a prior invocation of %matplotlib may have
220 # overwritten that.
220 # overwritten that.
221 # WARNING: this assumes matplotlib 1.1 or newer!!
221 # WARNING: this assumes matplotlib 1.1 or newer!!
222 backend = matplotlib.rcParamsOrig['backend']
222 backend = matplotlib.rcParamsOrig['backend']
223 # In this case, we need to find what the appropriate gui selection call
223 # In this case, we need to find what the appropriate gui selection call
224 # should be for IPython, so we can activate inputhook accordingly
224 # should be for IPython, so we can activate inputhook accordingly
225 gui = backend2gui.get(backend, None)
225 gui = backend2gui.get(backend, None)
226
226
227 # If we have already had a gui active, we need it and inline are the
227 # If we have already had a gui active, we need it and inline are the
228 # ones allowed.
228 # ones allowed.
229 if gui_select and gui != gui_select:
229 if gui_select and gui != gui_select:
230 gui = gui_select
230 gui = gui_select
231 backend = backends[gui]
231 backend = backends[gui]
232
232
233 return gui, backend
233 return gui, backend
234
234
235
235
236 def activate_matplotlib(backend):
236 def activate_matplotlib(backend):
237 """Activate the given backend and set interactive to True."""
237 """Activate the given backend and set interactive to True."""
238
238
239 import matplotlib
239 import matplotlib
240 matplotlib.interactive(True)
240 matplotlib.interactive(True)
241
241
242 # Matplotlib had a bug where even switch_backend could not force
242 # Matplotlib had a bug where even switch_backend could not force
243 # the rcParam to update. This needs to be set *before* the module
243 # the rcParam to update. This needs to be set *before* the module
244 # magic of switch_backend().
244 # magic of switch_backend().
245 matplotlib.rcParams['backend'] = backend
245 matplotlib.rcParams['backend'] = backend
246
246
247 import matplotlib.pyplot
247 import matplotlib.pyplot
248 matplotlib.pyplot.switch_backend(backend)
248 matplotlib.pyplot.switch_backend(backend)
249
249
250 # This must be imported last in the matplotlib series, after
250 # This must be imported last in the matplotlib series, after
251 # backend/interactivity choices have been made
251 # backend/interactivity choices have been made
252 import matplotlib.pylab as pylab
252 import matplotlib.pylab as pylab
253
253
254 pylab.show._needmain = False
254 pylab.show._needmain = False
255 # We need to detect at runtime whether show() is called by the user.
255 # We need to detect at runtime whether show() is called by the user.
256 # For this, we wrap it into a decorator which adds a 'called' flag.
256 # For this, we wrap it into a decorator which adds a 'called' flag.
257 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
257 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
258
258
259
259
260 def import_pylab(user_ns, import_all=True):
260 def import_pylab(user_ns, import_all=True):
261 """Populate the namespace with pylab-related values.
261 """Populate the namespace with pylab-related values.
262
262
263 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
263 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
264
264
265 Also imports a few names from IPython (figsize, display, getfigs)
265 Also imports a few names from IPython (figsize, display, getfigs)
266
266
267 """
267 """
268
268
269 # Import numpy as np/pyplot as plt are conventions we're trying to
269 # Import numpy as np/pyplot as plt are conventions we're trying to
270 # somewhat standardize on. Making them available to users by default
270 # somewhat standardize on. Making them available to users by default
271 # will greatly help this.
271 # will greatly help this.
272 s = ("import numpy\n"
272 s = ("import numpy\n"
273 "import matplotlib\n"
273 "import matplotlib\n"
274 "from matplotlib import pylab, mlab, pyplot\n"
274 "from matplotlib import pylab, mlab, pyplot\n"
275 "np = numpy\n"
275 "np = numpy\n"
276 "plt = pyplot\n"
276 "plt = pyplot\n"
277 )
277 )
278 exec s in user_ns
278 exec(s, user_ns)
279
279
280 if import_all:
280 if import_all:
281 s = ("from matplotlib.pylab import *\n"
281 s = ("from matplotlib.pylab import *\n"
282 "from numpy import *\n")
282 "from numpy import *\n")
283 exec s in user_ns
283 exec(s, user_ns)
284
284
285 # IPython symbols to add
285 # IPython symbols to add
286 user_ns['figsize'] = figsize
286 user_ns['figsize'] = figsize
287 from IPython.core.display import display
287 from IPython.core.display import display
288 # Add display and getfigs to the user's namespace
288 # Add display and getfigs to the user's namespace
289 user_ns['display'] = display
289 user_ns['display'] = display
290 user_ns['getfigs'] = getfigs
290 user_ns['getfigs'] = getfigs
291
291
292
292
293 def configure_inline_support(shell, backend):
293 def configure_inline_support(shell, backend):
294 """Configure an IPython shell object for matplotlib use.
294 """Configure an IPython shell object for matplotlib use.
295
295
296 Parameters
296 Parameters
297 ----------
297 ----------
298 shell : InteractiveShell instance
298 shell : InteractiveShell instance
299
299
300 backend : matplotlib backend
300 backend : matplotlib backend
301 """
301 """
302 # If using our svg payload backend, register the post-execution
302 # If using our svg payload backend, register the post-execution
303 # function that will pick up the results for display. This can only be
303 # function that will pick up the results for display. This can only be
304 # done with access to the real shell object.
304 # done with access to the real shell object.
305
305
306 # Note: if we can't load the inline backend, then there's no point
306 # Note: if we can't load the inline backend, then there's no point
307 # continuing (such as in terminal-only shells in environments without
307 # continuing (such as in terminal-only shells in environments without
308 # zeromq available).
308 # zeromq available).
309 try:
309 try:
310 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
310 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
311 except ImportError:
311 except ImportError:
312 return
312 return
313 from matplotlib import pyplot
313 from matplotlib import pyplot
314
314
315 cfg = InlineBackend.instance(parent=shell)
315 cfg = InlineBackend.instance(parent=shell)
316 cfg.shell = shell
316 cfg.shell = shell
317 if cfg not in shell.configurables:
317 if cfg not in shell.configurables:
318 shell.configurables.append(cfg)
318 shell.configurables.append(cfg)
319
319
320 if backend == backends['inline']:
320 if backend == backends['inline']:
321 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
321 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
322 shell.register_post_execute(flush_figures)
322 shell.register_post_execute(flush_figures)
323
323
324 # Save rcParams that will be overwrittern
324 # Save rcParams that will be overwrittern
325 shell._saved_rcParams = dict()
325 shell._saved_rcParams = dict()
326 for k in cfg.rc:
326 for k in cfg.rc:
327 shell._saved_rcParams[k] = pyplot.rcParams[k]
327 shell._saved_rcParams[k] = pyplot.rcParams[k]
328 # load inline_rc
328 # load inline_rc
329 pyplot.rcParams.update(cfg.rc)
329 pyplot.rcParams.update(cfg.rc)
330 else:
330 else:
331 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
331 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
332 if flush_figures in shell._post_execute:
332 if flush_figures in shell._post_execute:
333 shell._post_execute.pop(flush_figures)
333 shell._post_execute.pop(flush_figures)
334 if hasattr(shell, '_saved_rcParams'):
334 if hasattr(shell, '_saved_rcParams'):
335 pyplot.rcParams.update(shell._saved_rcParams)
335 pyplot.rcParams.update(shell._saved_rcParams)
336 del shell._saved_rcParams
336 del shell._saved_rcParams
337
337
338 # Setup the default figure format
338 # Setup the default figure format
339 select_figure_format(shell, cfg.figure_format)
339 select_figure_format(shell, cfg.figure_format)
340
340
@@ -1,583 +1,583 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the inputsplitter module.
2 """Tests for the inputsplitter module.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 * Fernando Perez
6 * Fernando Perez
7 * Robert Kern
7 * Robert Kern
8 """
8 """
9 from __future__ import print_function
9 from __future__ import print_function
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2010-2011 The IPython Development Team
11 # Copyright (C) 2010-2011 The IPython Development Team
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # stdlib
20 # stdlib
21 import unittest
21 import unittest
22 import sys
22 import sys
23
23
24 # Third party
24 # Third party
25 import nose.tools as nt
25 import nose.tools as nt
26
26
27 # Our own
27 # Our own
28 from IPython.core import inputsplitter as isp
28 from IPython.core import inputsplitter as isp
29 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
29 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
30 from IPython.testing import tools as tt
30 from IPython.testing import tools as tt
31 from IPython.utils import py3compat
31 from IPython.utils import py3compat
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Semi-complete examples (also used as tests)
34 # Semi-complete examples (also used as tests)
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 # Note: at the bottom, there's a slightly more complete version of this that
37 # Note: at the bottom, there's a slightly more complete version of this that
38 # can be useful during development of code here.
38 # can be useful during development of code here.
39
39
40 def mini_interactive_loop(input_func):
40 def mini_interactive_loop(input_func):
41 """Minimal example of the logic of an interactive interpreter loop.
41 """Minimal example of the logic of an interactive interpreter loop.
42
42
43 This serves as an example, and it is used by the test system with a fake
43 This serves as an example, and it is used by the test system with a fake
44 raw_input that simulates interactive input."""
44 raw_input that simulates interactive input."""
45
45
46 from IPython.core.inputsplitter import InputSplitter
46 from IPython.core.inputsplitter import InputSplitter
47
47
48 isp = InputSplitter()
48 isp = InputSplitter()
49 # In practice, this input loop would be wrapped in an outside loop to read
49 # In practice, this input loop would be wrapped in an outside loop to read
50 # input indefinitely, until some exit/quit command was issued. Here we
50 # input indefinitely, until some exit/quit command was issued. Here we
51 # only illustrate the basic inner loop.
51 # only illustrate the basic inner loop.
52 while isp.push_accepts_more():
52 while isp.push_accepts_more():
53 indent = ' '*isp.indent_spaces
53 indent = ' '*isp.indent_spaces
54 prompt = '>>> ' + indent
54 prompt = '>>> ' + indent
55 line = indent + input_func(prompt)
55 line = indent + input_func(prompt)
56 isp.push(line)
56 isp.push(line)
57
57
58 # Here we just return input so we can use it in a test suite, but a real
58 # Here we just return input so we can use it in a test suite, but a real
59 # interpreter would instead send it for execution somewhere.
59 # interpreter would instead send it for execution somewhere.
60 src = isp.source_reset()
60 src = isp.source_reset()
61 #print 'Input source was:\n', src # dbg
61 #print 'Input source was:\n', src # dbg
62 return src
62 return src
63
63
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65 # Test utilities, just for local use
65 # Test utilities, just for local use
66 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
67
67
68 def assemble(block):
68 def assemble(block):
69 """Assemble a block into multi-line sub-blocks."""
69 """Assemble a block into multi-line sub-blocks."""
70 return ['\n'.join(sub_block)+'\n' for sub_block in block]
70 return ['\n'.join(sub_block)+'\n' for sub_block in block]
71
71
72
72
73 def pseudo_input(lines):
73 def pseudo_input(lines):
74 """Return a function that acts like raw_input but feeds the input list."""
74 """Return a function that acts like raw_input but feeds the input list."""
75 ilines = iter(lines)
75 ilines = iter(lines)
76 def raw_in(prompt):
76 def raw_in(prompt):
77 try:
77 try:
78 return next(ilines)
78 return next(ilines)
79 except StopIteration:
79 except StopIteration:
80 return ''
80 return ''
81 return raw_in
81 return raw_in
82
82
83 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
84 # Tests
84 # Tests
85 #-----------------------------------------------------------------------------
85 #-----------------------------------------------------------------------------
86 def test_spaces():
86 def test_spaces():
87 tests = [('', 0),
87 tests = [('', 0),
88 (' ', 1),
88 (' ', 1),
89 ('\n', 0),
89 ('\n', 0),
90 (' \n', 1),
90 (' \n', 1),
91 ('x', 0),
91 ('x', 0),
92 (' x', 1),
92 (' x', 1),
93 (' x',2),
93 (' x',2),
94 (' x',4),
94 (' x',4),
95 # Note: tabs are counted as a single whitespace!
95 # Note: tabs are counted as a single whitespace!
96 ('\tx', 1),
96 ('\tx', 1),
97 ('\t x', 2),
97 ('\t x', 2),
98 ]
98 ]
99 tt.check_pairs(isp.num_ini_spaces, tests)
99 tt.check_pairs(isp.num_ini_spaces, tests)
100
100
101
101
102 def test_remove_comments():
102 def test_remove_comments():
103 tests = [('text', 'text'),
103 tests = [('text', 'text'),
104 ('text # comment', 'text '),
104 ('text # comment', 'text '),
105 ('text # comment\n', 'text \n'),
105 ('text # comment\n', 'text \n'),
106 ('text # comment \n', 'text \n'),
106 ('text # comment \n', 'text \n'),
107 ('line # c \nline\n','line \nline\n'),
107 ('line # c \nline\n','line \nline\n'),
108 ('line # c \nline#c2 \nline\nline #c\n\n',
108 ('line # c \nline#c2 \nline\nline #c\n\n',
109 'line \nline\nline\nline \n\n'),
109 'line \nline\nline\nline \n\n'),
110 ]
110 ]
111 tt.check_pairs(isp.remove_comments, tests)
111 tt.check_pairs(isp.remove_comments, tests)
112
112
113
113
114 def test_get_input_encoding():
114 def test_get_input_encoding():
115 encoding = isp.get_input_encoding()
115 encoding = isp.get_input_encoding()
116 nt.assert_true(isinstance(encoding, basestring))
116 nt.assert_true(isinstance(encoding, basestring))
117 # simple-minded check that at least encoding a simple string works with the
117 # simple-minded check that at least encoding a simple string works with the
118 # encoding we got.
118 # encoding we got.
119 nt.assert_equal(u'test'.encode(encoding), b'test')
119 nt.assert_equal(u'test'.encode(encoding), b'test')
120
120
121
121
122 class NoInputEncodingTestCase(unittest.TestCase):
122 class NoInputEncodingTestCase(unittest.TestCase):
123 def setUp(self):
123 def setUp(self):
124 self.old_stdin = sys.stdin
124 self.old_stdin = sys.stdin
125 class X: pass
125 class X: pass
126 fake_stdin = X()
126 fake_stdin = X()
127 sys.stdin = fake_stdin
127 sys.stdin = fake_stdin
128
128
129 def test(self):
129 def test(self):
130 # Verify that if sys.stdin has no 'encoding' attribute we do the right
130 # Verify that if sys.stdin has no 'encoding' attribute we do the right
131 # thing
131 # thing
132 enc = isp.get_input_encoding()
132 enc = isp.get_input_encoding()
133 self.assertEqual(enc, 'ascii')
133 self.assertEqual(enc, 'ascii')
134
134
135 def tearDown(self):
135 def tearDown(self):
136 sys.stdin = self.old_stdin
136 sys.stdin = self.old_stdin
137
137
138
138
139 class InputSplitterTestCase(unittest.TestCase):
139 class InputSplitterTestCase(unittest.TestCase):
140 def setUp(self):
140 def setUp(self):
141 self.isp = isp.InputSplitter()
141 self.isp = isp.InputSplitter()
142
142
143 def test_reset(self):
143 def test_reset(self):
144 isp = self.isp
144 isp = self.isp
145 isp.push('x=1')
145 isp.push('x=1')
146 isp.reset()
146 isp.reset()
147 self.assertEqual(isp._buffer, [])
147 self.assertEqual(isp._buffer, [])
148 self.assertEqual(isp.indent_spaces, 0)
148 self.assertEqual(isp.indent_spaces, 0)
149 self.assertEqual(isp.source, '')
149 self.assertEqual(isp.source, '')
150 self.assertEqual(isp.code, None)
150 self.assertEqual(isp.code, None)
151 self.assertEqual(isp._is_complete, False)
151 self.assertEqual(isp._is_complete, False)
152
152
153 def test_source(self):
153 def test_source(self):
154 self.isp._store('1')
154 self.isp._store('1')
155 self.isp._store('2')
155 self.isp._store('2')
156 self.assertEqual(self.isp.source, '1\n2\n')
156 self.assertEqual(self.isp.source, '1\n2\n')
157 self.assertTrue(len(self.isp._buffer)>0)
157 self.assertTrue(len(self.isp._buffer)>0)
158 self.assertEqual(self.isp.source_reset(), '1\n2\n')
158 self.assertEqual(self.isp.source_reset(), '1\n2\n')
159 self.assertEqual(self.isp._buffer, [])
159 self.assertEqual(self.isp._buffer, [])
160 self.assertEqual(self.isp.source, '')
160 self.assertEqual(self.isp.source, '')
161
161
162 def test_indent(self):
162 def test_indent(self):
163 isp = self.isp # shorthand
163 isp = self.isp # shorthand
164 isp.push('x=1')
164 isp.push('x=1')
165 self.assertEqual(isp.indent_spaces, 0)
165 self.assertEqual(isp.indent_spaces, 0)
166 isp.push('if 1:\n x=1')
166 isp.push('if 1:\n x=1')
167 self.assertEqual(isp.indent_spaces, 4)
167 self.assertEqual(isp.indent_spaces, 4)
168 isp.push('y=2\n')
168 isp.push('y=2\n')
169 self.assertEqual(isp.indent_spaces, 0)
169 self.assertEqual(isp.indent_spaces, 0)
170
170
171 def test_indent2(self):
171 def test_indent2(self):
172 isp = self.isp
172 isp = self.isp
173 isp.push('if 1:')
173 isp.push('if 1:')
174 self.assertEqual(isp.indent_spaces, 4)
174 self.assertEqual(isp.indent_spaces, 4)
175 isp.push(' x=1')
175 isp.push(' x=1')
176 self.assertEqual(isp.indent_spaces, 4)
176 self.assertEqual(isp.indent_spaces, 4)
177 # Blank lines shouldn't change the indent level
177 # Blank lines shouldn't change the indent level
178 isp.push(' '*2)
178 isp.push(' '*2)
179 self.assertEqual(isp.indent_spaces, 4)
179 self.assertEqual(isp.indent_spaces, 4)
180
180
181 def test_indent3(self):
181 def test_indent3(self):
182 isp = self.isp
182 isp = self.isp
183 # When a multiline statement contains parens or multiline strings, we
183 # When a multiline statement contains parens or multiline strings, we
184 # shouldn't get confused.
184 # shouldn't get confused.
185 isp.push("if 1:")
185 isp.push("if 1:")
186 isp.push(" x = (1+\n 2)")
186 isp.push(" x = (1+\n 2)")
187 self.assertEqual(isp.indent_spaces, 4)
187 self.assertEqual(isp.indent_spaces, 4)
188
188
189 def test_indent4(self):
189 def test_indent4(self):
190 isp = self.isp
190 isp = self.isp
191 # whitespace after ':' should not screw up indent level
191 # whitespace after ':' should not screw up indent level
192 isp.push('if 1: \n x=1')
192 isp.push('if 1: \n x=1')
193 self.assertEqual(isp.indent_spaces, 4)
193 self.assertEqual(isp.indent_spaces, 4)
194 isp.push('y=2\n')
194 isp.push('y=2\n')
195 self.assertEqual(isp.indent_spaces, 0)
195 self.assertEqual(isp.indent_spaces, 0)
196 isp.push('if 1:\t\n x=1')
196 isp.push('if 1:\t\n x=1')
197 self.assertEqual(isp.indent_spaces, 4)
197 self.assertEqual(isp.indent_spaces, 4)
198 isp.push('y=2\n')
198 isp.push('y=2\n')
199 self.assertEqual(isp.indent_spaces, 0)
199 self.assertEqual(isp.indent_spaces, 0)
200
200
201 def test_dedent_pass(self):
201 def test_dedent_pass(self):
202 isp = self.isp # shorthand
202 isp = self.isp # shorthand
203 # should NOT cause dedent
203 # should NOT cause dedent
204 isp.push('if 1:\n passes = 5')
204 isp.push('if 1:\n passes = 5')
205 self.assertEqual(isp.indent_spaces, 4)
205 self.assertEqual(isp.indent_spaces, 4)
206 isp.push('if 1:\n pass')
206 isp.push('if 1:\n pass')
207 self.assertEqual(isp.indent_spaces, 0)
207 self.assertEqual(isp.indent_spaces, 0)
208 isp.push('if 1:\n pass ')
208 isp.push('if 1:\n pass ')
209 self.assertEqual(isp.indent_spaces, 0)
209 self.assertEqual(isp.indent_spaces, 0)
210
210
211 def test_dedent_break(self):
211 def test_dedent_break(self):
212 isp = self.isp # shorthand
212 isp = self.isp # shorthand
213 # should NOT cause dedent
213 # should NOT cause dedent
214 isp.push('while 1:\n breaks = 5')
214 isp.push('while 1:\n breaks = 5')
215 self.assertEqual(isp.indent_spaces, 4)
215 self.assertEqual(isp.indent_spaces, 4)
216 isp.push('while 1:\n break')
216 isp.push('while 1:\n break')
217 self.assertEqual(isp.indent_spaces, 0)
217 self.assertEqual(isp.indent_spaces, 0)
218 isp.push('while 1:\n break ')
218 isp.push('while 1:\n break ')
219 self.assertEqual(isp.indent_spaces, 0)
219 self.assertEqual(isp.indent_spaces, 0)
220
220
221 def test_dedent_continue(self):
221 def test_dedent_continue(self):
222 isp = self.isp # shorthand
222 isp = self.isp # shorthand
223 # should NOT cause dedent
223 # should NOT cause dedent
224 isp.push('while 1:\n continues = 5')
224 isp.push('while 1:\n continues = 5')
225 self.assertEqual(isp.indent_spaces, 4)
225 self.assertEqual(isp.indent_spaces, 4)
226 isp.push('while 1:\n continue')
226 isp.push('while 1:\n continue')
227 self.assertEqual(isp.indent_spaces, 0)
227 self.assertEqual(isp.indent_spaces, 0)
228 isp.push('while 1:\n continue ')
228 isp.push('while 1:\n continue ')
229 self.assertEqual(isp.indent_spaces, 0)
229 self.assertEqual(isp.indent_spaces, 0)
230
230
231 def test_dedent_raise(self):
231 def test_dedent_raise(self):
232 isp = self.isp # shorthand
232 isp = self.isp # shorthand
233 # should NOT cause dedent
233 # should NOT cause dedent
234 isp.push('if 1:\n raised = 4')
234 isp.push('if 1:\n raised = 4')
235 self.assertEqual(isp.indent_spaces, 4)
235 self.assertEqual(isp.indent_spaces, 4)
236 isp.push('if 1:\n raise TypeError()')
236 isp.push('if 1:\n raise TypeError()')
237 self.assertEqual(isp.indent_spaces, 0)
237 self.assertEqual(isp.indent_spaces, 0)
238 isp.push('if 1:\n raise')
238 isp.push('if 1:\n raise')
239 self.assertEqual(isp.indent_spaces, 0)
239 self.assertEqual(isp.indent_spaces, 0)
240 isp.push('if 1:\n raise ')
240 isp.push('if 1:\n raise ')
241 self.assertEqual(isp.indent_spaces, 0)
241 self.assertEqual(isp.indent_spaces, 0)
242
242
243 def test_dedent_return(self):
243 def test_dedent_return(self):
244 isp = self.isp # shorthand
244 isp = self.isp # shorthand
245 # should NOT cause dedent
245 # should NOT cause dedent
246 isp.push('if 1:\n returning = 4')
246 isp.push('if 1:\n returning = 4')
247 self.assertEqual(isp.indent_spaces, 4)
247 self.assertEqual(isp.indent_spaces, 4)
248 isp.push('if 1:\n return 5 + 493')
248 isp.push('if 1:\n return 5 + 493')
249 self.assertEqual(isp.indent_spaces, 0)
249 self.assertEqual(isp.indent_spaces, 0)
250 isp.push('if 1:\n return')
250 isp.push('if 1:\n return')
251 self.assertEqual(isp.indent_spaces, 0)
251 self.assertEqual(isp.indent_spaces, 0)
252 isp.push('if 1:\n return ')
252 isp.push('if 1:\n return ')
253 self.assertEqual(isp.indent_spaces, 0)
253 self.assertEqual(isp.indent_spaces, 0)
254 isp.push('if 1:\n return(0)')
254 isp.push('if 1:\n return(0)')
255 self.assertEqual(isp.indent_spaces, 0)
255 self.assertEqual(isp.indent_spaces, 0)
256
256
257 def test_push(self):
257 def test_push(self):
258 isp = self.isp
258 isp = self.isp
259 self.assertTrue(isp.push('x=1'))
259 self.assertTrue(isp.push('x=1'))
260
260
261 def test_push2(self):
261 def test_push2(self):
262 isp = self.isp
262 isp = self.isp
263 self.assertFalse(isp.push('if 1:'))
263 self.assertFalse(isp.push('if 1:'))
264 for line in [' x=1', '# a comment', ' y=2']:
264 for line in [' x=1', '# a comment', ' y=2']:
265 print(line)
265 print(line)
266 self.assertTrue(isp.push(line))
266 self.assertTrue(isp.push(line))
267
267
268 def test_push3(self):
268 def test_push3(self):
269 isp = self.isp
269 isp = self.isp
270 isp.push('if True:')
270 isp.push('if True:')
271 isp.push(' a = 1')
271 isp.push(' a = 1')
272 self.assertFalse(isp.push('b = [1,'))
272 self.assertFalse(isp.push('b = [1,'))
273
273
274 def test_push_accepts_more(self):
274 def test_push_accepts_more(self):
275 isp = self.isp
275 isp = self.isp
276 isp.push('x=1')
276 isp.push('x=1')
277 self.assertFalse(isp.push_accepts_more())
277 self.assertFalse(isp.push_accepts_more())
278
278
279 def test_push_accepts_more2(self):
279 def test_push_accepts_more2(self):
280 isp = self.isp
280 isp = self.isp
281 isp.push('if 1:')
281 isp.push('if 1:')
282 self.assertTrue(isp.push_accepts_more())
282 self.assertTrue(isp.push_accepts_more())
283 isp.push(' x=1')
283 isp.push(' x=1')
284 self.assertTrue(isp.push_accepts_more())
284 self.assertTrue(isp.push_accepts_more())
285 isp.push('')
285 isp.push('')
286 self.assertFalse(isp.push_accepts_more())
286 self.assertFalse(isp.push_accepts_more())
287
287
288 def test_push_accepts_more3(self):
288 def test_push_accepts_more3(self):
289 isp = self.isp
289 isp = self.isp
290 isp.push("x = (2+\n3)")
290 isp.push("x = (2+\n3)")
291 self.assertFalse(isp.push_accepts_more())
291 self.assertFalse(isp.push_accepts_more())
292
292
293 def test_push_accepts_more4(self):
293 def test_push_accepts_more4(self):
294 isp = self.isp
294 isp = self.isp
295 # When a multiline statement contains parens or multiline strings, we
295 # When a multiline statement contains parens or multiline strings, we
296 # shouldn't get confused.
296 # shouldn't get confused.
297 # FIXME: we should be able to better handle de-dents in statements like
297 # FIXME: we should be able to better handle de-dents in statements like
298 # multiline strings and multiline expressions (continued with \ or
298 # multiline strings and multiline expressions (continued with \ or
299 # parens). Right now we aren't handling the indentation tracking quite
299 # parens). Right now we aren't handling the indentation tracking quite
300 # correctly with this, though in practice it may not be too much of a
300 # correctly with this, though in practice it may not be too much of a
301 # problem. We'll need to see.
301 # problem. We'll need to see.
302 isp.push("if 1:")
302 isp.push("if 1:")
303 isp.push(" x = (2+")
303 isp.push(" x = (2+")
304 isp.push(" 3)")
304 isp.push(" 3)")
305 self.assertTrue(isp.push_accepts_more())
305 self.assertTrue(isp.push_accepts_more())
306 isp.push(" y = 3")
306 isp.push(" y = 3")
307 self.assertTrue(isp.push_accepts_more())
307 self.assertTrue(isp.push_accepts_more())
308 isp.push('')
308 isp.push('')
309 self.assertFalse(isp.push_accepts_more())
309 self.assertFalse(isp.push_accepts_more())
310
310
311 def test_push_accepts_more5(self):
311 def test_push_accepts_more5(self):
312 isp = self.isp
312 isp = self.isp
313 isp.push('try:')
313 isp.push('try:')
314 isp.push(' a = 5')
314 isp.push(' a = 5')
315 isp.push('except:')
315 isp.push('except:')
316 isp.push(' raise')
316 isp.push(' raise')
317 # We want to be able to add an else: block at this point, so it should
317 # We want to be able to add an else: block at this point, so it should
318 # wait for a blank line.
318 # wait for a blank line.
319 self.assertTrue(isp.push_accepts_more())
319 self.assertTrue(isp.push_accepts_more())
320
320
321 def test_continuation(self):
321 def test_continuation(self):
322 isp = self.isp
322 isp = self.isp
323 isp.push("import os, \\")
323 isp.push("import os, \\")
324 self.assertTrue(isp.push_accepts_more())
324 self.assertTrue(isp.push_accepts_more())
325 isp.push("sys")
325 isp.push("sys")
326 self.assertFalse(isp.push_accepts_more())
326 self.assertFalse(isp.push_accepts_more())
327
327
328 def test_syntax_error(self):
328 def test_syntax_error(self):
329 isp = self.isp
329 isp = self.isp
330 # Syntax errors immediately produce a 'ready' block, so the invalid
330 # Syntax errors immediately produce a 'ready' block, so the invalid
331 # Python can be sent to the kernel for evaluation with possible ipython
331 # Python can be sent to the kernel for evaluation with possible ipython
332 # special-syntax conversion.
332 # special-syntax conversion.
333 isp.push('run foo')
333 isp.push('run foo')
334 self.assertFalse(isp.push_accepts_more())
334 self.assertFalse(isp.push_accepts_more())
335
335
336 def test_unicode(self):
336 def test_unicode(self):
337 self.isp.push(u"Pérez")
337 self.isp.push(u"Pérez")
338 self.isp.push(u'\xc3\xa9')
338 self.isp.push(u'\xc3\xa9')
339 self.isp.push(u"u'\xc3\xa9'")
339 self.isp.push(u"u'\xc3\xa9'")
340
340
341 def test_line_continuation(self):
341 def test_line_continuation(self):
342 """ Test issue #2108."""
342 """ Test issue #2108."""
343 isp = self.isp
343 isp = self.isp
344 # A blank line after a line continuation should not accept more
344 # A blank line after a line continuation should not accept more
345 isp.push("1 \\\n\n")
345 isp.push("1 \\\n\n")
346 self.assertFalse(isp.push_accepts_more())
346 self.assertFalse(isp.push_accepts_more())
347 # Whitespace after a \ is a SyntaxError. The only way to test that
347 # Whitespace after a \ is a SyntaxError. The only way to test that
348 # here is to test that push doesn't accept more (as with
348 # here is to test that push doesn't accept more (as with
349 # test_syntax_error() above).
349 # test_syntax_error() above).
350 isp.push(r"1 \ ")
350 isp.push(r"1 \ ")
351 self.assertFalse(isp.push_accepts_more())
351 self.assertFalse(isp.push_accepts_more())
352 # Even if the line is continuable (c.f. the regular Python
352 # Even if the line is continuable (c.f. the regular Python
353 # interpreter)
353 # interpreter)
354 isp.push(r"(1 \ ")
354 isp.push(r"(1 \ ")
355 self.assertFalse(isp.push_accepts_more())
355 self.assertFalse(isp.push_accepts_more())
356
356
357 class InteractiveLoopTestCase(unittest.TestCase):
357 class InteractiveLoopTestCase(unittest.TestCase):
358 """Tests for an interactive loop like a python shell.
358 """Tests for an interactive loop like a python shell.
359 """
359 """
360 def check_ns(self, lines, ns):
360 def check_ns(self, lines, ns):
361 """Validate that the given input lines produce the resulting namespace.
361 """Validate that the given input lines produce the resulting namespace.
362
362
363 Note: the input lines are given exactly as they would be typed in an
363 Note: the input lines are given exactly as they would be typed in an
364 auto-indenting environment, as mini_interactive_loop above already does
364 auto-indenting environment, as mini_interactive_loop above already does
365 auto-indenting and prepends spaces to the input.
365 auto-indenting and prepends spaces to the input.
366 """
366 """
367 src = mini_interactive_loop(pseudo_input(lines))
367 src = mini_interactive_loop(pseudo_input(lines))
368 test_ns = {}
368 test_ns = {}
369 exec src in test_ns
369 exec(src, test_ns)
370 # We can't check that the provided ns is identical to the test_ns,
370 # We can't check that the provided ns is identical to the test_ns,
371 # because Python fills test_ns with extra keys (copyright, etc). But
371 # because Python fills test_ns with extra keys (copyright, etc). But
372 # we can check that the given dict is *contained* in test_ns
372 # we can check that the given dict is *contained* in test_ns
373 for k,v in ns.iteritems():
373 for k,v in ns.iteritems():
374 self.assertEqual(test_ns[k], v)
374 self.assertEqual(test_ns[k], v)
375
375
376 def test_simple(self):
376 def test_simple(self):
377 self.check_ns(['x=1'], dict(x=1))
377 self.check_ns(['x=1'], dict(x=1))
378
378
379 def test_simple2(self):
379 def test_simple2(self):
380 self.check_ns(['if 1:', 'x=2'], dict(x=2))
380 self.check_ns(['if 1:', 'x=2'], dict(x=2))
381
381
382 def test_xy(self):
382 def test_xy(self):
383 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
383 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
384
384
385 def test_abc(self):
385 def test_abc(self):
386 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
386 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
387
387
388 def test_multi(self):
388 def test_multi(self):
389 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
389 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
390
390
391
391
392 class IPythonInputTestCase(InputSplitterTestCase):
392 class IPythonInputTestCase(InputSplitterTestCase):
393 """By just creating a new class whose .isp is a different instance, we
393 """By just creating a new class whose .isp is a different instance, we
394 re-run the same test battery on the new input splitter.
394 re-run the same test battery on the new input splitter.
395
395
396 In addition, this runs the tests over the syntax and syntax_ml dicts that
396 In addition, this runs the tests over the syntax and syntax_ml dicts that
397 were tested by individual functions, as part of the OO interface.
397 were tested by individual functions, as part of the OO interface.
398
398
399 It also makes some checks on the raw buffer storage.
399 It also makes some checks on the raw buffer storage.
400 """
400 """
401
401
402 def setUp(self):
402 def setUp(self):
403 self.isp = isp.IPythonInputSplitter()
403 self.isp = isp.IPythonInputSplitter()
404
404
405 def test_syntax(self):
405 def test_syntax(self):
406 """Call all single-line syntax tests from the main object"""
406 """Call all single-line syntax tests from the main object"""
407 isp = self.isp
407 isp = self.isp
408 for example in syntax.itervalues():
408 for example in syntax.itervalues():
409 for raw, out_t in example:
409 for raw, out_t in example:
410 if raw.startswith(' '):
410 if raw.startswith(' '):
411 continue
411 continue
412
412
413 isp.push(raw+'\n')
413 isp.push(raw+'\n')
414 out, out_raw = isp.source_raw_reset()
414 out, out_raw = isp.source_raw_reset()
415 self.assertEqual(out.rstrip(), out_t,
415 self.assertEqual(out.rstrip(), out_t,
416 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
416 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
417 self.assertEqual(out_raw.rstrip(), raw.rstrip())
417 self.assertEqual(out_raw.rstrip(), raw.rstrip())
418
418
419 def test_syntax_multiline(self):
419 def test_syntax_multiline(self):
420 isp = self.isp
420 isp = self.isp
421 for example in syntax_ml.itervalues():
421 for example in syntax_ml.itervalues():
422 for line_pairs in example:
422 for line_pairs in example:
423 out_t_parts = []
423 out_t_parts = []
424 raw_parts = []
424 raw_parts = []
425 for lraw, out_t_part in line_pairs:
425 for lraw, out_t_part in line_pairs:
426 if out_t_part is not None:
426 if out_t_part is not None:
427 out_t_parts.append(out_t_part)
427 out_t_parts.append(out_t_part)
428
428
429 if lraw is not None:
429 if lraw is not None:
430 isp.push(lraw)
430 isp.push(lraw)
431 raw_parts.append(lraw)
431 raw_parts.append(lraw)
432
432
433 out, out_raw = isp.source_raw_reset()
433 out, out_raw = isp.source_raw_reset()
434 out_t = '\n'.join(out_t_parts).rstrip()
434 out_t = '\n'.join(out_t_parts).rstrip()
435 raw = '\n'.join(raw_parts).rstrip()
435 raw = '\n'.join(raw_parts).rstrip()
436 self.assertEqual(out.rstrip(), out_t)
436 self.assertEqual(out.rstrip(), out_t)
437 self.assertEqual(out_raw.rstrip(), raw)
437 self.assertEqual(out_raw.rstrip(), raw)
438
438
439 def test_syntax_multiline_cell(self):
439 def test_syntax_multiline_cell(self):
440 isp = self.isp
440 isp = self.isp
441 for example in syntax_ml.itervalues():
441 for example in syntax_ml.itervalues():
442
442
443 out_t_parts = []
443 out_t_parts = []
444 for line_pairs in example:
444 for line_pairs in example:
445 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
445 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
446 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
446 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
447 out = isp.transform_cell(raw)
447 out = isp.transform_cell(raw)
448 # Match ignoring trailing whitespace
448 # Match ignoring trailing whitespace
449 self.assertEqual(out.rstrip(), out_t.rstrip())
449 self.assertEqual(out.rstrip(), out_t.rstrip())
450
450
451 def test_cellmagic_preempt(self):
451 def test_cellmagic_preempt(self):
452 isp = self.isp
452 isp = self.isp
453 for raw, name, line, cell in [
453 for raw, name, line, cell in [
454 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
454 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
455 ("%%cellm \nline\n>>>hi", u'cellm', u'', u'line\n>>>hi'),
455 ("%%cellm \nline\n>>>hi", u'cellm', u'', u'line\n>>>hi'),
456 (">>>%%cellm \nline\n>>>hi", u'cellm', u'', u'line\nhi'),
456 (">>>%%cellm \nline\n>>>hi", u'cellm', u'', u'line\nhi'),
457 ("%%cellm \n>>>hi", u'cellm', u'', u'hi'),
457 ("%%cellm \n>>>hi", u'cellm', u'', u'hi'),
458 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
458 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
459 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
459 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
460 ]:
460 ]:
461 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
461 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
462 name, line, cell
462 name, line, cell
463 )
463 )
464 out = isp.transform_cell(raw)
464 out = isp.transform_cell(raw)
465 self.assertEqual(out.rstrip(), expected.rstrip())
465 self.assertEqual(out.rstrip(), expected.rstrip())
466
466
467
467
468
468
469 #-----------------------------------------------------------------------------
469 #-----------------------------------------------------------------------------
470 # Main - use as a script, mostly for developer experiments
470 # Main - use as a script, mostly for developer experiments
471 #-----------------------------------------------------------------------------
471 #-----------------------------------------------------------------------------
472
472
473 if __name__ == '__main__':
473 if __name__ == '__main__':
474 # A simple demo for interactive experimentation. This code will not get
474 # A simple demo for interactive experimentation. This code will not get
475 # picked up by any test suite.
475 # picked up by any test suite.
476 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
476 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
477
477
478 # configure here the syntax to use, prompt and whether to autoindent
478 # configure here the syntax to use, prompt and whether to autoindent
479 #isp, start_prompt = InputSplitter(), '>>> '
479 #isp, start_prompt = InputSplitter(), '>>> '
480 isp, start_prompt = IPythonInputSplitter(), 'In> '
480 isp, start_prompt = IPythonInputSplitter(), 'In> '
481
481
482 autoindent = True
482 autoindent = True
483 #autoindent = False
483 #autoindent = False
484
484
485 try:
485 try:
486 while True:
486 while True:
487 prompt = start_prompt
487 prompt = start_prompt
488 while isp.push_accepts_more():
488 while isp.push_accepts_more():
489 indent = ' '*isp.indent_spaces
489 indent = ' '*isp.indent_spaces
490 if autoindent:
490 if autoindent:
491 line = indent + raw_input(prompt+indent)
491 line = indent + raw_input(prompt+indent)
492 else:
492 else:
493 line = raw_input(prompt)
493 line = raw_input(prompt)
494 isp.push(line)
494 isp.push(line)
495 prompt = '... '
495 prompt = '... '
496
496
497 # Here we just return input so we can use it in a test suite, but a
497 # Here we just return input so we can use it in a test suite, but a
498 # real interpreter would instead send it for execution somewhere.
498 # real interpreter would instead send it for execution somewhere.
499 #src = isp.source; raise EOFError # dbg
499 #src = isp.source; raise EOFError # dbg
500 src, raw = isp.source_raw_reset()
500 src, raw = isp.source_raw_reset()
501 print('Input source was:\n', src)
501 print('Input source was:\n', src)
502 print('Raw source was:\n', raw)
502 print('Raw source was:\n', raw)
503 except EOFError:
503 except EOFError:
504 print('Bye')
504 print('Bye')
505
505
506 # Tests for cell magics support
506 # Tests for cell magics support
507
507
508 def test_last_blank():
508 def test_last_blank():
509 nt.assert_false(isp.last_blank(''))
509 nt.assert_false(isp.last_blank(''))
510 nt.assert_false(isp.last_blank('abc'))
510 nt.assert_false(isp.last_blank('abc'))
511 nt.assert_false(isp.last_blank('abc\n'))
511 nt.assert_false(isp.last_blank('abc\n'))
512 nt.assert_false(isp.last_blank('abc\na'))
512 nt.assert_false(isp.last_blank('abc\na'))
513
513
514 nt.assert_true(isp.last_blank('\n'))
514 nt.assert_true(isp.last_blank('\n'))
515 nt.assert_true(isp.last_blank('\n '))
515 nt.assert_true(isp.last_blank('\n '))
516 nt.assert_true(isp.last_blank('abc\n '))
516 nt.assert_true(isp.last_blank('abc\n '))
517 nt.assert_true(isp.last_blank('abc\n\n'))
517 nt.assert_true(isp.last_blank('abc\n\n'))
518 nt.assert_true(isp.last_blank('abc\nd\n\n'))
518 nt.assert_true(isp.last_blank('abc\nd\n\n'))
519 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
519 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
520 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
520 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
521
521
522
522
523 def test_last_two_blanks():
523 def test_last_two_blanks():
524 nt.assert_false(isp.last_two_blanks(''))
524 nt.assert_false(isp.last_two_blanks(''))
525 nt.assert_false(isp.last_two_blanks('abc'))
525 nt.assert_false(isp.last_two_blanks('abc'))
526 nt.assert_false(isp.last_two_blanks('abc\n'))
526 nt.assert_false(isp.last_two_blanks('abc\n'))
527 nt.assert_false(isp.last_two_blanks('abc\n\na'))
527 nt.assert_false(isp.last_two_blanks('abc\n\na'))
528 nt.assert_false(isp.last_two_blanks('abc\n \n'))
528 nt.assert_false(isp.last_two_blanks('abc\n \n'))
529 nt.assert_false(isp.last_two_blanks('abc\n\n'))
529 nt.assert_false(isp.last_two_blanks('abc\n\n'))
530
530
531 nt.assert_true(isp.last_two_blanks('\n\n'))
531 nt.assert_true(isp.last_two_blanks('\n\n'))
532 nt.assert_true(isp.last_two_blanks('\n\n '))
532 nt.assert_true(isp.last_two_blanks('\n\n '))
533 nt.assert_true(isp.last_two_blanks('\n \n'))
533 nt.assert_true(isp.last_two_blanks('\n \n'))
534 nt.assert_true(isp.last_two_blanks('abc\n\n '))
534 nt.assert_true(isp.last_two_blanks('abc\n\n '))
535 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
535 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
536 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
536 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
537 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
537 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
538 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
538 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
539 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
539 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
540 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
540 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
541
541
542
542
543 class CellMagicsCommon(object):
543 class CellMagicsCommon(object):
544
544
545 def test_whole_cell(self):
545 def test_whole_cell(self):
546 src = "%%cellm line\nbody\n"
546 src = "%%cellm line\nbody\n"
547 sp = self.sp
547 sp = self.sp
548 sp.push(src)
548 sp.push(src)
549 out = sp.source_reset()
549 out = sp.source_reset()
550 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
550 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
551 nt.assert_equal(out, py3compat.u_format(ref))
551 nt.assert_equal(out, py3compat.u_format(ref))
552
552
553 def test_cellmagic_help(self):
553 def test_cellmagic_help(self):
554 self.sp.push('%%cellm?')
554 self.sp.push('%%cellm?')
555 nt.assert_false(self.sp.push_accepts_more())
555 nt.assert_false(self.sp.push_accepts_more())
556
556
557 def tearDown(self):
557 def tearDown(self):
558 self.sp.reset()
558 self.sp.reset()
559
559
560
560
561 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
561 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
562 sp = isp.IPythonInputSplitter(line_input_checker=False)
562 sp = isp.IPythonInputSplitter(line_input_checker=False)
563
563
564 def test_incremental(self):
564 def test_incremental(self):
565 sp = self.sp
565 sp = self.sp
566 sp.push('%%cellm firstline\n')
566 sp.push('%%cellm firstline\n')
567 nt.assert_true(sp.push_accepts_more()) #1
567 nt.assert_true(sp.push_accepts_more()) #1
568 sp.push('line2\n')
568 sp.push('line2\n')
569 nt.assert_true(sp.push_accepts_more()) #2
569 nt.assert_true(sp.push_accepts_more()) #2
570 sp.push('\n')
570 sp.push('\n')
571 # This should accept a blank line and carry on until the cell is reset
571 # This should accept a blank line and carry on until the cell is reset
572 nt.assert_true(sp.push_accepts_more()) #3
572 nt.assert_true(sp.push_accepts_more()) #3
573
573
574 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
574 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
575 sp = isp.IPythonInputSplitter(line_input_checker=True)
575 sp = isp.IPythonInputSplitter(line_input_checker=True)
576
576
577 def test_incremental(self):
577 def test_incremental(self):
578 sp = self.sp
578 sp = self.sp
579 sp.push('%%cellm line2\n')
579 sp.push('%%cellm line2\n')
580 nt.assert_true(sp.push_accepts_more()) #1
580 nt.assert_true(sp.push_accepts_more()) #1
581 sp.push('\n')
581 sp.push('\n')
582 # In this case, a blank line should end the cell magic
582 # In this case, a blank line should end the cell magic
583 nt.assert_false(sp.push_accepts_more()) #2
583 nt.assert_false(sp.push_accepts_more()) #2
@@ -1,317 +1,317 b''
1 """Tests for autoreload extension.
1 """Tests for autoreload extension.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 IPython Development Team.
4 # Copyright (c) 2012 IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import os
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18 import shutil
18 import shutil
19 import random
19 import random
20 import time
20 import time
21 from StringIO import StringIO
21 from StringIO import StringIO
22
22
23 import nose.tools as nt
23 import nose.tools as nt
24 import IPython.testing.tools as tt
24 import IPython.testing.tools as tt
25
25
26 from IPython.extensions.autoreload import AutoreloadMagics
26 from IPython.extensions.autoreload import AutoreloadMagics
27 from IPython.core.hooks import TryNext
27 from IPython.core.hooks import TryNext
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Test fixture
30 # Test fixture
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 noop = lambda *a, **kw: None
33 noop = lambda *a, **kw: None
34
34
35 class FakeShell(object):
35 class FakeShell(object):
36
36
37 def __init__(self):
37 def __init__(self):
38 self.ns = {}
38 self.ns = {}
39 self.auto_magics = AutoreloadMagics(shell=self)
39 self.auto_magics = AutoreloadMagics(shell=self)
40
40
41 register_magics = set_hook = noop
41 register_magics = set_hook = noop
42
42
43 def run_code(self, code):
43 def run_code(self, code):
44 try:
44 try:
45 self.auto_magics.pre_run_code_hook(self)
45 self.auto_magics.pre_run_code_hook(self)
46 except TryNext:
46 except TryNext:
47 pass
47 pass
48 exec code in self.ns
48 exec(code, self.ns)
49
49
50 def push(self, items):
50 def push(self, items):
51 self.ns.update(items)
51 self.ns.update(items)
52
52
53 def magic_autoreload(self, parameter):
53 def magic_autoreload(self, parameter):
54 self.auto_magics.autoreload(parameter)
54 self.auto_magics.autoreload(parameter)
55
55
56 def magic_aimport(self, parameter, stream=None):
56 def magic_aimport(self, parameter, stream=None):
57 self.auto_magics.aimport(parameter, stream=stream)
57 self.auto_magics.aimport(parameter, stream=stream)
58
58
59
59
60 class Fixture(object):
60 class Fixture(object):
61 """Fixture for creating test module files"""
61 """Fixture for creating test module files"""
62
62
63 test_dir = None
63 test_dir = None
64 old_sys_path = None
64 old_sys_path = None
65 filename_chars = "abcdefghijklmopqrstuvwxyz0123456789"
65 filename_chars = "abcdefghijklmopqrstuvwxyz0123456789"
66
66
67 def setUp(self):
67 def setUp(self):
68 self.test_dir = tempfile.mkdtemp()
68 self.test_dir = tempfile.mkdtemp()
69 self.old_sys_path = list(sys.path)
69 self.old_sys_path = list(sys.path)
70 sys.path.insert(0, self.test_dir)
70 sys.path.insert(0, self.test_dir)
71 self.shell = FakeShell()
71 self.shell = FakeShell()
72
72
73 def tearDown(self):
73 def tearDown(self):
74 shutil.rmtree(self.test_dir)
74 shutil.rmtree(self.test_dir)
75 sys.path = self.old_sys_path
75 sys.path = self.old_sys_path
76
76
77 self.test_dir = None
77 self.test_dir = None
78 self.old_sys_path = None
78 self.old_sys_path = None
79 self.shell = None
79 self.shell = None
80
80
81 def get_module(self):
81 def get_module(self):
82 module_name = "tmpmod_" + "".join(random.sample(self.filename_chars,20))
82 module_name = "tmpmod_" + "".join(random.sample(self.filename_chars,20))
83 if module_name in sys.modules:
83 if module_name in sys.modules:
84 del sys.modules[module_name]
84 del sys.modules[module_name]
85 file_name = os.path.join(self.test_dir, module_name + ".py")
85 file_name = os.path.join(self.test_dir, module_name + ".py")
86 return module_name, file_name
86 return module_name, file_name
87
87
88 def write_file(self, filename, content):
88 def write_file(self, filename, content):
89 """
89 """
90 Write a file, and force a timestamp difference of at least one second
90 Write a file, and force a timestamp difference of at least one second
91
91
92 Notes
92 Notes
93 -----
93 -----
94 Python's .pyc files record the timestamp of their compilation
94 Python's .pyc files record the timestamp of their compilation
95 with a time resolution of one second.
95 with a time resolution of one second.
96
96
97 Therefore, we need to force a timestamp difference between .py
97 Therefore, we need to force a timestamp difference between .py
98 and .pyc, without having the .py file be timestamped in the
98 and .pyc, without having the .py file be timestamped in the
99 future, and without changing the timestamp of the .pyc file
99 future, and without changing the timestamp of the .pyc file
100 (because that is stored in the file). The only reliable way
100 (because that is stored in the file). The only reliable way
101 to achieve this seems to be to sleep.
101 to achieve this seems to be to sleep.
102 """
102 """
103
103
104 # Sleep one second + eps
104 # Sleep one second + eps
105 time.sleep(1.05)
105 time.sleep(1.05)
106
106
107 # Write
107 # Write
108 f = open(filename, 'w')
108 f = open(filename, 'w')
109 try:
109 try:
110 f.write(content)
110 f.write(content)
111 finally:
111 finally:
112 f.close()
112 f.close()
113
113
114 def new_module(self, code):
114 def new_module(self, code):
115 mod_name, mod_fn = self.get_module()
115 mod_name, mod_fn = self.get_module()
116 f = open(mod_fn, 'w')
116 f = open(mod_fn, 'w')
117 try:
117 try:
118 f.write(code)
118 f.write(code)
119 finally:
119 finally:
120 f.close()
120 f.close()
121 return mod_name, mod_fn
121 return mod_name, mod_fn
122
122
123 #-----------------------------------------------------------------------------
123 #-----------------------------------------------------------------------------
124 # Test automatic reloading
124 # Test automatic reloading
125 #-----------------------------------------------------------------------------
125 #-----------------------------------------------------------------------------
126
126
127 class TestAutoreload(Fixture):
127 class TestAutoreload(Fixture):
128 def _check_smoketest(self, use_aimport=True):
128 def _check_smoketest(self, use_aimport=True):
129 """
129 """
130 Functional test for the automatic reloader using either
130 Functional test for the automatic reloader using either
131 '%autoreload 1' or '%autoreload 2'
131 '%autoreload 1' or '%autoreload 2'
132 """
132 """
133
133
134 mod_name, mod_fn = self.new_module("""
134 mod_name, mod_fn = self.new_module("""
135 x = 9
135 x = 9
136
136
137 z = 123 # this item will be deleted
137 z = 123 # this item will be deleted
138
138
139 def foo(y):
139 def foo(y):
140 return y + 3
140 return y + 3
141
141
142 class Baz(object):
142 class Baz(object):
143 def __init__(self, x):
143 def __init__(self, x):
144 self.x = x
144 self.x = x
145 def bar(self, y):
145 def bar(self, y):
146 return self.x + y
146 return self.x + y
147 @property
147 @property
148 def quux(self):
148 def quux(self):
149 return 42
149 return 42
150 def zzz(self):
150 def zzz(self):
151 '''This method will be deleted below'''
151 '''This method will be deleted below'''
152 return 99
152 return 99
153
153
154 class Bar: # old-style class: weakref doesn't work for it on Python < 2.7
154 class Bar: # old-style class: weakref doesn't work for it on Python < 2.7
155 def foo(self):
155 def foo(self):
156 return 1
156 return 1
157 """)
157 """)
158
158
159 #
159 #
160 # Import module, and mark for reloading
160 # Import module, and mark for reloading
161 #
161 #
162 if use_aimport:
162 if use_aimport:
163 self.shell.magic_autoreload("1")
163 self.shell.magic_autoreload("1")
164 self.shell.magic_aimport(mod_name)
164 self.shell.magic_aimport(mod_name)
165 stream = StringIO()
165 stream = StringIO()
166 self.shell.magic_aimport("", stream=stream)
166 self.shell.magic_aimport("", stream=stream)
167 nt.assert_true(("Modules to reload:\n%s" % mod_name) in
167 nt.assert_true(("Modules to reload:\n%s" % mod_name) in
168 stream.getvalue())
168 stream.getvalue())
169
169
170 nt.assert_raises(
170 nt.assert_raises(
171 ImportError,
171 ImportError,
172 self.shell.magic_aimport, "tmpmod_as318989e89ds")
172 self.shell.magic_aimport, "tmpmod_as318989e89ds")
173 else:
173 else:
174 self.shell.magic_autoreload("2")
174 self.shell.magic_autoreload("2")
175 self.shell.run_code("import %s" % mod_name)
175 self.shell.run_code("import %s" % mod_name)
176 stream = StringIO()
176 stream = StringIO()
177 self.shell.magic_aimport("", stream=stream)
177 self.shell.magic_aimport("", stream=stream)
178 nt.assert_true("Modules to reload:\nall-except-skipped" in
178 nt.assert_true("Modules to reload:\nall-except-skipped" in
179 stream.getvalue())
179 stream.getvalue())
180 nt.assert_in(mod_name, self.shell.ns)
180 nt.assert_in(mod_name, self.shell.ns)
181
181
182 mod = sys.modules[mod_name]
182 mod = sys.modules[mod_name]
183
183
184 #
184 #
185 # Test module contents
185 # Test module contents
186 #
186 #
187 old_foo = mod.foo
187 old_foo = mod.foo
188 old_obj = mod.Baz(9)
188 old_obj = mod.Baz(9)
189 old_obj2 = mod.Bar()
189 old_obj2 = mod.Bar()
190
190
191 def check_module_contents():
191 def check_module_contents():
192 nt.assert_equal(mod.x, 9)
192 nt.assert_equal(mod.x, 9)
193 nt.assert_equal(mod.z, 123)
193 nt.assert_equal(mod.z, 123)
194
194
195 nt.assert_equal(old_foo(0), 3)
195 nt.assert_equal(old_foo(0), 3)
196 nt.assert_equal(mod.foo(0), 3)
196 nt.assert_equal(mod.foo(0), 3)
197
197
198 obj = mod.Baz(9)
198 obj = mod.Baz(9)
199 nt.assert_equal(old_obj.bar(1), 10)
199 nt.assert_equal(old_obj.bar(1), 10)
200 nt.assert_equal(obj.bar(1), 10)
200 nt.assert_equal(obj.bar(1), 10)
201 nt.assert_equal(obj.quux, 42)
201 nt.assert_equal(obj.quux, 42)
202 nt.assert_equal(obj.zzz(), 99)
202 nt.assert_equal(obj.zzz(), 99)
203
203
204 obj2 = mod.Bar()
204 obj2 = mod.Bar()
205 nt.assert_equal(old_obj2.foo(), 1)
205 nt.assert_equal(old_obj2.foo(), 1)
206 nt.assert_equal(obj2.foo(), 1)
206 nt.assert_equal(obj2.foo(), 1)
207
207
208 check_module_contents()
208 check_module_contents()
209
209
210 #
210 #
211 # Simulate a failed reload: no reload should occur and exactly
211 # Simulate a failed reload: no reload should occur and exactly
212 # one error message should be printed
212 # one error message should be printed
213 #
213 #
214 self.write_file(mod_fn, """
214 self.write_file(mod_fn, """
215 a syntax error
215 a syntax error
216 """)
216 """)
217
217
218 with tt.AssertPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
218 with tt.AssertPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
219 self.shell.run_code("pass") # trigger reload
219 self.shell.run_code("pass") # trigger reload
220 with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
220 with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
221 self.shell.run_code("pass") # trigger another reload
221 self.shell.run_code("pass") # trigger another reload
222 check_module_contents()
222 check_module_contents()
223
223
224 #
224 #
225 # Rewrite module (this time reload should succeed)
225 # Rewrite module (this time reload should succeed)
226 #
226 #
227 self.write_file(mod_fn, """
227 self.write_file(mod_fn, """
228 x = 10
228 x = 10
229
229
230 def foo(y):
230 def foo(y):
231 return y + 4
231 return y + 4
232
232
233 class Baz(object):
233 class Baz(object):
234 def __init__(self, x):
234 def __init__(self, x):
235 self.x = x
235 self.x = x
236 def bar(self, y):
236 def bar(self, y):
237 return self.x + y + 1
237 return self.x + y + 1
238 @property
238 @property
239 def quux(self):
239 def quux(self):
240 return 43
240 return 43
241
241
242 class Bar: # old-style class
242 class Bar: # old-style class
243 def foo(self):
243 def foo(self):
244 return 2
244 return 2
245 """)
245 """)
246
246
247 def check_module_contents():
247 def check_module_contents():
248 nt.assert_equal(mod.x, 10)
248 nt.assert_equal(mod.x, 10)
249 nt.assert_false(hasattr(mod, 'z'))
249 nt.assert_false(hasattr(mod, 'z'))
250
250
251 nt.assert_equal(old_foo(0), 4) # superreload magic!
251 nt.assert_equal(old_foo(0), 4) # superreload magic!
252 nt.assert_equal(mod.foo(0), 4)
252 nt.assert_equal(mod.foo(0), 4)
253
253
254 obj = mod.Baz(9)
254 obj = mod.Baz(9)
255 nt.assert_equal(old_obj.bar(1), 11) # superreload magic!
255 nt.assert_equal(old_obj.bar(1), 11) # superreload magic!
256 nt.assert_equal(obj.bar(1), 11)
256 nt.assert_equal(obj.bar(1), 11)
257
257
258 nt.assert_equal(old_obj.quux, 43)
258 nt.assert_equal(old_obj.quux, 43)
259 nt.assert_equal(obj.quux, 43)
259 nt.assert_equal(obj.quux, 43)
260
260
261 nt.assert_false(hasattr(old_obj, 'zzz'))
261 nt.assert_false(hasattr(old_obj, 'zzz'))
262 nt.assert_false(hasattr(obj, 'zzz'))
262 nt.assert_false(hasattr(obj, 'zzz'))
263
263
264 obj2 = mod.Bar()
264 obj2 = mod.Bar()
265 nt.assert_equal(old_obj2.foo(), 2)
265 nt.assert_equal(old_obj2.foo(), 2)
266 nt.assert_equal(obj2.foo(), 2)
266 nt.assert_equal(obj2.foo(), 2)
267
267
268 self.shell.run_code("pass") # trigger reload
268 self.shell.run_code("pass") # trigger reload
269 check_module_contents()
269 check_module_contents()
270
270
271 #
271 #
272 # Another failure case: deleted file (shouldn't reload)
272 # Another failure case: deleted file (shouldn't reload)
273 #
273 #
274 os.unlink(mod_fn)
274 os.unlink(mod_fn)
275
275
276 self.shell.run_code("pass") # trigger reload
276 self.shell.run_code("pass") # trigger reload
277 check_module_contents()
277 check_module_contents()
278
278
279 #
279 #
280 # Disable autoreload and rewrite module: no reload should occur
280 # Disable autoreload and rewrite module: no reload should occur
281 #
281 #
282 if use_aimport:
282 if use_aimport:
283 self.shell.magic_aimport("-" + mod_name)
283 self.shell.magic_aimport("-" + mod_name)
284 stream = StringIO()
284 stream = StringIO()
285 self.shell.magic_aimport("", stream=stream)
285 self.shell.magic_aimport("", stream=stream)
286 nt.assert_true(("Modules to skip:\n%s" % mod_name) in
286 nt.assert_true(("Modules to skip:\n%s" % mod_name) in
287 stream.getvalue())
287 stream.getvalue())
288
288
289 # This should succeed, although no such module exists
289 # This should succeed, although no such module exists
290 self.shell.magic_aimport("-tmpmod_as318989e89ds")
290 self.shell.magic_aimport("-tmpmod_as318989e89ds")
291 else:
291 else:
292 self.shell.magic_autoreload("0")
292 self.shell.magic_autoreload("0")
293
293
294 self.write_file(mod_fn, """
294 self.write_file(mod_fn, """
295 x = -99
295 x = -99
296 """)
296 """)
297
297
298 self.shell.run_code("pass") # trigger reload
298 self.shell.run_code("pass") # trigger reload
299 self.shell.run_code("pass")
299 self.shell.run_code("pass")
300 check_module_contents()
300 check_module_contents()
301
301
302 #
302 #
303 # Re-enable autoreload: reload should now occur
303 # Re-enable autoreload: reload should now occur
304 #
304 #
305 if use_aimport:
305 if use_aimport:
306 self.shell.magic_aimport(mod_name)
306 self.shell.magic_aimport(mod_name)
307 else:
307 else:
308 self.shell.magic_autoreload("")
308 self.shell.magic_autoreload("")
309
309
310 self.shell.run_code("pass") # trigger reload
310 self.shell.run_code("pass") # trigger reload
311 nt.assert_equal(mod.x, -99)
311 nt.assert_equal(mod.x, -99)
312
312
313 def test_smoketest_aimport(self):
313 def test_smoketest_aimport(self):
314 self._check_smoketest(use_aimport=True)
314 self._check_smoketest(use_aimport=True)
315
315
316 def test_smoketest_autoreload(self):
316 def test_smoketest_autoreload(self):
317 self._check_smoketest(use_aimport=False)
317 self._check_smoketest(use_aimport=False)
@@ -1,221 +1,221 b''
1 ########################## LICENCE ###############################
1 ########################## LICENCE ###############################
2
2
3 # Copyright (c) 2005-2012, Michele Simionato
3 # Copyright (c) 2005-2012, Michele Simionato
4 # All rights reserved.
4 # All rights reserved.
5
5
6 # Redistribution and use in source and binary forms, with or without
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are
7 # modification, are permitted provided that the following conditions are
8 # met:
8 # met:
9
9
10 # Redistributions of source code must retain the above copyright
10 # Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
11 # notice, this list of conditions and the following disclaimer.
12 # Redistributions in bytecode form must reproduce the above copyright
12 # Redistributions in bytecode form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in
13 # notice, this list of conditions and the following disclaimer in
14 # the documentation and/or other materials provided with the
14 # the documentation and/or other materials provided with the
15 # distribution.
15 # distribution.
16
16
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
26 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28 # DAMAGE.
28 # DAMAGE.
29
29
30 """
30 """
31 Decorator module, see http://pypi.python.org/pypi/decorator
31 Decorator module, see http://pypi.python.org/pypi/decorator
32 for the documentation.
32 for the documentation.
33 """
33 """
34 from __future__ import print_function
34 from __future__ import print_function
35
35
36 __version__ = '3.3.3'
36 __version__ = '3.3.3'
37
37
38 __all__ = ["decorator", "FunctionMaker", "partial"]
38 __all__ = ["decorator", "FunctionMaker", "partial"]
39
39
40 import sys, re, inspect
40 import sys, re, inspect
41
41
42 try:
42 try:
43 from functools import partial
43 from functools import partial
44 except ImportError: # for Python version < 2.5
44 except ImportError: # for Python version < 2.5
45 class partial(object):
45 class partial(object):
46 "A simple replacement of functools.partial"
46 "A simple replacement of functools.partial"
47 def __init__(self, func, *args, **kw):
47 def __init__(self, func, *args, **kw):
48 self.func = func
48 self.func = func
49 self.args = args
49 self.args = args
50 self.keywords = kw
50 self.keywords = kw
51 def __call__(self, *otherargs, **otherkw):
51 def __call__(self, *otherargs, **otherkw):
52 kw = self.keywords.copy()
52 kw = self.keywords.copy()
53 kw.update(otherkw)
53 kw.update(otherkw)
54 return self.func(*(self.args + otherargs), **kw)
54 return self.func(*(self.args + otherargs), **kw)
55
55
56 if sys.version >= '3':
56 if sys.version >= '3':
57 from inspect import getfullargspec
57 from inspect import getfullargspec
58 else:
58 else:
59 class getfullargspec(object):
59 class getfullargspec(object):
60 "A quick and dirty replacement for getfullargspec for Python 2.X"
60 "A quick and dirty replacement for getfullargspec for Python 2.X"
61 def __init__(self, f):
61 def __init__(self, f):
62 self.args, self.varargs, self.varkw, self.defaults = \
62 self.args, self.varargs, self.varkw, self.defaults = \
63 inspect.getargspec(f)
63 inspect.getargspec(f)
64 self.kwonlyargs = []
64 self.kwonlyargs = []
65 self.kwonlydefaults = None
65 self.kwonlydefaults = None
66 def __iter__(self):
66 def __iter__(self):
67 yield self.args
67 yield self.args
68 yield self.varargs
68 yield self.varargs
69 yield self.varkw
69 yield self.varkw
70 yield self.defaults
70 yield self.defaults
71
71
72 DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(')
72 DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(')
73
73
74 # basic functionality
74 # basic functionality
75 class FunctionMaker(object):
75 class FunctionMaker(object):
76 """
76 """
77 An object with the ability to create functions with a given signature.
77 An object with the ability to create functions with a given signature.
78 It has attributes name, doc, module, signature, defaults, dict and
78 It has attributes name, doc, module, signature, defaults, dict and
79 methods update and make.
79 methods update and make.
80 """
80 """
81 def __init__(self, func=None, name=None, signature=None,
81 def __init__(self, func=None, name=None, signature=None,
82 defaults=None, doc=None, module=None, funcdict=None):
82 defaults=None, doc=None, module=None, funcdict=None):
83 self.shortsignature = signature
83 self.shortsignature = signature
84 if func:
84 if func:
85 # func can be a class or a callable, but not an instance method
85 # func can be a class or a callable, but not an instance method
86 self.name = func.__name__
86 self.name = func.__name__
87 if self.name == '<lambda>': # small hack for lambda functions
87 if self.name == '<lambda>': # small hack for lambda functions
88 self.name = '_lambda_'
88 self.name = '_lambda_'
89 self.doc = func.__doc__
89 self.doc = func.__doc__
90 self.module = func.__module__
90 self.module = func.__module__
91 if inspect.isfunction(func):
91 if inspect.isfunction(func):
92 argspec = getfullargspec(func)
92 argspec = getfullargspec(func)
93 self.annotations = getattr(func, '__annotations__', {})
93 self.annotations = getattr(func, '__annotations__', {})
94 for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs',
94 for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs',
95 'kwonlydefaults'):
95 'kwonlydefaults'):
96 setattr(self, a, getattr(argspec, a))
96 setattr(self, a, getattr(argspec, a))
97 for i, arg in enumerate(self.args):
97 for i, arg in enumerate(self.args):
98 setattr(self, 'arg%d' % i, arg)
98 setattr(self, 'arg%d' % i, arg)
99 if sys.version < '3': # easy way
99 if sys.version < '3': # easy way
100 self.shortsignature = self.signature = \
100 self.shortsignature = self.signature = \
101 inspect.formatargspec(
101 inspect.formatargspec(
102 formatvalue=lambda val: "", *argspec)[1:-1]
102 formatvalue=lambda val: "", *argspec)[1:-1]
103 else: # Python 3 way
103 else: # Python 3 way
104 self.signature = self.shortsignature = ', '.join(self.args)
104 self.signature = self.shortsignature = ', '.join(self.args)
105 if self.varargs:
105 if self.varargs:
106 self.signature += ', *' + self.varargs
106 self.signature += ', *' + self.varargs
107 self.shortsignature += ', *' + self.varargs
107 self.shortsignature += ', *' + self.varargs
108 if self.kwonlyargs:
108 if self.kwonlyargs:
109 for a in self.kwonlyargs:
109 for a in self.kwonlyargs:
110 self.signature += ', %s=None' % a
110 self.signature += ', %s=None' % a
111 self.shortsignature += ', %s=%s' % (a, a)
111 self.shortsignature += ', %s=%s' % (a, a)
112 if self.varkw:
112 if self.varkw:
113 self.signature += ', **' + self.varkw
113 self.signature += ', **' + self.varkw
114 self.shortsignature += ', **' + self.varkw
114 self.shortsignature += ', **' + self.varkw
115 self.dict = func.__dict__.copy()
115 self.dict = func.__dict__.copy()
116 # func=None happens when decorating a caller
116 # func=None happens when decorating a caller
117 if name:
117 if name:
118 self.name = name
118 self.name = name
119 if signature is not None:
119 if signature is not None:
120 self.signature = signature
120 self.signature = signature
121 if defaults:
121 if defaults:
122 self.defaults = defaults
122 self.defaults = defaults
123 if doc:
123 if doc:
124 self.doc = doc
124 self.doc = doc
125 if module:
125 if module:
126 self.module = module
126 self.module = module
127 if funcdict:
127 if funcdict:
128 self.dict = funcdict
128 self.dict = funcdict
129 # check existence required attributes
129 # check existence required attributes
130 assert hasattr(self, 'name')
130 assert hasattr(self, 'name')
131 if not hasattr(self, 'signature'):
131 if not hasattr(self, 'signature'):
132 raise TypeError('You are decorating a non function: %s' % func)
132 raise TypeError('You are decorating a non function: %s' % func)
133
133
134 def update(self, func, **kw):
134 def update(self, func, **kw):
135 "Update the signature of func with the data in self"
135 "Update the signature of func with the data in self"
136 func.__name__ = self.name
136 func.__name__ = self.name
137 func.__doc__ = getattr(self, 'doc', None)
137 func.__doc__ = getattr(self, 'doc', None)
138 func.__dict__ = getattr(self, 'dict', {})
138 func.__dict__ = getattr(self, 'dict', {})
139 func.func_defaults = getattr(self, 'defaults', ())
139 func.func_defaults = getattr(self, 'defaults', ())
140 func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
140 func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
141 func.__annotations__ = getattr(self, 'annotations', None)
141 func.__annotations__ = getattr(self, 'annotations', None)
142 callermodule = sys._getframe(3).f_globals.get('__name__', '?')
142 callermodule = sys._getframe(3).f_globals.get('__name__', '?')
143 func.__module__ = getattr(self, 'module', callermodule)
143 func.__module__ = getattr(self, 'module', callermodule)
144 func.__dict__.update(kw)
144 func.__dict__.update(kw)
145
145
146 def make(self, src_templ, evaldict=None, addsource=False, **attrs):
146 def make(self, src_templ, evaldict=None, addsource=False, **attrs):
147 "Make a new function from a given template and update the signature"
147 "Make a new function from a given template and update the signature"
148 src = src_templ % vars(self) # expand name and signature
148 src = src_templ % vars(self) # expand name and signature
149 evaldict = evaldict or {}
149 evaldict = evaldict or {}
150 mo = DEF.match(src)
150 mo = DEF.match(src)
151 if mo is None:
151 if mo is None:
152 raise SyntaxError('not a valid function template\n%s' % src)
152 raise SyntaxError('not a valid function template\n%s' % src)
153 name = mo.group(1) # extract the function name
153 name = mo.group(1) # extract the function name
154 names = set([name] + [arg.strip(' *') for arg in
154 names = set([name] + [arg.strip(' *') for arg in
155 self.shortsignature.split(',')])
155 self.shortsignature.split(',')])
156 for n in names:
156 for n in names:
157 if n in ('_func_', '_call_'):
157 if n in ('_func_', '_call_'):
158 raise NameError('%s is overridden in\n%s' % (n, src))
158 raise NameError('%s is overridden in\n%s' % (n, src))
159 if not src.endswith('\n'): # add a newline just for safety
159 if not src.endswith('\n'): # add a newline just for safety
160 src += '\n' # this is needed in old versions of Python
160 src += '\n' # this is needed in old versions of Python
161 try:
161 try:
162 code = compile(src, '<string>', 'single')
162 code = compile(src, '<string>', 'single')
163 # print >> sys.stderr, 'Compiling %s' % src
163 # print >> sys.stderr, 'Compiling %s' % src
164 exec code in evaldict
164 exec(code, evaldict)
165 except:
165 except:
166 print('Error in generated code:', file=sys.stderr)
166 print('Error in generated code:', file=sys.stderr)
167 print(src, file=sys.stderr)
167 print(src, file=sys.stderr)
168 raise
168 raise
169 func = evaldict[name]
169 func = evaldict[name]
170 if addsource:
170 if addsource:
171 attrs['__source__'] = src
171 attrs['__source__'] = src
172 self.update(func, **attrs)
172 self.update(func, **attrs)
173 return func
173 return func
174
174
175 @classmethod
175 @classmethod
176 def create(cls, obj, body, evaldict, defaults=None,
176 def create(cls, obj, body, evaldict, defaults=None,
177 doc=None, module=None, addsource=True, **attrs):
177 doc=None, module=None, addsource=True, **attrs):
178 """
178 """
179 Create a function from the strings name, signature and body.
179 Create a function from the strings name, signature and body.
180 evaldict is the evaluation dictionary. If addsource is true an attribute
180 evaldict is the evaluation dictionary. If addsource is true an attribute
181 __source__ is added to the result. The attributes attrs are added,
181 __source__ is added to the result. The attributes attrs are added,
182 if any.
182 if any.
183 """
183 """
184 if isinstance(obj, str): # "name(signature)"
184 if isinstance(obj, str): # "name(signature)"
185 name, rest = obj.strip().split('(', 1)
185 name, rest = obj.strip().split('(', 1)
186 signature = rest[:-1] #strip a right parens
186 signature = rest[:-1] #strip a right parens
187 func = None
187 func = None
188 else: # a function
188 else: # a function
189 name = None
189 name = None
190 signature = None
190 signature = None
191 func = obj
191 func = obj
192 self = cls(func, name, signature, defaults, doc, module)
192 self = cls(func, name, signature, defaults, doc, module)
193 ibody = '\n'.join(' ' + line for line in body.splitlines())
193 ibody = '\n'.join(' ' + line for line in body.splitlines())
194 return self.make('def %(name)s(%(signature)s):\n' + ibody,
194 return self.make('def %(name)s(%(signature)s):\n' + ibody,
195 evaldict, addsource, **attrs)
195 evaldict, addsource, **attrs)
196
196
197 def decorator(caller, func=None):
197 def decorator(caller, func=None):
198 """
198 """
199 decorator(caller) converts a caller function into a decorator;
199 decorator(caller) converts a caller function into a decorator;
200 decorator(caller, func) decorates a function using a caller.
200 decorator(caller, func) decorates a function using a caller.
201 """
201 """
202 if func is not None: # returns a decorated function
202 if func is not None: # returns a decorated function
203 evaldict = func.func_globals.copy()
203 evaldict = func.func_globals.copy()
204 evaldict['_call_'] = caller
204 evaldict['_call_'] = caller
205 evaldict['_func_'] = func
205 evaldict['_func_'] = func
206 return FunctionMaker.create(
206 return FunctionMaker.create(
207 func, "return _call_(_func_, %(shortsignature)s)",
207 func, "return _call_(_func_, %(shortsignature)s)",
208 evaldict, undecorated=func, __wrapped__=func)
208 evaldict, undecorated=func, __wrapped__=func)
209 else: # returns a decorator
209 else: # returns a decorator
210 if isinstance(caller, partial):
210 if isinstance(caller, partial):
211 return partial(decorator, caller)
211 return partial(decorator, caller)
212 # otherwise assume caller is a function
212 # otherwise assume caller is a function
213 first = inspect.getargspec(caller)[0][0] # first arg
213 first = inspect.getargspec(caller)[0][0] # first arg
214 evaldict = caller.func_globals.copy()
214 evaldict = caller.func_globals.copy()
215 evaldict['_call_'] = caller
215 evaldict['_call_'] = caller
216 evaldict['decorator'] = decorator
216 evaldict['decorator'] = decorator
217 return FunctionMaker.create(
217 return FunctionMaker.create(
218 '%s(%s)' % (caller.__name__, first),
218 '%s(%s)' % (caller.__name__, first),
219 'return decorator(_call_, %s)' % first,
219 'return decorator(_call_, %s)' % first,
220 evaldict, undecorated=caller, __wrapped__=caller,
220 evaldict, undecorated=caller, __wrapped__=caller,
221 doc=caller.__doc__, module=caller.__module__)
221 doc=caller.__doc__, module=caller.__module__)
@@ -1,789 +1,789 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """An interactive kernel that talks to frontends over 0MQ."""
2 """An interactive kernel that talks to frontends over 0MQ."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Imports
5 # Imports
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 # Standard library imports
9 # Standard library imports
10 import __builtin__
10 import __builtin__
11 import sys
11 import sys
12 import time
12 import time
13 import traceback
13 import traceback
14 import logging
14 import logging
15 import uuid
15 import uuid
16
16
17 from datetime import datetime
17 from datetime import datetime
18 from signal import (
18 from signal import (
19 signal, default_int_handler, SIGINT
19 signal, default_int_handler, SIGINT
20 )
20 )
21
21
22 # System library imports
22 # System library imports
23 import zmq
23 import zmq
24 from zmq.eventloop import ioloop
24 from zmq.eventloop import ioloop
25 from zmq.eventloop.zmqstream import ZMQStream
25 from zmq.eventloop.zmqstream import ZMQStream
26
26
27 # Local imports
27 # Local imports
28 from IPython.config.configurable import Configurable
28 from IPython.config.configurable import Configurable
29 from IPython.core.error import StdinNotImplementedError
29 from IPython.core.error import StdinNotImplementedError
30 from IPython.core import release
30 from IPython.core import release
31 from IPython.utils import py3compat
31 from IPython.utils import py3compat
32 from IPython.utils.jsonutil import json_clean
32 from IPython.utils.jsonutil import json_clean
33 from IPython.utils.traitlets import (
33 from IPython.utils.traitlets import (
34 Any, Instance, Float, Dict, List, Set, Integer, Unicode,
34 Any, Instance, Float, Dict, List, Set, Integer, Unicode,
35 Type
35 Type
36 )
36 )
37
37
38 from .serialize import serialize_object, unpack_apply_message
38 from .serialize import serialize_object, unpack_apply_message
39 from .session import Session
39 from .session import Session
40 from .zmqshell import ZMQInteractiveShell
40 from .zmqshell import ZMQInteractiveShell
41
41
42
42
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44 # Main kernel class
44 # Main kernel class
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 protocol_version = list(release.kernel_protocol_version_info)
47 protocol_version = list(release.kernel_protocol_version_info)
48 ipython_version = list(release.version_info)
48 ipython_version = list(release.version_info)
49 language_version = list(sys.version_info[:3])
49 language_version = list(sys.version_info[:3])
50
50
51
51
52 class Kernel(Configurable):
52 class Kernel(Configurable):
53
53
54 #---------------------------------------------------------------------------
54 #---------------------------------------------------------------------------
55 # Kernel interface
55 # Kernel interface
56 #---------------------------------------------------------------------------
56 #---------------------------------------------------------------------------
57
57
58 # attribute to override with a GUI
58 # attribute to override with a GUI
59 eventloop = Any(None)
59 eventloop = Any(None)
60 def _eventloop_changed(self, name, old, new):
60 def _eventloop_changed(self, name, old, new):
61 """schedule call to eventloop from IOLoop"""
61 """schedule call to eventloop from IOLoop"""
62 loop = ioloop.IOLoop.instance()
62 loop = ioloop.IOLoop.instance()
63 loop.add_timeout(time.time()+0.1, self.enter_eventloop)
63 loop.add_timeout(time.time()+0.1, self.enter_eventloop)
64
64
65 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
65 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
66 shell_class = Type(ZMQInteractiveShell)
66 shell_class = Type(ZMQInteractiveShell)
67
67
68 session = Instance(Session)
68 session = Instance(Session)
69 profile_dir = Instance('IPython.core.profiledir.ProfileDir')
69 profile_dir = Instance('IPython.core.profiledir.ProfileDir')
70 shell_streams = List()
70 shell_streams = List()
71 control_stream = Instance(ZMQStream)
71 control_stream = Instance(ZMQStream)
72 iopub_socket = Instance(zmq.Socket)
72 iopub_socket = Instance(zmq.Socket)
73 stdin_socket = Instance(zmq.Socket)
73 stdin_socket = Instance(zmq.Socket)
74 log = Instance(logging.Logger)
74 log = Instance(logging.Logger)
75
75
76 user_module = Any()
76 user_module = Any()
77 def _user_module_changed(self, name, old, new):
77 def _user_module_changed(self, name, old, new):
78 if self.shell is not None:
78 if self.shell is not None:
79 self.shell.user_module = new
79 self.shell.user_module = new
80
80
81 user_ns = Instance(dict, args=None, allow_none=True)
81 user_ns = Instance(dict, args=None, allow_none=True)
82 def _user_ns_changed(self, name, old, new):
82 def _user_ns_changed(self, name, old, new):
83 if self.shell is not None:
83 if self.shell is not None:
84 self.shell.user_ns = new
84 self.shell.user_ns = new
85 self.shell.init_user_ns()
85 self.shell.init_user_ns()
86
86
87 # identities:
87 # identities:
88 int_id = Integer(-1)
88 int_id = Integer(-1)
89 ident = Unicode()
89 ident = Unicode()
90
90
91 def _ident_default(self):
91 def _ident_default(self):
92 return unicode(uuid.uuid4())
92 return unicode(uuid.uuid4())
93
93
94
94
95 # Private interface
95 # Private interface
96
96
97 # Time to sleep after flushing the stdout/err buffers in each execute
97 # Time to sleep after flushing the stdout/err buffers in each execute
98 # cycle. While this introduces a hard limit on the minimal latency of the
98 # cycle. While this introduces a hard limit on the minimal latency of the
99 # execute cycle, it helps prevent output synchronization problems for
99 # execute cycle, it helps prevent output synchronization problems for
100 # clients.
100 # clients.
101 # Units are in seconds. The minimum zmq latency on local host is probably
101 # Units are in seconds. The minimum zmq latency on local host is probably
102 # ~150 microseconds, set this to 500us for now. We may need to increase it
102 # ~150 microseconds, set this to 500us for now. We may need to increase it
103 # a little if it's not enough after more interactive testing.
103 # a little if it's not enough after more interactive testing.
104 _execute_sleep = Float(0.0005, config=True)
104 _execute_sleep = Float(0.0005, config=True)
105
105
106 # Frequency of the kernel's event loop.
106 # Frequency of the kernel's event loop.
107 # Units are in seconds, kernel subclasses for GUI toolkits may need to
107 # Units are in seconds, kernel subclasses for GUI toolkits may need to
108 # adapt to milliseconds.
108 # adapt to milliseconds.
109 _poll_interval = Float(0.05, config=True)
109 _poll_interval = Float(0.05, config=True)
110
110
111 # If the shutdown was requested over the network, we leave here the
111 # If the shutdown was requested over the network, we leave here the
112 # necessary reply message so it can be sent by our registered atexit
112 # necessary reply message so it can be sent by our registered atexit
113 # handler. This ensures that the reply is only sent to clients truly at
113 # handler. This ensures that the reply is only sent to clients truly at
114 # the end of our shutdown process (which happens after the underlying
114 # the end of our shutdown process (which happens after the underlying
115 # IPython shell's own shutdown).
115 # IPython shell's own shutdown).
116 _shutdown_message = None
116 _shutdown_message = None
117
117
118 # This is a dict of port number that the kernel is listening on. It is set
118 # This is a dict of port number that the kernel is listening on. It is set
119 # by record_ports and used by connect_request.
119 # by record_ports and used by connect_request.
120 _recorded_ports = Dict()
120 _recorded_ports = Dict()
121
121
122 # A reference to the Python builtin 'raw_input' function.
122 # A reference to the Python builtin 'raw_input' function.
123 # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3)
123 # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3)
124 _sys_raw_input = Any()
124 _sys_raw_input = Any()
125 _sys_eval_input = Any()
125 _sys_eval_input = Any()
126
126
127 # set of aborted msg_ids
127 # set of aborted msg_ids
128 aborted = Set()
128 aborted = Set()
129
129
130
130
131 def __init__(self, **kwargs):
131 def __init__(self, **kwargs):
132 super(Kernel, self).__init__(**kwargs)
132 super(Kernel, self).__init__(**kwargs)
133
133
134 # Initialize the InteractiveShell subclass
134 # Initialize the InteractiveShell subclass
135 self.shell = self.shell_class.instance(parent=self,
135 self.shell = self.shell_class.instance(parent=self,
136 profile_dir = self.profile_dir,
136 profile_dir = self.profile_dir,
137 user_module = self.user_module,
137 user_module = self.user_module,
138 user_ns = self.user_ns,
138 user_ns = self.user_ns,
139 kernel = self,
139 kernel = self,
140 )
140 )
141 self.shell.displayhook.session = self.session
141 self.shell.displayhook.session = self.session
142 self.shell.displayhook.pub_socket = self.iopub_socket
142 self.shell.displayhook.pub_socket = self.iopub_socket
143 self.shell.displayhook.topic = self._topic('pyout')
143 self.shell.displayhook.topic = self._topic('pyout')
144 self.shell.display_pub.session = self.session
144 self.shell.display_pub.session = self.session
145 self.shell.display_pub.pub_socket = self.iopub_socket
145 self.shell.display_pub.pub_socket = self.iopub_socket
146 self.shell.data_pub.session = self.session
146 self.shell.data_pub.session = self.session
147 self.shell.data_pub.pub_socket = self.iopub_socket
147 self.shell.data_pub.pub_socket = self.iopub_socket
148
148
149 # TMP - hack while developing
149 # TMP - hack while developing
150 self.shell._reply_content = None
150 self.shell._reply_content = None
151
151
152 # Build dict of handlers for message types
152 # Build dict of handlers for message types
153 msg_types = [ 'execute_request', 'complete_request',
153 msg_types = [ 'execute_request', 'complete_request',
154 'object_info_request', 'history_request',
154 'object_info_request', 'history_request',
155 'kernel_info_request',
155 'kernel_info_request',
156 'connect_request', 'shutdown_request',
156 'connect_request', 'shutdown_request',
157 'apply_request',
157 'apply_request',
158 ]
158 ]
159 self.shell_handlers = {}
159 self.shell_handlers = {}
160 for msg_type in msg_types:
160 for msg_type in msg_types:
161 self.shell_handlers[msg_type] = getattr(self, msg_type)
161 self.shell_handlers[msg_type] = getattr(self, msg_type)
162
162
163 comm_msg_types = [ 'comm_open', 'comm_msg', 'comm_close' ]
163 comm_msg_types = [ 'comm_open', 'comm_msg', 'comm_close' ]
164 comm_manager = self.shell.comm_manager
164 comm_manager = self.shell.comm_manager
165 for msg_type in comm_msg_types:
165 for msg_type in comm_msg_types:
166 self.shell_handlers[msg_type] = getattr(comm_manager, msg_type)
166 self.shell_handlers[msg_type] = getattr(comm_manager, msg_type)
167
167
168 control_msg_types = msg_types + [ 'clear_request', 'abort_request' ]
168 control_msg_types = msg_types + [ 'clear_request', 'abort_request' ]
169 self.control_handlers = {}
169 self.control_handlers = {}
170 for msg_type in control_msg_types:
170 for msg_type in control_msg_types:
171 self.control_handlers[msg_type] = getattr(self, msg_type)
171 self.control_handlers[msg_type] = getattr(self, msg_type)
172
172
173
173
174 def dispatch_control(self, msg):
174 def dispatch_control(self, msg):
175 """dispatch control requests"""
175 """dispatch control requests"""
176 idents,msg = self.session.feed_identities(msg, copy=False)
176 idents,msg = self.session.feed_identities(msg, copy=False)
177 try:
177 try:
178 msg = self.session.unserialize(msg, content=True, copy=False)
178 msg = self.session.unserialize(msg, content=True, copy=False)
179 except:
179 except:
180 self.log.error("Invalid Control Message", exc_info=True)
180 self.log.error("Invalid Control Message", exc_info=True)
181 return
181 return
182
182
183 self.log.debug("Control received: %s", msg)
183 self.log.debug("Control received: %s", msg)
184
184
185 header = msg['header']
185 header = msg['header']
186 msg_id = header['msg_id']
186 msg_id = header['msg_id']
187 msg_type = header['msg_type']
187 msg_type = header['msg_type']
188
188
189 handler = self.control_handlers.get(msg_type, None)
189 handler = self.control_handlers.get(msg_type, None)
190 if handler is None:
190 if handler is None:
191 self.log.error("UNKNOWN CONTROL MESSAGE TYPE: %r", msg_type)
191 self.log.error("UNKNOWN CONTROL MESSAGE TYPE: %r", msg_type)
192 else:
192 else:
193 try:
193 try:
194 handler(self.control_stream, idents, msg)
194 handler(self.control_stream, idents, msg)
195 except Exception:
195 except Exception:
196 self.log.error("Exception in control handler:", exc_info=True)
196 self.log.error("Exception in control handler:", exc_info=True)
197
197
198 def dispatch_shell(self, stream, msg):
198 def dispatch_shell(self, stream, msg):
199 """dispatch shell requests"""
199 """dispatch shell requests"""
200 # flush control requests first
200 # flush control requests first
201 if self.control_stream:
201 if self.control_stream:
202 self.control_stream.flush()
202 self.control_stream.flush()
203
203
204 idents,msg = self.session.feed_identities(msg, copy=False)
204 idents,msg = self.session.feed_identities(msg, copy=False)
205 try:
205 try:
206 msg = self.session.unserialize(msg, content=True, copy=False)
206 msg = self.session.unserialize(msg, content=True, copy=False)
207 except:
207 except:
208 self.log.error("Invalid Message", exc_info=True)
208 self.log.error("Invalid Message", exc_info=True)
209 return
209 return
210
210
211 header = msg['header']
211 header = msg['header']
212 msg_id = header['msg_id']
212 msg_id = header['msg_id']
213 msg_type = msg['header']['msg_type']
213 msg_type = msg['header']['msg_type']
214
214
215 # Print some info about this message and leave a '--->' marker, so it's
215 # Print some info about this message and leave a '--->' marker, so it's
216 # easier to trace visually the message chain when debugging. Each
216 # easier to trace visually the message chain when debugging. Each
217 # handler prints its message at the end.
217 # handler prints its message at the end.
218 self.log.debug('\n*** MESSAGE TYPE:%s***', msg_type)
218 self.log.debug('\n*** MESSAGE TYPE:%s***', msg_type)
219 self.log.debug(' Content: %s\n --->\n ', msg['content'])
219 self.log.debug(' Content: %s\n --->\n ', msg['content'])
220
220
221 if msg_id in self.aborted:
221 if msg_id in self.aborted:
222 self.aborted.remove(msg_id)
222 self.aborted.remove(msg_id)
223 # is it safe to assume a msg_id will not be resubmitted?
223 # is it safe to assume a msg_id will not be resubmitted?
224 reply_type = msg_type.split('_')[0] + '_reply'
224 reply_type = msg_type.split('_')[0] + '_reply'
225 status = {'status' : 'aborted'}
225 status = {'status' : 'aborted'}
226 md = {'engine' : self.ident}
226 md = {'engine' : self.ident}
227 md.update(status)
227 md.update(status)
228 reply_msg = self.session.send(stream, reply_type, metadata=md,
228 reply_msg = self.session.send(stream, reply_type, metadata=md,
229 content=status, parent=msg, ident=idents)
229 content=status, parent=msg, ident=idents)
230 return
230 return
231
231
232 handler = self.shell_handlers.get(msg_type, None)
232 handler = self.shell_handlers.get(msg_type, None)
233 if handler is None:
233 if handler is None:
234 self.log.error("UNKNOWN MESSAGE TYPE: %r", msg_type)
234 self.log.error("UNKNOWN MESSAGE TYPE: %r", msg_type)
235 else:
235 else:
236 # ensure default_int_handler during handler call
236 # ensure default_int_handler during handler call
237 sig = signal(SIGINT, default_int_handler)
237 sig = signal(SIGINT, default_int_handler)
238 try:
238 try:
239 handler(stream, idents, msg)
239 handler(stream, idents, msg)
240 except Exception:
240 except Exception:
241 self.log.error("Exception in message handler:", exc_info=True)
241 self.log.error("Exception in message handler:", exc_info=True)
242 finally:
242 finally:
243 signal(SIGINT, sig)
243 signal(SIGINT, sig)
244
244
245 def enter_eventloop(self):
245 def enter_eventloop(self):
246 """enter eventloop"""
246 """enter eventloop"""
247 self.log.info("entering eventloop")
247 self.log.info("entering eventloop")
248 # restore default_int_handler
248 # restore default_int_handler
249 signal(SIGINT, default_int_handler)
249 signal(SIGINT, default_int_handler)
250 while self.eventloop is not None:
250 while self.eventloop is not None:
251 try:
251 try:
252 self.eventloop(self)
252 self.eventloop(self)
253 except KeyboardInterrupt:
253 except KeyboardInterrupt:
254 # Ctrl-C shouldn't crash the kernel
254 # Ctrl-C shouldn't crash the kernel
255 self.log.error("KeyboardInterrupt caught in kernel")
255 self.log.error("KeyboardInterrupt caught in kernel")
256 continue
256 continue
257 else:
257 else:
258 # eventloop exited cleanly, this means we should stop (right?)
258 # eventloop exited cleanly, this means we should stop (right?)
259 self.eventloop = None
259 self.eventloop = None
260 break
260 break
261 self.log.info("exiting eventloop")
261 self.log.info("exiting eventloop")
262
262
263 def start(self):
263 def start(self):
264 """register dispatchers for streams"""
264 """register dispatchers for streams"""
265 self.shell.exit_now = False
265 self.shell.exit_now = False
266 if self.control_stream:
266 if self.control_stream:
267 self.control_stream.on_recv(self.dispatch_control, copy=False)
267 self.control_stream.on_recv(self.dispatch_control, copy=False)
268
268
269 def make_dispatcher(stream):
269 def make_dispatcher(stream):
270 def dispatcher(msg):
270 def dispatcher(msg):
271 return self.dispatch_shell(stream, msg)
271 return self.dispatch_shell(stream, msg)
272 return dispatcher
272 return dispatcher
273
273
274 for s in self.shell_streams:
274 for s in self.shell_streams:
275 s.on_recv(make_dispatcher(s), copy=False)
275 s.on_recv(make_dispatcher(s), copy=False)
276
276
277 # publish idle status
277 # publish idle status
278 self._publish_status('starting')
278 self._publish_status('starting')
279
279
280 def do_one_iteration(self):
280 def do_one_iteration(self):
281 """step eventloop just once"""
281 """step eventloop just once"""
282 if self.control_stream:
282 if self.control_stream:
283 self.control_stream.flush()
283 self.control_stream.flush()
284 for stream in self.shell_streams:
284 for stream in self.shell_streams:
285 # handle at most one request per iteration
285 # handle at most one request per iteration
286 stream.flush(zmq.POLLIN, 1)
286 stream.flush(zmq.POLLIN, 1)
287 stream.flush(zmq.POLLOUT)
287 stream.flush(zmq.POLLOUT)
288
288
289
289
290 def record_ports(self, ports):
290 def record_ports(self, ports):
291 """Record the ports that this kernel is using.
291 """Record the ports that this kernel is using.
292
292
293 The creator of the Kernel instance must call this methods if they
293 The creator of the Kernel instance must call this methods if they
294 want the :meth:`connect_request` method to return the port numbers.
294 want the :meth:`connect_request` method to return the port numbers.
295 """
295 """
296 self._recorded_ports = ports
296 self._recorded_ports = ports
297
297
298 #---------------------------------------------------------------------------
298 #---------------------------------------------------------------------------
299 # Kernel request handlers
299 # Kernel request handlers
300 #---------------------------------------------------------------------------
300 #---------------------------------------------------------------------------
301
301
302 def _make_metadata(self, other=None):
302 def _make_metadata(self, other=None):
303 """init metadata dict, for execute/apply_reply"""
303 """init metadata dict, for execute/apply_reply"""
304 new_md = {
304 new_md = {
305 'dependencies_met' : True,
305 'dependencies_met' : True,
306 'engine' : self.ident,
306 'engine' : self.ident,
307 'started': datetime.now(),
307 'started': datetime.now(),
308 }
308 }
309 if other:
309 if other:
310 new_md.update(other)
310 new_md.update(other)
311 return new_md
311 return new_md
312
312
313 def _publish_pyin(self, code, parent, execution_count):
313 def _publish_pyin(self, code, parent, execution_count):
314 """Publish the code request on the pyin stream."""
314 """Publish the code request on the pyin stream."""
315
315
316 self.session.send(self.iopub_socket, u'pyin',
316 self.session.send(self.iopub_socket, u'pyin',
317 {u'code':code, u'execution_count': execution_count},
317 {u'code':code, u'execution_count': execution_count},
318 parent=parent, ident=self._topic('pyin')
318 parent=parent, ident=self._topic('pyin')
319 )
319 )
320
320
321 def _publish_status(self, status, parent=None):
321 def _publish_status(self, status, parent=None):
322 """send status (busy/idle) on IOPub"""
322 """send status (busy/idle) on IOPub"""
323 self.session.send(self.iopub_socket,
323 self.session.send(self.iopub_socket,
324 u'status',
324 u'status',
325 {u'execution_state': status},
325 {u'execution_state': status},
326 parent=parent,
326 parent=parent,
327 ident=self._topic('status'),
327 ident=self._topic('status'),
328 )
328 )
329
329
330
330
331 def execute_request(self, stream, ident, parent):
331 def execute_request(self, stream, ident, parent):
332 """handle an execute_request"""
332 """handle an execute_request"""
333
333
334 self._publish_status(u'busy', parent)
334 self._publish_status(u'busy', parent)
335
335
336 try:
336 try:
337 content = parent[u'content']
337 content = parent[u'content']
338 code = content[u'code']
338 code = content[u'code']
339 silent = content[u'silent']
339 silent = content[u'silent']
340 store_history = content.get(u'store_history', not silent)
340 store_history = content.get(u'store_history', not silent)
341 except:
341 except:
342 self.log.error("Got bad msg: ")
342 self.log.error("Got bad msg: ")
343 self.log.error("%s", parent)
343 self.log.error("%s", parent)
344 return
344 return
345
345
346 md = self._make_metadata(parent['metadata'])
346 md = self._make_metadata(parent['metadata'])
347
347
348 shell = self.shell # we'll need this a lot here
348 shell = self.shell # we'll need this a lot here
349
349
350 # Replace raw_input. Note that is not sufficient to replace
350 # Replace raw_input. Note that is not sufficient to replace
351 # raw_input in the user namespace.
351 # raw_input in the user namespace.
352 if content.get('allow_stdin', False):
352 if content.get('allow_stdin', False):
353 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
353 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
354 input = lambda prompt='': eval(raw_input(prompt))
354 input = lambda prompt='': eval(raw_input(prompt))
355 else:
355 else:
356 raw_input = input = lambda prompt='' : self._no_raw_input()
356 raw_input = input = lambda prompt='' : self._no_raw_input()
357
357
358 if py3compat.PY3:
358 if py3compat.PY3:
359 self._sys_raw_input = __builtin__.input
359 self._sys_raw_input = __builtin__.input
360 __builtin__.input = raw_input
360 __builtin__.input = raw_input
361 else:
361 else:
362 self._sys_raw_input = __builtin__.raw_input
362 self._sys_raw_input = __builtin__.raw_input
363 self._sys_eval_input = __builtin__.input
363 self._sys_eval_input = __builtin__.input
364 __builtin__.raw_input = raw_input
364 __builtin__.raw_input = raw_input
365 __builtin__.input = input
365 __builtin__.input = input
366
366
367 # Set the parent message of the display hook and out streams.
367 # Set the parent message of the display hook and out streams.
368 shell.set_parent(parent)
368 shell.set_parent(parent)
369
369
370 # Re-broadcast our input for the benefit of listening clients, and
370 # Re-broadcast our input for the benefit of listening clients, and
371 # start computing output
371 # start computing output
372 if not silent:
372 if not silent:
373 self._publish_pyin(code, parent, shell.execution_count)
373 self._publish_pyin(code, parent, shell.execution_count)
374
374
375 reply_content = {}
375 reply_content = {}
376 try:
376 try:
377 # FIXME: the shell calls the exception handler itself.
377 # FIXME: the shell calls the exception handler itself.
378 shell.run_cell(code, store_history=store_history, silent=silent)
378 shell.run_cell(code, store_history=store_history, silent=silent)
379 except:
379 except:
380 status = u'error'
380 status = u'error'
381 # FIXME: this code right now isn't being used yet by default,
381 # FIXME: this code right now isn't being used yet by default,
382 # because the run_cell() call above directly fires off exception
382 # because the run_cell() call above directly fires off exception
383 # reporting. This code, therefore, is only active in the scenario
383 # reporting. This code, therefore, is only active in the scenario
384 # where runlines itself has an unhandled exception. We need to
384 # where runlines itself has an unhandled exception. We need to
385 # uniformize this, for all exception construction to come from a
385 # uniformize this, for all exception construction to come from a
386 # single location in the codbase.
386 # single location in the codbase.
387 etype, evalue, tb = sys.exc_info()
387 etype, evalue, tb = sys.exc_info()
388 tb_list = traceback.format_exception(etype, evalue, tb)
388 tb_list = traceback.format_exception(etype, evalue, tb)
389 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
389 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
390 else:
390 else:
391 status = u'ok'
391 status = u'ok'
392 finally:
392 finally:
393 # Restore raw_input.
393 # Restore raw_input.
394 if py3compat.PY3:
394 if py3compat.PY3:
395 __builtin__.input = self._sys_raw_input
395 __builtin__.input = self._sys_raw_input
396 else:
396 else:
397 __builtin__.raw_input = self._sys_raw_input
397 __builtin__.raw_input = self._sys_raw_input
398 __builtin__.input = self._sys_eval_input
398 __builtin__.input = self._sys_eval_input
399
399
400 reply_content[u'status'] = status
400 reply_content[u'status'] = status
401
401
402 # Return the execution counter so clients can display prompts
402 # Return the execution counter so clients can display prompts
403 reply_content['execution_count'] = shell.execution_count - 1
403 reply_content['execution_count'] = shell.execution_count - 1
404
404
405 # FIXME - fish exception info out of shell, possibly left there by
405 # FIXME - fish exception info out of shell, possibly left there by
406 # runlines. We'll need to clean up this logic later.
406 # runlines. We'll need to clean up this logic later.
407 if shell._reply_content is not None:
407 if shell._reply_content is not None:
408 reply_content.update(shell._reply_content)
408 reply_content.update(shell._reply_content)
409 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='execute')
409 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='execute')
410 reply_content['engine_info'] = e_info
410 reply_content['engine_info'] = e_info
411 # reset after use
411 # reset after use
412 shell._reply_content = None
412 shell._reply_content = None
413
413
414 if 'traceback' in reply_content:
414 if 'traceback' in reply_content:
415 self.log.info("Exception in execute request:\n%s", '\n'.join(reply_content['traceback']))
415 self.log.info("Exception in execute request:\n%s", '\n'.join(reply_content['traceback']))
416
416
417
417
418 # At this point, we can tell whether the main code execution succeeded
418 # At this point, we can tell whether the main code execution succeeded
419 # or not. If it did, we proceed to evaluate user_variables/expressions
419 # or not. If it did, we proceed to evaluate user_variables/expressions
420 if reply_content['status'] == 'ok':
420 if reply_content['status'] == 'ok':
421 reply_content[u'user_variables'] = \
421 reply_content[u'user_variables'] = \
422 shell.user_variables(content.get(u'user_variables', []))
422 shell.user_variables(content.get(u'user_variables', []))
423 reply_content[u'user_expressions'] = \
423 reply_content[u'user_expressions'] = \
424 shell.user_expressions(content.get(u'user_expressions', {}))
424 shell.user_expressions(content.get(u'user_expressions', {}))
425 else:
425 else:
426 # If there was an error, don't even try to compute variables or
426 # If there was an error, don't even try to compute variables or
427 # expressions
427 # expressions
428 reply_content[u'user_variables'] = {}
428 reply_content[u'user_variables'] = {}
429 reply_content[u'user_expressions'] = {}
429 reply_content[u'user_expressions'] = {}
430
430
431 # Payloads should be retrieved regardless of outcome, so we can both
431 # Payloads should be retrieved regardless of outcome, so we can both
432 # recover partial output (that could have been generated early in a
432 # recover partial output (that could have been generated early in a
433 # block, before an error) and clear the payload system always.
433 # block, before an error) and clear the payload system always.
434 reply_content[u'payload'] = shell.payload_manager.read_payload()
434 reply_content[u'payload'] = shell.payload_manager.read_payload()
435 # Be agressive about clearing the payload because we don't want
435 # Be agressive about clearing the payload because we don't want
436 # it to sit in memory until the next execute_request comes in.
436 # it to sit in memory until the next execute_request comes in.
437 shell.payload_manager.clear_payload()
437 shell.payload_manager.clear_payload()
438
438
439 # Flush output before sending the reply.
439 # Flush output before sending the reply.
440 sys.stdout.flush()
440 sys.stdout.flush()
441 sys.stderr.flush()
441 sys.stderr.flush()
442 # FIXME: on rare occasions, the flush doesn't seem to make it to the
442 # FIXME: on rare occasions, the flush doesn't seem to make it to the
443 # clients... This seems to mitigate the problem, but we definitely need
443 # clients... This seems to mitigate the problem, but we definitely need
444 # to better understand what's going on.
444 # to better understand what's going on.
445 if self._execute_sleep:
445 if self._execute_sleep:
446 time.sleep(self._execute_sleep)
446 time.sleep(self._execute_sleep)
447
447
448 # Send the reply.
448 # Send the reply.
449 reply_content = json_clean(reply_content)
449 reply_content = json_clean(reply_content)
450
450
451 md['status'] = reply_content['status']
451 md['status'] = reply_content['status']
452 if reply_content['status'] == 'error' and \
452 if reply_content['status'] == 'error' and \
453 reply_content['ename'] == 'UnmetDependency':
453 reply_content['ename'] == 'UnmetDependency':
454 md['dependencies_met'] = False
454 md['dependencies_met'] = False
455
455
456 reply_msg = self.session.send(stream, u'execute_reply',
456 reply_msg = self.session.send(stream, u'execute_reply',
457 reply_content, parent, metadata=md,
457 reply_content, parent, metadata=md,
458 ident=ident)
458 ident=ident)
459
459
460 self.log.debug("%s", reply_msg)
460 self.log.debug("%s", reply_msg)
461
461
462 if not silent and reply_msg['content']['status'] == u'error':
462 if not silent and reply_msg['content']['status'] == u'error':
463 self._abort_queues()
463 self._abort_queues()
464
464
465 self._publish_status(u'idle', parent)
465 self._publish_status(u'idle', parent)
466
466
467 def complete_request(self, stream, ident, parent):
467 def complete_request(self, stream, ident, parent):
468 txt, matches = self._complete(parent)
468 txt, matches = self._complete(parent)
469 matches = {'matches' : matches,
469 matches = {'matches' : matches,
470 'matched_text' : txt,
470 'matched_text' : txt,
471 'status' : 'ok'}
471 'status' : 'ok'}
472 matches = json_clean(matches)
472 matches = json_clean(matches)
473 completion_msg = self.session.send(stream, 'complete_reply',
473 completion_msg = self.session.send(stream, 'complete_reply',
474 matches, parent, ident)
474 matches, parent, ident)
475 self.log.debug("%s", completion_msg)
475 self.log.debug("%s", completion_msg)
476
476
477 def object_info_request(self, stream, ident, parent):
477 def object_info_request(self, stream, ident, parent):
478 content = parent['content']
478 content = parent['content']
479 object_info = self.shell.object_inspect(content['oname'],
479 object_info = self.shell.object_inspect(content['oname'],
480 detail_level = content.get('detail_level', 0)
480 detail_level = content.get('detail_level', 0)
481 )
481 )
482 # Before we send this object over, we scrub it for JSON usage
482 # Before we send this object over, we scrub it for JSON usage
483 oinfo = json_clean(object_info)
483 oinfo = json_clean(object_info)
484 msg = self.session.send(stream, 'object_info_reply',
484 msg = self.session.send(stream, 'object_info_reply',
485 oinfo, parent, ident)
485 oinfo, parent, ident)
486 self.log.debug("%s", msg)
486 self.log.debug("%s", msg)
487
487
488 def history_request(self, stream, ident, parent):
488 def history_request(self, stream, ident, parent):
489 # We need to pull these out, as passing **kwargs doesn't work with
489 # We need to pull these out, as passing **kwargs doesn't work with
490 # unicode keys before Python 2.6.5.
490 # unicode keys before Python 2.6.5.
491 hist_access_type = parent['content']['hist_access_type']
491 hist_access_type = parent['content']['hist_access_type']
492 raw = parent['content']['raw']
492 raw = parent['content']['raw']
493 output = parent['content']['output']
493 output = parent['content']['output']
494 if hist_access_type == 'tail':
494 if hist_access_type == 'tail':
495 n = parent['content']['n']
495 n = parent['content']['n']
496 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
496 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
497 include_latest=True)
497 include_latest=True)
498
498
499 elif hist_access_type == 'range':
499 elif hist_access_type == 'range':
500 session = parent['content']['session']
500 session = parent['content']['session']
501 start = parent['content']['start']
501 start = parent['content']['start']
502 stop = parent['content']['stop']
502 stop = parent['content']['stop']
503 hist = self.shell.history_manager.get_range(session, start, stop,
503 hist = self.shell.history_manager.get_range(session, start, stop,
504 raw=raw, output=output)
504 raw=raw, output=output)
505
505
506 elif hist_access_type == 'search':
506 elif hist_access_type == 'search':
507 n = parent['content'].get('n')
507 n = parent['content'].get('n')
508 unique = parent['content'].get('unique', False)
508 unique = parent['content'].get('unique', False)
509 pattern = parent['content']['pattern']
509 pattern = parent['content']['pattern']
510 hist = self.shell.history_manager.search(
510 hist = self.shell.history_manager.search(
511 pattern, raw=raw, output=output, n=n, unique=unique)
511 pattern, raw=raw, output=output, n=n, unique=unique)
512
512
513 else:
513 else:
514 hist = []
514 hist = []
515 hist = list(hist)
515 hist = list(hist)
516 content = {'history' : hist}
516 content = {'history' : hist}
517 content = json_clean(content)
517 content = json_clean(content)
518 msg = self.session.send(stream, 'history_reply',
518 msg = self.session.send(stream, 'history_reply',
519 content, parent, ident)
519 content, parent, ident)
520 self.log.debug("Sending history reply with %i entries", len(hist))
520 self.log.debug("Sending history reply with %i entries", len(hist))
521
521
522 def connect_request(self, stream, ident, parent):
522 def connect_request(self, stream, ident, parent):
523 if self._recorded_ports is not None:
523 if self._recorded_ports is not None:
524 content = self._recorded_ports.copy()
524 content = self._recorded_ports.copy()
525 else:
525 else:
526 content = {}
526 content = {}
527 msg = self.session.send(stream, 'connect_reply',
527 msg = self.session.send(stream, 'connect_reply',
528 content, parent, ident)
528 content, parent, ident)
529 self.log.debug("%s", msg)
529 self.log.debug("%s", msg)
530
530
531 def kernel_info_request(self, stream, ident, parent):
531 def kernel_info_request(self, stream, ident, parent):
532 vinfo = {
532 vinfo = {
533 'protocol_version': protocol_version,
533 'protocol_version': protocol_version,
534 'ipython_version': ipython_version,
534 'ipython_version': ipython_version,
535 'language_version': language_version,
535 'language_version': language_version,
536 'language': 'python',
536 'language': 'python',
537 }
537 }
538 msg = self.session.send(stream, 'kernel_info_reply',
538 msg = self.session.send(stream, 'kernel_info_reply',
539 vinfo, parent, ident)
539 vinfo, parent, ident)
540 self.log.debug("%s", msg)
540 self.log.debug("%s", msg)
541
541
542 def shutdown_request(self, stream, ident, parent):
542 def shutdown_request(self, stream, ident, parent):
543 self.shell.exit_now = True
543 self.shell.exit_now = True
544 content = dict(status='ok')
544 content = dict(status='ok')
545 content.update(parent['content'])
545 content.update(parent['content'])
546 self.session.send(stream, u'shutdown_reply', content, parent, ident=ident)
546 self.session.send(stream, u'shutdown_reply', content, parent, ident=ident)
547 # same content, but different msg_id for broadcasting on IOPub
547 # same content, but different msg_id for broadcasting on IOPub
548 self._shutdown_message = self.session.msg(u'shutdown_reply',
548 self._shutdown_message = self.session.msg(u'shutdown_reply',
549 content, parent
549 content, parent
550 )
550 )
551
551
552 self._at_shutdown()
552 self._at_shutdown()
553 # call sys.exit after a short delay
553 # call sys.exit after a short delay
554 loop = ioloop.IOLoop.instance()
554 loop = ioloop.IOLoop.instance()
555 loop.add_timeout(time.time()+0.1, loop.stop)
555 loop.add_timeout(time.time()+0.1, loop.stop)
556
556
557 #---------------------------------------------------------------------------
557 #---------------------------------------------------------------------------
558 # Engine methods
558 # Engine methods
559 #---------------------------------------------------------------------------
559 #---------------------------------------------------------------------------
560
560
561 def apply_request(self, stream, ident, parent):
561 def apply_request(self, stream, ident, parent):
562 try:
562 try:
563 content = parent[u'content']
563 content = parent[u'content']
564 bufs = parent[u'buffers']
564 bufs = parent[u'buffers']
565 msg_id = parent['header']['msg_id']
565 msg_id = parent['header']['msg_id']
566 except:
566 except:
567 self.log.error("Got bad msg: %s", parent, exc_info=True)
567 self.log.error("Got bad msg: %s", parent, exc_info=True)
568 return
568 return
569
569
570 self._publish_status(u'busy', parent)
570 self._publish_status(u'busy', parent)
571
571
572 # Set the parent message of the display hook and out streams.
572 # Set the parent message of the display hook and out streams.
573 shell = self.shell
573 shell = self.shell
574 shell.set_parent(parent)
574 shell.set_parent(parent)
575
575
576 # pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
576 # pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
577 # self.iopub_socket.send(pyin_msg)
577 # self.iopub_socket.send(pyin_msg)
578 # self.session.send(self.iopub_socket, u'pyin', {u'code':code},parent=parent)
578 # self.session.send(self.iopub_socket, u'pyin', {u'code':code},parent=parent)
579 md = self._make_metadata(parent['metadata'])
579 md = self._make_metadata(parent['metadata'])
580 try:
580 try:
581 working = shell.user_ns
581 working = shell.user_ns
582
582
583 prefix = "_"+str(msg_id).replace("-","")+"_"
583 prefix = "_"+str(msg_id).replace("-","")+"_"
584
584
585 f,args,kwargs = unpack_apply_message(bufs, working, copy=False)
585 f,args,kwargs = unpack_apply_message(bufs, working, copy=False)
586
586
587 fname = getattr(f, '__name__', 'f')
587 fname = getattr(f, '__name__', 'f')
588
588
589 fname = prefix+"f"
589 fname = prefix+"f"
590 argname = prefix+"args"
590 argname = prefix+"args"
591 kwargname = prefix+"kwargs"
591 kwargname = prefix+"kwargs"
592 resultname = prefix+"result"
592 resultname = prefix+"result"
593
593
594 ns = { fname : f, argname : args, kwargname : kwargs , resultname : None }
594 ns = { fname : f, argname : args, kwargname : kwargs , resultname : None }
595 # print ns
595 # print ns
596 working.update(ns)
596 working.update(ns)
597 code = "%s = %s(*%s,**%s)" % (resultname, fname, argname, kwargname)
597 code = "%s = %s(*%s,**%s)" % (resultname, fname, argname, kwargname)
598 try:
598 try:
599 exec code in shell.user_global_ns, shell.user_ns
599 exec(code, shell.user_global_ns, shell.user_ns)
600 result = working.get(resultname)
600 result = working.get(resultname)
601 finally:
601 finally:
602 for key in ns.iterkeys():
602 for key in ns.iterkeys():
603 working.pop(key)
603 working.pop(key)
604
604
605 result_buf = serialize_object(result,
605 result_buf = serialize_object(result,
606 buffer_threshold=self.session.buffer_threshold,
606 buffer_threshold=self.session.buffer_threshold,
607 item_threshold=self.session.item_threshold,
607 item_threshold=self.session.item_threshold,
608 )
608 )
609
609
610 except:
610 except:
611 # invoke IPython traceback formatting
611 # invoke IPython traceback formatting
612 shell.showtraceback()
612 shell.showtraceback()
613 # FIXME - fish exception info out of shell, possibly left there by
613 # FIXME - fish exception info out of shell, possibly left there by
614 # run_code. We'll need to clean up this logic later.
614 # run_code. We'll need to clean up this logic later.
615 reply_content = {}
615 reply_content = {}
616 if shell._reply_content is not None:
616 if shell._reply_content is not None:
617 reply_content.update(shell._reply_content)
617 reply_content.update(shell._reply_content)
618 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='apply')
618 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='apply')
619 reply_content['engine_info'] = e_info
619 reply_content['engine_info'] = e_info
620 # reset after use
620 # reset after use
621 shell._reply_content = None
621 shell._reply_content = None
622
622
623 self.session.send(self.iopub_socket, u'pyerr', reply_content, parent=parent,
623 self.session.send(self.iopub_socket, u'pyerr', reply_content, parent=parent,
624 ident=self._topic('pyerr'))
624 ident=self._topic('pyerr'))
625 self.log.info("Exception in apply request:\n%s", '\n'.join(reply_content['traceback']))
625 self.log.info("Exception in apply request:\n%s", '\n'.join(reply_content['traceback']))
626 result_buf = []
626 result_buf = []
627
627
628 if reply_content['ename'] == 'UnmetDependency':
628 if reply_content['ename'] == 'UnmetDependency':
629 md['dependencies_met'] = False
629 md['dependencies_met'] = False
630 else:
630 else:
631 reply_content = {'status' : 'ok'}
631 reply_content = {'status' : 'ok'}
632
632
633 # put 'ok'/'error' status in header, for scheduler introspection:
633 # put 'ok'/'error' status in header, for scheduler introspection:
634 md['status'] = reply_content['status']
634 md['status'] = reply_content['status']
635
635
636 # flush i/o
636 # flush i/o
637 sys.stdout.flush()
637 sys.stdout.flush()
638 sys.stderr.flush()
638 sys.stderr.flush()
639
639
640 reply_msg = self.session.send(stream, u'apply_reply', reply_content,
640 reply_msg = self.session.send(stream, u'apply_reply', reply_content,
641 parent=parent, ident=ident,buffers=result_buf, metadata=md)
641 parent=parent, ident=ident,buffers=result_buf, metadata=md)
642
642
643 self._publish_status(u'idle', parent)
643 self._publish_status(u'idle', parent)
644
644
645 #---------------------------------------------------------------------------
645 #---------------------------------------------------------------------------
646 # Control messages
646 # Control messages
647 #---------------------------------------------------------------------------
647 #---------------------------------------------------------------------------
648
648
649 def abort_request(self, stream, ident, parent):
649 def abort_request(self, stream, ident, parent):
650 """abort a specifig msg by id"""
650 """abort a specifig msg by id"""
651 msg_ids = parent['content'].get('msg_ids', None)
651 msg_ids = parent['content'].get('msg_ids', None)
652 if isinstance(msg_ids, basestring):
652 if isinstance(msg_ids, basestring):
653 msg_ids = [msg_ids]
653 msg_ids = [msg_ids]
654 if not msg_ids:
654 if not msg_ids:
655 self.abort_queues()
655 self.abort_queues()
656 for mid in msg_ids:
656 for mid in msg_ids:
657 self.aborted.add(str(mid))
657 self.aborted.add(str(mid))
658
658
659 content = dict(status='ok')
659 content = dict(status='ok')
660 reply_msg = self.session.send(stream, 'abort_reply', content=content,
660 reply_msg = self.session.send(stream, 'abort_reply', content=content,
661 parent=parent, ident=ident)
661 parent=parent, ident=ident)
662 self.log.debug("%s", reply_msg)
662 self.log.debug("%s", reply_msg)
663
663
664 def clear_request(self, stream, idents, parent):
664 def clear_request(self, stream, idents, parent):
665 """Clear our namespace."""
665 """Clear our namespace."""
666 self.shell.reset(False)
666 self.shell.reset(False)
667 msg = self.session.send(stream, 'clear_reply', ident=idents, parent=parent,
667 msg = self.session.send(stream, 'clear_reply', ident=idents, parent=parent,
668 content = dict(status='ok'))
668 content = dict(status='ok'))
669
669
670
670
671 #---------------------------------------------------------------------------
671 #---------------------------------------------------------------------------
672 # Protected interface
672 # Protected interface
673 #---------------------------------------------------------------------------
673 #---------------------------------------------------------------------------
674
674
675 def _wrap_exception(self, method=None):
675 def _wrap_exception(self, method=None):
676 # import here, because _wrap_exception is only used in parallel,
676 # import here, because _wrap_exception is only used in parallel,
677 # and parallel has higher min pyzmq version
677 # and parallel has higher min pyzmq version
678 from IPython.parallel.error import wrap_exception
678 from IPython.parallel.error import wrap_exception
679 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method=method)
679 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method=method)
680 content = wrap_exception(e_info)
680 content = wrap_exception(e_info)
681 return content
681 return content
682
682
683 def _topic(self, topic):
683 def _topic(self, topic):
684 """prefixed topic for IOPub messages"""
684 """prefixed topic for IOPub messages"""
685 if self.int_id >= 0:
685 if self.int_id >= 0:
686 base = "engine.%i" % self.int_id
686 base = "engine.%i" % self.int_id
687 else:
687 else:
688 base = "kernel.%s" % self.ident
688 base = "kernel.%s" % self.ident
689
689
690 return py3compat.cast_bytes("%s.%s" % (base, topic))
690 return py3compat.cast_bytes("%s.%s" % (base, topic))
691
691
692 def _abort_queues(self):
692 def _abort_queues(self):
693 for stream in self.shell_streams:
693 for stream in self.shell_streams:
694 if stream:
694 if stream:
695 self._abort_queue(stream)
695 self._abort_queue(stream)
696
696
697 def _abort_queue(self, stream):
697 def _abort_queue(self, stream):
698 poller = zmq.Poller()
698 poller = zmq.Poller()
699 poller.register(stream.socket, zmq.POLLIN)
699 poller.register(stream.socket, zmq.POLLIN)
700 while True:
700 while True:
701 idents,msg = self.session.recv(stream, zmq.NOBLOCK, content=True)
701 idents,msg = self.session.recv(stream, zmq.NOBLOCK, content=True)
702 if msg is None:
702 if msg is None:
703 return
703 return
704
704
705 self.log.info("Aborting:")
705 self.log.info("Aborting:")
706 self.log.info("%s", msg)
706 self.log.info("%s", msg)
707 msg_type = msg['header']['msg_type']
707 msg_type = msg['header']['msg_type']
708 reply_type = msg_type.split('_')[0] + '_reply'
708 reply_type = msg_type.split('_')[0] + '_reply'
709
709
710 status = {'status' : 'aborted'}
710 status = {'status' : 'aborted'}
711 md = {'engine' : self.ident}
711 md = {'engine' : self.ident}
712 md.update(status)
712 md.update(status)
713 reply_msg = self.session.send(stream, reply_type, metadata=md,
713 reply_msg = self.session.send(stream, reply_type, metadata=md,
714 content=status, parent=msg, ident=idents)
714 content=status, parent=msg, ident=idents)
715 self.log.debug("%s", reply_msg)
715 self.log.debug("%s", reply_msg)
716 # We need to wait a bit for requests to come in. This can probably
716 # We need to wait a bit for requests to come in. This can probably
717 # be set shorter for true asynchronous clients.
717 # be set shorter for true asynchronous clients.
718 poller.poll(50)
718 poller.poll(50)
719
719
720
720
721 def _no_raw_input(self):
721 def _no_raw_input(self):
722 """Raise StdinNotImplentedError if active frontend doesn't support
722 """Raise StdinNotImplentedError if active frontend doesn't support
723 stdin."""
723 stdin."""
724 raise StdinNotImplementedError("raw_input was called, but this "
724 raise StdinNotImplementedError("raw_input was called, but this "
725 "frontend does not support stdin.")
725 "frontend does not support stdin.")
726
726
727 def _raw_input(self, prompt, ident, parent):
727 def _raw_input(self, prompt, ident, parent):
728 # Flush output before making the request.
728 # Flush output before making the request.
729 sys.stderr.flush()
729 sys.stderr.flush()
730 sys.stdout.flush()
730 sys.stdout.flush()
731 # flush the stdin socket, to purge stale replies
731 # flush the stdin socket, to purge stale replies
732 while True:
732 while True:
733 try:
733 try:
734 self.stdin_socket.recv_multipart(zmq.NOBLOCK)
734 self.stdin_socket.recv_multipart(zmq.NOBLOCK)
735 except zmq.ZMQError as e:
735 except zmq.ZMQError as e:
736 if e.errno == zmq.EAGAIN:
736 if e.errno == zmq.EAGAIN:
737 break
737 break
738 else:
738 else:
739 raise
739 raise
740
740
741 # Send the input request.
741 # Send the input request.
742 content = json_clean(dict(prompt=prompt))
742 content = json_clean(dict(prompt=prompt))
743 self.session.send(self.stdin_socket, u'input_request', content, parent,
743 self.session.send(self.stdin_socket, u'input_request', content, parent,
744 ident=ident)
744 ident=ident)
745
745
746 # Await a response.
746 # Await a response.
747 while True:
747 while True:
748 try:
748 try:
749 ident, reply = self.session.recv(self.stdin_socket, 0)
749 ident, reply = self.session.recv(self.stdin_socket, 0)
750 except Exception:
750 except Exception:
751 self.log.warn("Invalid Message:", exc_info=True)
751 self.log.warn("Invalid Message:", exc_info=True)
752 except KeyboardInterrupt:
752 except KeyboardInterrupt:
753 # re-raise KeyboardInterrupt, to truncate traceback
753 # re-raise KeyboardInterrupt, to truncate traceback
754 raise KeyboardInterrupt
754 raise KeyboardInterrupt
755 else:
755 else:
756 break
756 break
757 try:
757 try:
758 value = py3compat.unicode_to_str(reply['content']['value'])
758 value = py3compat.unicode_to_str(reply['content']['value'])
759 except:
759 except:
760 self.log.error("Got bad raw_input reply: ")
760 self.log.error("Got bad raw_input reply: ")
761 self.log.error("%s", parent)
761 self.log.error("%s", parent)
762 value = ''
762 value = ''
763 if value == '\x04':
763 if value == '\x04':
764 # EOF
764 # EOF
765 raise EOFError
765 raise EOFError
766 return value
766 return value
767
767
768 def _complete(self, msg):
768 def _complete(self, msg):
769 c = msg['content']
769 c = msg['content']
770 try:
770 try:
771 cpos = int(c['cursor_pos'])
771 cpos = int(c['cursor_pos'])
772 except:
772 except:
773 # If we don't get something that we can convert to an integer, at
773 # If we don't get something that we can convert to an integer, at
774 # least attempt the completion guessing the cursor is at the end of
774 # least attempt the completion guessing the cursor is at the end of
775 # the text, if there's any, and otherwise of the line
775 # the text, if there's any, and otherwise of the line
776 cpos = len(c['text'])
776 cpos = len(c['text'])
777 if cpos==0:
777 if cpos==0:
778 cpos = len(c['line'])
778 cpos = len(c['line'])
779 return self.shell.complete(c['text'], c['line'], cpos)
779 return self.shell.complete(c['text'], c['line'], cpos)
780
780
781 def _at_shutdown(self):
781 def _at_shutdown(self):
782 """Actions taken at shutdown by the kernel, called by python's atexit.
782 """Actions taken at shutdown by the kernel, called by python's atexit.
783 """
783 """
784 # io.rprint("Kernel at_shutdown") # dbg
784 # io.rprint("Kernel at_shutdown") # dbg
785 if self._shutdown_message is not None:
785 if self._shutdown_message is not None:
786 self.session.send(self.iopub_socket, self._shutdown_message, ident=self._topic('shutdown'))
786 self.session.send(self.iopub_socket, self._shutdown_message, ident=self._topic('shutdown'))
787 self.log.debug("%s", self._shutdown_message)
787 self.log.debug("%s", self._shutdown_message)
788 [ s.flush(zmq.POLLOUT) for s in self.shell_streams ]
788 [ s.flush(zmq.POLLOUT) for s in self.shell_streams ]
789
789
@@ -1,582 +1,582 b''
1 """Module for interactive demos using IPython.
1 """Module for interactive demos using IPython.
2
2
3 This module implements a few classes for running Python scripts interactively
3 This module implements a few classes for running Python scripts interactively
4 in IPython for demonstrations. With very simple markup (a few tags in
4 in IPython for demonstrations. With very simple markup (a few tags in
5 comments), you can control points where the script stops executing and returns
5 comments), you can control points where the script stops executing and returns
6 control to IPython.
6 control to IPython.
7
7
8
8
9 Provided classes
9 Provided classes
10 ----------------
10 ----------------
11
11
12 The classes are (see their docstrings for further details):
12 The classes are (see their docstrings for further details):
13
13
14 - Demo: pure python demos
14 - Demo: pure python demos
15
15
16 - IPythonDemo: demos with input to be processed by IPython as if it had been
16 - IPythonDemo: demos with input to be processed by IPython as if it had been
17 typed interactively (so magics work, as well as any other special syntax you
17 typed interactively (so magics work, as well as any other special syntax you
18 may have added via input prefilters).
18 may have added via input prefilters).
19
19
20 - LineDemo: single-line version of the Demo class. These demos are executed
20 - LineDemo: single-line version of the Demo class. These demos are executed
21 one line at a time, and require no markup.
21 one line at a time, and require no markup.
22
22
23 - IPythonLineDemo: IPython version of the LineDemo class (the demo is
23 - IPythonLineDemo: IPython version of the LineDemo class (the demo is
24 executed a line at a time, but processed via IPython).
24 executed a line at a time, but processed via IPython).
25
25
26 - ClearMixin: mixin to make Demo classes with less visual clutter. It
26 - ClearMixin: mixin to make Demo classes with less visual clutter. It
27 declares an empty marquee and a pre_cmd that clears the screen before each
27 declares an empty marquee and a pre_cmd that clears the screen before each
28 block (see Subclassing below).
28 block (see Subclassing below).
29
29
30 - ClearDemo, ClearIPDemo: mixin-enabled versions of the Demo and IPythonDemo
30 - ClearDemo, ClearIPDemo: mixin-enabled versions of the Demo and IPythonDemo
31 classes.
31 classes.
32
32
33 Inheritance diagram:
33 Inheritance diagram:
34
34
35 .. inheritance-diagram:: IPython.lib.demo
35 .. inheritance-diagram:: IPython.lib.demo
36 :parts: 3
36 :parts: 3
37
37
38 Subclassing
38 Subclassing
39 -----------
39 -----------
40
40
41 The classes here all include a few methods meant to make customization by
41 The classes here all include a few methods meant to make customization by
42 subclassing more convenient. Their docstrings below have some more details:
42 subclassing more convenient. Their docstrings below have some more details:
43
43
44 - marquee(): generates a marquee to provide visible on-screen markers at each
44 - marquee(): generates a marquee to provide visible on-screen markers at each
45 block start and end.
45 block start and end.
46
46
47 - pre_cmd(): run right before the execution of each block.
47 - pre_cmd(): run right before the execution of each block.
48
48
49 - post_cmd(): run right after the execution of each block. If the block
49 - post_cmd(): run right after the execution of each block. If the block
50 raises an exception, this is NOT called.
50 raises an exception, this is NOT called.
51
51
52
52
53 Operation
53 Operation
54 ---------
54 ---------
55
55
56 The file is run in its own empty namespace (though you can pass it a string of
56 The file is run in its own empty namespace (though you can pass it a string of
57 arguments as if in a command line environment, and it will see those as
57 arguments as if in a command line environment, and it will see those as
58 sys.argv). But at each stop, the global IPython namespace is updated with the
58 sys.argv). But at each stop, the global IPython namespace is updated with the
59 current internal demo namespace, so you can work interactively with the data
59 current internal demo namespace, so you can work interactively with the data
60 accumulated so far.
60 accumulated so far.
61
61
62 By default, each block of code is printed (with syntax highlighting) before
62 By default, each block of code is printed (with syntax highlighting) before
63 executing it and you have to confirm execution. This is intended to show the
63 executing it and you have to confirm execution. This is intended to show the
64 code to an audience first so you can discuss it, and only proceed with
64 code to an audience first so you can discuss it, and only proceed with
65 execution once you agree. There are a few tags which allow you to modify this
65 execution once you agree. There are a few tags which allow you to modify this
66 behavior.
66 behavior.
67
67
68 The supported tags are:
68 The supported tags are:
69
69
70 # <demo> stop
70 # <demo> stop
71
71
72 Defines block boundaries, the points where IPython stops execution of the
72 Defines block boundaries, the points where IPython stops execution of the
73 file and returns to the interactive prompt.
73 file and returns to the interactive prompt.
74
74
75 You can optionally mark the stop tag with extra dashes before and after the
75 You can optionally mark the stop tag with extra dashes before and after the
76 word 'stop', to help visually distinguish the blocks in a text editor:
76 word 'stop', to help visually distinguish the blocks in a text editor:
77
77
78 # <demo> --- stop ---
78 # <demo> --- stop ---
79
79
80
80
81 # <demo> silent
81 # <demo> silent
82
82
83 Make a block execute silently (and hence automatically). Typically used in
83 Make a block execute silently (and hence automatically). Typically used in
84 cases where you have some boilerplate or initialization code which you need
84 cases where you have some boilerplate or initialization code which you need
85 executed but do not want to be seen in the demo.
85 executed but do not want to be seen in the demo.
86
86
87 # <demo> auto
87 # <demo> auto
88
88
89 Make a block execute automatically, but still being printed. Useful for
89 Make a block execute automatically, but still being printed. Useful for
90 simple code which does not warrant discussion, since it avoids the extra
90 simple code which does not warrant discussion, since it avoids the extra
91 manual confirmation.
91 manual confirmation.
92
92
93 # <demo> auto_all
93 # <demo> auto_all
94
94
95 This tag can _only_ be in the first block, and if given it overrides the
95 This tag can _only_ be in the first block, and if given it overrides the
96 individual auto tags to make the whole demo fully automatic (no block asks
96 individual auto tags to make the whole demo fully automatic (no block asks
97 for confirmation). It can also be given at creation time (or the attribute
97 for confirmation). It can also be given at creation time (or the attribute
98 set later) to override what's in the file.
98 set later) to override what's in the file.
99
99
100 While _any_ python file can be run as a Demo instance, if there are no stop
100 While _any_ python file can be run as a Demo instance, if there are no stop
101 tags the whole file will run in a single block (no different that calling
101 tags the whole file will run in a single block (no different that calling
102 first %pycat and then %run). The minimal markup to make this useful is to
102 first %pycat and then %run). The minimal markup to make this useful is to
103 place a set of stop tags; the other tags are only there to let you fine-tune
103 place a set of stop tags; the other tags are only there to let you fine-tune
104 the execution.
104 the execution.
105
105
106 This is probably best explained with the simple example file below. You can
106 This is probably best explained with the simple example file below. You can
107 copy this into a file named ex_demo.py, and try running it via::
107 copy this into a file named ex_demo.py, and try running it via::
108
108
109 from IPython.demo import Demo
109 from IPython.demo import Demo
110 d = Demo('ex_demo.py')
110 d = Demo('ex_demo.py')
111 d()
111 d()
112
112
113 Each time you call the demo object, it runs the next block. The demo object
113 Each time you call the demo object, it runs the next block. The demo object
114 has a few useful methods for navigation, like again(), edit(), jump(), seek()
114 has a few useful methods for navigation, like again(), edit(), jump(), seek()
115 and back(). It can be reset for a new run via reset() or reloaded from disk
115 and back(). It can be reset for a new run via reset() or reloaded from disk
116 (in case you've edited the source) via reload(). See their docstrings below.
116 (in case you've edited the source) via reload(). See their docstrings below.
117
117
118 Note: To make this simpler to explore, a file called "demo-exercizer.py" has
118 Note: To make this simpler to explore, a file called "demo-exercizer.py" has
119 been added to the "docs/examples/core" directory. Just cd to this directory in
119 been added to the "docs/examples/core" directory. Just cd to this directory in
120 an IPython session, and type::
120 an IPython session, and type::
121
121
122 %run demo-exercizer.py
122 %run demo-exercizer.py
123
123
124 and then follow the directions.
124 and then follow the directions.
125
125
126 Example
126 Example
127 -------
127 -------
128
128
129 The following is a very simple example of a valid demo file.
129 The following is a very simple example of a valid demo file.
130
130
131 ::
131 ::
132
132
133 #################### EXAMPLE DEMO <ex_demo.py> ###############################
133 #################### EXAMPLE DEMO <ex_demo.py> ###############################
134 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
134 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
135
135
136 print 'Hello, welcome to an interactive IPython demo.'
136 print 'Hello, welcome to an interactive IPython demo.'
137
137
138 # The mark below defines a block boundary, which is a point where IPython will
138 # The mark below defines a block boundary, which is a point where IPython will
139 # stop execution and return to the interactive prompt. The dashes are actually
139 # stop execution and return to the interactive prompt. The dashes are actually
140 # optional and used only as a visual aid to clearly separate blocks while
140 # optional and used only as a visual aid to clearly separate blocks while
141 # editing the demo code.
141 # editing the demo code.
142 # <demo> stop
142 # <demo> stop
143
143
144 x = 1
144 x = 1
145 y = 2
145 y = 2
146
146
147 # <demo> stop
147 # <demo> stop
148
148
149 # the mark below makes this block as silent
149 # the mark below makes this block as silent
150 # <demo> silent
150 # <demo> silent
151
151
152 print 'This is a silent block, which gets executed but not printed.'
152 print 'This is a silent block, which gets executed but not printed.'
153
153
154 # <demo> stop
154 # <demo> stop
155 # <demo> auto
155 # <demo> auto
156 print 'This is an automatic block.'
156 print 'This is an automatic block.'
157 print 'It is executed without asking for confirmation, but printed.'
157 print 'It is executed without asking for confirmation, but printed.'
158 z = x+y
158 z = x+y
159
159
160 print 'z=',x
160 print 'z=',x
161
161
162 # <demo> stop
162 # <demo> stop
163 # This is just another normal block.
163 # This is just another normal block.
164 print 'z is now:', z
164 print 'z is now:', z
165
165
166 print 'bye!'
166 print 'bye!'
167 ################### END EXAMPLE DEMO <ex_demo.py> ############################
167 ################### END EXAMPLE DEMO <ex_demo.py> ############################
168 """
168 """
169
169
170 from __future__ import unicode_literals
170 from __future__ import unicode_literals
171
171
172 #*****************************************************************************
172 #*****************************************************************************
173 # Copyright (C) 2005-2006 Fernando Perez. <Fernando.Perez@colorado.edu>
173 # Copyright (C) 2005-2006 Fernando Perez. <Fernando.Perez@colorado.edu>
174 #
174 #
175 # Distributed under the terms of the BSD License. The full license is in
175 # Distributed under the terms of the BSD License. The full license is in
176 # the file COPYING, distributed as part of this software.
176 # the file COPYING, distributed as part of this software.
177 #
177 #
178 #*****************************************************************************
178 #*****************************************************************************
179 from __future__ import print_function
179 from __future__ import print_function
180
180
181 import os
181 import os
182 import re
182 import re
183 import shlex
183 import shlex
184 import sys
184 import sys
185
185
186 from IPython.utils import io
186 from IPython.utils import io
187 from IPython.utils.text import marquee
187 from IPython.utils.text import marquee
188 from IPython.utils import openpy
188 from IPython.utils import openpy
189 __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError']
189 __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError']
190
190
191 class DemoError(Exception): pass
191 class DemoError(Exception): pass
192
192
193 def re_mark(mark):
193 def re_mark(mark):
194 return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE)
194 return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE)
195
195
196 class Demo(object):
196 class Demo(object):
197
197
198 re_stop = re_mark('-*\s?stop\s?-*')
198 re_stop = re_mark('-*\s?stop\s?-*')
199 re_silent = re_mark('silent')
199 re_silent = re_mark('silent')
200 re_auto = re_mark('auto')
200 re_auto = re_mark('auto')
201 re_auto_all = re_mark('auto_all')
201 re_auto_all = re_mark('auto_all')
202
202
203 def __init__(self,src,title='',arg_str='',auto_all=None):
203 def __init__(self,src,title='',arg_str='',auto_all=None):
204 """Make a new demo object. To run the demo, simply call the object.
204 """Make a new demo object. To run the demo, simply call the object.
205
205
206 See the module docstring for full details and an example (you can use
206 See the module docstring for full details and an example (you can use
207 IPython.Demo? in IPython to see it).
207 IPython.Demo? in IPython to see it).
208
208
209 Inputs:
209 Inputs:
210
210
211 - src is either a file, or file-like object, or a
211 - src is either a file, or file-like object, or a
212 string that can be resolved to a filename.
212 string that can be resolved to a filename.
213
213
214 Optional inputs:
214 Optional inputs:
215
215
216 - title: a string to use as the demo name. Of most use when the demo
216 - title: a string to use as the demo name. Of most use when the demo
217 you are making comes from an object that has no filename, or if you
217 you are making comes from an object that has no filename, or if you
218 want an alternate denotation distinct from the filename.
218 want an alternate denotation distinct from the filename.
219
219
220 - arg_str(''): a string of arguments, internally converted to a list
220 - arg_str(''): a string of arguments, internally converted to a list
221 just like sys.argv, so the demo script can see a similar
221 just like sys.argv, so the demo script can see a similar
222 environment.
222 environment.
223
223
224 - auto_all(None): global flag to run all blocks automatically without
224 - auto_all(None): global flag to run all blocks automatically without
225 confirmation. This attribute overrides the block-level tags and
225 confirmation. This attribute overrides the block-level tags and
226 applies to the whole demo. It is an attribute of the object, and
226 applies to the whole demo. It is an attribute of the object, and
227 can be changed at runtime simply by reassigning it to a boolean
227 can be changed at runtime simply by reassigning it to a boolean
228 value.
228 value.
229 """
229 """
230 if hasattr(src, "read"):
230 if hasattr(src, "read"):
231 # It seems to be a file or a file-like object
231 # It seems to be a file or a file-like object
232 self.fname = "from a file-like object"
232 self.fname = "from a file-like object"
233 if title == '':
233 if title == '':
234 self.title = "from a file-like object"
234 self.title = "from a file-like object"
235 else:
235 else:
236 self.title = title
236 self.title = title
237 else:
237 else:
238 # Assume it's a string or something that can be converted to one
238 # Assume it's a string or something that can be converted to one
239 self.fname = src
239 self.fname = src
240 if title == '':
240 if title == '':
241 (filepath, filename) = os.path.split(src)
241 (filepath, filename) = os.path.split(src)
242 self.title = filename
242 self.title = filename
243 else:
243 else:
244 self.title = title
244 self.title = title
245 self.sys_argv = [src] + shlex.split(arg_str)
245 self.sys_argv = [src] + shlex.split(arg_str)
246 self.auto_all = auto_all
246 self.auto_all = auto_all
247 self.src = src
247 self.src = src
248
248
249 # get a few things from ipython. While it's a bit ugly design-wise,
249 # get a few things from ipython. While it's a bit ugly design-wise,
250 # it ensures that things like color scheme and the like are always in
250 # it ensures that things like color scheme and the like are always in
251 # sync with the ipython mode being used. This class is only meant to
251 # sync with the ipython mode being used. This class is only meant to
252 # be used inside ipython anyways, so it's OK.
252 # be used inside ipython anyways, so it's OK.
253 ip = get_ipython() # this is in builtins whenever IPython is running
253 ip = get_ipython() # this is in builtins whenever IPython is running
254 self.ip_ns = ip.user_ns
254 self.ip_ns = ip.user_ns
255 self.ip_colorize = ip.pycolorize
255 self.ip_colorize = ip.pycolorize
256 self.ip_showtb = ip.showtraceback
256 self.ip_showtb = ip.showtraceback
257 self.ip_run_cell = ip.run_cell
257 self.ip_run_cell = ip.run_cell
258 self.shell = ip
258 self.shell = ip
259
259
260 # load user data and initialize data structures
260 # load user data and initialize data structures
261 self.reload()
261 self.reload()
262
262
263 def fload(self):
263 def fload(self):
264 """Load file object."""
264 """Load file object."""
265 # read data and parse into blocks
265 # read data and parse into blocks
266 if hasattr(self, 'fobj') and self.fobj is not None:
266 if hasattr(self, 'fobj') and self.fobj is not None:
267 self.fobj.close()
267 self.fobj.close()
268 if hasattr(self.src, "read"):
268 if hasattr(self.src, "read"):
269 # It seems to be a file or a file-like object
269 # It seems to be a file or a file-like object
270 self.fobj = self.src
270 self.fobj = self.src
271 else:
271 else:
272 # Assume it's a string or something that can be converted to one
272 # Assume it's a string or something that can be converted to one
273 self.fobj = openpy.open(self.fname)
273 self.fobj = openpy.open(self.fname)
274
274
275 def reload(self):
275 def reload(self):
276 """Reload source from disk and initialize state."""
276 """Reload source from disk and initialize state."""
277 self.fload()
277 self.fload()
278
278
279 self.src = "".join(openpy.strip_encoding_cookie(self.fobj))
279 self.src = "".join(openpy.strip_encoding_cookie(self.fobj))
280 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
280 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
281 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
281 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
282 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
282 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
283
283
284 # if auto_all is not given (def. None), we read it from the file
284 # if auto_all is not given (def. None), we read it from the file
285 if self.auto_all is None:
285 if self.auto_all is None:
286 self.auto_all = bool(self.re_auto_all.findall(src_b[0]))
286 self.auto_all = bool(self.re_auto_all.findall(src_b[0]))
287 else:
287 else:
288 self.auto_all = bool(self.auto_all)
288 self.auto_all = bool(self.auto_all)
289
289
290 # Clean the sources from all markup so it doesn't get displayed when
290 # Clean the sources from all markup so it doesn't get displayed when
291 # running the demo
291 # running the demo
292 src_blocks = []
292 src_blocks = []
293 auto_strip = lambda s: self.re_auto.sub('',s)
293 auto_strip = lambda s: self.re_auto.sub('',s)
294 for i,b in enumerate(src_b):
294 for i,b in enumerate(src_b):
295 if self._auto[i]:
295 if self._auto[i]:
296 src_blocks.append(auto_strip(b))
296 src_blocks.append(auto_strip(b))
297 else:
297 else:
298 src_blocks.append(b)
298 src_blocks.append(b)
299 # remove the auto_all marker
299 # remove the auto_all marker
300 src_blocks[0] = self.re_auto_all.sub('',src_blocks[0])
300 src_blocks[0] = self.re_auto_all.sub('',src_blocks[0])
301
301
302 self.nblocks = len(src_blocks)
302 self.nblocks = len(src_blocks)
303 self.src_blocks = src_blocks
303 self.src_blocks = src_blocks
304
304
305 # also build syntax-highlighted source
305 # also build syntax-highlighted source
306 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
306 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
307
307
308 # ensure clean namespace and seek offset
308 # ensure clean namespace and seek offset
309 self.reset()
309 self.reset()
310
310
311 def reset(self):
311 def reset(self):
312 """Reset the namespace and seek pointer to restart the demo"""
312 """Reset the namespace and seek pointer to restart the demo"""
313 self.user_ns = {}
313 self.user_ns = {}
314 self.finished = False
314 self.finished = False
315 self.block_index = 0
315 self.block_index = 0
316
316
317 def _validate_index(self,index):
317 def _validate_index(self,index):
318 if index<0 or index>=self.nblocks:
318 if index<0 or index>=self.nblocks:
319 raise ValueError('invalid block index %s' % index)
319 raise ValueError('invalid block index %s' % index)
320
320
321 def _get_index(self,index):
321 def _get_index(self,index):
322 """Get the current block index, validating and checking status.
322 """Get the current block index, validating and checking status.
323
323
324 Returns None if the demo is finished"""
324 Returns None if the demo is finished"""
325
325
326 if index is None:
326 if index is None:
327 if self.finished:
327 if self.finished:
328 print('Demo finished. Use <demo_name>.reset() if you want to rerun it.', file=io.stdout)
328 print('Demo finished. Use <demo_name>.reset() if you want to rerun it.', file=io.stdout)
329 return None
329 return None
330 index = self.block_index
330 index = self.block_index
331 else:
331 else:
332 self._validate_index(index)
332 self._validate_index(index)
333 return index
333 return index
334
334
335 def seek(self,index):
335 def seek(self,index):
336 """Move the current seek pointer to the given block.
336 """Move the current seek pointer to the given block.
337
337
338 You can use negative indices to seek from the end, with identical
338 You can use negative indices to seek from the end, with identical
339 semantics to those of Python lists."""
339 semantics to those of Python lists."""
340 if index<0:
340 if index<0:
341 index = self.nblocks + index
341 index = self.nblocks + index
342 self._validate_index(index)
342 self._validate_index(index)
343 self.block_index = index
343 self.block_index = index
344 self.finished = False
344 self.finished = False
345
345
346 def back(self,num=1):
346 def back(self,num=1):
347 """Move the seek pointer back num blocks (default is 1)."""
347 """Move the seek pointer back num blocks (default is 1)."""
348 self.seek(self.block_index-num)
348 self.seek(self.block_index-num)
349
349
350 def jump(self,num=1):
350 def jump(self,num=1):
351 """Jump a given number of blocks relative to the current one.
351 """Jump a given number of blocks relative to the current one.
352
352
353 The offset can be positive or negative, defaults to 1."""
353 The offset can be positive or negative, defaults to 1."""
354 self.seek(self.block_index+num)
354 self.seek(self.block_index+num)
355
355
356 def again(self):
356 def again(self):
357 """Move the seek pointer back one block and re-execute."""
357 """Move the seek pointer back one block and re-execute."""
358 self.back(1)
358 self.back(1)
359 self()
359 self()
360
360
361 def edit(self,index=None):
361 def edit(self,index=None):
362 """Edit a block.
362 """Edit a block.
363
363
364 If no number is given, use the last block executed.
364 If no number is given, use the last block executed.
365
365
366 This edits the in-memory copy of the demo, it does NOT modify the
366 This edits the in-memory copy of the demo, it does NOT modify the
367 original source file. If you want to do that, simply open the file in
367 original source file. If you want to do that, simply open the file in
368 an editor and use reload() when you make changes to the file. This
368 an editor and use reload() when you make changes to the file. This
369 method is meant to let you change a block during a demonstration for
369 method is meant to let you change a block during a demonstration for
370 explanatory purposes, without damaging your original script."""
370 explanatory purposes, without damaging your original script."""
371
371
372 index = self._get_index(index)
372 index = self._get_index(index)
373 if index is None:
373 if index is None:
374 return
374 return
375 # decrease the index by one (unless we're at the very beginning), so
375 # decrease the index by one (unless we're at the very beginning), so
376 # that the default demo.edit() call opens up the sblock we've last run
376 # that the default demo.edit() call opens up the sblock we've last run
377 if index>0:
377 if index>0:
378 index -= 1
378 index -= 1
379
379
380 filename = self.shell.mktempfile(self.src_blocks[index])
380 filename = self.shell.mktempfile(self.src_blocks[index])
381 self.shell.hooks.editor(filename,1)
381 self.shell.hooks.editor(filename,1)
382 with open(filename, 'r') as f:
382 with open(filename, 'r') as f:
383 new_block = f.read()
383 new_block = f.read()
384 # update the source and colored block
384 # update the source and colored block
385 self.src_blocks[index] = new_block
385 self.src_blocks[index] = new_block
386 self.src_blocks_colored[index] = self.ip_colorize(new_block)
386 self.src_blocks_colored[index] = self.ip_colorize(new_block)
387 self.block_index = index
387 self.block_index = index
388 # call to run with the newly edited index
388 # call to run with the newly edited index
389 self()
389 self()
390
390
391 def show(self,index=None):
391 def show(self,index=None):
392 """Show a single block on screen"""
392 """Show a single block on screen"""
393
393
394 index = self._get_index(index)
394 index = self._get_index(index)
395 if index is None:
395 if index is None:
396 return
396 return
397
397
398 print(self.marquee('<%s> block # %s (%s remaining)' %
398 print(self.marquee('<%s> block # %s (%s remaining)' %
399 (self.title,index,self.nblocks-index-1)), file=io.stdout)
399 (self.title,index,self.nblocks-index-1)), file=io.stdout)
400 print((self.src_blocks_colored[index]), file=io.stdout)
400 print((self.src_blocks_colored[index]), file=io.stdout)
401 sys.stdout.flush()
401 sys.stdout.flush()
402
402
403 def show_all(self):
403 def show_all(self):
404 """Show entire demo on screen, block by block"""
404 """Show entire demo on screen, block by block"""
405
405
406 fname = self.title
406 fname = self.title
407 title = self.title
407 title = self.title
408 nblocks = self.nblocks
408 nblocks = self.nblocks
409 silent = self._silent
409 silent = self._silent
410 marquee = self.marquee
410 marquee = self.marquee
411 for index,block in enumerate(self.src_blocks_colored):
411 for index,block in enumerate(self.src_blocks_colored):
412 if silent[index]:
412 if silent[index]:
413 print(marquee('<%s> SILENT block # %s (%s remaining)' %
413 print(marquee('<%s> SILENT block # %s (%s remaining)' %
414 (title,index,nblocks-index-1)), file=io.stdout)
414 (title,index,nblocks-index-1)), file=io.stdout)
415 else:
415 else:
416 print(marquee('<%s> block # %s (%s remaining)' %
416 print(marquee('<%s> block # %s (%s remaining)' %
417 (title,index,nblocks-index-1)), file=io.stdout)
417 (title,index,nblocks-index-1)), file=io.stdout)
418 print(block, end=' ', file=io.stdout)
418 print(block, end=' ', file=io.stdout)
419 sys.stdout.flush()
419 sys.stdout.flush()
420
420
421 def run_cell(self,source):
421 def run_cell(self,source):
422 """Execute a string with one or more lines of code"""
422 """Execute a string with one or more lines of code"""
423
423
424 exec source in self.user_ns
424 exec(source, self.user_ns)
425
425
426 def __call__(self,index=None):
426 def __call__(self,index=None):
427 """run a block of the demo.
427 """run a block of the demo.
428
428
429 If index is given, it should be an integer >=1 and <= nblocks. This
429 If index is given, it should be an integer >=1 and <= nblocks. This
430 means that the calling convention is one off from typical Python
430 means that the calling convention is one off from typical Python
431 lists. The reason for the inconsistency is that the demo always
431 lists. The reason for the inconsistency is that the demo always
432 prints 'Block n/N, and N is the total, so it would be very odd to use
432 prints 'Block n/N, and N is the total, so it would be very odd to use
433 zero-indexing here."""
433 zero-indexing here."""
434
434
435 index = self._get_index(index)
435 index = self._get_index(index)
436 if index is None:
436 if index is None:
437 return
437 return
438 try:
438 try:
439 marquee = self.marquee
439 marquee = self.marquee
440 next_block = self.src_blocks[index]
440 next_block = self.src_blocks[index]
441 self.block_index += 1
441 self.block_index += 1
442 if self._silent[index]:
442 if self._silent[index]:
443 print(marquee('Executing silent block # %s (%s remaining)' %
443 print(marquee('Executing silent block # %s (%s remaining)' %
444 (index,self.nblocks-index-1)), file=io.stdout)
444 (index,self.nblocks-index-1)), file=io.stdout)
445 else:
445 else:
446 self.pre_cmd()
446 self.pre_cmd()
447 self.show(index)
447 self.show(index)
448 if self.auto_all or self._auto[index]:
448 if self.auto_all or self._auto[index]:
449 print(marquee('output:'), file=io.stdout)
449 print(marquee('output:'), file=io.stdout)
450 else:
450 else:
451 print(marquee('Press <q> to quit, <Enter> to execute...'), end=' ', file=io.stdout)
451 print(marquee('Press <q> to quit, <Enter> to execute...'), end=' ', file=io.stdout)
452 ans = raw_input().strip()
452 ans = raw_input().strip()
453 if ans:
453 if ans:
454 print(marquee('Block NOT executed'), file=io.stdout)
454 print(marquee('Block NOT executed'), file=io.stdout)
455 return
455 return
456 try:
456 try:
457 save_argv = sys.argv
457 save_argv = sys.argv
458 sys.argv = self.sys_argv
458 sys.argv = self.sys_argv
459 self.run_cell(next_block)
459 self.run_cell(next_block)
460 self.post_cmd()
460 self.post_cmd()
461 finally:
461 finally:
462 sys.argv = save_argv
462 sys.argv = save_argv
463
463
464 except:
464 except:
465 self.ip_showtb(filename=self.fname)
465 self.ip_showtb(filename=self.fname)
466 else:
466 else:
467 self.ip_ns.update(self.user_ns)
467 self.ip_ns.update(self.user_ns)
468
468
469 if self.block_index == self.nblocks:
469 if self.block_index == self.nblocks:
470 mq1 = self.marquee('END OF DEMO')
470 mq1 = self.marquee('END OF DEMO')
471 if mq1:
471 if mq1:
472 # avoid spurious print >>io.stdout,s if empty marquees are used
472 # avoid spurious print >>io.stdout,s if empty marquees are used
473 print(file=io.stdout)
473 print(file=io.stdout)
474 print(mq1, file=io.stdout)
474 print(mq1, file=io.stdout)
475 print(self.marquee('Use <demo_name>.reset() if you want to rerun it.'), file=io.stdout)
475 print(self.marquee('Use <demo_name>.reset() if you want to rerun it.'), file=io.stdout)
476 self.finished = True
476 self.finished = True
477
477
478 # These methods are meant to be overridden by subclasses who may wish to
478 # These methods are meant to be overridden by subclasses who may wish to
479 # customize the behavior of of their demos.
479 # customize the behavior of of their demos.
480 def marquee(self,txt='',width=78,mark='*'):
480 def marquee(self,txt='',width=78,mark='*'):
481 """Return the input string centered in a 'marquee'."""
481 """Return the input string centered in a 'marquee'."""
482 return marquee(txt,width,mark)
482 return marquee(txt,width,mark)
483
483
484 def pre_cmd(self):
484 def pre_cmd(self):
485 """Method called before executing each block."""
485 """Method called before executing each block."""
486 pass
486 pass
487
487
488 def post_cmd(self):
488 def post_cmd(self):
489 """Method called after executing each block."""
489 """Method called after executing each block."""
490 pass
490 pass
491
491
492
492
493 class IPythonDemo(Demo):
493 class IPythonDemo(Demo):
494 """Class for interactive demos with IPython's input processing applied.
494 """Class for interactive demos with IPython's input processing applied.
495
495
496 This subclasses Demo, but instead of executing each block by the Python
496 This subclasses Demo, but instead of executing each block by the Python
497 interpreter (via exec), it actually calls IPython on it, so that any input
497 interpreter (via exec), it actually calls IPython on it, so that any input
498 filters which may be in place are applied to the input block.
498 filters which may be in place are applied to the input block.
499
499
500 If you have an interactive environment which exposes special input
500 If you have an interactive environment which exposes special input
501 processing, you can use this class instead to write demo scripts which
501 processing, you can use this class instead to write demo scripts which
502 operate exactly as if you had typed them interactively. The default Demo
502 operate exactly as if you had typed them interactively. The default Demo
503 class requires the input to be valid, pure Python code.
503 class requires the input to be valid, pure Python code.
504 """
504 """
505
505
506 def run_cell(self,source):
506 def run_cell(self,source):
507 """Execute a string with one or more lines of code"""
507 """Execute a string with one or more lines of code"""
508
508
509 self.shell.run_cell(source)
509 self.shell.run_cell(source)
510
510
511 class LineDemo(Demo):
511 class LineDemo(Demo):
512 """Demo where each line is executed as a separate block.
512 """Demo where each line is executed as a separate block.
513
513
514 The input script should be valid Python code.
514 The input script should be valid Python code.
515
515
516 This class doesn't require any markup at all, and it's meant for simple
516 This class doesn't require any markup at all, and it's meant for simple
517 scripts (with no nesting or any kind of indentation) which consist of
517 scripts (with no nesting or any kind of indentation) which consist of
518 multiple lines of input to be executed, one at a time, as if they had been
518 multiple lines of input to be executed, one at a time, as if they had been
519 typed in the interactive prompt.
519 typed in the interactive prompt.
520
520
521 Note: the input can not have *any* indentation, which means that only
521 Note: the input can not have *any* indentation, which means that only
522 single-lines of input are accepted, not even function definitions are
522 single-lines of input are accepted, not even function definitions are
523 valid."""
523 valid."""
524
524
525 def reload(self):
525 def reload(self):
526 """Reload source from disk and initialize state."""
526 """Reload source from disk and initialize state."""
527 # read data and parse into blocks
527 # read data and parse into blocks
528 self.fload()
528 self.fload()
529 lines = self.fobj.readlines()
529 lines = self.fobj.readlines()
530 src_b = [l for l in lines if l.strip()]
530 src_b = [l for l in lines if l.strip()]
531 nblocks = len(src_b)
531 nblocks = len(src_b)
532 self.src = ''.join(lines)
532 self.src = ''.join(lines)
533 self._silent = [False]*nblocks
533 self._silent = [False]*nblocks
534 self._auto = [True]*nblocks
534 self._auto = [True]*nblocks
535 self.auto_all = True
535 self.auto_all = True
536 self.nblocks = nblocks
536 self.nblocks = nblocks
537 self.src_blocks = src_b
537 self.src_blocks = src_b
538
538
539 # also build syntax-highlighted source
539 # also build syntax-highlighted source
540 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
540 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
541
541
542 # ensure clean namespace and seek offset
542 # ensure clean namespace and seek offset
543 self.reset()
543 self.reset()
544
544
545
545
546 class IPythonLineDemo(IPythonDemo,LineDemo):
546 class IPythonLineDemo(IPythonDemo,LineDemo):
547 """Variant of the LineDemo class whose input is processed by IPython."""
547 """Variant of the LineDemo class whose input is processed by IPython."""
548 pass
548 pass
549
549
550
550
551 class ClearMixin(object):
551 class ClearMixin(object):
552 """Use this mixin to make Demo classes with less visual clutter.
552 """Use this mixin to make Demo classes with less visual clutter.
553
553
554 Demos using this mixin will clear the screen before every block and use
554 Demos using this mixin will clear the screen before every block and use
555 blank marquees.
555 blank marquees.
556
556
557 Note that in order for the methods defined here to actually override those
557 Note that in order for the methods defined here to actually override those
558 of the classes it's mixed with, it must go /first/ in the inheritance
558 of the classes it's mixed with, it must go /first/ in the inheritance
559 tree. For example:
559 tree. For example:
560
560
561 class ClearIPDemo(ClearMixin,IPythonDemo): pass
561 class ClearIPDemo(ClearMixin,IPythonDemo): pass
562
562
563 will provide an IPythonDemo class with the mixin's features.
563 will provide an IPythonDemo class with the mixin's features.
564 """
564 """
565
565
566 def marquee(self,txt='',width=78,mark='*'):
566 def marquee(self,txt='',width=78,mark='*'):
567 """Blank marquee that returns '' no matter what the input."""
567 """Blank marquee that returns '' no matter what the input."""
568 return ''
568 return ''
569
569
570 def pre_cmd(self):
570 def pre_cmd(self):
571 """Method called before executing each block.
571 """Method called before executing each block.
572
572
573 This one simply clears the screen."""
573 This one simply clears the screen."""
574 from IPython.utils.terminal import term_clear
574 from IPython.utils.terminal import term_clear
575 term_clear()
575 term_clear()
576
576
577 class ClearDemo(ClearMixin,Demo):
577 class ClearDemo(ClearMixin,Demo):
578 pass
578 pass
579
579
580
580
581 class ClearIPDemo(ClearMixin,IPythonDemo):
581 class ClearIPDemo(ClearMixin,IPythonDemo):
582 pass
582 pass
@@ -1,547 +1,547 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 The IPython controller application.
4 The IPython controller application.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * MinRK
9 * MinRK
10
10
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 from __future__ import with_statement
24 from __future__ import with_statement
25
25
26 import json
26 import json
27 import os
27 import os
28 import stat
28 import stat
29 import sys
29 import sys
30
30
31 from multiprocessing import Process
31 from multiprocessing import Process
32 from signal import signal, SIGINT, SIGABRT, SIGTERM
32 from signal import signal, SIGINT, SIGABRT, SIGTERM
33
33
34 import zmq
34 import zmq
35 from zmq.devices import ProcessMonitoredQueue
35 from zmq.devices import ProcessMonitoredQueue
36 from zmq.log.handlers import PUBHandler
36 from zmq.log.handlers import PUBHandler
37
37
38 from IPython.core.profiledir import ProfileDir
38 from IPython.core.profiledir import ProfileDir
39
39
40 from IPython.parallel.apps.baseapp import (
40 from IPython.parallel.apps.baseapp import (
41 BaseParallelApplication,
41 BaseParallelApplication,
42 base_aliases,
42 base_aliases,
43 base_flags,
43 base_flags,
44 catch_config_error,
44 catch_config_error,
45 )
45 )
46 from IPython.utils.importstring import import_item
46 from IPython.utils.importstring import import_item
47 from IPython.utils.localinterfaces import localhost, public_ips
47 from IPython.utils.localinterfaces import localhost, public_ips
48 from IPython.utils.traitlets import Instance, Unicode, Bool, List, Dict, TraitError
48 from IPython.utils.traitlets import Instance, Unicode, Bool, List, Dict, TraitError
49
49
50 from IPython.kernel.zmq.session import (
50 from IPython.kernel.zmq.session import (
51 Session, session_aliases, session_flags, default_secure
51 Session, session_aliases, session_flags, default_secure
52 )
52 )
53
53
54 from IPython.parallel.controller.heartmonitor import HeartMonitor
54 from IPython.parallel.controller.heartmonitor import HeartMonitor
55 from IPython.parallel.controller.hub import HubFactory
55 from IPython.parallel.controller.hub import HubFactory
56 from IPython.parallel.controller.scheduler import TaskScheduler,launch_scheduler
56 from IPython.parallel.controller.scheduler import TaskScheduler,launch_scheduler
57 from IPython.parallel.controller.dictdb import DictDB
57 from IPython.parallel.controller.dictdb import DictDB
58
58
59 from IPython.parallel.util import split_url, disambiguate_url, set_hwm
59 from IPython.parallel.util import split_url, disambiguate_url, set_hwm
60
60
61 # conditional import of SQLiteDB / MongoDB backend class
61 # conditional import of SQLiteDB / MongoDB backend class
62 real_dbs = []
62 real_dbs = []
63
63
64 try:
64 try:
65 from IPython.parallel.controller.sqlitedb import SQLiteDB
65 from IPython.parallel.controller.sqlitedb import SQLiteDB
66 except ImportError:
66 except ImportError:
67 pass
67 pass
68 else:
68 else:
69 real_dbs.append(SQLiteDB)
69 real_dbs.append(SQLiteDB)
70
70
71 try:
71 try:
72 from IPython.parallel.controller.mongodb import MongoDB
72 from IPython.parallel.controller.mongodb import MongoDB
73 except ImportError:
73 except ImportError:
74 pass
74 pass
75 else:
75 else:
76 real_dbs.append(MongoDB)
76 real_dbs.append(MongoDB)
77
77
78
78
79
79
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81 # Module level variables
81 # Module level variables
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83
83
84
84
85 _description = """Start the IPython controller for parallel computing.
85 _description = """Start the IPython controller for parallel computing.
86
86
87 The IPython controller provides a gateway between the IPython engines and
87 The IPython controller provides a gateway between the IPython engines and
88 clients. The controller needs to be started before the engines and can be
88 clients. The controller needs to be started before the engines and can be
89 configured using command line options or using a cluster directory. Cluster
89 configured using command line options or using a cluster directory. Cluster
90 directories contain config, log and security files and are usually located in
90 directories contain config, log and security files and are usually located in
91 your ipython directory and named as "profile_name". See the `profile`
91 your ipython directory and named as "profile_name". See the `profile`
92 and `profile-dir` options for details.
92 and `profile-dir` options for details.
93 """
93 """
94
94
95 _examples = """
95 _examples = """
96 ipcontroller --ip=192.168.0.1 --port=1000 # listen on ip, port for engines
96 ipcontroller --ip=192.168.0.1 --port=1000 # listen on ip, port for engines
97 ipcontroller --scheme=pure # use the pure zeromq scheduler
97 ipcontroller --scheme=pure # use the pure zeromq scheduler
98 """
98 """
99
99
100
100
101 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
102 # The main application
102 # The main application
103 #-----------------------------------------------------------------------------
103 #-----------------------------------------------------------------------------
104 flags = {}
104 flags = {}
105 flags.update(base_flags)
105 flags.update(base_flags)
106 flags.update({
106 flags.update({
107 'usethreads' : ( {'IPControllerApp' : {'use_threads' : True}},
107 'usethreads' : ( {'IPControllerApp' : {'use_threads' : True}},
108 'Use threads instead of processes for the schedulers'),
108 'Use threads instead of processes for the schedulers'),
109 'sqlitedb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.sqlitedb.SQLiteDB'}},
109 'sqlitedb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.sqlitedb.SQLiteDB'}},
110 'use the SQLiteDB backend'),
110 'use the SQLiteDB backend'),
111 'mongodb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.mongodb.MongoDB'}},
111 'mongodb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.mongodb.MongoDB'}},
112 'use the MongoDB backend'),
112 'use the MongoDB backend'),
113 'dictdb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.dictdb.DictDB'}},
113 'dictdb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.dictdb.DictDB'}},
114 'use the in-memory DictDB backend'),
114 'use the in-memory DictDB backend'),
115 'nodb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.dictdb.NoDB'}},
115 'nodb' : ({'HubFactory' : {'db_class' : 'IPython.parallel.controller.dictdb.NoDB'}},
116 """use dummy DB backend, which doesn't store any information.
116 """use dummy DB backend, which doesn't store any information.
117
117
118 This is the default as of IPython 0.13.
118 This is the default as of IPython 0.13.
119
119
120 To enable delayed or repeated retrieval of results from the Hub,
120 To enable delayed or repeated retrieval of results from the Hub,
121 select one of the true db backends.
121 select one of the true db backends.
122 """),
122 """),
123 'reuse' : ({'IPControllerApp' : {'reuse_files' : True}},
123 'reuse' : ({'IPControllerApp' : {'reuse_files' : True}},
124 'reuse existing json connection files'),
124 'reuse existing json connection files'),
125 'restore' : ({'IPControllerApp' : {'restore_engines' : True, 'reuse_files' : True}},
125 'restore' : ({'IPControllerApp' : {'restore_engines' : True, 'reuse_files' : True}},
126 'Attempt to restore engines from a JSON file. '
126 'Attempt to restore engines from a JSON file. '
127 'For use when resuming a crashed controller'),
127 'For use when resuming a crashed controller'),
128 })
128 })
129
129
130 flags.update(session_flags)
130 flags.update(session_flags)
131
131
132 aliases = dict(
132 aliases = dict(
133 ssh = 'IPControllerApp.ssh_server',
133 ssh = 'IPControllerApp.ssh_server',
134 enginessh = 'IPControllerApp.engine_ssh_server',
134 enginessh = 'IPControllerApp.engine_ssh_server',
135 location = 'IPControllerApp.location',
135 location = 'IPControllerApp.location',
136
136
137 url = 'HubFactory.url',
137 url = 'HubFactory.url',
138 ip = 'HubFactory.ip',
138 ip = 'HubFactory.ip',
139 transport = 'HubFactory.transport',
139 transport = 'HubFactory.transport',
140 port = 'HubFactory.regport',
140 port = 'HubFactory.regport',
141
141
142 ping = 'HeartMonitor.period',
142 ping = 'HeartMonitor.period',
143
143
144 scheme = 'TaskScheduler.scheme_name',
144 scheme = 'TaskScheduler.scheme_name',
145 hwm = 'TaskScheduler.hwm',
145 hwm = 'TaskScheduler.hwm',
146 )
146 )
147 aliases.update(base_aliases)
147 aliases.update(base_aliases)
148 aliases.update(session_aliases)
148 aliases.update(session_aliases)
149
149
150 class IPControllerApp(BaseParallelApplication):
150 class IPControllerApp(BaseParallelApplication):
151
151
152 name = u'ipcontroller'
152 name = u'ipcontroller'
153 description = _description
153 description = _description
154 examples = _examples
154 examples = _examples
155 classes = [ProfileDir, Session, HubFactory, TaskScheduler, HeartMonitor, DictDB] + real_dbs
155 classes = [ProfileDir, Session, HubFactory, TaskScheduler, HeartMonitor, DictDB] + real_dbs
156
156
157 # change default to True
157 # change default to True
158 auto_create = Bool(True, config=True,
158 auto_create = Bool(True, config=True,
159 help="""Whether to create profile dir if it doesn't exist.""")
159 help="""Whether to create profile dir if it doesn't exist.""")
160
160
161 reuse_files = Bool(False, config=True,
161 reuse_files = Bool(False, config=True,
162 help="""Whether to reuse existing json connection files.
162 help="""Whether to reuse existing json connection files.
163 If False, connection files will be removed on a clean exit.
163 If False, connection files will be removed on a clean exit.
164 """
164 """
165 )
165 )
166 restore_engines = Bool(False, config=True,
166 restore_engines = Bool(False, config=True,
167 help="""Reload engine state from JSON file
167 help="""Reload engine state from JSON file
168 """
168 """
169 )
169 )
170 ssh_server = Unicode(u'', config=True,
170 ssh_server = Unicode(u'', config=True,
171 help="""ssh url for clients to use when connecting to the Controller
171 help="""ssh url for clients to use when connecting to the Controller
172 processes. It should be of the form: [user@]server[:port]. The
172 processes. It should be of the form: [user@]server[:port]. The
173 Controller's listening addresses must be accessible from the ssh server""",
173 Controller's listening addresses must be accessible from the ssh server""",
174 )
174 )
175 engine_ssh_server = Unicode(u'', config=True,
175 engine_ssh_server = Unicode(u'', config=True,
176 help="""ssh url for engines to use when connecting to the Controller
176 help="""ssh url for engines to use when connecting to the Controller
177 processes. It should be of the form: [user@]server[:port]. The
177 processes. It should be of the form: [user@]server[:port]. The
178 Controller's listening addresses must be accessible from the ssh server""",
178 Controller's listening addresses must be accessible from the ssh server""",
179 )
179 )
180 location = Unicode(u'', config=True,
180 location = Unicode(u'', config=True,
181 help="""The external IP or domain name of the Controller, used for disambiguating
181 help="""The external IP or domain name of the Controller, used for disambiguating
182 engine and client connections.""",
182 engine and client connections.""",
183 )
183 )
184 import_statements = List([], config=True,
184 import_statements = List([], config=True,
185 help="import statements to be run at startup. Necessary in some environments"
185 help="import statements to be run at startup. Necessary in some environments"
186 )
186 )
187
187
188 use_threads = Bool(False, config=True,
188 use_threads = Bool(False, config=True,
189 help='Use threads instead of processes for the schedulers',
189 help='Use threads instead of processes for the schedulers',
190 )
190 )
191
191
192 engine_json_file = Unicode('ipcontroller-engine.json', config=True,
192 engine_json_file = Unicode('ipcontroller-engine.json', config=True,
193 help="JSON filename where engine connection info will be stored.")
193 help="JSON filename where engine connection info will be stored.")
194 client_json_file = Unicode('ipcontroller-client.json', config=True,
194 client_json_file = Unicode('ipcontroller-client.json', config=True,
195 help="JSON filename where client connection info will be stored.")
195 help="JSON filename where client connection info will be stored.")
196
196
197 def _cluster_id_changed(self, name, old, new):
197 def _cluster_id_changed(self, name, old, new):
198 super(IPControllerApp, self)._cluster_id_changed(name, old, new)
198 super(IPControllerApp, self)._cluster_id_changed(name, old, new)
199 self.engine_json_file = "%s-engine.json" % self.name
199 self.engine_json_file = "%s-engine.json" % self.name
200 self.client_json_file = "%s-client.json" % self.name
200 self.client_json_file = "%s-client.json" % self.name
201
201
202
202
203 # internal
203 # internal
204 children = List()
204 children = List()
205 mq_class = Unicode('zmq.devices.ProcessMonitoredQueue')
205 mq_class = Unicode('zmq.devices.ProcessMonitoredQueue')
206
206
207 def _use_threads_changed(self, name, old, new):
207 def _use_threads_changed(self, name, old, new):
208 self.mq_class = 'zmq.devices.%sMonitoredQueue'%('Thread' if new else 'Process')
208 self.mq_class = 'zmq.devices.%sMonitoredQueue'%('Thread' if new else 'Process')
209
209
210 write_connection_files = Bool(True,
210 write_connection_files = Bool(True,
211 help="""Whether to write connection files to disk.
211 help="""Whether to write connection files to disk.
212 True in all cases other than runs with `reuse_files=True` *after the first*
212 True in all cases other than runs with `reuse_files=True` *after the first*
213 """
213 """
214 )
214 )
215
215
216 aliases = Dict(aliases)
216 aliases = Dict(aliases)
217 flags = Dict(flags)
217 flags = Dict(flags)
218
218
219
219
220 def save_connection_dict(self, fname, cdict):
220 def save_connection_dict(self, fname, cdict):
221 """save a connection dict to json file."""
221 """save a connection dict to json file."""
222 c = self.config
222 c = self.config
223 url = cdict['registration']
223 url = cdict['registration']
224 location = cdict['location']
224 location = cdict['location']
225
225
226 if not location:
226 if not location:
227 if public_ips():
227 if public_ips():
228 location = public_ips()[-1]
228 location = public_ips()[-1]
229 else:
229 else:
230 self.log.warn("Could not identify this machine's IP, assuming %s."
230 self.log.warn("Could not identify this machine's IP, assuming %s."
231 " You may need to specify '--location=<external_ip_address>' to help"
231 " You may need to specify '--location=<external_ip_address>' to help"
232 " IPython decide when to connect via loopback." % localhost() )
232 " IPython decide when to connect via loopback." % localhost() )
233 location = localhost()
233 location = localhost()
234 cdict['location'] = location
234 cdict['location'] = location
235 fname = os.path.join(self.profile_dir.security_dir, fname)
235 fname = os.path.join(self.profile_dir.security_dir, fname)
236 self.log.info("writing connection info to %s", fname)
236 self.log.info("writing connection info to %s", fname)
237 with open(fname, 'w') as f:
237 with open(fname, 'w') as f:
238 f.write(json.dumps(cdict, indent=2))
238 f.write(json.dumps(cdict, indent=2))
239 os.chmod(fname, stat.S_IRUSR|stat.S_IWUSR)
239 os.chmod(fname, stat.S_IRUSR|stat.S_IWUSR)
240
240
241 def load_config_from_json(self):
241 def load_config_from_json(self):
242 """load config from existing json connector files."""
242 """load config from existing json connector files."""
243 c = self.config
243 c = self.config
244 self.log.debug("loading config from JSON")
244 self.log.debug("loading config from JSON")
245
245
246 # load engine config
246 # load engine config
247
247
248 fname = os.path.join(self.profile_dir.security_dir, self.engine_json_file)
248 fname = os.path.join(self.profile_dir.security_dir, self.engine_json_file)
249 self.log.info("loading connection info from %s", fname)
249 self.log.info("loading connection info from %s", fname)
250 with open(fname) as f:
250 with open(fname) as f:
251 ecfg = json.loads(f.read())
251 ecfg = json.loads(f.read())
252
252
253 # json gives unicode, Session.key wants bytes
253 # json gives unicode, Session.key wants bytes
254 c.Session.key = ecfg['key'].encode('ascii')
254 c.Session.key = ecfg['key'].encode('ascii')
255
255
256 xport,ip = ecfg['interface'].split('://')
256 xport,ip = ecfg['interface'].split('://')
257
257
258 c.HubFactory.engine_ip = ip
258 c.HubFactory.engine_ip = ip
259 c.HubFactory.engine_transport = xport
259 c.HubFactory.engine_transport = xport
260
260
261 self.location = ecfg['location']
261 self.location = ecfg['location']
262 if not self.engine_ssh_server:
262 if not self.engine_ssh_server:
263 self.engine_ssh_server = ecfg['ssh']
263 self.engine_ssh_server = ecfg['ssh']
264
264
265 # load client config
265 # load client config
266
266
267 fname = os.path.join(self.profile_dir.security_dir, self.client_json_file)
267 fname = os.path.join(self.profile_dir.security_dir, self.client_json_file)
268 self.log.info("loading connection info from %s", fname)
268 self.log.info("loading connection info from %s", fname)
269 with open(fname) as f:
269 with open(fname) as f:
270 ccfg = json.loads(f.read())
270 ccfg = json.loads(f.read())
271
271
272 for key in ('key', 'registration', 'pack', 'unpack', 'signature_scheme'):
272 for key in ('key', 'registration', 'pack', 'unpack', 'signature_scheme'):
273 assert ccfg[key] == ecfg[key], "mismatch between engine and client info: %r" % key
273 assert ccfg[key] == ecfg[key], "mismatch between engine and client info: %r" % key
274
274
275 xport,addr = ccfg['interface'].split('://')
275 xport,addr = ccfg['interface'].split('://')
276
276
277 c.HubFactory.client_transport = xport
277 c.HubFactory.client_transport = xport
278 c.HubFactory.client_ip = ip
278 c.HubFactory.client_ip = ip
279 if not self.ssh_server:
279 if not self.ssh_server:
280 self.ssh_server = ccfg['ssh']
280 self.ssh_server = ccfg['ssh']
281
281
282 # load port config:
282 # load port config:
283 c.HubFactory.regport = ecfg['registration']
283 c.HubFactory.regport = ecfg['registration']
284 c.HubFactory.hb = (ecfg['hb_ping'], ecfg['hb_pong'])
284 c.HubFactory.hb = (ecfg['hb_ping'], ecfg['hb_pong'])
285 c.HubFactory.control = (ccfg['control'], ecfg['control'])
285 c.HubFactory.control = (ccfg['control'], ecfg['control'])
286 c.HubFactory.mux = (ccfg['mux'], ecfg['mux'])
286 c.HubFactory.mux = (ccfg['mux'], ecfg['mux'])
287 c.HubFactory.task = (ccfg['task'], ecfg['task'])
287 c.HubFactory.task = (ccfg['task'], ecfg['task'])
288 c.HubFactory.iopub = (ccfg['iopub'], ecfg['iopub'])
288 c.HubFactory.iopub = (ccfg['iopub'], ecfg['iopub'])
289 c.HubFactory.notifier_port = ccfg['notification']
289 c.HubFactory.notifier_port = ccfg['notification']
290
290
291 def cleanup_connection_files(self):
291 def cleanup_connection_files(self):
292 if self.reuse_files:
292 if self.reuse_files:
293 self.log.debug("leaving JSON connection files for reuse")
293 self.log.debug("leaving JSON connection files for reuse")
294 return
294 return
295 self.log.debug("cleaning up JSON connection files")
295 self.log.debug("cleaning up JSON connection files")
296 for f in (self.client_json_file, self.engine_json_file):
296 for f in (self.client_json_file, self.engine_json_file):
297 f = os.path.join(self.profile_dir.security_dir, f)
297 f = os.path.join(self.profile_dir.security_dir, f)
298 try:
298 try:
299 os.remove(f)
299 os.remove(f)
300 except Exception as e:
300 except Exception as e:
301 self.log.error("Failed to cleanup connection file: %s", e)
301 self.log.error("Failed to cleanup connection file: %s", e)
302 else:
302 else:
303 self.log.debug(u"removed %s", f)
303 self.log.debug(u"removed %s", f)
304
304
305 def load_secondary_config(self):
305 def load_secondary_config(self):
306 """secondary config, loading from JSON and setting defaults"""
306 """secondary config, loading from JSON and setting defaults"""
307 if self.reuse_files:
307 if self.reuse_files:
308 try:
308 try:
309 self.load_config_from_json()
309 self.load_config_from_json()
310 except (AssertionError,IOError) as e:
310 except (AssertionError,IOError) as e:
311 self.log.error("Could not load config from JSON: %s" % e)
311 self.log.error("Could not load config from JSON: %s" % e)
312 else:
312 else:
313 # successfully loaded config from JSON, and reuse=True
313 # successfully loaded config from JSON, and reuse=True
314 # no need to wite back the same file
314 # no need to wite back the same file
315 self.write_connection_files = False
315 self.write_connection_files = False
316
316
317 # switch Session.key default to secure
317 # switch Session.key default to secure
318 default_secure(self.config)
318 default_secure(self.config)
319 self.log.debug("Config changed")
319 self.log.debug("Config changed")
320 self.log.debug(repr(self.config))
320 self.log.debug(repr(self.config))
321
321
322 def init_hub(self):
322 def init_hub(self):
323 c = self.config
323 c = self.config
324
324
325 self.do_import_statements()
325 self.do_import_statements()
326
326
327 try:
327 try:
328 self.factory = HubFactory(config=c, log=self.log)
328 self.factory = HubFactory(config=c, log=self.log)
329 # self.start_logging()
329 # self.start_logging()
330 self.factory.init_hub()
330 self.factory.init_hub()
331 except TraitError:
331 except TraitError:
332 raise
332 raise
333 except Exception:
333 except Exception:
334 self.log.error("Couldn't construct the Controller", exc_info=True)
334 self.log.error("Couldn't construct the Controller", exc_info=True)
335 self.exit(1)
335 self.exit(1)
336
336
337 if self.write_connection_files:
337 if self.write_connection_files:
338 # save to new json config files
338 # save to new json config files
339 f = self.factory
339 f = self.factory
340 base = {
340 base = {
341 'key' : f.session.key.decode('ascii'),
341 'key' : f.session.key.decode('ascii'),
342 'location' : self.location,
342 'location' : self.location,
343 'pack' : f.session.packer,
343 'pack' : f.session.packer,
344 'unpack' : f.session.unpacker,
344 'unpack' : f.session.unpacker,
345 'signature_scheme' : f.session.signature_scheme,
345 'signature_scheme' : f.session.signature_scheme,
346 }
346 }
347
347
348 cdict = {'ssh' : self.ssh_server}
348 cdict = {'ssh' : self.ssh_server}
349 cdict.update(f.client_info)
349 cdict.update(f.client_info)
350 cdict.update(base)
350 cdict.update(base)
351 self.save_connection_dict(self.client_json_file, cdict)
351 self.save_connection_dict(self.client_json_file, cdict)
352
352
353 edict = {'ssh' : self.engine_ssh_server}
353 edict = {'ssh' : self.engine_ssh_server}
354 edict.update(f.engine_info)
354 edict.update(f.engine_info)
355 edict.update(base)
355 edict.update(base)
356 self.save_connection_dict(self.engine_json_file, edict)
356 self.save_connection_dict(self.engine_json_file, edict)
357
357
358 fname = "engines%s.json" % self.cluster_id
358 fname = "engines%s.json" % self.cluster_id
359 self.factory.hub.engine_state_file = os.path.join(self.profile_dir.log_dir, fname)
359 self.factory.hub.engine_state_file = os.path.join(self.profile_dir.log_dir, fname)
360 if self.restore_engines:
360 if self.restore_engines:
361 self.factory.hub._load_engine_state()
361 self.factory.hub._load_engine_state()
362
362
363 def init_schedulers(self):
363 def init_schedulers(self):
364 children = self.children
364 children = self.children
365 mq = import_item(str(self.mq_class))
365 mq = import_item(str(self.mq_class))
366
366
367 f = self.factory
367 f = self.factory
368 ident = f.session.bsession
368 ident = f.session.bsession
369 # disambiguate url, in case of *
369 # disambiguate url, in case of *
370 monitor_url = disambiguate_url(f.monitor_url)
370 monitor_url = disambiguate_url(f.monitor_url)
371 # maybe_inproc = 'inproc://monitor' if self.use_threads else monitor_url
371 # maybe_inproc = 'inproc://monitor' if self.use_threads else monitor_url
372 # IOPub relay (in a Process)
372 # IOPub relay (in a Process)
373 q = mq(zmq.PUB, zmq.SUB, zmq.PUB, b'N/A',b'iopub')
373 q = mq(zmq.PUB, zmq.SUB, zmq.PUB, b'N/A',b'iopub')
374 q.bind_in(f.client_url('iopub'))
374 q.bind_in(f.client_url('iopub'))
375 q.setsockopt_in(zmq.IDENTITY, ident + b"_iopub")
375 q.setsockopt_in(zmq.IDENTITY, ident + b"_iopub")
376 q.bind_out(f.engine_url('iopub'))
376 q.bind_out(f.engine_url('iopub'))
377 q.setsockopt_out(zmq.SUBSCRIBE, b'')
377 q.setsockopt_out(zmq.SUBSCRIBE, b'')
378 q.connect_mon(monitor_url)
378 q.connect_mon(monitor_url)
379 q.daemon=True
379 q.daemon=True
380 children.append(q)
380 children.append(q)
381
381
382 # Multiplexer Queue (in a Process)
382 # Multiplexer Queue (in a Process)
383 q = mq(zmq.ROUTER, zmq.ROUTER, zmq.PUB, b'in', b'out')
383 q = mq(zmq.ROUTER, zmq.ROUTER, zmq.PUB, b'in', b'out')
384
384
385 q.bind_in(f.client_url('mux'))
385 q.bind_in(f.client_url('mux'))
386 q.setsockopt_in(zmq.IDENTITY, b'mux_in')
386 q.setsockopt_in(zmq.IDENTITY, b'mux_in')
387 q.bind_out(f.engine_url('mux'))
387 q.bind_out(f.engine_url('mux'))
388 q.setsockopt_out(zmq.IDENTITY, b'mux_out')
388 q.setsockopt_out(zmq.IDENTITY, b'mux_out')
389 q.connect_mon(monitor_url)
389 q.connect_mon(monitor_url)
390 q.daemon=True
390 q.daemon=True
391 children.append(q)
391 children.append(q)
392
392
393 # Control Queue (in a Process)
393 # Control Queue (in a Process)
394 q = mq(zmq.ROUTER, zmq.ROUTER, zmq.PUB, b'incontrol', b'outcontrol')
394 q = mq(zmq.ROUTER, zmq.ROUTER, zmq.PUB, b'incontrol', b'outcontrol')
395 q.bind_in(f.client_url('control'))
395 q.bind_in(f.client_url('control'))
396 q.setsockopt_in(zmq.IDENTITY, b'control_in')
396 q.setsockopt_in(zmq.IDENTITY, b'control_in')
397 q.bind_out(f.engine_url('control'))
397 q.bind_out(f.engine_url('control'))
398 q.setsockopt_out(zmq.IDENTITY, b'control_out')
398 q.setsockopt_out(zmq.IDENTITY, b'control_out')
399 q.connect_mon(monitor_url)
399 q.connect_mon(monitor_url)
400 q.daemon=True
400 q.daemon=True
401 children.append(q)
401 children.append(q)
402 if 'TaskScheduler.scheme_name' in self.config:
402 if 'TaskScheduler.scheme_name' in self.config:
403 scheme = self.config.TaskScheduler.scheme_name
403 scheme = self.config.TaskScheduler.scheme_name
404 else:
404 else:
405 scheme = TaskScheduler.scheme_name.get_default_value()
405 scheme = TaskScheduler.scheme_name.get_default_value()
406 # Task Queue (in a Process)
406 # Task Queue (in a Process)
407 if scheme == 'pure':
407 if scheme == 'pure':
408 self.log.warn("task::using pure DEALER Task scheduler")
408 self.log.warn("task::using pure DEALER Task scheduler")
409 q = mq(zmq.ROUTER, zmq.DEALER, zmq.PUB, b'intask', b'outtask')
409 q = mq(zmq.ROUTER, zmq.DEALER, zmq.PUB, b'intask', b'outtask')
410 # q.setsockopt_out(zmq.HWM, hub.hwm)
410 # q.setsockopt_out(zmq.HWM, hub.hwm)
411 q.bind_in(f.client_url('task'))
411 q.bind_in(f.client_url('task'))
412 q.setsockopt_in(zmq.IDENTITY, b'task_in')
412 q.setsockopt_in(zmq.IDENTITY, b'task_in')
413 q.bind_out(f.engine_url('task'))
413 q.bind_out(f.engine_url('task'))
414 q.setsockopt_out(zmq.IDENTITY, b'task_out')
414 q.setsockopt_out(zmq.IDENTITY, b'task_out')
415 q.connect_mon(monitor_url)
415 q.connect_mon(monitor_url)
416 q.daemon=True
416 q.daemon=True
417 children.append(q)
417 children.append(q)
418 elif scheme == 'none':
418 elif scheme == 'none':
419 self.log.warn("task::using no Task scheduler")
419 self.log.warn("task::using no Task scheduler")
420
420
421 else:
421 else:
422 self.log.info("task::using Python %s Task scheduler"%scheme)
422 self.log.info("task::using Python %s Task scheduler"%scheme)
423 sargs = (f.client_url('task'), f.engine_url('task'),
423 sargs = (f.client_url('task'), f.engine_url('task'),
424 monitor_url, disambiguate_url(f.client_url('notification')),
424 monitor_url, disambiguate_url(f.client_url('notification')),
425 disambiguate_url(f.client_url('registration')),
425 disambiguate_url(f.client_url('registration')),
426 )
426 )
427 kwargs = dict(logname='scheduler', loglevel=self.log_level,
427 kwargs = dict(logname='scheduler', loglevel=self.log_level,
428 log_url = self.log_url, config=dict(self.config))
428 log_url = self.log_url, config=dict(self.config))
429 if 'Process' in self.mq_class:
429 if 'Process' in self.mq_class:
430 # run the Python scheduler in a Process
430 # run the Python scheduler in a Process
431 q = Process(target=launch_scheduler, args=sargs, kwargs=kwargs)
431 q = Process(target=launch_scheduler, args=sargs, kwargs=kwargs)
432 q.daemon=True
432 q.daemon=True
433 children.append(q)
433 children.append(q)
434 else:
434 else:
435 # single-threaded Controller
435 # single-threaded Controller
436 kwargs['in_thread'] = True
436 kwargs['in_thread'] = True
437 launch_scheduler(*sargs, **kwargs)
437 launch_scheduler(*sargs, **kwargs)
438
438
439 # set unlimited HWM for all relay devices
439 # set unlimited HWM for all relay devices
440 if hasattr(zmq, 'SNDHWM'):
440 if hasattr(zmq, 'SNDHWM'):
441 q = children[0]
441 q = children[0]
442 q.setsockopt_in(zmq.RCVHWM, 0)
442 q.setsockopt_in(zmq.RCVHWM, 0)
443 q.setsockopt_out(zmq.SNDHWM, 0)
443 q.setsockopt_out(zmq.SNDHWM, 0)
444
444
445 for q in children[1:]:
445 for q in children[1:]:
446 if not hasattr(q, 'setsockopt_in'):
446 if not hasattr(q, 'setsockopt_in'):
447 continue
447 continue
448 q.setsockopt_in(zmq.SNDHWM, 0)
448 q.setsockopt_in(zmq.SNDHWM, 0)
449 q.setsockopt_in(zmq.RCVHWM, 0)
449 q.setsockopt_in(zmq.RCVHWM, 0)
450 q.setsockopt_out(zmq.SNDHWM, 0)
450 q.setsockopt_out(zmq.SNDHWM, 0)
451 q.setsockopt_out(zmq.RCVHWM, 0)
451 q.setsockopt_out(zmq.RCVHWM, 0)
452 q.setsockopt_mon(zmq.SNDHWM, 0)
452 q.setsockopt_mon(zmq.SNDHWM, 0)
453
453
454
454
455 def terminate_children(self):
455 def terminate_children(self):
456 child_procs = []
456 child_procs = []
457 for child in self.children:
457 for child in self.children:
458 if isinstance(child, ProcessMonitoredQueue):
458 if isinstance(child, ProcessMonitoredQueue):
459 child_procs.append(child.launcher)
459 child_procs.append(child.launcher)
460 elif isinstance(child, Process):
460 elif isinstance(child, Process):
461 child_procs.append(child)
461 child_procs.append(child)
462 if child_procs:
462 if child_procs:
463 self.log.critical("terminating children...")
463 self.log.critical("terminating children...")
464 for child in child_procs:
464 for child in child_procs:
465 try:
465 try:
466 child.terminate()
466 child.terminate()
467 except OSError:
467 except OSError:
468 # already dead
468 # already dead
469 pass
469 pass
470
470
471 def handle_signal(self, sig, frame):
471 def handle_signal(self, sig, frame):
472 self.log.critical("Received signal %i, shutting down", sig)
472 self.log.critical("Received signal %i, shutting down", sig)
473 self.terminate_children()
473 self.terminate_children()
474 self.loop.stop()
474 self.loop.stop()
475
475
476 def init_signal(self):
476 def init_signal(self):
477 for sig in (SIGINT, SIGABRT, SIGTERM):
477 for sig in (SIGINT, SIGABRT, SIGTERM):
478 signal(sig, self.handle_signal)
478 signal(sig, self.handle_signal)
479
479
480 def do_import_statements(self):
480 def do_import_statements(self):
481 statements = self.import_statements
481 statements = self.import_statements
482 for s in statements:
482 for s in statements:
483 try:
483 try:
484 self.log.msg("Executing statement: '%s'" % s)
484 self.log.msg("Executing statement: '%s'" % s)
485 exec s in globals(), locals()
485 exec(s, globals(), locals())
486 except:
486 except:
487 self.log.msg("Error running statement: %s" % s)
487 self.log.msg("Error running statement: %s" % s)
488
488
489 def forward_logging(self):
489 def forward_logging(self):
490 if self.log_url:
490 if self.log_url:
491 self.log.info("Forwarding logging to %s"%self.log_url)
491 self.log.info("Forwarding logging to %s"%self.log_url)
492 context = zmq.Context.instance()
492 context = zmq.Context.instance()
493 lsock = context.socket(zmq.PUB)
493 lsock = context.socket(zmq.PUB)
494 lsock.connect(self.log_url)
494 lsock.connect(self.log_url)
495 handler = PUBHandler(lsock)
495 handler = PUBHandler(lsock)
496 handler.root_topic = 'controller'
496 handler.root_topic = 'controller'
497 handler.setLevel(self.log_level)
497 handler.setLevel(self.log_level)
498 self.log.addHandler(handler)
498 self.log.addHandler(handler)
499
499
500 @catch_config_error
500 @catch_config_error
501 def initialize(self, argv=None):
501 def initialize(self, argv=None):
502 super(IPControllerApp, self).initialize(argv)
502 super(IPControllerApp, self).initialize(argv)
503 self.forward_logging()
503 self.forward_logging()
504 self.load_secondary_config()
504 self.load_secondary_config()
505 self.init_hub()
505 self.init_hub()
506 self.init_schedulers()
506 self.init_schedulers()
507
507
508 def start(self):
508 def start(self):
509 # Start the subprocesses:
509 # Start the subprocesses:
510 self.factory.start()
510 self.factory.start()
511 # children must be started before signals are setup,
511 # children must be started before signals are setup,
512 # otherwise signal-handling will fire multiple times
512 # otherwise signal-handling will fire multiple times
513 for child in self.children:
513 for child in self.children:
514 child.start()
514 child.start()
515 self.init_signal()
515 self.init_signal()
516
516
517 self.write_pid_file(overwrite=True)
517 self.write_pid_file(overwrite=True)
518
518
519 try:
519 try:
520 self.factory.loop.start()
520 self.factory.loop.start()
521 except KeyboardInterrupt:
521 except KeyboardInterrupt:
522 self.log.critical("Interrupted, Exiting...\n")
522 self.log.critical("Interrupted, Exiting...\n")
523 finally:
523 finally:
524 self.cleanup_connection_files()
524 self.cleanup_connection_files()
525
525
526
526
527 def launch_new_instance(*args, **kwargs):
527 def launch_new_instance(*args, **kwargs):
528 """Create and run the IPython controller"""
528 """Create and run the IPython controller"""
529 if sys.platform == 'win32':
529 if sys.platform == 'win32':
530 # make sure we don't get called from a multiprocessing subprocess
530 # make sure we don't get called from a multiprocessing subprocess
531 # this can result in infinite Controllers being started on Windows
531 # this can result in infinite Controllers being started on Windows
532 # which doesn't have a proper fork, so multiprocessing is wonky
532 # which doesn't have a proper fork, so multiprocessing is wonky
533
533
534 # this only comes up when IPython has been installed using vanilla
534 # this only comes up when IPython has been installed using vanilla
535 # setuptools, and *not* distribute.
535 # setuptools, and *not* distribute.
536 import multiprocessing
536 import multiprocessing
537 p = multiprocessing.current_process()
537 p = multiprocessing.current_process()
538 # the main process has name 'MainProcess'
538 # the main process has name 'MainProcess'
539 # subprocesses will have names like 'Process-1'
539 # subprocesses will have names like 'Process-1'
540 if p.name != 'MainProcess':
540 if p.name != 'MainProcess':
541 # we are a subprocess, don't start another Controller!
541 # we are a subprocess, don't start another Controller!
542 return
542 return
543 return IPControllerApp.launch_instance(*args, **kwargs)
543 return IPControllerApp.launch_instance(*args, **kwargs)
544
544
545
545
546 if __name__ == '__main__':
546 if __name__ == '__main__':
547 launch_new_instance()
547 launch_new_instance()
@@ -1,384 +1,384 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 The IPython engine application
4 The IPython engine application
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * MinRK
9 * MinRK
10
10
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008-2011 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import json
24 import json
25 import os
25 import os
26 import sys
26 import sys
27 import time
27 import time
28
28
29 import zmq
29 import zmq
30 from zmq.eventloop import ioloop
30 from zmq.eventloop import ioloop
31
31
32 from IPython.core.profiledir import ProfileDir
32 from IPython.core.profiledir import ProfileDir
33 from IPython.parallel.apps.baseapp import (
33 from IPython.parallel.apps.baseapp import (
34 BaseParallelApplication,
34 BaseParallelApplication,
35 base_aliases,
35 base_aliases,
36 base_flags,
36 base_flags,
37 catch_config_error,
37 catch_config_error,
38 )
38 )
39 from IPython.kernel.zmq.log import EnginePUBHandler
39 from IPython.kernel.zmq.log import EnginePUBHandler
40 from IPython.kernel.zmq.ipkernel import Kernel
40 from IPython.kernel.zmq.ipkernel import Kernel
41 from IPython.kernel.zmq.kernelapp import IPKernelApp
41 from IPython.kernel.zmq.kernelapp import IPKernelApp
42 from IPython.kernel.zmq.session import (
42 from IPython.kernel.zmq.session import (
43 Session, session_aliases, session_flags
43 Session, session_aliases, session_flags
44 )
44 )
45 from IPython.kernel.zmq.zmqshell import ZMQInteractiveShell
45 from IPython.kernel.zmq.zmqshell import ZMQInteractiveShell
46
46
47 from IPython.config.configurable import Configurable
47 from IPython.config.configurable import Configurable
48
48
49 from IPython.parallel.engine.engine import EngineFactory
49 from IPython.parallel.engine.engine import EngineFactory
50 from IPython.parallel.util import disambiguate_ip_address
50 from IPython.parallel.util import disambiguate_ip_address
51
51
52 from IPython.utils.importstring import import_item
52 from IPython.utils.importstring import import_item
53 from IPython.utils.py3compat import cast_bytes
53 from IPython.utils.py3compat import cast_bytes
54 from IPython.utils.traitlets import Bool, Unicode, Dict, List, Float, Instance
54 from IPython.utils.traitlets import Bool, Unicode, Dict, List, Float, Instance
55
55
56
56
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58 # Module level variables
58 # Module level variables
59 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
60
60
61 _description = """Start an IPython engine for parallel computing.
61 _description = """Start an IPython engine for parallel computing.
62
62
63 IPython engines run in parallel and perform computations on behalf of a client
63 IPython engines run in parallel and perform computations on behalf of a client
64 and controller. A controller needs to be started before the engines. The
64 and controller. A controller needs to be started before the engines. The
65 engine can be configured using command line options or using a cluster
65 engine can be configured using command line options or using a cluster
66 directory. Cluster directories contain config, log and security files and are
66 directory. Cluster directories contain config, log and security files and are
67 usually located in your ipython directory and named as "profile_name".
67 usually located in your ipython directory and named as "profile_name".
68 See the `profile` and `profile-dir` options for details.
68 See the `profile` and `profile-dir` options for details.
69 """
69 """
70
70
71 _examples = """
71 _examples = """
72 ipengine --ip=192.168.0.1 --port=1000 # connect to hub at ip and port
72 ipengine --ip=192.168.0.1 --port=1000 # connect to hub at ip and port
73 ipengine --log-to-file --log-level=DEBUG # log to a file with DEBUG verbosity
73 ipengine --log-to-file --log-level=DEBUG # log to a file with DEBUG verbosity
74 """
74 """
75
75
76 #-----------------------------------------------------------------------------
76 #-----------------------------------------------------------------------------
77 # MPI configuration
77 # MPI configuration
78 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
79
79
80 mpi4py_init = """from mpi4py import MPI as mpi
80 mpi4py_init = """from mpi4py import MPI as mpi
81 mpi.size = mpi.COMM_WORLD.Get_size()
81 mpi.size = mpi.COMM_WORLD.Get_size()
82 mpi.rank = mpi.COMM_WORLD.Get_rank()
82 mpi.rank = mpi.COMM_WORLD.Get_rank()
83 """
83 """
84
84
85
85
86 pytrilinos_init = """from PyTrilinos import Epetra
86 pytrilinos_init = """from PyTrilinos import Epetra
87 class SimpleStruct:
87 class SimpleStruct:
88 pass
88 pass
89 mpi = SimpleStruct()
89 mpi = SimpleStruct()
90 mpi.rank = 0
90 mpi.rank = 0
91 mpi.size = 0
91 mpi.size = 0
92 """
92 """
93
93
94 class MPI(Configurable):
94 class MPI(Configurable):
95 """Configurable for MPI initialization"""
95 """Configurable for MPI initialization"""
96 use = Unicode('', config=True,
96 use = Unicode('', config=True,
97 help='How to enable MPI (mpi4py, pytrilinos, or empty string to disable).'
97 help='How to enable MPI (mpi4py, pytrilinos, or empty string to disable).'
98 )
98 )
99
99
100 def _use_changed(self, name, old, new):
100 def _use_changed(self, name, old, new):
101 # load default init script if it's not set
101 # load default init script if it's not set
102 if not self.init_script:
102 if not self.init_script:
103 self.init_script = self.default_inits.get(new, '')
103 self.init_script = self.default_inits.get(new, '')
104
104
105 init_script = Unicode('', config=True,
105 init_script = Unicode('', config=True,
106 help="Initialization code for MPI")
106 help="Initialization code for MPI")
107
107
108 default_inits = Dict({'mpi4py' : mpi4py_init, 'pytrilinos':pytrilinos_init},
108 default_inits = Dict({'mpi4py' : mpi4py_init, 'pytrilinos':pytrilinos_init},
109 config=True)
109 config=True)
110
110
111
111
112 #-----------------------------------------------------------------------------
112 #-----------------------------------------------------------------------------
113 # Main application
113 # Main application
114 #-----------------------------------------------------------------------------
114 #-----------------------------------------------------------------------------
115 aliases = dict(
115 aliases = dict(
116 file = 'IPEngineApp.url_file',
116 file = 'IPEngineApp.url_file',
117 c = 'IPEngineApp.startup_command',
117 c = 'IPEngineApp.startup_command',
118 s = 'IPEngineApp.startup_script',
118 s = 'IPEngineApp.startup_script',
119
119
120 url = 'EngineFactory.url',
120 url = 'EngineFactory.url',
121 ssh = 'EngineFactory.sshserver',
121 ssh = 'EngineFactory.sshserver',
122 sshkey = 'EngineFactory.sshkey',
122 sshkey = 'EngineFactory.sshkey',
123 ip = 'EngineFactory.ip',
123 ip = 'EngineFactory.ip',
124 transport = 'EngineFactory.transport',
124 transport = 'EngineFactory.transport',
125 port = 'EngineFactory.regport',
125 port = 'EngineFactory.regport',
126 location = 'EngineFactory.location',
126 location = 'EngineFactory.location',
127
127
128 timeout = 'EngineFactory.timeout',
128 timeout = 'EngineFactory.timeout',
129
129
130 mpi = 'MPI.use',
130 mpi = 'MPI.use',
131
131
132 )
132 )
133 aliases.update(base_aliases)
133 aliases.update(base_aliases)
134 aliases.update(session_aliases)
134 aliases.update(session_aliases)
135 flags = {}
135 flags = {}
136 flags.update(base_flags)
136 flags.update(base_flags)
137 flags.update(session_flags)
137 flags.update(session_flags)
138
138
139 class IPEngineApp(BaseParallelApplication):
139 class IPEngineApp(BaseParallelApplication):
140
140
141 name = 'ipengine'
141 name = 'ipengine'
142 description = _description
142 description = _description
143 examples = _examples
143 examples = _examples
144 classes = List([ZMQInteractiveShell, ProfileDir, Session, EngineFactory, Kernel, MPI])
144 classes = List([ZMQInteractiveShell, ProfileDir, Session, EngineFactory, Kernel, MPI])
145
145
146 startup_script = Unicode(u'', config=True,
146 startup_script = Unicode(u'', config=True,
147 help='specify a script to be run at startup')
147 help='specify a script to be run at startup')
148 startup_command = Unicode('', config=True,
148 startup_command = Unicode('', config=True,
149 help='specify a command to be run at startup')
149 help='specify a command to be run at startup')
150
150
151 url_file = Unicode(u'', config=True,
151 url_file = Unicode(u'', config=True,
152 help="""The full location of the file containing the connection information for
152 help="""The full location of the file containing the connection information for
153 the controller. If this is not given, the file must be in the
153 the controller. If this is not given, the file must be in the
154 security directory of the cluster directory. This location is
154 security directory of the cluster directory. This location is
155 resolved using the `profile` or `profile_dir` options.""",
155 resolved using the `profile` or `profile_dir` options.""",
156 )
156 )
157 wait_for_url_file = Float(5, config=True,
157 wait_for_url_file = Float(5, config=True,
158 help="""The maximum number of seconds to wait for url_file to exist.
158 help="""The maximum number of seconds to wait for url_file to exist.
159 This is useful for batch-systems and shared-filesystems where the
159 This is useful for batch-systems and shared-filesystems where the
160 controller and engine are started at the same time and it
160 controller and engine are started at the same time and it
161 may take a moment for the controller to write the connector files.""")
161 may take a moment for the controller to write the connector files.""")
162
162
163 url_file_name = Unicode(u'ipcontroller-engine.json', config=True)
163 url_file_name = Unicode(u'ipcontroller-engine.json', config=True)
164
164
165 def _cluster_id_changed(self, name, old, new):
165 def _cluster_id_changed(self, name, old, new):
166 if new:
166 if new:
167 base = 'ipcontroller-%s' % new
167 base = 'ipcontroller-%s' % new
168 else:
168 else:
169 base = 'ipcontroller'
169 base = 'ipcontroller'
170 self.url_file_name = "%s-engine.json" % base
170 self.url_file_name = "%s-engine.json" % base
171
171
172 log_url = Unicode('', config=True,
172 log_url = Unicode('', config=True,
173 help="""The URL for the iploggerapp instance, for forwarding
173 help="""The URL for the iploggerapp instance, for forwarding
174 logging to a central location.""")
174 logging to a central location.""")
175
175
176 # an IPKernelApp instance, used to setup listening for shell frontends
176 # an IPKernelApp instance, used to setup listening for shell frontends
177 kernel_app = Instance(IPKernelApp)
177 kernel_app = Instance(IPKernelApp)
178
178
179 aliases = Dict(aliases)
179 aliases = Dict(aliases)
180 flags = Dict(flags)
180 flags = Dict(flags)
181
181
182 @property
182 @property
183 def kernel(self):
183 def kernel(self):
184 """allow access to the Kernel object, so I look like IPKernelApp"""
184 """allow access to the Kernel object, so I look like IPKernelApp"""
185 return self.engine.kernel
185 return self.engine.kernel
186
186
187 def find_url_file(self):
187 def find_url_file(self):
188 """Set the url file.
188 """Set the url file.
189
189
190 Here we don't try to actually see if it exists for is valid as that
190 Here we don't try to actually see if it exists for is valid as that
191 is hadled by the connection logic.
191 is hadled by the connection logic.
192 """
192 """
193 config = self.config
193 config = self.config
194 # Find the actual controller key file
194 # Find the actual controller key file
195 if not self.url_file:
195 if not self.url_file:
196 self.url_file = os.path.join(
196 self.url_file = os.path.join(
197 self.profile_dir.security_dir,
197 self.profile_dir.security_dir,
198 self.url_file_name
198 self.url_file_name
199 )
199 )
200
200
201 def load_connector_file(self):
201 def load_connector_file(self):
202 """load config from a JSON connector file,
202 """load config from a JSON connector file,
203 at a *lower* priority than command-line/config files.
203 at a *lower* priority than command-line/config files.
204 """
204 """
205
205
206 self.log.info("Loading url_file %r", self.url_file)
206 self.log.info("Loading url_file %r", self.url_file)
207 config = self.config
207 config = self.config
208
208
209 with open(self.url_file) as f:
209 with open(self.url_file) as f:
210 d = json.loads(f.read())
210 d = json.loads(f.read())
211
211
212 # allow hand-override of location for disambiguation
212 # allow hand-override of location for disambiguation
213 # and ssh-server
213 # and ssh-server
214 if 'EngineFactory.location' not in config:
214 if 'EngineFactory.location' not in config:
215 config.EngineFactory.location = d['location']
215 config.EngineFactory.location = d['location']
216 if 'EngineFactory.sshserver' not in config:
216 if 'EngineFactory.sshserver' not in config:
217 config.EngineFactory.sshserver = d.get('ssh')
217 config.EngineFactory.sshserver = d.get('ssh')
218
218
219 location = config.EngineFactory.location
219 location = config.EngineFactory.location
220
220
221 proto, ip = d['interface'].split('://')
221 proto, ip = d['interface'].split('://')
222 ip = disambiguate_ip_address(ip, location)
222 ip = disambiguate_ip_address(ip, location)
223 d['interface'] = '%s://%s' % (proto, ip)
223 d['interface'] = '%s://%s' % (proto, ip)
224
224
225 # DO NOT allow override of basic URLs, serialization, or key
225 # DO NOT allow override of basic URLs, serialization, or key
226 # JSON file takes top priority there
226 # JSON file takes top priority there
227 config.Session.key = cast_bytes(d['key'])
227 config.Session.key = cast_bytes(d['key'])
228 config.Session.signature_scheme = d['signature_scheme']
228 config.Session.signature_scheme = d['signature_scheme']
229
229
230 config.EngineFactory.url = d['interface'] + ':%i' % d['registration']
230 config.EngineFactory.url = d['interface'] + ':%i' % d['registration']
231
231
232 config.Session.packer = d['pack']
232 config.Session.packer = d['pack']
233 config.Session.unpacker = d['unpack']
233 config.Session.unpacker = d['unpack']
234
234
235 self.log.debug("Config changed:")
235 self.log.debug("Config changed:")
236 self.log.debug("%r", config)
236 self.log.debug("%r", config)
237 self.connection_info = d
237 self.connection_info = d
238
238
239 def bind_kernel(self, **kwargs):
239 def bind_kernel(self, **kwargs):
240 """Promote engine to listening kernel, accessible to frontends."""
240 """Promote engine to listening kernel, accessible to frontends."""
241 if self.kernel_app is not None:
241 if self.kernel_app is not None:
242 return
242 return
243
243
244 self.log.info("Opening ports for direct connections as an IPython kernel")
244 self.log.info("Opening ports for direct connections as an IPython kernel")
245
245
246 kernel = self.kernel
246 kernel = self.kernel
247
247
248 kwargs.setdefault('config', self.config)
248 kwargs.setdefault('config', self.config)
249 kwargs.setdefault('log', self.log)
249 kwargs.setdefault('log', self.log)
250 kwargs.setdefault('profile_dir', self.profile_dir)
250 kwargs.setdefault('profile_dir', self.profile_dir)
251 kwargs.setdefault('session', self.engine.session)
251 kwargs.setdefault('session', self.engine.session)
252
252
253 app = self.kernel_app = IPKernelApp(**kwargs)
253 app = self.kernel_app = IPKernelApp(**kwargs)
254
254
255 # allow IPKernelApp.instance():
255 # allow IPKernelApp.instance():
256 IPKernelApp._instance = app
256 IPKernelApp._instance = app
257
257
258 app.init_connection_file()
258 app.init_connection_file()
259 # relevant contents of init_sockets:
259 # relevant contents of init_sockets:
260
260
261 app.shell_port = app._bind_socket(kernel.shell_streams[0], app.shell_port)
261 app.shell_port = app._bind_socket(kernel.shell_streams[0], app.shell_port)
262 app.log.debug("shell ROUTER Channel on port: %i", app.shell_port)
262 app.log.debug("shell ROUTER Channel on port: %i", app.shell_port)
263
263
264 app.iopub_port = app._bind_socket(kernel.iopub_socket, app.iopub_port)
264 app.iopub_port = app._bind_socket(kernel.iopub_socket, app.iopub_port)
265 app.log.debug("iopub PUB Channel on port: %i", app.iopub_port)
265 app.log.debug("iopub PUB Channel on port: %i", app.iopub_port)
266
266
267 kernel.stdin_socket = self.engine.context.socket(zmq.ROUTER)
267 kernel.stdin_socket = self.engine.context.socket(zmq.ROUTER)
268 app.stdin_port = app._bind_socket(kernel.stdin_socket, app.stdin_port)
268 app.stdin_port = app._bind_socket(kernel.stdin_socket, app.stdin_port)
269 app.log.debug("stdin ROUTER Channel on port: %i", app.stdin_port)
269 app.log.debug("stdin ROUTER Channel on port: %i", app.stdin_port)
270
270
271 # start the heartbeat, and log connection info:
271 # start the heartbeat, and log connection info:
272
272
273 app.init_heartbeat()
273 app.init_heartbeat()
274
274
275 app.log_connection_info()
275 app.log_connection_info()
276 app.write_connection_file()
276 app.write_connection_file()
277
277
278
278
279 def init_engine(self):
279 def init_engine(self):
280 # This is the working dir by now.
280 # This is the working dir by now.
281 sys.path.insert(0, '')
281 sys.path.insert(0, '')
282 config = self.config
282 config = self.config
283 # print config
283 # print config
284 self.find_url_file()
284 self.find_url_file()
285
285
286 # was the url manually specified?
286 # was the url manually specified?
287 keys = set(self.config.EngineFactory.keys())
287 keys = set(self.config.EngineFactory.keys())
288 keys = keys.union(set(self.config.RegistrationFactory.keys()))
288 keys = keys.union(set(self.config.RegistrationFactory.keys()))
289
289
290 if keys.intersection(set(['ip', 'url', 'port'])):
290 if keys.intersection(set(['ip', 'url', 'port'])):
291 # Connection info was specified, don't wait for the file
291 # Connection info was specified, don't wait for the file
292 url_specified = True
292 url_specified = True
293 self.wait_for_url_file = 0
293 self.wait_for_url_file = 0
294 else:
294 else:
295 url_specified = False
295 url_specified = False
296
296
297 if self.wait_for_url_file and not os.path.exists(self.url_file):
297 if self.wait_for_url_file and not os.path.exists(self.url_file):
298 self.log.warn("url_file %r not found", self.url_file)
298 self.log.warn("url_file %r not found", self.url_file)
299 self.log.warn("Waiting up to %.1f seconds for it to arrive.", self.wait_for_url_file)
299 self.log.warn("Waiting up to %.1f seconds for it to arrive.", self.wait_for_url_file)
300 tic = time.time()
300 tic = time.time()
301 while not os.path.exists(self.url_file) and (time.time()-tic < self.wait_for_url_file):
301 while not os.path.exists(self.url_file) and (time.time()-tic < self.wait_for_url_file):
302 # wait for url_file to exist, or until time limit
302 # wait for url_file to exist, or until time limit
303 time.sleep(0.1)
303 time.sleep(0.1)
304
304
305 if os.path.exists(self.url_file):
305 if os.path.exists(self.url_file):
306 self.load_connector_file()
306 self.load_connector_file()
307 elif not url_specified:
307 elif not url_specified:
308 self.log.fatal("Fatal: url file never arrived: %s", self.url_file)
308 self.log.fatal("Fatal: url file never arrived: %s", self.url_file)
309 self.exit(1)
309 self.exit(1)
310
310
311 exec_lines = []
311 exec_lines = []
312 for app in ('IPKernelApp', 'InteractiveShellApp'):
312 for app in ('IPKernelApp', 'InteractiveShellApp'):
313 if '%s.exec_lines' in config:
313 if '%s.exec_lines' in config:
314 exec_lines = config.IPKernelApp.exec_lines = config[app].exec_lines
314 exec_lines = config.IPKernelApp.exec_lines = config[app].exec_lines
315 break
315 break
316
316
317 exec_files = []
317 exec_files = []
318 for app in ('IPKernelApp', 'InteractiveShellApp'):
318 for app in ('IPKernelApp', 'InteractiveShellApp'):
319 if '%s.exec_files' in config:
319 if '%s.exec_files' in config:
320 exec_files = config.IPKernelApp.exec_files = config[app].exec_files
320 exec_files = config.IPKernelApp.exec_files = config[app].exec_files
321 break
321 break
322
322
323 if self.startup_script:
323 if self.startup_script:
324 exec_files.append(self.startup_script)
324 exec_files.append(self.startup_script)
325 if self.startup_command:
325 if self.startup_command:
326 exec_lines.append(self.startup_command)
326 exec_lines.append(self.startup_command)
327
327
328 # Create the underlying shell class and Engine
328 # Create the underlying shell class and Engine
329 # shell_class = import_item(self.master_config.Global.shell_class)
329 # shell_class = import_item(self.master_config.Global.shell_class)
330 # print self.config
330 # print self.config
331 try:
331 try:
332 self.engine = EngineFactory(config=config, log=self.log,
332 self.engine = EngineFactory(config=config, log=self.log,
333 connection_info=self.connection_info,
333 connection_info=self.connection_info,
334 )
334 )
335 except:
335 except:
336 self.log.error("Couldn't start the Engine", exc_info=True)
336 self.log.error("Couldn't start the Engine", exc_info=True)
337 self.exit(1)
337 self.exit(1)
338
338
339 def forward_logging(self):
339 def forward_logging(self):
340 if self.log_url:
340 if self.log_url:
341 self.log.info("Forwarding logging to %s", self.log_url)
341 self.log.info("Forwarding logging to %s", self.log_url)
342 context = self.engine.context
342 context = self.engine.context
343 lsock = context.socket(zmq.PUB)
343 lsock = context.socket(zmq.PUB)
344 lsock.connect(self.log_url)
344 lsock.connect(self.log_url)
345 handler = EnginePUBHandler(self.engine, lsock)
345 handler = EnginePUBHandler(self.engine, lsock)
346 handler.setLevel(self.log_level)
346 handler.setLevel(self.log_level)
347 self.log.addHandler(handler)
347 self.log.addHandler(handler)
348
348
349 def init_mpi(self):
349 def init_mpi(self):
350 global mpi
350 global mpi
351 self.mpi = MPI(parent=self)
351 self.mpi = MPI(parent=self)
352
352
353 mpi_import_statement = self.mpi.init_script
353 mpi_import_statement = self.mpi.init_script
354 if mpi_import_statement:
354 if mpi_import_statement:
355 try:
355 try:
356 self.log.info("Initializing MPI:")
356 self.log.info("Initializing MPI:")
357 self.log.info(mpi_import_statement)
357 self.log.info(mpi_import_statement)
358 exec mpi_import_statement in globals()
358 exec(mpi_import_statement, globals())
359 except:
359 except:
360 mpi = None
360 mpi = None
361 else:
361 else:
362 mpi = None
362 mpi = None
363
363
364 @catch_config_error
364 @catch_config_error
365 def initialize(self, argv=None):
365 def initialize(self, argv=None):
366 super(IPEngineApp, self).initialize(argv)
366 super(IPEngineApp, self).initialize(argv)
367 self.init_mpi()
367 self.init_mpi()
368 self.init_engine()
368 self.init_engine()
369 self.forward_logging()
369 self.forward_logging()
370
370
371 def start(self):
371 def start(self):
372 self.engine.start()
372 self.engine.start()
373 try:
373 try:
374 self.engine.loop.start()
374 self.engine.loop.start()
375 except KeyboardInterrupt:
375 except KeyboardInterrupt:
376 self.log.critical("Engine Interrupted, shutting down...\n")
376 self.log.critical("Engine Interrupted, shutting down...\n")
377
377
378
378
379 launch_new_instance = IPEngineApp.launch_instance
379 launch_new_instance = IPEngineApp.launch_instance
380
380
381
381
382 if __name__ == '__main__':
382 if __name__ == '__main__':
383 launch_new_instance()
383 launch_new_instance()
384
384
@@ -1,225 +1,225 b''
1 """Dependency utilities
1 """Dependency utilities
2
2
3 Authors:
3 Authors:
4
4
5 * Min RK
5 * Min RK
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2013 The IPython Development Team
8 # Copyright (C) 2013 The IPython Development Team
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 from types import ModuleType
14 from types import ModuleType
15
15
16 from IPython.parallel.client.asyncresult import AsyncResult
16 from IPython.parallel.client.asyncresult import AsyncResult
17 from IPython.parallel.error import UnmetDependency
17 from IPython.parallel.error import UnmetDependency
18 from IPython.parallel.util import interactive
18 from IPython.parallel.util import interactive
19 from IPython.utils import py3compat
19 from IPython.utils import py3compat
20 from IPython.utils.pickleutil import can, uncan
20 from IPython.utils.pickleutil import can, uncan
21
21
22 class depend(object):
22 class depend(object):
23 """Dependency decorator, for use with tasks.
23 """Dependency decorator, for use with tasks.
24
24
25 `@depend` lets you define a function for engine dependencies
25 `@depend` lets you define a function for engine dependencies
26 just like you use `apply` for tasks.
26 just like you use `apply` for tasks.
27
27
28
28
29 Examples
29 Examples
30 --------
30 --------
31 ::
31 ::
32
32
33 @depend(df, a,b, c=5)
33 @depend(df, a,b, c=5)
34 def f(m,n,p)
34 def f(m,n,p)
35
35
36 view.apply(f, 1,2,3)
36 view.apply(f, 1,2,3)
37
37
38 will call df(a,b,c=5) on the engine, and if it returns False or
38 will call df(a,b,c=5) on the engine, and if it returns False or
39 raises an UnmetDependency error, then the task will not be run
39 raises an UnmetDependency error, then the task will not be run
40 and another engine will be tried.
40 and another engine will be tried.
41 """
41 """
42 def __init__(self, f, *args, **kwargs):
42 def __init__(self, f, *args, **kwargs):
43 self.f = f
43 self.f = f
44 self.args = args
44 self.args = args
45 self.kwargs = kwargs
45 self.kwargs = kwargs
46
46
47 def __call__(self, f):
47 def __call__(self, f):
48 return dependent(f, self.f, *self.args, **self.kwargs)
48 return dependent(f, self.f, *self.args, **self.kwargs)
49
49
50 class dependent(object):
50 class dependent(object):
51 """A function that depends on another function.
51 """A function that depends on another function.
52 This is an object to prevent the closure used
52 This is an object to prevent the closure used
53 in traditional decorators, which are not picklable.
53 in traditional decorators, which are not picklable.
54 """
54 """
55
55
56 def __init__(self, f, df, *dargs, **dkwargs):
56 def __init__(self, f, df, *dargs, **dkwargs):
57 self.f = f
57 self.f = f
58 self.func_name = getattr(f, '__name__', 'f')
58 self.func_name = getattr(f, '__name__', 'f')
59 self.df = df
59 self.df = df
60 self.dargs = dargs
60 self.dargs = dargs
61 self.dkwargs = dkwargs
61 self.dkwargs = dkwargs
62
62
63 def check_dependency(self):
63 def check_dependency(self):
64 if self.df(*self.dargs, **self.dkwargs) is False:
64 if self.df(*self.dargs, **self.dkwargs) is False:
65 raise UnmetDependency()
65 raise UnmetDependency()
66
66
67 def __call__(self, *args, **kwargs):
67 def __call__(self, *args, **kwargs):
68 return self.f(*args, **kwargs)
68 return self.f(*args, **kwargs)
69
69
70 if not py3compat.PY3:
70 if not py3compat.PY3:
71 @property
71 @property
72 def __name__(self):
72 def __name__(self):
73 return self.func_name
73 return self.func_name
74
74
75 @interactive
75 @interactive
76 def _require(*modules, **mapping):
76 def _require(*modules, **mapping):
77 """Helper for @require decorator."""
77 """Helper for @require decorator."""
78 from IPython.parallel.error import UnmetDependency
78 from IPython.parallel.error import UnmetDependency
79 from IPython.utils.pickleutil import uncan
79 from IPython.utils.pickleutil import uncan
80 user_ns = globals()
80 user_ns = globals()
81 for name in modules:
81 for name in modules:
82 try:
82 try:
83 exec 'import %s' % name in user_ns
83 exec('import %s' % name, user_ns)
84 except ImportError:
84 except ImportError:
85 raise UnmetDependency(name)
85 raise UnmetDependency(name)
86
86
87 for name, cobj in mapping.items():
87 for name, cobj in mapping.items():
88 user_ns[name] = uncan(cobj, user_ns)
88 user_ns[name] = uncan(cobj, user_ns)
89 return True
89 return True
90
90
91 def require(*objects, **mapping):
91 def require(*objects, **mapping):
92 """Simple decorator for requiring local objects and modules to be available
92 """Simple decorator for requiring local objects and modules to be available
93 when the decorated function is called on the engine.
93 when the decorated function is called on the engine.
94
94
95 Modules specified by name or passed directly will be imported
95 Modules specified by name or passed directly will be imported
96 prior to calling the decorated function.
96 prior to calling the decorated function.
97
97
98 Objects other than modules will be pushed as a part of the task.
98 Objects other than modules will be pushed as a part of the task.
99 Functions can be passed positionally,
99 Functions can be passed positionally,
100 and will be pushed to the engine with their __name__.
100 and will be pushed to the engine with their __name__.
101 Other objects can be passed by keyword arg.
101 Other objects can be passed by keyword arg.
102
102
103 Examples
103 Examples
104 --------
104 --------
105
105
106 In [1]: @require('numpy')
106 In [1]: @require('numpy')
107 ...: def norm(a):
107 ...: def norm(a):
108 ...: return numpy.linalg.norm(a,2)
108 ...: return numpy.linalg.norm(a,2)
109
109
110 In [2]: foo = lambda x: x*x
110 In [2]: foo = lambda x: x*x
111 In [3]: @require(foo)
111 In [3]: @require(foo)
112 ...: def bar(a):
112 ...: def bar(a):
113 ...: return foo(1-a)
113 ...: return foo(1-a)
114 """
114 """
115 names = []
115 names = []
116 for obj in objects:
116 for obj in objects:
117 if isinstance(obj, ModuleType):
117 if isinstance(obj, ModuleType):
118 obj = obj.__name__
118 obj = obj.__name__
119
119
120 if isinstance(obj, basestring):
120 if isinstance(obj, basestring):
121 names.append(obj)
121 names.append(obj)
122 elif hasattr(obj, '__name__'):
122 elif hasattr(obj, '__name__'):
123 mapping[obj.__name__] = obj
123 mapping[obj.__name__] = obj
124 else:
124 else:
125 raise TypeError("Objects other than modules and functions "
125 raise TypeError("Objects other than modules and functions "
126 "must be passed by kwarg, but got: %s" % type(obj)
126 "must be passed by kwarg, but got: %s" % type(obj)
127 )
127 )
128
128
129 for name, obj in mapping.items():
129 for name, obj in mapping.items():
130 mapping[name] = can(obj)
130 mapping[name] = can(obj)
131 return depend(_require, *names, **mapping)
131 return depend(_require, *names, **mapping)
132
132
133 class Dependency(set):
133 class Dependency(set):
134 """An object for representing a set of msg_id dependencies.
134 """An object for representing a set of msg_id dependencies.
135
135
136 Subclassed from set().
136 Subclassed from set().
137
137
138 Parameters
138 Parameters
139 ----------
139 ----------
140 dependencies: list/set of msg_ids or AsyncResult objects or output of Dependency.as_dict()
140 dependencies: list/set of msg_ids or AsyncResult objects or output of Dependency.as_dict()
141 The msg_ids to depend on
141 The msg_ids to depend on
142 all : bool [default True]
142 all : bool [default True]
143 Whether the dependency should be considered met when *all* depending tasks have completed
143 Whether the dependency should be considered met when *all* depending tasks have completed
144 or only when *any* have been completed.
144 or only when *any* have been completed.
145 success : bool [default True]
145 success : bool [default True]
146 Whether to consider successes as fulfilling dependencies.
146 Whether to consider successes as fulfilling dependencies.
147 failure : bool [default False]
147 failure : bool [default False]
148 Whether to consider failures as fulfilling dependencies.
148 Whether to consider failures as fulfilling dependencies.
149
149
150 If `all=success=True` and `failure=False`, then the task will fail with an ImpossibleDependency
150 If `all=success=True` and `failure=False`, then the task will fail with an ImpossibleDependency
151 as soon as the first depended-upon task fails.
151 as soon as the first depended-upon task fails.
152 """
152 """
153
153
154 all=True
154 all=True
155 success=True
155 success=True
156 failure=True
156 failure=True
157
157
158 def __init__(self, dependencies=[], all=True, success=True, failure=False):
158 def __init__(self, dependencies=[], all=True, success=True, failure=False):
159 if isinstance(dependencies, dict):
159 if isinstance(dependencies, dict):
160 # load from dict
160 # load from dict
161 all = dependencies.get('all', True)
161 all = dependencies.get('all', True)
162 success = dependencies.get('success', success)
162 success = dependencies.get('success', success)
163 failure = dependencies.get('failure', failure)
163 failure = dependencies.get('failure', failure)
164 dependencies = dependencies.get('dependencies', [])
164 dependencies = dependencies.get('dependencies', [])
165 ids = []
165 ids = []
166
166
167 # extract ids from various sources:
167 # extract ids from various sources:
168 if isinstance(dependencies, (basestring, AsyncResult)):
168 if isinstance(dependencies, (basestring, AsyncResult)):
169 dependencies = [dependencies]
169 dependencies = [dependencies]
170 for d in dependencies:
170 for d in dependencies:
171 if isinstance(d, basestring):
171 if isinstance(d, basestring):
172 ids.append(d)
172 ids.append(d)
173 elif isinstance(d, AsyncResult):
173 elif isinstance(d, AsyncResult):
174 ids.extend(d.msg_ids)
174 ids.extend(d.msg_ids)
175 else:
175 else:
176 raise TypeError("invalid dependency type: %r"%type(d))
176 raise TypeError("invalid dependency type: %r"%type(d))
177
177
178 set.__init__(self, ids)
178 set.__init__(self, ids)
179 self.all = all
179 self.all = all
180 if not (success or failure):
180 if not (success or failure):
181 raise ValueError("Must depend on at least one of successes or failures!")
181 raise ValueError("Must depend on at least one of successes or failures!")
182 self.success=success
182 self.success=success
183 self.failure = failure
183 self.failure = failure
184
184
185 def check(self, completed, failed=None):
185 def check(self, completed, failed=None):
186 """check whether our dependencies have been met."""
186 """check whether our dependencies have been met."""
187 if len(self) == 0:
187 if len(self) == 0:
188 return True
188 return True
189 against = set()
189 against = set()
190 if self.success:
190 if self.success:
191 against = completed
191 against = completed
192 if failed is not None and self.failure:
192 if failed is not None and self.failure:
193 against = against.union(failed)
193 against = against.union(failed)
194 if self.all:
194 if self.all:
195 return self.issubset(against)
195 return self.issubset(against)
196 else:
196 else:
197 return not self.isdisjoint(against)
197 return not self.isdisjoint(against)
198
198
199 def unreachable(self, completed, failed=None):
199 def unreachable(self, completed, failed=None):
200 """return whether this dependency has become impossible."""
200 """return whether this dependency has become impossible."""
201 if len(self) == 0:
201 if len(self) == 0:
202 return False
202 return False
203 against = set()
203 against = set()
204 if not self.success:
204 if not self.success:
205 against = completed
205 against = completed
206 if failed is not None and not self.failure:
206 if failed is not None and not self.failure:
207 against = against.union(failed)
207 against = against.union(failed)
208 if self.all:
208 if self.all:
209 return not self.isdisjoint(against)
209 return not self.isdisjoint(against)
210 else:
210 else:
211 return self.issubset(against)
211 return self.issubset(against)
212
212
213
213
214 def as_dict(self):
214 def as_dict(self):
215 """Represent this dependency as a dict. For json compatibility."""
215 """Represent this dependency as a dict. For json compatibility."""
216 return dict(
216 return dict(
217 dependencies=list(self),
217 dependencies=list(self),
218 all=self.all,
218 all=self.all,
219 success=self.success,
219 success=self.success,
220 failure=self.failure
220 failure=self.failure
221 )
221 )
222
222
223
223
224 __all__ = ['depend', 'require', 'dependent', 'Dependency']
224 __all__ = ['depend', 'require', 'dependent', 'Dependency']
225
225
@@ -1,368 +1,368 b''
1 """some generic utilities for dealing with classes, urls, and serialization
1 """some generic utilities for dealing with classes, urls, and serialization
2
2
3 Authors:
3 Authors:
4
4
5 * Min RK
5 * Min RK
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2010-2011 The IPython Development Team
8 # Copyright (C) 2010-2011 The IPython Development Team
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Standard library imports.
18 # Standard library imports.
19 import logging
19 import logging
20 import os
20 import os
21 import re
21 import re
22 import stat
22 import stat
23 import socket
23 import socket
24 import sys
24 import sys
25 from signal import signal, SIGINT, SIGABRT, SIGTERM
25 from signal import signal, SIGINT, SIGABRT, SIGTERM
26 try:
26 try:
27 from signal import SIGKILL
27 from signal import SIGKILL
28 except ImportError:
28 except ImportError:
29 SIGKILL=None
29 SIGKILL=None
30
30
31 try:
31 try:
32 import cPickle
32 import cPickle
33 pickle = cPickle
33 pickle = cPickle
34 except:
34 except:
35 cPickle = None
35 cPickle = None
36 import pickle
36 import pickle
37
37
38 # System library imports
38 # System library imports
39 import zmq
39 import zmq
40 from zmq.log import handlers
40 from zmq.log import handlers
41
41
42 from IPython.external.decorator import decorator
42 from IPython.external.decorator import decorator
43
43
44 # IPython imports
44 # IPython imports
45 from IPython.config.application import Application
45 from IPython.config.application import Application
46 from IPython.utils.localinterfaces import localhost, is_public_ip, public_ips
46 from IPython.utils.localinterfaces import localhost, is_public_ip, public_ips
47 from IPython.kernel.zmq.log import EnginePUBHandler
47 from IPython.kernel.zmq.log import EnginePUBHandler
48 from IPython.kernel.zmq.serialize import (
48 from IPython.kernel.zmq.serialize import (
49 unserialize_object, serialize_object, pack_apply_message, unpack_apply_message
49 unserialize_object, serialize_object, pack_apply_message, unpack_apply_message
50 )
50 )
51
51
52 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
53 # Classes
53 # Classes
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55
55
56 class Namespace(dict):
56 class Namespace(dict):
57 """Subclass of dict for attribute access to keys."""
57 """Subclass of dict for attribute access to keys."""
58
58
59 def __getattr__(self, key):
59 def __getattr__(self, key):
60 """getattr aliased to getitem"""
60 """getattr aliased to getitem"""
61 if key in self.iterkeys():
61 if key in self.iterkeys():
62 return self[key]
62 return self[key]
63 else:
63 else:
64 raise NameError(key)
64 raise NameError(key)
65
65
66 def __setattr__(self, key, value):
66 def __setattr__(self, key, value):
67 """setattr aliased to setitem, with strict"""
67 """setattr aliased to setitem, with strict"""
68 if hasattr(dict, key):
68 if hasattr(dict, key):
69 raise KeyError("Cannot override dict keys %r"%key)
69 raise KeyError("Cannot override dict keys %r"%key)
70 self[key] = value
70 self[key] = value
71
71
72
72
73 class ReverseDict(dict):
73 class ReverseDict(dict):
74 """simple double-keyed subset of dict methods."""
74 """simple double-keyed subset of dict methods."""
75
75
76 def __init__(self, *args, **kwargs):
76 def __init__(self, *args, **kwargs):
77 dict.__init__(self, *args, **kwargs)
77 dict.__init__(self, *args, **kwargs)
78 self._reverse = dict()
78 self._reverse = dict()
79 for key, value in self.iteritems():
79 for key, value in self.iteritems():
80 self._reverse[value] = key
80 self._reverse[value] = key
81
81
82 def __getitem__(self, key):
82 def __getitem__(self, key):
83 try:
83 try:
84 return dict.__getitem__(self, key)
84 return dict.__getitem__(self, key)
85 except KeyError:
85 except KeyError:
86 return self._reverse[key]
86 return self._reverse[key]
87
87
88 def __setitem__(self, key, value):
88 def __setitem__(self, key, value):
89 if key in self._reverse:
89 if key in self._reverse:
90 raise KeyError("Can't have key %r on both sides!"%key)
90 raise KeyError("Can't have key %r on both sides!"%key)
91 dict.__setitem__(self, key, value)
91 dict.__setitem__(self, key, value)
92 self._reverse[value] = key
92 self._reverse[value] = key
93
93
94 def pop(self, key):
94 def pop(self, key):
95 value = dict.pop(self, key)
95 value = dict.pop(self, key)
96 self._reverse.pop(value)
96 self._reverse.pop(value)
97 return value
97 return value
98
98
99 def get(self, key, default=None):
99 def get(self, key, default=None):
100 try:
100 try:
101 return self[key]
101 return self[key]
102 except KeyError:
102 except KeyError:
103 return default
103 return default
104
104
105 #-----------------------------------------------------------------------------
105 #-----------------------------------------------------------------------------
106 # Functions
106 # Functions
107 #-----------------------------------------------------------------------------
107 #-----------------------------------------------------------------------------
108
108
109 @decorator
109 @decorator
110 def log_errors(f, self, *args, **kwargs):
110 def log_errors(f, self, *args, **kwargs):
111 """decorator to log unhandled exceptions raised in a method.
111 """decorator to log unhandled exceptions raised in a method.
112
112
113 For use wrapping on_recv callbacks, so that exceptions
113 For use wrapping on_recv callbacks, so that exceptions
114 do not cause the stream to be closed.
114 do not cause the stream to be closed.
115 """
115 """
116 try:
116 try:
117 return f(self, *args, **kwargs)
117 return f(self, *args, **kwargs)
118 except Exception:
118 except Exception:
119 self.log.error("Uncaught exception in %r" % f, exc_info=True)
119 self.log.error("Uncaught exception in %r" % f, exc_info=True)
120
120
121
121
122 def is_url(url):
122 def is_url(url):
123 """boolean check for whether a string is a zmq url"""
123 """boolean check for whether a string is a zmq url"""
124 if '://' not in url:
124 if '://' not in url:
125 return False
125 return False
126 proto, addr = url.split('://', 1)
126 proto, addr = url.split('://', 1)
127 if proto.lower() not in ['tcp','pgm','epgm','ipc','inproc']:
127 if proto.lower() not in ['tcp','pgm','epgm','ipc','inproc']:
128 return False
128 return False
129 return True
129 return True
130
130
131 def validate_url(url):
131 def validate_url(url):
132 """validate a url for zeromq"""
132 """validate a url for zeromq"""
133 if not isinstance(url, basestring):
133 if not isinstance(url, basestring):
134 raise TypeError("url must be a string, not %r"%type(url))
134 raise TypeError("url must be a string, not %r"%type(url))
135 url = url.lower()
135 url = url.lower()
136
136
137 proto_addr = url.split('://')
137 proto_addr = url.split('://')
138 assert len(proto_addr) == 2, 'Invalid url: %r'%url
138 assert len(proto_addr) == 2, 'Invalid url: %r'%url
139 proto, addr = proto_addr
139 proto, addr = proto_addr
140 assert proto in ['tcp','pgm','epgm','ipc','inproc'], "Invalid protocol: %r"%proto
140 assert proto in ['tcp','pgm','epgm','ipc','inproc'], "Invalid protocol: %r"%proto
141
141
142 # domain pattern adapted from http://www.regexlib.com/REDetails.aspx?regexp_id=391
142 # domain pattern adapted from http://www.regexlib.com/REDetails.aspx?regexp_id=391
143 # author: Remi Sabourin
143 # author: Remi Sabourin
144 pat = re.compile(r'^([\w\d]([\w\d\-]{0,61}[\w\d])?\.)*[\w\d]([\w\d\-]{0,61}[\w\d])?$')
144 pat = re.compile(r'^([\w\d]([\w\d\-]{0,61}[\w\d])?\.)*[\w\d]([\w\d\-]{0,61}[\w\d])?$')
145
145
146 if proto == 'tcp':
146 if proto == 'tcp':
147 lis = addr.split(':')
147 lis = addr.split(':')
148 assert len(lis) == 2, 'Invalid url: %r'%url
148 assert len(lis) == 2, 'Invalid url: %r'%url
149 addr,s_port = lis
149 addr,s_port = lis
150 try:
150 try:
151 port = int(s_port)
151 port = int(s_port)
152 except ValueError:
152 except ValueError:
153 raise AssertionError("Invalid port %r in url: %r"%(port, url))
153 raise AssertionError("Invalid port %r in url: %r"%(port, url))
154
154
155 assert addr == '*' or pat.match(addr) is not None, 'Invalid url: %r'%url
155 assert addr == '*' or pat.match(addr) is not None, 'Invalid url: %r'%url
156
156
157 else:
157 else:
158 # only validate tcp urls currently
158 # only validate tcp urls currently
159 pass
159 pass
160
160
161 return True
161 return True
162
162
163
163
164 def validate_url_container(container):
164 def validate_url_container(container):
165 """validate a potentially nested collection of urls."""
165 """validate a potentially nested collection of urls."""
166 if isinstance(container, basestring):
166 if isinstance(container, basestring):
167 url = container
167 url = container
168 return validate_url(url)
168 return validate_url(url)
169 elif isinstance(container, dict):
169 elif isinstance(container, dict):
170 container = container.itervalues()
170 container = container.itervalues()
171
171
172 for element in container:
172 for element in container:
173 validate_url_container(element)
173 validate_url_container(element)
174
174
175
175
176 def split_url(url):
176 def split_url(url):
177 """split a zmq url (tcp://ip:port) into ('tcp','ip','port')."""
177 """split a zmq url (tcp://ip:port) into ('tcp','ip','port')."""
178 proto_addr = url.split('://')
178 proto_addr = url.split('://')
179 assert len(proto_addr) == 2, 'Invalid url: %r'%url
179 assert len(proto_addr) == 2, 'Invalid url: %r'%url
180 proto, addr = proto_addr
180 proto, addr = proto_addr
181 lis = addr.split(':')
181 lis = addr.split(':')
182 assert len(lis) == 2, 'Invalid url: %r'%url
182 assert len(lis) == 2, 'Invalid url: %r'%url
183 addr,s_port = lis
183 addr,s_port = lis
184 return proto,addr,s_port
184 return proto,addr,s_port
185
185
186 def disambiguate_ip_address(ip, location=None):
186 def disambiguate_ip_address(ip, location=None):
187 """turn multi-ip interfaces '0.0.0.0' and '*' into connectable
187 """turn multi-ip interfaces '0.0.0.0' and '*' into connectable
188 ones, based on the location (default interpretation of location is localhost)."""
188 ones, based on the location (default interpretation of location is localhost)."""
189 if ip in ('0.0.0.0', '*'):
189 if ip in ('0.0.0.0', '*'):
190 if location is None or is_public_ip(location) or not public_ips():
190 if location is None or is_public_ip(location) or not public_ips():
191 # If location is unspecified or cannot be determined, assume local
191 # If location is unspecified or cannot be determined, assume local
192 ip = localhost()
192 ip = localhost()
193 elif location:
193 elif location:
194 return location
194 return location
195 return ip
195 return ip
196
196
197 def disambiguate_url(url, location=None):
197 def disambiguate_url(url, location=None):
198 """turn multi-ip interfaces '0.0.0.0' and '*' into connectable
198 """turn multi-ip interfaces '0.0.0.0' and '*' into connectable
199 ones, based on the location (default interpretation is localhost).
199 ones, based on the location (default interpretation is localhost).
200
200
201 This is for zeromq urls, such as tcp://*:10101."""
201 This is for zeromq urls, such as tcp://*:10101."""
202 try:
202 try:
203 proto,ip,port = split_url(url)
203 proto,ip,port = split_url(url)
204 except AssertionError:
204 except AssertionError:
205 # probably not tcp url; could be ipc, etc.
205 # probably not tcp url; could be ipc, etc.
206 return url
206 return url
207
207
208 ip = disambiguate_ip_address(ip,location)
208 ip = disambiguate_ip_address(ip,location)
209
209
210 return "%s://%s:%s"%(proto,ip,port)
210 return "%s://%s:%s"%(proto,ip,port)
211
211
212
212
213 #--------------------------------------------------------------------------
213 #--------------------------------------------------------------------------
214 # helpers for implementing old MEC API via view.apply
214 # helpers for implementing old MEC API via view.apply
215 #--------------------------------------------------------------------------
215 #--------------------------------------------------------------------------
216
216
217 def interactive(f):
217 def interactive(f):
218 """decorator for making functions appear as interactively defined.
218 """decorator for making functions appear as interactively defined.
219 This results in the function being linked to the user_ns as globals()
219 This results in the function being linked to the user_ns as globals()
220 instead of the module globals().
220 instead of the module globals().
221 """
221 """
222 f.__module__ = '__main__'
222 f.__module__ = '__main__'
223 return f
223 return f
224
224
225 @interactive
225 @interactive
226 def _push(**ns):
226 def _push(**ns):
227 """helper method for implementing `client.push` via `client.apply`"""
227 """helper method for implementing `client.push` via `client.apply`"""
228 user_ns = globals()
228 user_ns = globals()
229 tmp = '_IP_PUSH_TMP_'
229 tmp = '_IP_PUSH_TMP_'
230 while tmp in user_ns:
230 while tmp in user_ns:
231 tmp = tmp + '_'
231 tmp = tmp + '_'
232 try:
232 try:
233 for name, value in ns.iteritems():
233 for name, value in ns.iteritems():
234 user_ns[tmp] = value
234 user_ns[tmp] = value
235 exec "%s = %s" % (name, tmp) in user_ns
235 exec("%s = %s" % (name, tmp), user_ns)
236 finally:
236 finally:
237 user_ns.pop(tmp, None)
237 user_ns.pop(tmp, None)
238
238
239 @interactive
239 @interactive
240 def _pull(keys):
240 def _pull(keys):
241 """helper method for implementing `client.pull` via `client.apply`"""
241 """helper method for implementing `client.pull` via `client.apply`"""
242 if isinstance(keys, (list,tuple, set)):
242 if isinstance(keys, (list,tuple, set)):
243 return map(lambda key: eval(key, globals()), keys)
243 return map(lambda key: eval(key, globals()), keys)
244 else:
244 else:
245 return eval(keys, globals())
245 return eval(keys, globals())
246
246
247 @interactive
247 @interactive
248 def _execute(code):
248 def _execute(code):
249 """helper method for implementing `client.execute` via `client.apply`"""
249 """helper method for implementing `client.execute` via `client.apply`"""
250 exec code in globals()
250 exec(code, globals())
251
251
252 #--------------------------------------------------------------------------
252 #--------------------------------------------------------------------------
253 # extra process management utilities
253 # extra process management utilities
254 #--------------------------------------------------------------------------
254 #--------------------------------------------------------------------------
255
255
256 _random_ports = set()
256 _random_ports = set()
257
257
258 def select_random_ports(n):
258 def select_random_ports(n):
259 """Selects and return n random ports that are available."""
259 """Selects and return n random ports that are available."""
260 ports = []
260 ports = []
261 for i in xrange(n):
261 for i in xrange(n):
262 sock = socket.socket()
262 sock = socket.socket()
263 sock.bind(('', 0))
263 sock.bind(('', 0))
264 while sock.getsockname()[1] in _random_ports:
264 while sock.getsockname()[1] in _random_ports:
265 sock.close()
265 sock.close()
266 sock = socket.socket()
266 sock = socket.socket()
267 sock.bind(('', 0))
267 sock.bind(('', 0))
268 ports.append(sock)
268 ports.append(sock)
269 for i, sock in enumerate(ports):
269 for i, sock in enumerate(ports):
270 port = sock.getsockname()[1]
270 port = sock.getsockname()[1]
271 sock.close()
271 sock.close()
272 ports[i] = port
272 ports[i] = port
273 _random_ports.add(port)
273 _random_ports.add(port)
274 return ports
274 return ports
275
275
276 def signal_children(children):
276 def signal_children(children):
277 """Relay interupt/term signals to children, for more solid process cleanup."""
277 """Relay interupt/term signals to children, for more solid process cleanup."""
278 def terminate_children(sig, frame):
278 def terminate_children(sig, frame):
279 log = Application.instance().log
279 log = Application.instance().log
280 log.critical("Got signal %i, terminating children..."%sig)
280 log.critical("Got signal %i, terminating children..."%sig)
281 for child in children:
281 for child in children:
282 child.terminate()
282 child.terminate()
283
283
284 sys.exit(sig != SIGINT)
284 sys.exit(sig != SIGINT)
285 # sys.exit(sig)
285 # sys.exit(sig)
286 for sig in (SIGINT, SIGABRT, SIGTERM):
286 for sig in (SIGINT, SIGABRT, SIGTERM):
287 signal(sig, terminate_children)
287 signal(sig, terminate_children)
288
288
289 def generate_exec_key(keyfile):
289 def generate_exec_key(keyfile):
290 import uuid
290 import uuid
291 newkey = str(uuid.uuid4())
291 newkey = str(uuid.uuid4())
292 with open(keyfile, 'w') as f:
292 with open(keyfile, 'w') as f:
293 # f.write('ipython-key ')
293 # f.write('ipython-key ')
294 f.write(newkey+'\n')
294 f.write(newkey+'\n')
295 # set user-only RW permissions (0600)
295 # set user-only RW permissions (0600)
296 # this will have no effect on Windows
296 # this will have no effect on Windows
297 os.chmod(keyfile, stat.S_IRUSR|stat.S_IWUSR)
297 os.chmod(keyfile, stat.S_IRUSR|stat.S_IWUSR)
298
298
299
299
300 def integer_loglevel(loglevel):
300 def integer_loglevel(loglevel):
301 try:
301 try:
302 loglevel = int(loglevel)
302 loglevel = int(loglevel)
303 except ValueError:
303 except ValueError:
304 if isinstance(loglevel, str):
304 if isinstance(loglevel, str):
305 loglevel = getattr(logging, loglevel)
305 loglevel = getattr(logging, loglevel)
306 return loglevel
306 return loglevel
307
307
308 def connect_logger(logname, context, iface, root="ip", loglevel=logging.DEBUG):
308 def connect_logger(logname, context, iface, root="ip", loglevel=logging.DEBUG):
309 logger = logging.getLogger(logname)
309 logger = logging.getLogger(logname)
310 if any([isinstance(h, handlers.PUBHandler) for h in logger.handlers]):
310 if any([isinstance(h, handlers.PUBHandler) for h in logger.handlers]):
311 # don't add a second PUBHandler
311 # don't add a second PUBHandler
312 return
312 return
313 loglevel = integer_loglevel(loglevel)
313 loglevel = integer_loglevel(loglevel)
314 lsock = context.socket(zmq.PUB)
314 lsock = context.socket(zmq.PUB)
315 lsock.connect(iface)
315 lsock.connect(iface)
316 handler = handlers.PUBHandler(lsock)
316 handler = handlers.PUBHandler(lsock)
317 handler.setLevel(loglevel)
317 handler.setLevel(loglevel)
318 handler.root_topic = root
318 handler.root_topic = root
319 logger.addHandler(handler)
319 logger.addHandler(handler)
320 logger.setLevel(loglevel)
320 logger.setLevel(loglevel)
321
321
322 def connect_engine_logger(context, iface, engine, loglevel=logging.DEBUG):
322 def connect_engine_logger(context, iface, engine, loglevel=logging.DEBUG):
323 logger = logging.getLogger()
323 logger = logging.getLogger()
324 if any([isinstance(h, handlers.PUBHandler) for h in logger.handlers]):
324 if any([isinstance(h, handlers.PUBHandler) for h in logger.handlers]):
325 # don't add a second PUBHandler
325 # don't add a second PUBHandler
326 return
326 return
327 loglevel = integer_loglevel(loglevel)
327 loglevel = integer_loglevel(loglevel)
328 lsock = context.socket(zmq.PUB)
328 lsock = context.socket(zmq.PUB)
329 lsock.connect(iface)
329 lsock.connect(iface)
330 handler = EnginePUBHandler(engine, lsock)
330 handler = EnginePUBHandler(engine, lsock)
331 handler.setLevel(loglevel)
331 handler.setLevel(loglevel)
332 logger.addHandler(handler)
332 logger.addHandler(handler)
333 logger.setLevel(loglevel)
333 logger.setLevel(loglevel)
334 return logger
334 return logger
335
335
336 def local_logger(logname, loglevel=logging.DEBUG):
336 def local_logger(logname, loglevel=logging.DEBUG):
337 loglevel = integer_loglevel(loglevel)
337 loglevel = integer_loglevel(loglevel)
338 logger = logging.getLogger(logname)
338 logger = logging.getLogger(logname)
339 if any([isinstance(h, logging.StreamHandler) for h in logger.handlers]):
339 if any([isinstance(h, logging.StreamHandler) for h in logger.handlers]):
340 # don't add a second StreamHandler
340 # don't add a second StreamHandler
341 return
341 return
342 handler = logging.StreamHandler()
342 handler = logging.StreamHandler()
343 handler.setLevel(loglevel)
343 handler.setLevel(loglevel)
344 formatter = logging.Formatter("%(asctime)s.%(msecs).03d [%(name)s] %(message)s",
344 formatter = logging.Formatter("%(asctime)s.%(msecs).03d [%(name)s] %(message)s",
345 datefmt="%Y-%m-%d %H:%M:%S")
345 datefmt="%Y-%m-%d %H:%M:%S")
346 handler.setFormatter(formatter)
346 handler.setFormatter(formatter)
347
347
348 logger.addHandler(handler)
348 logger.addHandler(handler)
349 logger.setLevel(loglevel)
349 logger.setLevel(loglevel)
350 return logger
350 return logger
351
351
352 def set_hwm(sock, hwm=0):
352 def set_hwm(sock, hwm=0):
353 """set zmq High Water Mark on a socket
353 """set zmq High Water Mark on a socket
354
354
355 in a way that always works for various pyzmq / libzmq versions.
355 in a way that always works for various pyzmq / libzmq versions.
356 """
356 """
357 import zmq
357 import zmq
358
358
359 for key in ('HWM', 'SNDHWM', 'RCVHWM'):
359 for key in ('HWM', 'SNDHWM', 'RCVHWM'):
360 opt = getattr(zmq, key, None)
360 opt = getattr(zmq, key, None)
361 if opt is None:
361 if opt is None:
362 continue
362 continue
363 try:
363 try:
364 sock.setsockopt(opt, hwm)
364 sock.setsockopt(opt, hwm)
365 except zmq.ZMQError:
365 except zmq.ZMQError:
366 pass
366 pass
367
367
368 No newline at end of file
368
@@ -1,206 +1,206 b''
1 # coding: utf-8
1 # coding: utf-8
2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 import __builtin__
3 import __builtin__
4 import functools
4 import functools
5 import sys
5 import sys
6 import re
6 import re
7 import types
7 import types
8
8
9 from .encoding import DEFAULT_ENCODING
9 from .encoding import DEFAULT_ENCODING
10
10
11 orig_open = open
11 orig_open = open
12
12
13 def no_code(x, encoding=None):
13 def no_code(x, encoding=None):
14 return x
14 return x
15
15
16 def decode(s, encoding=None):
16 def decode(s, encoding=None):
17 encoding = encoding or DEFAULT_ENCODING
17 encoding = encoding or DEFAULT_ENCODING
18 return s.decode(encoding, "replace")
18 return s.decode(encoding, "replace")
19
19
20 def encode(u, encoding=None):
20 def encode(u, encoding=None):
21 encoding = encoding or DEFAULT_ENCODING
21 encoding = encoding or DEFAULT_ENCODING
22 return u.encode(encoding, "replace")
22 return u.encode(encoding, "replace")
23
23
24
24
25 def cast_unicode(s, encoding=None):
25 def cast_unicode(s, encoding=None):
26 if isinstance(s, bytes):
26 if isinstance(s, bytes):
27 return decode(s, encoding)
27 return decode(s, encoding)
28 return s
28 return s
29
29
30 def cast_bytes(s, encoding=None):
30 def cast_bytes(s, encoding=None):
31 if not isinstance(s, bytes):
31 if not isinstance(s, bytes):
32 return encode(s, encoding)
32 return encode(s, encoding)
33 return s
33 return s
34
34
35 def _modify_str_or_docstring(str_change_func):
35 def _modify_str_or_docstring(str_change_func):
36 @functools.wraps(str_change_func)
36 @functools.wraps(str_change_func)
37 def wrapper(func_or_str):
37 def wrapper(func_or_str):
38 if isinstance(func_or_str, basestring):
38 if isinstance(func_or_str, basestring):
39 func = None
39 func = None
40 doc = func_or_str
40 doc = func_or_str
41 else:
41 else:
42 func = func_or_str
42 func = func_or_str
43 doc = func.__doc__
43 doc = func.__doc__
44
44
45 doc = str_change_func(doc)
45 doc = str_change_func(doc)
46
46
47 if func:
47 if func:
48 func.__doc__ = doc
48 func.__doc__ = doc
49 return func
49 return func
50 return doc
50 return doc
51 return wrapper
51 return wrapper
52
52
53 def safe_unicode(e):
53 def safe_unicode(e):
54 """unicode(e) with various fallbacks. Used for exceptions, which may not be
54 """unicode(e) with various fallbacks. Used for exceptions, which may not be
55 safe to call unicode() on.
55 safe to call unicode() on.
56 """
56 """
57 try:
57 try:
58 return unicode(e)
58 return unicode(e)
59 except UnicodeError:
59 except UnicodeError:
60 pass
60 pass
61
61
62 try:
62 try:
63 return str_to_unicode(str(e))
63 return str_to_unicode(str(e))
64 except UnicodeError:
64 except UnicodeError:
65 pass
65 pass
66
66
67 try:
67 try:
68 return str_to_unicode(repr(e))
68 return str_to_unicode(repr(e))
69 except UnicodeError:
69 except UnicodeError:
70 pass
70 pass
71
71
72 return u'Unrecoverably corrupt evalue'
72 return u'Unrecoverably corrupt evalue'
73
73
74 if sys.version_info[0] >= 3:
74 if sys.version_info[0] >= 3:
75 PY3 = True
75 PY3 = True
76
76
77 input = input
77 input = input
78 builtin_mod_name = "builtins"
78 builtin_mod_name = "builtins"
79
79
80 str_to_unicode = no_code
80 str_to_unicode = no_code
81 unicode_to_str = no_code
81 unicode_to_str = no_code
82 str_to_bytes = encode
82 str_to_bytes = encode
83 bytes_to_str = decode
83 bytes_to_str = decode
84 cast_bytes_py2 = no_code
84 cast_bytes_py2 = no_code
85
85
86 string_types = (str,)
86 string_types = (str,)
87 unicode_type = str
87 unicode_type = str
88
88
89 def isidentifier(s, dotted=False):
89 def isidentifier(s, dotted=False):
90 if dotted:
90 if dotted:
91 return all(isidentifier(a) for a in s.split("."))
91 return all(isidentifier(a) for a in s.split("."))
92 return s.isidentifier()
92 return s.isidentifier()
93
93
94 open = orig_open
94 open = orig_open
95
95
96 MethodType = types.MethodType
96 MethodType = types.MethodType
97
97
98 def execfile(fname, glob, loc=None):
98 def execfile(fname, glob, loc=None):
99 loc = loc if (loc is not None) else glob
99 loc = loc if (loc is not None) else glob
100 with open(fname, 'rb') as f:
100 with open(fname, 'rb') as f:
101 exec compile(f.read(), fname, 'exec') in glob, loc
101 exec(compile(f.read(), fname, 'exec'), glob, loc)
102
102
103 # Refactor print statements in doctests.
103 # Refactor print statements in doctests.
104 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
104 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
105 def _print_statement_sub(match):
105 def _print_statement_sub(match):
106 expr = match.groups('expr')
106 expr = match.groups('expr')
107 return "print(%s)" % expr
107 return "print(%s)" % expr
108
108
109 @_modify_str_or_docstring
109 @_modify_str_or_docstring
110 def doctest_refactor_print(doc):
110 def doctest_refactor_print(doc):
111 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
111 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
112 unfortunately doesn't pick up on our doctests.
112 unfortunately doesn't pick up on our doctests.
113
113
114 Can accept a string or a function, so it can be used as a decorator."""
114 Can accept a string or a function, so it can be used as a decorator."""
115 return _print_statement_re.sub(_print_statement_sub, doc)
115 return _print_statement_re.sub(_print_statement_sub, doc)
116
116
117 # Abstract u'abc' syntax:
117 # Abstract u'abc' syntax:
118 @_modify_str_or_docstring
118 @_modify_str_or_docstring
119 def u_format(s):
119 def u_format(s):
120 """"{u}'abc'" --> "'abc'" (Python 3)
120 """"{u}'abc'" --> "'abc'" (Python 3)
121
121
122 Accepts a string or a function, so it can be used as a decorator."""
122 Accepts a string or a function, so it can be used as a decorator."""
123 return s.format(u='')
123 return s.format(u='')
124
124
125 else:
125 else:
126 PY3 = False
126 PY3 = False
127
127
128 input = raw_input
128 input = raw_input
129 builtin_mod_name = "__builtin__"
129 builtin_mod_name = "__builtin__"
130
130
131 str_to_unicode = decode
131 str_to_unicode = decode
132 unicode_to_str = encode
132 unicode_to_str = encode
133 str_to_bytes = no_code
133 str_to_bytes = no_code
134 bytes_to_str = no_code
134 bytes_to_str = no_code
135 cast_bytes_py2 = cast_bytes
135 cast_bytes_py2 = cast_bytes
136
136
137 string_types = (str, unicode)
137 string_types = (str, unicode)
138 unicode_type = unicode
138 unicode_type = unicode
139
139
140 import re
140 import re
141 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
141 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
142 def isidentifier(s, dotted=False):
142 def isidentifier(s, dotted=False):
143 if dotted:
143 if dotted:
144 return all(isidentifier(a) for a in s.split("."))
144 return all(isidentifier(a) for a in s.split("."))
145 return bool(_name_re.match(s))
145 return bool(_name_re.match(s))
146
146
147 class open(object):
147 class open(object):
148 """Wrapper providing key part of Python 3 open() interface."""
148 """Wrapper providing key part of Python 3 open() interface."""
149 def __init__(self, fname, mode="r", encoding="utf-8"):
149 def __init__(self, fname, mode="r", encoding="utf-8"):
150 self.f = orig_open(fname, mode)
150 self.f = orig_open(fname, mode)
151 self.enc = encoding
151 self.enc = encoding
152
152
153 def write(self, s):
153 def write(self, s):
154 return self.f.write(s.encode(self.enc))
154 return self.f.write(s.encode(self.enc))
155
155
156 def read(self, size=-1):
156 def read(self, size=-1):
157 return self.f.read(size).decode(self.enc)
157 return self.f.read(size).decode(self.enc)
158
158
159 def close(self):
159 def close(self):
160 return self.f.close()
160 return self.f.close()
161
161
162 def __enter__(self):
162 def __enter__(self):
163 return self
163 return self
164
164
165 def __exit__(self, etype, value, traceback):
165 def __exit__(self, etype, value, traceback):
166 self.f.close()
166 self.f.close()
167
167
168 def MethodType(func, instance):
168 def MethodType(func, instance):
169 return types.MethodType(func, instance, type(instance))
169 return types.MethodType(func, instance, type(instance))
170
170
171 # don't override system execfile on 2.x:
171 # don't override system execfile on 2.x:
172 execfile = execfile
172 execfile = execfile
173
173
174 def doctest_refactor_print(func_or_str):
174 def doctest_refactor_print(func_or_str):
175 return func_or_str
175 return func_or_str
176
176
177
177
178 # Abstract u'abc' syntax:
178 # Abstract u'abc' syntax:
179 @_modify_str_or_docstring
179 @_modify_str_or_docstring
180 def u_format(s):
180 def u_format(s):
181 """"{u}'abc'" --> "u'abc'" (Python 2)
181 """"{u}'abc'" --> "u'abc'" (Python 2)
182
182
183 Accepts a string or a function, so it can be used as a decorator."""
183 Accepts a string or a function, so it can be used as a decorator."""
184 return s.format(u='u')
184 return s.format(u='u')
185
185
186 if sys.platform == 'win32':
186 if sys.platform == 'win32':
187 def execfile(fname, glob=None, loc=None):
187 def execfile(fname, glob=None, loc=None):
188 loc = loc if (loc is not None) else glob
188 loc = loc if (loc is not None) else glob
189 # The rstrip() is necessary b/c trailing whitespace in files will
189 # The rstrip() is necessary b/c trailing whitespace in files will
190 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
190 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
191 # but we still support 2.6). See issue 1027.
191 # but we still support 2.6). See issue 1027.
192 scripttext = __builtin__.open(fname).read().rstrip() + '\n'
192 scripttext = __builtin__.open(fname).read().rstrip() + '\n'
193 # compile converts unicode filename to str assuming
193 # compile converts unicode filename to str assuming
194 # ascii. Let's do the conversion before calling compile
194 # ascii. Let's do the conversion before calling compile
195 if isinstance(fname, unicode):
195 if isinstance(fname, unicode):
196 filename = unicode_to_str(fname)
196 filename = unicode_to_str(fname)
197 else:
197 else:
198 filename = fname
198 filename = fname
199 exec compile(scripttext, filename, 'exec') in glob, loc
199 exec(compile(scripttext, filename, 'exec'), glob, loc)
200 else:
200 else:
201 def execfile(fname, *where):
201 def execfile(fname, *where):
202 if isinstance(fname, unicode):
202 if isinstance(fname, unicode):
203 filename = fname.encode(sys.getfilesystemencoding())
203 filename = fname.encode(sys.getfilesystemencoding())
204 else:
204 else:
205 filename = fname
205 filename = fname
206 __builtin__.execfile(filename, *where)
206 __builtin__.execfile(filename, *where)
General Comments 0
You need to be logged in to leave comments. Login now