##// END OF EJS Templates
Replace all import of IPython.utils.warn module
Pierre Gerold -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,257 +1,257 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 System command aliases.
3 System command aliases.
4
4
5 Authors:
5 Authors:
6
6
7 * Fernando Perez
7 * Fernando Perez
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2011 The IPython Development Team
12 # Copyright (C) 2008-2011 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License.
14 # Distributed under the terms of the BSD License.
15 #
15 #
16 # The full license is in the file COPYING.txt, distributed with this software.
16 # The full license is in the file COPYING.txt, distributed with this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 import re
24 import re
25 import sys
25 import sys
26
26
27 from traitlets.config.configurable import Configurable
27 from traitlets.config.configurable import Configurable
28 from IPython.core.error import UsageError
28 from IPython.core.error import UsageError
29
29
30 from IPython.utils.py3compat import string_types
30 from IPython.utils.py3compat import string_types
31 from traitlets import List, Instance
31 from traitlets import List, Instance
32 from IPython.utils.warn import error
32 from logging import error
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Utilities
35 # Utilities
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 # This is used as the pattern for calls to split_user_input.
38 # This is used as the pattern for calls to split_user_input.
39 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
39 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
40
40
41 def default_aliases():
41 def default_aliases():
42 """Return list of shell aliases to auto-define.
42 """Return list of shell aliases to auto-define.
43 """
43 """
44 # Note: the aliases defined here should be safe to use on a kernel
44 # Note: the aliases defined here should be safe to use on a kernel
45 # regardless of what frontend it is attached to. Frontends that use a
45 # regardless of what frontend it is attached to. Frontends that use a
46 # kernel in-process can define additional aliases that will only work in
46 # kernel in-process can define additional aliases that will only work in
47 # their case. For example, things like 'less' or 'clear' that manipulate
47 # their case. For example, things like 'less' or 'clear' that manipulate
48 # the terminal should NOT be declared here, as they will only work if the
48 # the terminal should NOT be declared here, as they will only work if the
49 # kernel is running inside a true terminal, and not over the network.
49 # kernel is running inside a true terminal, and not over the network.
50
50
51 if os.name == 'posix':
51 if os.name == 'posix':
52 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
52 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
53 ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'),
53 ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'),
54 ('cat', 'cat'),
54 ('cat', 'cat'),
55 ]
55 ]
56 # Useful set of ls aliases. The GNU and BSD options are a little
56 # Useful set of ls aliases. The GNU and BSD options are a little
57 # different, so we make aliases that provide as similar as possible
57 # different, so we make aliases that provide as similar as possible
58 # behavior in ipython, by passing the right flags for each platform
58 # behavior in ipython, by passing the right flags for each platform
59 if sys.platform.startswith('linux'):
59 if sys.platform.startswith('linux'):
60 ls_aliases = [('ls', 'ls -F --color'),
60 ls_aliases = [('ls', 'ls -F --color'),
61 # long ls
61 # long ls
62 ('ll', 'ls -F -o --color'),
62 ('ll', 'ls -F -o --color'),
63 # ls normal files only
63 # ls normal files only
64 ('lf', 'ls -F -o --color %l | grep ^-'),
64 ('lf', 'ls -F -o --color %l | grep ^-'),
65 # ls symbolic links
65 # ls symbolic links
66 ('lk', 'ls -F -o --color %l | grep ^l'),
66 ('lk', 'ls -F -o --color %l | grep ^l'),
67 # directories or links to directories,
67 # directories or links to directories,
68 ('ldir', 'ls -F -o --color %l | grep /$'),
68 ('ldir', 'ls -F -o --color %l | grep /$'),
69 # things which are executable
69 # things which are executable
70 ('lx', 'ls -F -o --color %l | grep ^-..x'),
70 ('lx', 'ls -F -o --color %l | grep ^-..x'),
71 ]
71 ]
72 elif sys.platform.startswith('openbsd') or sys.platform.startswith('netbsd'):
72 elif sys.platform.startswith('openbsd') or sys.platform.startswith('netbsd'):
73 # OpenBSD, NetBSD. The ls implementation on these platforms do not support
73 # OpenBSD, NetBSD. The ls implementation on these platforms do not support
74 # the -G switch and lack the ability to use colorized output.
74 # the -G switch and lack the ability to use colorized output.
75 ls_aliases = [('ls', 'ls -F'),
75 ls_aliases = [('ls', 'ls -F'),
76 # long ls
76 # long ls
77 ('ll', 'ls -F -l'),
77 ('ll', 'ls -F -l'),
78 # ls normal files only
78 # ls normal files only
79 ('lf', 'ls -F -l %l | grep ^-'),
79 ('lf', 'ls -F -l %l | grep ^-'),
80 # ls symbolic links
80 # ls symbolic links
81 ('lk', 'ls -F -l %l | grep ^l'),
81 ('lk', 'ls -F -l %l | grep ^l'),
82 # directories or links to directories,
82 # directories or links to directories,
83 ('ldir', 'ls -F -l %l | grep /$'),
83 ('ldir', 'ls -F -l %l | grep /$'),
84 # things which are executable
84 # things which are executable
85 ('lx', 'ls -F -l %l | grep ^-..x'),
85 ('lx', 'ls -F -l %l | grep ^-..x'),
86 ]
86 ]
87 else:
87 else:
88 # BSD, OSX, etc.
88 # BSD, OSX, etc.
89 ls_aliases = [('ls', 'ls -F -G'),
89 ls_aliases = [('ls', 'ls -F -G'),
90 # long ls
90 # long ls
91 ('ll', 'ls -F -l -G'),
91 ('ll', 'ls -F -l -G'),
92 # ls normal files only
92 # ls normal files only
93 ('lf', 'ls -F -l -G %l | grep ^-'),
93 ('lf', 'ls -F -l -G %l | grep ^-'),
94 # ls symbolic links
94 # ls symbolic links
95 ('lk', 'ls -F -l -G %l | grep ^l'),
95 ('lk', 'ls -F -l -G %l | grep ^l'),
96 # directories or links to directories,
96 # directories or links to directories,
97 ('ldir', 'ls -F -G -l %l | grep /$'),
97 ('ldir', 'ls -F -G -l %l | grep /$'),
98 # things which are executable
98 # things which are executable
99 ('lx', 'ls -F -l -G %l | grep ^-..x'),
99 ('lx', 'ls -F -l -G %l | grep ^-..x'),
100 ]
100 ]
101 default_aliases = default_aliases + ls_aliases
101 default_aliases = default_aliases + ls_aliases
102 elif os.name in ['nt', 'dos']:
102 elif os.name in ['nt', 'dos']:
103 default_aliases = [('ls', 'dir /on'),
103 default_aliases = [('ls', 'dir /on'),
104 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
104 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
105 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
105 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
106 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
106 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
107 ]
107 ]
108 else:
108 else:
109 default_aliases = []
109 default_aliases = []
110
110
111 return default_aliases
111 return default_aliases
112
112
113
113
114 class AliasError(Exception):
114 class AliasError(Exception):
115 pass
115 pass
116
116
117
117
118 class InvalidAliasError(AliasError):
118 class InvalidAliasError(AliasError):
119 pass
119 pass
120
120
121 class Alias(object):
121 class Alias(object):
122 """Callable object storing the details of one alias.
122 """Callable object storing the details of one alias.
123
123
124 Instances are registered as magic functions to allow use of aliases.
124 Instances are registered as magic functions to allow use of aliases.
125 """
125 """
126
126
127 # Prepare blacklist
127 # Prepare blacklist
128 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
128 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
129
129
130 def __init__(self, shell, name, cmd):
130 def __init__(self, shell, name, cmd):
131 self.shell = shell
131 self.shell = shell
132 self.name = name
132 self.name = name
133 self.cmd = cmd
133 self.cmd = cmd
134 self.__doc__ = "Alias for `!{}`".format(cmd)
134 self.__doc__ = "Alias for `!{}`".format(cmd)
135 self.nargs = self.validate()
135 self.nargs = self.validate()
136
136
137 def validate(self):
137 def validate(self):
138 """Validate the alias, and return the number of arguments."""
138 """Validate the alias, and return the number of arguments."""
139 if self.name in self.blacklist:
139 if self.name in self.blacklist:
140 raise InvalidAliasError("The name %s can't be aliased "
140 raise InvalidAliasError("The name %s can't be aliased "
141 "because it is a keyword or builtin." % self.name)
141 "because it is a keyword or builtin." % self.name)
142 try:
142 try:
143 caller = self.shell.magics_manager.magics['line'][self.name]
143 caller = self.shell.magics_manager.magics['line'][self.name]
144 except KeyError:
144 except KeyError:
145 pass
145 pass
146 else:
146 else:
147 if not isinstance(caller, Alias):
147 if not isinstance(caller, Alias):
148 raise InvalidAliasError("The name %s can't be aliased "
148 raise InvalidAliasError("The name %s can't be aliased "
149 "because it is another magic command." % self.name)
149 "because it is another magic command." % self.name)
150
150
151 if not (isinstance(self.cmd, string_types)):
151 if not (isinstance(self.cmd, string_types)):
152 raise InvalidAliasError("An alias command must be a string, "
152 raise InvalidAliasError("An alias command must be a string, "
153 "got: %r" % self.cmd)
153 "got: %r" % self.cmd)
154
154
155 nargs = self.cmd.count('%s') - self.cmd.count('%%s')
155 nargs = self.cmd.count('%s') - self.cmd.count('%%s')
156
156
157 if (nargs > 0) and (self.cmd.find('%l') >= 0):
157 if (nargs > 0) and (self.cmd.find('%l') >= 0):
158 raise InvalidAliasError('The %s and %l specifiers are mutually '
158 raise InvalidAliasError('The %s and %l specifiers are mutually '
159 'exclusive in alias definitions.')
159 'exclusive in alias definitions.')
160
160
161 return nargs
161 return nargs
162
162
163 def __repr__(self):
163 def __repr__(self):
164 return "<alias {} for {!r}>".format(self.name, self.cmd)
164 return "<alias {} for {!r}>".format(self.name, self.cmd)
165
165
166 def __call__(self, rest=''):
166 def __call__(self, rest=''):
167 cmd = self.cmd
167 cmd = self.cmd
168 nargs = self.nargs
168 nargs = self.nargs
169 # Expand the %l special to be the user's input line
169 # Expand the %l special to be the user's input line
170 if cmd.find('%l') >= 0:
170 if cmd.find('%l') >= 0:
171 cmd = cmd.replace('%l', rest)
171 cmd = cmd.replace('%l', rest)
172 rest = ''
172 rest = ''
173
173
174 if nargs==0:
174 if nargs==0:
175 if cmd.find('%%s') >= 1:
175 if cmd.find('%%s') >= 1:
176 cmd = cmd.replace('%%s', '%s')
176 cmd = cmd.replace('%%s', '%s')
177 # Simple, argument-less aliases
177 # Simple, argument-less aliases
178 cmd = '%s %s' % (cmd, rest)
178 cmd = '%s %s' % (cmd, rest)
179 else:
179 else:
180 # Handle aliases with positional arguments
180 # Handle aliases with positional arguments
181 args = rest.split(None, nargs)
181 args = rest.split(None, nargs)
182 if len(args) < nargs:
182 if len(args) < nargs:
183 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
183 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
184 (self.name, nargs, len(args)))
184 (self.name, nargs, len(args)))
185 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
185 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
186
186
187 self.shell.system(cmd)
187 self.shell.system(cmd)
188
188
189 #-----------------------------------------------------------------------------
189 #-----------------------------------------------------------------------------
190 # Main AliasManager class
190 # Main AliasManager class
191 #-----------------------------------------------------------------------------
191 #-----------------------------------------------------------------------------
192
192
193 class AliasManager(Configurable):
193 class AliasManager(Configurable):
194
194
195 default_aliases = List(default_aliases(), config=True)
195 default_aliases = List(default_aliases(), config=True)
196 user_aliases = List(default_value=[], config=True)
196 user_aliases = List(default_value=[], config=True)
197 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
197 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
198
198
199 def __init__(self, shell=None, **kwargs):
199 def __init__(self, shell=None, **kwargs):
200 super(AliasManager, self).__init__(shell=shell, **kwargs)
200 super(AliasManager, self).__init__(shell=shell, **kwargs)
201 # For convenient access
201 # For convenient access
202 self.linemagics = self.shell.magics_manager.magics['line']
202 self.linemagics = self.shell.magics_manager.magics['line']
203 self.init_aliases()
203 self.init_aliases()
204
204
205 def init_aliases(self):
205 def init_aliases(self):
206 # Load default & user aliases
206 # Load default & user aliases
207 for name, cmd in self.default_aliases + self.user_aliases:
207 for name, cmd in self.default_aliases + self.user_aliases:
208 self.soft_define_alias(name, cmd)
208 self.soft_define_alias(name, cmd)
209
209
210 @property
210 @property
211 def aliases(self):
211 def aliases(self):
212 return [(n, func.cmd) for (n, func) in self.linemagics.items()
212 return [(n, func.cmd) for (n, func) in self.linemagics.items()
213 if isinstance(func, Alias)]
213 if isinstance(func, Alias)]
214
214
215 def soft_define_alias(self, name, cmd):
215 def soft_define_alias(self, name, cmd):
216 """Define an alias, but don't raise on an AliasError."""
216 """Define an alias, but don't raise on an AliasError."""
217 try:
217 try:
218 self.define_alias(name, cmd)
218 self.define_alias(name, cmd)
219 except AliasError as e:
219 except AliasError as e:
220 error("Invalid alias: %s" % e)
220 error("Invalid alias: %s" % e)
221
221
222 def define_alias(self, name, cmd):
222 def define_alias(self, name, cmd):
223 """Define a new alias after validating it.
223 """Define a new alias after validating it.
224
224
225 This will raise an :exc:`AliasError` if there are validation
225 This will raise an :exc:`AliasError` if there are validation
226 problems.
226 problems.
227 """
227 """
228 caller = Alias(shell=self.shell, name=name, cmd=cmd)
228 caller = Alias(shell=self.shell, name=name, cmd=cmd)
229 self.shell.magics_manager.register_function(caller, magic_kind='line',
229 self.shell.magics_manager.register_function(caller, magic_kind='line',
230 magic_name=name)
230 magic_name=name)
231
231
232 def get_alias(self, name):
232 def get_alias(self, name):
233 """Return an alias, or None if no alias by that name exists."""
233 """Return an alias, or None if no alias by that name exists."""
234 aname = self.linemagics.get(name, None)
234 aname = self.linemagics.get(name, None)
235 return aname if isinstance(aname, Alias) else None
235 return aname if isinstance(aname, Alias) else None
236
236
237 def is_alias(self, name):
237 def is_alias(self, name):
238 """Return whether or not a given name has been defined as an alias"""
238 """Return whether or not a given name has been defined as an alias"""
239 return self.get_alias(name) is not None
239 return self.get_alias(name) is not None
240
240
241 def undefine_alias(self, name):
241 def undefine_alias(self, name):
242 if self.is_alias(name):
242 if self.is_alias(name):
243 del self.linemagics[name]
243 del self.linemagics[name]
244 else:
244 else:
245 raise ValueError('%s is not an alias' % name)
245 raise ValueError('%s is not an alias' % name)
246
246
247 def clear_aliases(self):
247 def clear_aliases(self):
248 for name, cmd in self.aliases:
248 for name, cmd in self.aliases:
249 self.undefine_alias(name)
249 self.undefine_alias(name)
250
250
251 def retrieve_alias(self, name):
251 def retrieve_alias(self, name):
252 """Retrieve the command to which an alias expands."""
252 """Retrieve the command to which an alias expands."""
253 caller = self.get_alias(name)
253 caller = self.get_alias(name)
254 if caller:
254 if caller:
255 return caller.cmd
255 return caller.cmd
256 else:
256 else:
257 raise ValueError('%s is not an alias' % name)
257 raise ValueError('%s is not an alias' % name)
@@ -1,296 +1,295 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Displayhook for IPython.
2 """Displayhook for IPython.
3
3
4 This defines a callable class that IPython uses for `sys.displayhook`.
4 This defines a callable class that IPython uses for `sys.displayhook`.
5 """
5 """
6
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 from __future__ import print_function
10 from __future__ import print_function
11
11
12 import sys
12 import sys
13 import io as _io
13 import io as _io
14 import tokenize
14 import tokenize
15
15
16 from IPython.core.formatters import _safe_get_formatter_method
16 from IPython.core.formatters import _safe_get_formatter_method
17 from traitlets.config.configurable import Configurable
17 from traitlets.config.configurable import Configurable
18 from IPython.utils import io
18 from IPython.utils import io
19 from IPython.utils.py3compat import builtin_mod, cast_unicode_py2
19 from IPython.utils.py3compat import builtin_mod, cast_unicode_py2
20 from traitlets import Instance, Float
20 from traitlets import Instance, Float
21 from IPython.utils.warn import warn
21 from warnings import warn
22
22
23 # TODO: Move the various attributes (cache_size, [others now moved]). Some
23 # TODO: Move the various attributes (cache_size, [others now moved]). Some
24 # of these are also attributes of InteractiveShell. They should be on ONE object
24 # of these are also attributes of InteractiveShell. They should be on ONE object
25 # only and the other objects should ask that one object for their values.
25 # only and the other objects should ask that one object for their values.
26
26
27 class DisplayHook(Configurable):
27 class DisplayHook(Configurable):
28 """The custom IPython displayhook to replace sys.displayhook.
28 """The custom IPython displayhook to replace sys.displayhook.
29
29
30 This class does many things, but the basic idea is that it is a callable
30 This class does many things, but the basic idea is that it is a callable
31 that gets called anytime user code returns a value.
31 that gets called anytime user code returns a value.
32 """
32 """
33
33
34 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
34 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
35 allow_none=True)
35 allow_none=True)
36 exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
36 exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
37 allow_none=True)
37 allow_none=True)
38 cull_fraction = Float(0.2)
38 cull_fraction = Float(0.2)
39
39
40 def __init__(self, shell=None, cache_size=1000, **kwargs):
40 def __init__(self, shell=None, cache_size=1000, **kwargs):
41 super(DisplayHook, self).__init__(shell=shell, **kwargs)
41 super(DisplayHook, self).__init__(shell=shell, **kwargs)
42 cache_size_min = 3
42 cache_size_min = 3
43 if cache_size <= 0:
43 if cache_size <= 0:
44 self.do_full_cache = 0
44 self.do_full_cache = 0
45 cache_size = 0
45 cache_size = 0
46 elif cache_size < cache_size_min:
46 elif cache_size < cache_size_min:
47 self.do_full_cache = 0
47 self.do_full_cache = 0
48 cache_size = 0
48 cache_size = 0
49 warn('caching was disabled (min value for cache size is %s).' %
49 warn('caching was disabled (min value for cache size is %s).' %
50 cache_size_min,level=3)
50 cache_size_min,level=3)
51 else:
51 else:
52 self.do_full_cache = 1
52 self.do_full_cache = 1
53
53
54 self.cache_size = cache_size
54 self.cache_size = cache_size
55
55
56 # we need a reference to the user-level namespace
56 # we need a reference to the user-level namespace
57 self.shell = shell
57 self.shell = shell
58
58
59 self._,self.__,self.___ = '','',''
59 self._,self.__,self.___ = '','',''
60
60
61 # these are deliberately global:
61 # these are deliberately global:
62 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
62 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
63 self.shell.user_ns.update(to_user_ns)
63 self.shell.user_ns.update(to_user_ns)
64
64
65 @property
65 @property
66 def prompt_count(self):
66 def prompt_count(self):
67 return self.shell.execution_count
67 return self.shell.execution_count
68
68
69 #-------------------------------------------------------------------------
69 #-------------------------------------------------------------------------
70 # Methods used in __call__. Override these methods to modify the behavior
70 # Methods used in __call__. Override these methods to modify the behavior
71 # of the displayhook.
71 # of the displayhook.
72 #-------------------------------------------------------------------------
72 #-------------------------------------------------------------------------
73
73
74 def check_for_underscore(self):
74 def check_for_underscore(self):
75 """Check if the user has set the '_' variable by hand."""
75 """Check if the user has set the '_' variable by hand."""
76 # If something injected a '_' variable in __builtin__, delete
76 # If something injected a '_' variable in __builtin__, delete
77 # ipython's automatic one so we don't clobber that. gettext() in
77 # ipython's automatic one so we don't clobber that. gettext() in
78 # particular uses _, so we need to stay away from it.
78 # particular uses _, so we need to stay away from it.
79 if '_' in builtin_mod.__dict__:
79 if '_' in builtin_mod.__dict__:
80 try:
80 try:
81 del self.shell.user_ns['_']
81 del self.shell.user_ns['_']
82 except KeyError:
82 except KeyError:
83 pass
83 pass
84
84
85 def quiet(self):
85 def quiet(self):
86 """Should we silence the display hook because of ';'?"""
86 """Should we silence the display hook because of ';'?"""
87 # do not print output if input ends in ';'
87 # do not print output if input ends in ';'
88
88
89 try:
89 try:
90 cell = cast_unicode_py2(self.shell.history_manager.input_hist_parsed[-1])
90 cell = cast_unicode_py2(self.shell.history_manager.input_hist_parsed[-1])
91 except IndexError:
91 except IndexError:
92 # some uses of ipshellembed may fail here
92 # some uses of ipshellembed may fail here
93 return False
93 return False
94
94
95 sio = _io.StringIO(cell)
95 sio = _io.StringIO(cell)
96 tokens = list(tokenize.generate_tokens(sio.readline))
96 tokens = list(tokenize.generate_tokens(sio.readline))
97
97
98 for token in reversed(tokens):
98 for token in reversed(tokens):
99 if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):
99 if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):
100 continue
100 continue
101 if (token[0] == tokenize.OP) and (token[1] == ';'):
101 if (token[0] == tokenize.OP) and (token[1] == ';'):
102 return True
102 return True
103 else:
103 else:
104 return False
104 return False
105
105
106 def start_displayhook(self):
106 def start_displayhook(self):
107 """Start the displayhook, initializing resources."""
107 """Start the displayhook, initializing resources."""
108 pass
108 pass
109
109
110 def write_output_prompt(self):
110 def write_output_prompt(self):
111 """Write the output prompt.
111 """Write the output prompt.
112
112
113 The default implementation simply writes the prompt to
113 The default implementation simply writes the prompt to
114 ``io.stdout``.
114 ``io.stdout``.
115 """
115 """
116 # Use write, not print which adds an extra space.
116 # Use write, not print which adds an extra space.
117 io.stdout.write(self.shell.separate_out)
117 io.stdout.write(self.shell.separate_out)
118 outprompt = self.shell.prompt_manager.render('out')
118 outprompt = self.shell.prompt_manager.render('out')
119 if self.do_full_cache:
119 if self.do_full_cache:
120 io.stdout.write(outprompt)
120 io.stdout.write(outprompt)
121
121
122 def compute_format_data(self, result):
122 def compute_format_data(self, result):
123 """Compute format data of the object to be displayed.
123 """Compute format data of the object to be displayed.
124
124
125 The format data is a generalization of the :func:`repr` of an object.
125 The format data is a generalization of the :func:`repr` of an object.
126 In the default implementation the format data is a :class:`dict` of
126 In the default implementation the format data is a :class:`dict` of
127 key value pair where the keys are valid MIME types and the values
127 key value pair where the keys are valid MIME types and the values
128 are JSON'able data structure containing the raw data for that MIME
128 are JSON'able data structure containing the raw data for that MIME
129 type. It is up to frontends to determine pick a MIME to to use and
129 type. It is up to frontends to determine pick a MIME to to use and
130 display that data in an appropriate manner.
130 display that data in an appropriate manner.
131
131
132 This method only computes the format data for the object and should
132 This method only computes the format data for the object and should
133 NOT actually print or write that to a stream.
133 NOT actually print or write that to a stream.
134
134
135 Parameters
135 Parameters
136 ----------
136 ----------
137 result : object
137 result : object
138 The Python object passed to the display hook, whose format will be
138 The Python object passed to the display hook, whose format will be
139 computed.
139 computed.
140
140
141 Returns
141 Returns
142 -------
142 -------
143 (format_dict, md_dict) : dict
143 (format_dict, md_dict) : dict
144 format_dict is a :class:`dict` whose keys are valid MIME types and values are
144 format_dict is a :class:`dict` whose keys are valid MIME types and values are
145 JSON'able raw data for that MIME type. It is recommended that
145 JSON'able raw data for that MIME type. It is recommended that
146 all return values of this should always include the "text/plain"
146 all return values of this should always include the "text/plain"
147 MIME type representation of the object.
147 MIME type representation of the object.
148 md_dict is a :class:`dict` with the same MIME type keys
148 md_dict is a :class:`dict` with the same MIME type keys
149 of metadata associated with each output.
149 of metadata associated with each output.
150
150
151 """
151 """
152 return self.shell.display_formatter.format(result)
152 return self.shell.display_formatter.format(result)
153
153
154 def write_format_data(self, format_dict, md_dict=None):
154 def write_format_data(self, format_dict, md_dict=None):
155 """Write the format data dict to the frontend.
155 """Write the format data dict to the frontend.
156
156
157 This default version of this method simply writes the plain text
157 This default version of this method simply writes the plain text
158 representation of the object to ``io.stdout``. Subclasses should
158 representation of the object to ``io.stdout``. Subclasses should
159 override this method to send the entire `format_dict` to the
159 override this method to send the entire `format_dict` to the
160 frontends.
160 frontends.
161
161
162 Parameters
162 Parameters
163 ----------
163 ----------
164 format_dict : dict
164 format_dict : dict
165 The format dict for the object passed to `sys.displayhook`.
165 The format dict for the object passed to `sys.displayhook`.
166 md_dict : dict (optional)
166 md_dict : dict (optional)
167 The metadata dict to be associated with the display data.
167 The metadata dict to be associated with the display data.
168 """
168 """
169 if 'text/plain' not in format_dict:
169 if 'text/plain' not in format_dict:
170 # nothing to do
170 # nothing to do
171 return
171 return
172 # We want to print because we want to always make sure we have a
172 # We want to print because we want to always make sure we have a
173 # newline, even if all the prompt separators are ''. This is the
173 # newline, even if all the prompt separators are ''. This is the
174 # standard IPython behavior.
174 # standard IPython behavior.
175 result_repr = format_dict['text/plain']
175 result_repr = format_dict['text/plain']
176 if '\n' in result_repr:
176 if '\n' in result_repr:
177 # So that multi-line strings line up with the left column of
177 # So that multi-line strings line up with the left column of
178 # the screen, instead of having the output prompt mess up
178 # the screen, instead of having the output prompt mess up
179 # their first line.
179 # their first line.
180 # We use the prompt template instead of the expanded prompt
180 # We use the prompt template instead of the expanded prompt
181 # because the expansion may add ANSI escapes that will interfere
181 # because the expansion may add ANSI escapes that will interfere
182 # with our ability to determine whether or not we should add
182 # with our ability to determine whether or not we should add
183 # a newline.
183 # a newline.
184 prompt_template = self.shell.prompt_manager.out_template
184 prompt_template = self.shell.prompt_manager.out_template
185 if prompt_template and not prompt_template.endswith('\n'):
185 if prompt_template and not prompt_template.endswith('\n'):
186 # But avoid extraneous empty lines.
186 # But avoid extraneous empty lines.
187 result_repr = '\n' + result_repr
187 result_repr = '\n' + result_repr
188
188
189 print(result_repr, file=io.stdout)
189 print(result_repr, file=io.stdout)
190
190
191 def update_user_ns(self, result):
191 def update_user_ns(self, result):
192 """Update user_ns with various things like _, __, _1, etc."""
192 """Update user_ns with various things like _, __, _1, etc."""
193
193
194 # Avoid recursive reference when displaying _oh/Out
194 # Avoid recursive reference when displaying _oh/Out
195 if result is not self.shell.user_ns['_oh']:
195 if result is not self.shell.user_ns['_oh']:
196 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
196 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
197 self.cull_cache()
197 self.cull_cache()
198 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
198 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
199 # we cause buggy behavior for things like gettext).
199 # we cause buggy behavior for things like gettext).
200
200
201 if '_' not in builtin_mod.__dict__:
201 if '_' not in builtin_mod.__dict__:
202 self.___ = self.__
202 self.___ = self.__
203 self.__ = self._
203 self.__ = self._
204 self._ = result
204 self._ = result
205 self.shell.push({'_':self._,
205 self.shell.push({'_':self._,
206 '__':self.__,
206 '__':self.__,
207 '___':self.___}, interactive=False)
207 '___':self.___}, interactive=False)
208
208
209 # hackish access to top-level namespace to create _1,_2... dynamically
209 # hackish access to top-level namespace to create _1,_2... dynamically
210 to_main = {}
210 to_main = {}
211 if self.do_full_cache:
211 if self.do_full_cache:
212 new_result = '_'+repr(self.prompt_count)
212 new_result = '_'+repr(self.prompt_count)
213 to_main[new_result] = result
213 to_main[new_result] = result
214 self.shell.push(to_main, interactive=False)
214 self.shell.push(to_main, interactive=False)
215 self.shell.user_ns['_oh'][self.prompt_count] = result
215 self.shell.user_ns['_oh'][self.prompt_count] = result
216
216
217 def fill_exec_result(self, result):
217 def fill_exec_result(self, result):
218 if self.exec_result is not None:
218 if self.exec_result is not None:
219 self.exec_result.result = result
219 self.exec_result.result = result
220
220
221 def log_output(self, format_dict):
221 def log_output(self, format_dict):
222 """Log the output."""
222 """Log the output."""
223 if 'text/plain' not in format_dict:
223 if 'text/plain' not in format_dict:
224 # nothing to do
224 # nothing to do
225 return
225 return
226 if self.shell.logger.log_output:
226 if self.shell.logger.log_output:
227 self.shell.logger.log_write(format_dict['text/plain'], 'output')
227 self.shell.logger.log_write(format_dict['text/plain'], 'output')
228 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
228 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
229 format_dict['text/plain']
229 format_dict['text/plain']
230
230
231 def finish_displayhook(self):
231 def finish_displayhook(self):
232 """Finish up all displayhook activities."""
232 """Finish up all displayhook activities."""
233 io.stdout.write(self.shell.separate_out2)
233 io.stdout.write(self.shell.separate_out2)
234 io.stdout.flush()
234 io.stdout.flush()
235
235
236 def __call__(self, result=None):
236 def __call__(self, result=None):
237 """Printing with history cache management.
237 """Printing with history cache management.
238
238
239 This is invoked everytime the interpreter needs to print, and is
239 This is invoked everytime the interpreter needs to print, and is
240 activated by setting the variable sys.displayhook to it.
240 activated by setting the variable sys.displayhook to it.
241 """
241 """
242 self.check_for_underscore()
242 self.check_for_underscore()
243 if result is not None and not self.quiet():
243 if result is not None and not self.quiet():
244 self.start_displayhook()
244 self.start_displayhook()
245 self.write_output_prompt()
245 self.write_output_prompt()
246 format_dict, md_dict = self.compute_format_data(result)
246 format_dict, md_dict = self.compute_format_data(result)
247 self.update_user_ns(result)
247 self.update_user_ns(result)
248 self.fill_exec_result(result)
248 self.fill_exec_result(result)
249 if format_dict:
249 if format_dict:
250 self.write_format_data(format_dict, md_dict)
250 self.write_format_data(format_dict, md_dict)
251 self.log_output(format_dict)
251 self.log_output(format_dict)
252 self.finish_displayhook()
252 self.finish_displayhook()
253
253
254 def cull_cache(self):
254 def cull_cache(self):
255 """Output cache is full, cull the oldest entries"""
255 """Output cache is full, cull the oldest entries"""
256 oh = self.shell.user_ns.get('_oh', {})
256 oh = self.shell.user_ns.get('_oh', {})
257 sz = len(oh)
257 sz = len(oh)
258 cull_count = max(int(sz * self.cull_fraction), 2)
258 cull_count = max(int(sz * self.cull_fraction), 2)
259 warn('Output cache limit (currently {sz} entries) hit.\n'
259 warn('Output cache limit (currently {sz} entries) hit.\n'
260 'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
260 'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
261
261
262 for i, n in enumerate(sorted(oh)):
262 for i, n in enumerate(sorted(oh)):
263 if i >= cull_count:
263 if i >= cull_count:
264 break
264 break
265 self.shell.user_ns.pop('_%i' % n, None)
265 self.shell.user_ns.pop('_%i' % n, None)
266 oh.pop(n, None)
266 oh.pop(n, None)
267
267
268
268
269 def flush(self):
269 def flush(self):
270 if not self.do_full_cache:
270 if not self.do_full_cache:
271 raise ValueError("You shouldn't have reached the cache flush "
271 raise ValueError("You shouldn't have reached the cache flush "
272 "if full caching is not enabled!")
272 "if full caching is not enabled!")
273 # delete auto-generated vars from global namespace
273 # delete auto-generated vars from global namespace
274
274
275 for n in range(1,self.prompt_count + 1):
275 for n in range(1,self.prompt_count + 1):
276 key = '_'+repr(n)
276 key = '_'+repr(n)
277 try:
277 try:
278 del self.shell.user_ns[key]
278 del self.shell.user_ns[key]
279 except: pass
279 except: pass
280 # In some embedded circumstances, the user_ns doesn't have the
280 # In some embedded circumstances, the user_ns doesn't have the
281 # '_oh' key set up.
281 # '_oh' key set up.
282 oh = self.shell.user_ns.get('_oh', None)
282 oh = self.shell.user_ns.get('_oh', None)
283 if oh is not None:
283 if oh is not None:
284 oh.clear()
284 oh.clear()
285
285
286 # Release our own references to objects:
286 # Release our own references to objects:
287 self._, self.__, self.___ = '', '', ''
287 self._, self.__, self.___ = '', '', ''
288
288
289 if '_' not in builtin_mod.__dict__:
289 if '_' not in builtin_mod.__dict__:
290 self.shell.user_ns.update({'_':None,'__':None, '___':None})
290 self.shell.user_ns.update({'_':None,'__':None, '___':None})
291 import gc
291 import gc
292 # TODO: Is this really needed?
292 # TODO: Is this really needed?
293 # IronPython blocks here forever
293 # IronPython blocks here forever
294 if sys.platform != "cli":
294 if sys.platform != "cli":
295 gc.collect()
295 gc.collect()
296
@@ -1,883 +1,881 b''
1 """ History related magics and functionality """
1 """ History related magics and functionality """
2 #-----------------------------------------------------------------------------
2 #-----------------------------------------------------------------------------
3 # Copyright (C) 2010-2011 The IPython Development Team.
3 # Copyright (C) 2010-2011 The IPython Development Team.
4 #
4 #
5 # Distributed under the terms of the BSD License.
5 # Distributed under the terms of the BSD License.
6 #
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 from __future__ import print_function
13 from __future__ import print_function
14
14
15 # Stdlib imports
15 # Stdlib imports
16 import atexit
16 import atexit
17 import datetime
17 import datetime
18 import os
18 import os
19 import re
19 import re
20 try:
20 try:
21 import sqlite3
21 import sqlite3
22 except ImportError:
22 except ImportError:
23 try:
23 try:
24 from pysqlite2 import dbapi2 as sqlite3
24 from pysqlite2 import dbapi2 as sqlite3
25 except ImportError:
25 except ImportError:
26 sqlite3 = None
26 sqlite3 = None
27 import threading
27 import threading
28
28
29 # Our own packages
29 # Our own packages
30 from traitlets.config.configurable import Configurable
30 from traitlets.config.configurable import Configurable
31 from decorator import decorator
31 from decorator import decorator
32 from IPython.utils.decorators import undoc
32 from IPython.utils.decorators import undoc
33 from IPython.utils.path import locate_profile
33 from IPython.utils.path import locate_profile
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35 from traitlets import (
35 from traitlets import (
36 Any, Bool, Dict, Instance, Integer, List, Unicode, TraitError,
36 Any, Bool, Dict, Instance, Integer, List, Unicode, TraitError,
37 )
37 )
38 from IPython.utils.warn import warn
38 from warnings import warn
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Classes and functions
41 # Classes and functions
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 @undoc
44 @undoc
45 class DummyDB(object):
45 class DummyDB(object):
46 """Dummy DB that will act as a black hole for history.
46 """Dummy DB that will act as a black hole for history.
47
47
48 Only used in the absence of sqlite"""
48 Only used in the absence of sqlite"""
49 def execute(*args, **kwargs):
49 def execute(*args, **kwargs):
50 return []
50 return []
51
51
52 def commit(self, *args, **kwargs):
52 def commit(self, *args, **kwargs):
53 pass
53 pass
54
54
55 def __enter__(self, *args, **kwargs):
55 def __enter__(self, *args, **kwargs):
56 pass
56 pass
57
57
58 def __exit__(self, *args, **kwargs):
58 def __exit__(self, *args, **kwargs):
59 pass
59 pass
60
60
61
61
62 @decorator
62 @decorator
63 def needs_sqlite(f, self, *a, **kw):
63 def needs_sqlite(f, self, *a, **kw):
64 """Decorator: return an empty list in the absence of sqlite."""
64 """Decorator: return an empty list in the absence of sqlite."""
65 if sqlite3 is None or not self.enabled:
65 if sqlite3 is None or not self.enabled:
66 return []
66 return []
67 else:
67 else:
68 return f(self, *a, **kw)
68 return f(self, *a, **kw)
69
69
70
70
71 if sqlite3 is not None:
71 if sqlite3 is not None:
72 DatabaseError = sqlite3.DatabaseError
72 DatabaseError = sqlite3.DatabaseError
73 OperationalError = sqlite3.OperationalError
73 OperationalError = sqlite3.OperationalError
74 else:
74 else:
75 @undoc
75 @undoc
76 class DatabaseError(Exception):
76 class DatabaseError(Exception):
77 "Dummy exception when sqlite could not be imported. Should never occur."
77 "Dummy exception when sqlite could not be imported. Should never occur."
78
78
79 @undoc
79 @undoc
80 class OperationalError(Exception):
80 class OperationalError(Exception):
81 "Dummy exception when sqlite could not be imported. Should never occur."
81 "Dummy exception when sqlite could not be imported. Should never occur."
82
82
83 @decorator
83 @decorator
84 def catch_corrupt_db(f, self, *a, **kw):
84 def catch_corrupt_db(f, self, *a, **kw):
85 """A decorator which wraps HistoryAccessor method calls to catch errors from
85 """A decorator which wraps HistoryAccessor method calls to catch errors from
86 a corrupt SQLite database, move the old database out of the way, and create
86 a corrupt SQLite database, move the old database out of the way, and create
87 a new one.
87 a new one.
88 """
88 """
89 try:
89 try:
90 return f(self, *a, **kw)
90 return f(self, *a, **kw)
91 except (DatabaseError, OperationalError):
91 except (DatabaseError, OperationalError):
92 if os.path.isfile(self.hist_file):
92 if os.path.isfile(self.hist_file):
93 # Try to move the file out of the way
93 # Try to move the file out of the way
94 base,ext = os.path.splitext(self.hist_file)
94 base,ext = os.path.splitext(self.hist_file)
95 newpath = base + '-corrupt' + ext
95 newpath = base + '-corrupt' + ext
96 os.rename(self.hist_file, newpath)
96 os.rename(self.hist_file, newpath)
97 self.init_db()
97 self.init_db()
98 print("ERROR! History file wasn't a valid SQLite database.",
98 print("ERROR! History file wasn't a valid SQLite database.",
99 "It was moved to %s" % newpath, "and a new file created.")
99 "It was moved to %s" % newpath, "and a new file created.")
100 return []
100 return []
101
101
102 else:
102 else:
103 # The hist_file is probably :memory: or something else.
103 # The hist_file is probably :memory: or something else.
104 raise
104 raise
105
105
106 class HistoryAccessorBase(Configurable):
106 class HistoryAccessorBase(Configurable):
107 """An abstract class for History Accessors """
107 """An abstract class for History Accessors """
108
108
109 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
109 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
110 raise NotImplementedError
110 raise NotImplementedError
111
111
112 def search(self, pattern="*", raw=True, search_raw=True,
112 def search(self, pattern="*", raw=True, search_raw=True,
113 output=False, n=None, unique=False):
113 output=False, n=None, unique=False):
114 raise NotImplementedError
114 raise NotImplementedError
115
115
116 def get_range(self, session, start=1, stop=None, raw=True,output=False):
116 def get_range(self, session, start=1, stop=None, raw=True,output=False):
117 raise NotImplementedError
117 raise NotImplementedError
118
118
119 def get_range_by_str(self, rangestr, raw=True, output=False):
119 def get_range_by_str(self, rangestr, raw=True, output=False):
120 raise NotImplementedError
120 raise NotImplementedError
121
121
122
122
123 class HistoryAccessor(HistoryAccessorBase):
123 class HistoryAccessor(HistoryAccessorBase):
124 """Access the history database without adding to it.
124 """Access the history database without adding to it.
125
125
126 This is intended for use by standalone history tools. IPython shells use
126 This is intended for use by standalone history tools. IPython shells use
127 HistoryManager, below, which is a subclass of this."""
127 HistoryManager, below, which is a subclass of this."""
128
128
129 # String holding the path to the history file
129 # String holding the path to the history file
130 hist_file = Unicode(config=True,
130 hist_file = Unicode(config=True,
131 help="""Path to file to use for SQLite history database.
131 help="""Path to file to use for SQLite history database.
132
132
133 By default, IPython will put the history database in the IPython
133 By default, IPython will put the history database in the IPython
134 profile directory. If you would rather share one history among
134 profile directory. If you would rather share one history among
135 profiles, you can set this value in each, so that they are consistent.
135 profiles, you can set this value in each, so that they are consistent.
136
136
137 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
137 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
138 mounts. If you see IPython hanging, try setting this to something on a
138 mounts. If you see IPython hanging, try setting this to something on a
139 local disk, e.g::
139 local disk, e.g::
140
140
141 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
141 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
142
142
143 """)
143 """)
144
144
145 enabled = Bool(True, config=True,
145 enabled = Bool(True, config=True,
146 help="""enable the SQLite history
146 help="""enable the SQLite history
147
147
148 set enabled=False to disable the SQLite history,
148 set enabled=False to disable the SQLite history,
149 in which case there will be no stored history, no SQLite connection,
149 in which case there will be no stored history, no SQLite connection,
150 and no background saving thread. This may be necessary in some
150 and no background saving thread. This may be necessary in some
151 threaded environments where IPython is embedded.
151 threaded environments where IPython is embedded.
152 """
152 """
153 )
153 )
154
154
155 connection_options = Dict(config=True,
155 connection_options = Dict(config=True,
156 help="""Options for configuring the SQLite connection
156 help="""Options for configuring the SQLite connection
157
157
158 These options are passed as keyword args to sqlite3.connect
158 These options are passed as keyword args to sqlite3.connect
159 when establishing database conenctions.
159 when establishing database conenctions.
160 """
160 """
161 )
161 )
162
162
163 # The SQLite database
163 # The SQLite database
164 db = Any()
164 db = Any()
165 def _db_changed(self, name, old, new):
165 def _db_changed(self, name, old, new):
166 """validate the db, since it can be an Instance of two different types"""
166 """validate the db, since it can be an Instance of two different types"""
167 connection_types = (DummyDB,)
167 connection_types = (DummyDB,)
168 if sqlite3 is not None:
168 if sqlite3 is not None:
169 connection_types = (DummyDB, sqlite3.Connection)
169 connection_types = (DummyDB, sqlite3.Connection)
170 if not isinstance(new, connection_types):
170 if not isinstance(new, connection_types):
171 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
171 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
172 (self.__class__.__name__, new)
172 (self.__class__.__name__, new)
173 raise TraitError(msg)
173 raise TraitError(msg)
174
174
175 def __init__(self, profile='default', hist_file=u'', **traits):
175 def __init__(self, profile='default', hist_file=u'', **traits):
176 """Create a new history accessor.
176 """Create a new history accessor.
177
177
178 Parameters
178 Parameters
179 ----------
179 ----------
180 profile : str
180 profile : str
181 The name of the profile from which to open history.
181 The name of the profile from which to open history.
182 hist_file : str
182 hist_file : str
183 Path to an SQLite history database stored by IPython. If specified,
183 Path to an SQLite history database stored by IPython. If specified,
184 hist_file overrides profile.
184 hist_file overrides profile.
185 config : :class:`~traitlets.config.loader.Config`
185 config : :class:`~traitlets.config.loader.Config`
186 Config object. hist_file can also be set through this.
186 Config object. hist_file can also be set through this.
187 """
187 """
188 # We need a pointer back to the shell for various tasks.
188 # We need a pointer back to the shell for various tasks.
189 super(HistoryAccessor, self).__init__(**traits)
189 super(HistoryAccessor, self).__init__(**traits)
190 # defer setting hist_file from kwarg until after init,
190 # defer setting hist_file from kwarg until after init,
191 # otherwise the default kwarg value would clobber any value
191 # otherwise the default kwarg value would clobber any value
192 # set by config
192 # set by config
193 if hist_file:
193 if hist_file:
194 self.hist_file = hist_file
194 self.hist_file = hist_file
195
195
196 if self.hist_file == u'':
196 if self.hist_file == u'':
197 # No one has set the hist_file, yet.
197 # No one has set the hist_file, yet.
198 self.hist_file = self._get_hist_file_name(profile)
198 self.hist_file = self._get_hist_file_name(profile)
199
199
200 if sqlite3 is None and self.enabled:
200 if sqlite3 is None and self.enabled:
201 warn("IPython History requires SQLite, your history will not be saved")
201 warn("IPython History requires SQLite, your history will not be saved")
202 self.enabled = False
202 self.enabled = False
203
203
204 self.init_db()
204 self.init_db()
205
205
206 def _get_hist_file_name(self, profile='default'):
206 def _get_hist_file_name(self, profile='default'):
207 """Find the history file for the given profile name.
207 """Find the history file for the given profile name.
208
208
209 This is overridden by the HistoryManager subclass, to use the shell's
209 This is overridden by the HistoryManager subclass, to use the shell's
210 active profile.
210 active profile.
211
211
212 Parameters
212 Parameters
213 ----------
213 ----------
214 profile : str
214 profile : str
215 The name of a profile which has a history file.
215 The name of a profile which has a history file.
216 """
216 """
217 return os.path.join(locate_profile(profile), 'history.sqlite')
217 return os.path.join(locate_profile(profile), 'history.sqlite')
218
218
219 @catch_corrupt_db
219 @catch_corrupt_db
220 def init_db(self):
220 def init_db(self):
221 """Connect to the database, and create tables if necessary."""
221 """Connect to the database, and create tables if necessary."""
222 if not self.enabled:
222 if not self.enabled:
223 self.db = DummyDB()
223 self.db = DummyDB()
224 return
224 return
225
225
226 # use detect_types so that timestamps return datetime objects
226 # use detect_types so that timestamps return datetime objects
227 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
227 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
228 kwargs.update(self.connection_options)
228 kwargs.update(self.connection_options)
229 self.db = sqlite3.connect(self.hist_file, **kwargs)
229 self.db = sqlite3.connect(self.hist_file, **kwargs)
230 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
230 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
231 primary key autoincrement, start timestamp,
231 primary key autoincrement, start timestamp,
232 end timestamp, num_cmds integer, remark text)""")
232 end timestamp, num_cmds integer, remark text)""")
233 self.db.execute("""CREATE TABLE IF NOT EXISTS history
233 self.db.execute("""CREATE TABLE IF NOT EXISTS history
234 (session integer, line integer, source text, source_raw text,
234 (session integer, line integer, source text, source_raw text,
235 PRIMARY KEY (session, line))""")
235 PRIMARY KEY (session, line))""")
236 # Output history is optional, but ensure the table's there so it can be
236 # Output history is optional, but ensure the table's there so it can be
237 # enabled later.
237 # enabled later.
238 self.db.execute("""CREATE TABLE IF NOT EXISTS output_history
238 self.db.execute("""CREATE TABLE IF NOT EXISTS output_history
239 (session integer, line integer, output text,
239 (session integer, line integer, output text,
240 PRIMARY KEY (session, line))""")
240 PRIMARY KEY (session, line))""")
241 self.db.commit()
241 self.db.commit()
242
242
243 def writeout_cache(self):
243 def writeout_cache(self):
244 """Overridden by HistoryManager to dump the cache before certain
244 """Overridden by HistoryManager to dump the cache before certain
245 database lookups."""
245 database lookups."""
246 pass
246 pass
247
247
248 ## -------------------------------
248 ## -------------------------------
249 ## Methods for retrieving history:
249 ## Methods for retrieving history:
250 ## -------------------------------
250 ## -------------------------------
251 def _run_sql(self, sql, params, raw=True, output=False):
251 def _run_sql(self, sql, params, raw=True, output=False):
252 """Prepares and runs an SQL query for the history database.
252 """Prepares and runs an SQL query for the history database.
253
253
254 Parameters
254 Parameters
255 ----------
255 ----------
256 sql : str
256 sql : str
257 Any filtering expressions to go after SELECT ... FROM ...
257 Any filtering expressions to go after SELECT ... FROM ...
258 params : tuple
258 params : tuple
259 Parameters passed to the SQL query (to replace "?")
259 Parameters passed to the SQL query (to replace "?")
260 raw, output : bool
260 raw, output : bool
261 See :meth:`get_range`
261 See :meth:`get_range`
262
262
263 Returns
263 Returns
264 -------
264 -------
265 Tuples as :meth:`get_range`
265 Tuples as :meth:`get_range`
266 """
266 """
267 toget = 'source_raw' if raw else 'source'
267 toget = 'source_raw' if raw else 'source'
268 sqlfrom = "history"
268 sqlfrom = "history"
269 if output:
269 if output:
270 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
270 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
271 toget = "history.%s, output_history.output" % toget
271 toget = "history.%s, output_history.output" % toget
272 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
272 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
273 (toget, sqlfrom) + sql, params)
273 (toget, sqlfrom) + sql, params)
274 if output: # Regroup into 3-tuples, and parse JSON
274 if output: # Regroup into 3-tuples, and parse JSON
275 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
275 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
276 return cur
276 return cur
277
277
278 @needs_sqlite
278 @needs_sqlite
279 @catch_corrupt_db
279 @catch_corrupt_db
280 def get_session_info(self, session):
280 def get_session_info(self, session):
281 """Get info about a session.
281 """Get info about a session.
282
282
283 Parameters
283 Parameters
284 ----------
284 ----------
285
285
286 session : int
286 session : int
287 Session number to retrieve.
287 Session number to retrieve.
288
288
289 Returns
289 Returns
290 -------
290 -------
291
291
292 session_id : int
292 session_id : int
293 Session ID number
293 Session ID number
294 start : datetime
294 start : datetime
295 Timestamp for the start of the session.
295 Timestamp for the start of the session.
296 end : datetime
296 end : datetime
297 Timestamp for the end of the session, or None if IPython crashed.
297 Timestamp for the end of the session, or None if IPython crashed.
298 num_cmds : int
298 num_cmds : int
299 Number of commands run, or None if IPython crashed.
299 Number of commands run, or None if IPython crashed.
300 remark : unicode
300 remark : unicode
301 A manually set description.
301 A manually set description.
302 """
302 """
303 query = "SELECT * from sessions where session == ?"
303 query = "SELECT * from sessions where session == ?"
304 return self.db.execute(query, (session,)).fetchone()
304 return self.db.execute(query, (session,)).fetchone()
305
305
306 @catch_corrupt_db
306 @catch_corrupt_db
307 def get_last_session_id(self):
307 def get_last_session_id(self):
308 """Get the last session ID currently in the database.
308 """Get the last session ID currently in the database.
309
309
310 Within IPython, this should be the same as the value stored in
310 Within IPython, this should be the same as the value stored in
311 :attr:`HistoryManager.session_number`.
311 :attr:`HistoryManager.session_number`.
312 """
312 """
313 for record in self.get_tail(n=1, include_latest=True):
313 for record in self.get_tail(n=1, include_latest=True):
314 return record[0]
314 return record[0]
315
315
316 @catch_corrupt_db
316 @catch_corrupt_db
317 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
317 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
318 """Get the last n lines from the history database.
318 """Get the last n lines from the history database.
319
319
320 Parameters
320 Parameters
321 ----------
321 ----------
322 n : int
322 n : int
323 The number of lines to get
323 The number of lines to get
324 raw, output : bool
324 raw, output : bool
325 See :meth:`get_range`
325 See :meth:`get_range`
326 include_latest : bool
326 include_latest : bool
327 If False (default), n+1 lines are fetched, and the latest one
327 If False (default), n+1 lines are fetched, and the latest one
328 is discarded. This is intended to be used where the function
328 is discarded. This is intended to be used where the function
329 is called by a user command, which it should not return.
329 is called by a user command, which it should not return.
330
330
331 Returns
331 Returns
332 -------
332 -------
333 Tuples as :meth:`get_range`
333 Tuples as :meth:`get_range`
334 """
334 """
335 self.writeout_cache()
335 self.writeout_cache()
336 if not include_latest:
336 if not include_latest:
337 n += 1
337 n += 1
338 cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?",
338 cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?",
339 (n,), raw=raw, output=output)
339 (n,), raw=raw, output=output)
340 if not include_latest:
340 if not include_latest:
341 return reversed(list(cur)[1:])
341 return reversed(list(cur)[1:])
342 return reversed(list(cur))
342 return reversed(list(cur))
343
343
344 @catch_corrupt_db
344 @catch_corrupt_db
345 def search(self, pattern="*", raw=True, search_raw=True,
345 def search(self, pattern="*", raw=True, search_raw=True,
346 output=False, n=None, unique=False):
346 output=False, n=None, unique=False):
347 """Search the database using unix glob-style matching (wildcards
347 """Search the database using unix glob-style matching (wildcards
348 * and ?).
348 * and ?).
349
349
350 Parameters
350 Parameters
351 ----------
351 ----------
352 pattern : str
352 pattern : str
353 The wildcarded pattern to match when searching
353 The wildcarded pattern to match when searching
354 search_raw : bool
354 search_raw : bool
355 If True, search the raw input, otherwise, the parsed input
355 If True, search the raw input, otherwise, the parsed input
356 raw, output : bool
356 raw, output : bool
357 See :meth:`get_range`
357 See :meth:`get_range`
358 n : None or int
358 n : None or int
359 If an integer is given, it defines the limit of
359 If an integer is given, it defines the limit of
360 returned entries.
360 returned entries.
361 unique : bool
361 unique : bool
362 When it is true, return only unique entries.
362 When it is true, return only unique entries.
363
363
364 Returns
364 Returns
365 -------
365 -------
366 Tuples as :meth:`get_range`
366 Tuples as :meth:`get_range`
367 """
367 """
368 tosearch = "source_raw" if search_raw else "source"
368 tosearch = "source_raw" if search_raw else "source"
369 if output:
369 if output:
370 tosearch = "history." + tosearch
370 tosearch = "history." + tosearch
371 self.writeout_cache()
371 self.writeout_cache()
372 sqlform = "WHERE %s GLOB ?" % tosearch
372 sqlform = "WHERE %s GLOB ?" % tosearch
373 params = (pattern,)
373 params = (pattern,)
374 if unique:
374 if unique:
375 sqlform += ' GROUP BY {0}'.format(tosearch)
375 sqlform += ' GROUP BY {0}'.format(tosearch)
376 if n is not None:
376 if n is not None:
377 sqlform += " ORDER BY session DESC, line DESC LIMIT ?"
377 sqlform += " ORDER BY session DESC, line DESC LIMIT ?"
378 params += (n,)
378 params += (n,)
379 elif unique:
379 elif unique:
380 sqlform += " ORDER BY session, line"
380 sqlform += " ORDER BY session, line"
381 cur = self._run_sql(sqlform, params, raw=raw, output=output)
381 cur = self._run_sql(sqlform, params, raw=raw, output=output)
382 if n is not None:
382 if n is not None:
383 return reversed(list(cur))
383 return reversed(list(cur))
384 return cur
384 return cur
385
385
386 @catch_corrupt_db
386 @catch_corrupt_db
387 def get_range(self, session, start=1, stop=None, raw=True,output=False):
387 def get_range(self, session, start=1, stop=None, raw=True,output=False):
388 """Retrieve input by session.
388 """Retrieve input by session.
389
389
390 Parameters
390 Parameters
391 ----------
391 ----------
392 session : int
392 session : int
393 Session number to retrieve.
393 Session number to retrieve.
394 start : int
394 start : int
395 First line to retrieve.
395 First line to retrieve.
396 stop : int
396 stop : int
397 End of line range (excluded from output itself). If None, retrieve
397 End of line range (excluded from output itself). If None, retrieve
398 to the end of the session.
398 to the end of the session.
399 raw : bool
399 raw : bool
400 If True, return untranslated input
400 If True, return untranslated input
401 output : bool
401 output : bool
402 If True, attempt to include output. This will be 'real' Python
402 If True, attempt to include output. This will be 'real' Python
403 objects for the current session, or text reprs from previous
403 objects for the current session, or text reprs from previous
404 sessions if db_log_output was enabled at the time. Where no output
404 sessions if db_log_output was enabled at the time. Where no output
405 is found, None is used.
405 is found, None is used.
406
406
407 Returns
407 Returns
408 -------
408 -------
409 entries
409 entries
410 An iterator over the desired lines. Each line is a 3-tuple, either
410 An iterator over the desired lines. Each line is a 3-tuple, either
411 (session, line, input) if output is False, or
411 (session, line, input) if output is False, or
412 (session, line, (input, output)) if output is True.
412 (session, line, (input, output)) if output is True.
413 """
413 """
414 if stop:
414 if stop:
415 lineclause = "line >= ? AND line < ?"
415 lineclause = "line >= ? AND line < ?"
416 params = (session, start, stop)
416 params = (session, start, stop)
417 else:
417 else:
418 lineclause = "line>=?"
418 lineclause = "line>=?"
419 params = (session, start)
419 params = (session, start)
420
420
421 return self._run_sql("WHERE session==? AND %s" % lineclause,
421 return self._run_sql("WHERE session==? AND %s" % lineclause,
422 params, raw=raw, output=output)
422 params, raw=raw, output=output)
423
423
424 def get_range_by_str(self, rangestr, raw=True, output=False):
424 def get_range_by_str(self, rangestr, raw=True, output=False):
425 """Get lines of history from a string of ranges, as used by magic
425 """Get lines of history from a string of ranges, as used by magic
426 commands %hist, %save, %macro, etc.
426 commands %hist, %save, %macro, etc.
427
427
428 Parameters
428 Parameters
429 ----------
429 ----------
430 rangestr : str
430 rangestr : str
431 A string specifying ranges, e.g. "5 ~2/1-4". See
431 A string specifying ranges, e.g. "5 ~2/1-4". See
432 :func:`magic_history` for full details.
432 :func:`magic_history` for full details.
433 raw, output : bool
433 raw, output : bool
434 As :meth:`get_range`
434 As :meth:`get_range`
435
435
436 Returns
436 Returns
437 -------
437 -------
438 Tuples as :meth:`get_range`
438 Tuples as :meth:`get_range`
439 """
439 """
440 for sess, s, e in extract_hist_ranges(rangestr):
440 for sess, s, e in extract_hist_ranges(rangestr):
441 for line in self.get_range(sess, s, e, raw=raw, output=output):
441 for line in self.get_range(sess, s, e, raw=raw, output=output):
442 yield line
442 yield line
443
443
444
444
445 class HistoryManager(HistoryAccessor):
445 class HistoryManager(HistoryAccessor):
446 """A class to organize all history-related functionality in one place.
446 """A class to organize all history-related functionality in one place.
447 """
447 """
448 # Public interface
448 # Public interface
449
449
450 # An instance of the IPython shell we are attached to
450 # An instance of the IPython shell we are attached to
451 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
451 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
452 allow_none=True)
452 allow_none=True)
453 # Lists to hold processed and raw history. These start with a blank entry
453 # Lists to hold processed and raw history. These start with a blank entry
454 # so that we can index them starting from 1
454 # so that we can index them starting from 1
455 input_hist_parsed = List([""])
455 input_hist_parsed = List([""])
456 input_hist_raw = List([""])
456 input_hist_raw = List([""])
457 # A list of directories visited during session
457 # A list of directories visited during session
458 dir_hist = List()
458 dir_hist = List()
459 def _dir_hist_default(self):
459 def _dir_hist_default(self):
460 try:
460 try:
461 return [py3compat.getcwd()]
461 return [py3compat.getcwd()]
462 except OSError:
462 except OSError:
463 return []
463 return []
464
464
465 # A dict of output history, keyed with ints from the shell's
465 # A dict of output history, keyed with ints from the shell's
466 # execution count.
466 # execution count.
467 output_hist = Dict()
467 output_hist = Dict()
468 # The text/plain repr of outputs.
468 # The text/plain repr of outputs.
469 output_hist_reprs = Dict()
469 output_hist_reprs = Dict()
470
470
471 # The number of the current session in the history database
471 # The number of the current session in the history database
472 session_number = Integer()
472 session_number = Integer()
473
473
474 db_log_output = Bool(False, config=True,
474 db_log_output = Bool(False, config=True,
475 help="Should the history database include output? (default: no)"
475 help="Should the history database include output? (default: no)"
476 )
476 )
477 db_cache_size = Integer(0, config=True,
477 db_cache_size = Integer(0, config=True,
478 help="Write to database every x commands (higher values save disk access & power).\n"
478 help="Write to database every x commands (higher values save disk access & power).\n"
479 "Values of 1 or less effectively disable caching."
479 "Values of 1 or less effectively disable caching."
480 )
480 )
481 # The input and output caches
481 # The input and output caches
482 db_input_cache = List()
482 db_input_cache = List()
483 db_output_cache = List()
483 db_output_cache = List()
484
484
485 # History saving in separate thread
485 # History saving in separate thread
486 save_thread = Instance('IPython.core.history.HistorySavingThread',
486 save_thread = Instance('IPython.core.history.HistorySavingThread',
487 allow_none=True)
487 allow_none=True)
488 try: # Event is a function returning an instance of _Event...
488 try: # Event is a function returning an instance of _Event...
489 save_flag = Instance(threading._Event, allow_none=True)
489 save_flag = Instance(threading._Event, allow_none=True)
490 except AttributeError: # ...until Python 3.3, when it's a class.
490 except AttributeError: # ...until Python 3.3, when it's a class.
491 save_flag = Instance(threading.Event, allow_none=True)
491 save_flag = Instance(threading.Event, allow_none=True)
492
492
493 # Private interface
493 # Private interface
494 # Variables used to store the three last inputs from the user. On each new
494 # Variables used to store the three last inputs from the user. On each new
495 # history update, we populate the user's namespace with these, shifted as
495 # history update, we populate the user's namespace with these, shifted as
496 # necessary.
496 # necessary.
497 _i00 = Unicode(u'')
497 _i00 = Unicode(u'')
498 _i = Unicode(u'')
498 _i = Unicode(u'')
499 _ii = Unicode(u'')
499 _ii = Unicode(u'')
500 _iii = Unicode(u'')
500 _iii = Unicode(u'')
501
501
502 # A regex matching all forms of the exit command, so that we don't store
502 # A regex matching all forms of the exit command, so that we don't store
503 # them in the history (it's annoying to rewind the first entry and land on
503 # them in the history (it's annoying to rewind the first entry and land on
504 # an exit call).
504 # an exit call).
505 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
505 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
506
506
507 def __init__(self, shell=None, config=None, **traits):
507 def __init__(self, shell=None, config=None, **traits):
508 """Create a new history manager associated with a shell instance.
508 """Create a new history manager associated with a shell instance.
509 """
509 """
510 # We need a pointer back to the shell for various tasks.
510 # We need a pointer back to the shell for various tasks.
511 super(HistoryManager, self).__init__(shell=shell, config=config,
511 super(HistoryManager, self).__init__(shell=shell, config=config,
512 **traits)
512 **traits)
513 self.save_flag = threading.Event()
513 self.save_flag = threading.Event()
514 self.db_input_cache_lock = threading.Lock()
514 self.db_input_cache_lock = threading.Lock()
515 self.db_output_cache_lock = threading.Lock()
515 self.db_output_cache_lock = threading.Lock()
516
516
517 try:
517 try:
518 self.new_session()
518 self.new_session()
519 except OperationalError:
519 except OperationalError:
520 self.log.error("Failed to create history session in %s. History will not be saved.",
520 self.log.error("Failed to create history session in %s. History will not be saved.",
521 self.hist_file, exc_info=True)
521 self.hist_file, exc_info=True)
522 self.hist_file = ':memory:'
522 self.hist_file = ':memory:'
523
523
524 if self.enabled and self.hist_file != ':memory:':
524 if self.enabled and self.hist_file != ':memory:':
525 self.save_thread = HistorySavingThread(self)
525 self.save_thread = HistorySavingThread(self)
526 self.save_thread.start()
526 self.save_thread.start()
527
527
528 def _get_hist_file_name(self, profile=None):
528 def _get_hist_file_name(self, profile=None):
529 """Get default history file name based on the Shell's profile.
529 """Get default history file name based on the Shell's profile.
530
530
531 The profile parameter is ignored, but must exist for compatibility with
531 The profile parameter is ignored, but must exist for compatibility with
532 the parent class."""
532 the parent class."""
533 profile_dir = self.shell.profile_dir.location
533 profile_dir = self.shell.profile_dir.location
534 return os.path.join(profile_dir, 'history.sqlite')
534 return os.path.join(profile_dir, 'history.sqlite')
535
535
536 @needs_sqlite
536 @needs_sqlite
537 def new_session(self, conn=None):
537 def new_session(self, conn=None):
538 """Get a new session number."""
538 """Get a new session number."""
539 if conn is None:
539 if conn is None:
540 conn = self.db
540 conn = self.db
541
541
542 with conn:
542 with conn:
543 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
543 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
544 NULL, "") """, (datetime.datetime.now(),))
544 NULL, "") """, (datetime.datetime.now(),))
545 self.session_number = cur.lastrowid
545 self.session_number = cur.lastrowid
546
546
547 def end_session(self):
547 def end_session(self):
548 """Close the database session, filling in the end time and line count."""
548 """Close the database session, filling in the end time and line count."""
549 self.writeout_cache()
549 self.writeout_cache()
550 with self.db:
550 with self.db:
551 self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE
551 self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE
552 session==?""", (datetime.datetime.now(),
552 session==?""", (datetime.datetime.now(),
553 len(self.input_hist_parsed)-1, self.session_number))
553 len(self.input_hist_parsed)-1, self.session_number))
554 self.session_number = 0
554 self.session_number = 0
555
555
556 def name_session(self, name):
556 def name_session(self, name):
557 """Give the current session a name in the history database."""
557 """Give the current session a name in the history database."""
558 with self.db:
558 with self.db:
559 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
559 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
560 (name, self.session_number))
560 (name, self.session_number))
561
561
562 def reset(self, new_session=True):
562 def reset(self, new_session=True):
563 """Clear the session history, releasing all object references, and
563 """Clear the session history, releasing all object references, and
564 optionally open a new session."""
564 optionally open a new session."""
565 self.output_hist.clear()
565 self.output_hist.clear()
566 # The directory history can't be completely empty
566 # The directory history can't be completely empty
567 self.dir_hist[:] = [py3compat.getcwd()]
567 self.dir_hist[:] = [py3compat.getcwd()]
568
568
569 if new_session:
569 if new_session:
570 if self.session_number:
570 if self.session_number:
571 self.end_session()
571 self.end_session()
572 self.input_hist_parsed[:] = [""]
572 self.input_hist_parsed[:] = [""]
573 self.input_hist_raw[:] = [""]
573 self.input_hist_raw[:] = [""]
574 self.new_session()
574 self.new_session()
575
575
576 # ------------------------------
576 # ------------------------------
577 # Methods for retrieving history
577 # Methods for retrieving history
578 # ------------------------------
578 # ------------------------------
579 def get_session_info(self, session=0):
579 def get_session_info(self, session=0):
580 """Get info about a session.
580 """Get info about a session.
581
581
582 Parameters
582 Parameters
583 ----------
583 ----------
584
584
585 session : int
585 session : int
586 Session number to retrieve. The current session is 0, and negative
586 Session number to retrieve. The current session is 0, and negative
587 numbers count back from current session, so -1 is the previous session.
587 numbers count back from current session, so -1 is the previous session.
588
588
589 Returns
589 Returns
590 -------
590 -------
591
591
592 session_id : int
592 session_id : int
593 Session ID number
593 Session ID number
594 start : datetime
594 start : datetime
595 Timestamp for the start of the session.
595 Timestamp for the start of the session.
596 end : datetime
596 end : datetime
597 Timestamp for the end of the session, or None if IPython crashed.
597 Timestamp for the end of the session, or None if IPython crashed.
598 num_cmds : int
598 num_cmds : int
599 Number of commands run, or None if IPython crashed.
599 Number of commands run, or None if IPython crashed.
600 remark : unicode
600 remark : unicode
601 A manually set description.
601 A manually set description.
602 """
602 """
603 if session <= 0:
603 if session <= 0:
604 session += self.session_number
604 session += self.session_number
605
605
606 return super(HistoryManager, self).get_session_info(session=session)
606 return super(HistoryManager, self).get_session_info(session=session)
607
607
608 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
608 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
609 """Get input and output history from the current session. Called by
609 """Get input and output history from the current session. Called by
610 get_range, and takes similar parameters."""
610 get_range, and takes similar parameters."""
611 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
611 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
612
612
613 n = len(input_hist)
613 n = len(input_hist)
614 if start < 0:
614 if start < 0:
615 start += n
615 start += n
616 if not stop or (stop > n):
616 if not stop or (stop > n):
617 stop = n
617 stop = n
618 elif stop < 0:
618 elif stop < 0:
619 stop += n
619 stop += n
620
620
621 for i in range(start, stop):
621 for i in range(start, stop):
622 if output:
622 if output:
623 line = (input_hist[i], self.output_hist_reprs.get(i))
623 line = (input_hist[i], self.output_hist_reprs.get(i))
624 else:
624 else:
625 line = input_hist[i]
625 line = input_hist[i]
626 yield (0, i, line)
626 yield (0, i, line)
627
627
628 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
628 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
629 """Retrieve input by session.
629 """Retrieve input by session.
630
630
631 Parameters
631 Parameters
632 ----------
632 ----------
633 session : int
633 session : int
634 Session number to retrieve. The current session is 0, and negative
634 Session number to retrieve. The current session is 0, and negative
635 numbers count back from current session, so -1 is previous session.
635 numbers count back from current session, so -1 is previous session.
636 start : int
636 start : int
637 First line to retrieve.
637 First line to retrieve.
638 stop : int
638 stop : int
639 End of line range (excluded from output itself). If None, retrieve
639 End of line range (excluded from output itself). If None, retrieve
640 to the end of the session.
640 to the end of the session.
641 raw : bool
641 raw : bool
642 If True, return untranslated input
642 If True, return untranslated input
643 output : bool
643 output : bool
644 If True, attempt to include output. This will be 'real' Python
644 If True, attempt to include output. This will be 'real' Python
645 objects for the current session, or text reprs from previous
645 objects for the current session, or text reprs from previous
646 sessions if db_log_output was enabled at the time. Where no output
646 sessions if db_log_output was enabled at the time. Where no output
647 is found, None is used.
647 is found, None is used.
648
648
649 Returns
649 Returns
650 -------
650 -------
651 entries
651 entries
652 An iterator over the desired lines. Each line is a 3-tuple, either
652 An iterator over the desired lines. Each line is a 3-tuple, either
653 (session, line, input) if output is False, or
653 (session, line, input) if output is False, or
654 (session, line, (input, output)) if output is True.
654 (session, line, (input, output)) if output is True.
655 """
655 """
656 if session <= 0:
656 if session <= 0:
657 session += self.session_number
657 session += self.session_number
658 if session==self.session_number: # Current session
658 if session==self.session_number: # Current session
659 return self._get_range_session(start, stop, raw, output)
659 return self._get_range_session(start, stop, raw, output)
660 return super(HistoryManager, self).get_range(session, start, stop, raw,
660 return super(HistoryManager, self).get_range(session, start, stop, raw,
661 output)
661 output)
662
662
663 ## ----------------------------
663 ## ----------------------------
664 ## Methods for storing history:
664 ## Methods for storing history:
665 ## ----------------------------
665 ## ----------------------------
666 def store_inputs(self, line_num, source, source_raw=None):
666 def store_inputs(self, line_num, source, source_raw=None):
667 """Store source and raw input in history and create input cache
667 """Store source and raw input in history and create input cache
668 variables ``_i*``.
668 variables ``_i*``.
669
669
670 Parameters
670 Parameters
671 ----------
671 ----------
672 line_num : int
672 line_num : int
673 The prompt number of this input.
673 The prompt number of this input.
674
674
675 source : str
675 source : str
676 Python input.
676 Python input.
677
677
678 source_raw : str, optional
678 source_raw : str, optional
679 If given, this is the raw input without any IPython transformations
679 If given, this is the raw input without any IPython transformations
680 applied to it. If not given, ``source`` is used.
680 applied to it. If not given, ``source`` is used.
681 """
681 """
682 if source_raw is None:
682 if source_raw is None:
683 source_raw = source
683 source_raw = source
684 source = source.rstrip('\n')
684 source = source.rstrip('\n')
685 source_raw = source_raw.rstrip('\n')
685 source_raw = source_raw.rstrip('\n')
686
686
687 # do not store exit/quit commands
687 # do not store exit/quit commands
688 if self._exit_re.match(source_raw.strip()):
688 if self._exit_re.match(source_raw.strip()):
689 return
689 return
690
690
691 self.input_hist_parsed.append(source)
691 self.input_hist_parsed.append(source)
692 self.input_hist_raw.append(source_raw)
692 self.input_hist_raw.append(source_raw)
693
693
694 with self.db_input_cache_lock:
694 with self.db_input_cache_lock:
695 self.db_input_cache.append((line_num, source, source_raw))
695 self.db_input_cache.append((line_num, source, source_raw))
696 # Trigger to flush cache and write to DB.
696 # Trigger to flush cache and write to DB.
697 if len(self.db_input_cache) >= self.db_cache_size:
697 if len(self.db_input_cache) >= self.db_cache_size:
698 self.save_flag.set()
698 self.save_flag.set()
699
699
700 # update the auto _i variables
700 # update the auto _i variables
701 self._iii = self._ii
701 self._iii = self._ii
702 self._ii = self._i
702 self._ii = self._i
703 self._i = self._i00
703 self._i = self._i00
704 self._i00 = source_raw
704 self._i00 = source_raw
705
705
706 # hackish access to user namespace to create _i1,_i2... dynamically
706 # hackish access to user namespace to create _i1,_i2... dynamically
707 new_i = '_i%s' % line_num
707 new_i = '_i%s' % line_num
708 to_main = {'_i': self._i,
708 to_main = {'_i': self._i,
709 '_ii': self._ii,
709 '_ii': self._ii,
710 '_iii': self._iii,
710 '_iii': self._iii,
711 new_i : self._i00 }
711 new_i : self._i00 }
712
712
713 if self.shell is not None:
713 if self.shell is not None:
714 self.shell.push(to_main, interactive=False)
714 self.shell.push(to_main, interactive=False)
715
715
716 def store_output(self, line_num):
716 def store_output(self, line_num):
717 """If database output logging is enabled, this saves all the
717 """If database output logging is enabled, this saves all the
718 outputs from the indicated prompt number to the database. It's
718 outputs from the indicated prompt number to the database. It's
719 called by run_cell after code has been executed.
719 called by run_cell after code has been executed.
720
720
721 Parameters
721 Parameters
722 ----------
722 ----------
723 line_num : int
723 line_num : int
724 The line number from which to save outputs
724 The line number from which to save outputs
725 """
725 """
726 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
726 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
727 return
727 return
728 output = self.output_hist_reprs[line_num]
728 output = self.output_hist_reprs[line_num]
729
729
730 with self.db_output_cache_lock:
730 with self.db_output_cache_lock:
731 self.db_output_cache.append((line_num, output))
731 self.db_output_cache.append((line_num, output))
732 if self.db_cache_size <= 1:
732 if self.db_cache_size <= 1:
733 self.save_flag.set()
733 self.save_flag.set()
734
734
735 def _writeout_input_cache(self, conn):
735 def _writeout_input_cache(self, conn):
736 with conn:
736 with conn:
737 for line in self.db_input_cache:
737 for line in self.db_input_cache:
738 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
738 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
739 (self.session_number,)+line)
739 (self.session_number,)+line)
740
740
741 def _writeout_output_cache(self, conn):
741 def _writeout_output_cache(self, conn):
742 with conn:
742 with conn:
743 for line in self.db_output_cache:
743 for line in self.db_output_cache:
744 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
744 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
745 (self.session_number,)+line)
745 (self.session_number,)+line)
746
746
747 @needs_sqlite
747 @needs_sqlite
748 def writeout_cache(self, conn=None):
748 def writeout_cache(self, conn=None):
749 """Write any entries in the cache to the database."""
749 """Write any entries in the cache to the database."""
750 if conn is None:
750 if conn is None:
751 conn = self.db
751 conn = self.db
752
752
753 with self.db_input_cache_lock:
753 with self.db_input_cache_lock:
754 try:
754 try:
755 self._writeout_input_cache(conn)
755 self._writeout_input_cache(conn)
756 except sqlite3.IntegrityError:
756 except sqlite3.IntegrityError:
757 self.new_session(conn)
757 self.new_session(conn)
758 print("ERROR! Session/line number was not unique in",
758 print("ERROR! Session/line number was not unique in",
759 "database. History logging moved to new session",
759 "database. History logging moved to new session",
760 self.session_number)
760 self.session_number)
761 try:
761 try:
762 # Try writing to the new session. If this fails, don't
762 # Try writing to the new session. If this fails, don't
763 # recurse
763 # recurse
764 self._writeout_input_cache(conn)
764 self._writeout_input_cache(conn)
765 except sqlite3.IntegrityError:
765 except sqlite3.IntegrityError:
766 pass
766 pass
767 finally:
767 finally:
768 self.db_input_cache = []
768 self.db_input_cache = []
769
769
770 with self.db_output_cache_lock:
770 with self.db_output_cache_lock:
771 try:
771 try:
772 self._writeout_output_cache(conn)
772 self._writeout_output_cache(conn)
773 except sqlite3.IntegrityError:
773 except sqlite3.IntegrityError:
774 print("!! Session/line number for output was not unique",
774 print("!! Session/line number for output was not unique",
775 "in database. Output will not be stored.")
775 "in database. Output will not be stored.")
776 finally:
776 finally:
777 self.db_output_cache = []
777 self.db_output_cache = []
778
778
779
779
780 class HistorySavingThread(threading.Thread):
780 class HistorySavingThread(threading.Thread):
781 """This thread takes care of writing history to the database, so that
781 """This thread takes care of writing history to the database, so that
782 the UI isn't held up while that happens.
782 the UI isn't held up while that happens.
783
783
784 It waits for the HistoryManager's save_flag to be set, then writes out
784 It waits for the HistoryManager's save_flag to be set, then writes out
785 the history cache. The main thread is responsible for setting the flag when
785 the history cache. The main thread is responsible for setting the flag when
786 the cache size reaches a defined threshold."""
786 the cache size reaches a defined threshold."""
787 daemon = True
787 daemon = True
788 stop_now = False
788 stop_now = False
789 enabled = True
789 enabled = True
790 def __init__(self, history_manager):
790 def __init__(self, history_manager):
791 super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
791 super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
792 self.history_manager = history_manager
792 self.history_manager = history_manager
793 self.enabled = history_manager.enabled
793 self.enabled = history_manager.enabled
794 atexit.register(self.stop)
794 atexit.register(self.stop)
795
795
796 @needs_sqlite
796 @needs_sqlite
797 def run(self):
797 def run(self):
798 # We need a separate db connection per thread:
798 # We need a separate db connection per thread:
799 try:
799 try:
800 self.db = sqlite3.connect(self.history_manager.hist_file,
800 self.db = sqlite3.connect(self.history_manager.hist_file,
801 **self.history_manager.connection_options
801 **self.history_manager.connection_options
802 )
802 )
803 while True:
803 while True:
804 self.history_manager.save_flag.wait()
804 self.history_manager.save_flag.wait()
805 if self.stop_now:
805 if self.stop_now:
806 self.db.close()
806 self.db.close()
807 return
807 return
808 self.history_manager.save_flag.clear()
808 self.history_manager.save_flag.clear()
809 self.history_manager.writeout_cache(self.db)
809 self.history_manager.writeout_cache(self.db)
810 except Exception as e:
810 except Exception as e:
811 print(("The history saving thread hit an unexpected error (%s)."
811 print(("The history saving thread hit an unexpected error (%s)."
812 "History will not be written to the database.") % repr(e))
812 "History will not be written to the database.") % repr(e))
813
813
814 def stop(self):
814 def stop(self):
815 """This can be called from the main thread to safely stop this thread.
815 """This can be called from the main thread to safely stop this thread.
816
816
817 Note that it does not attempt to write out remaining history before
817 Note that it does not attempt to write out remaining history before
818 exiting. That should be done by calling the HistoryManager's
818 exiting. That should be done by calling the HistoryManager's
819 end_session method."""
819 end_session method."""
820 self.stop_now = True
820 self.stop_now = True
821 self.history_manager.save_flag.set()
821 self.history_manager.save_flag.set()
822 self.join()
822 self.join()
823
823
824
824
825 # To match, e.g. ~5/8-~2/3
825 # To match, e.g. ~5/8-~2/3
826 range_re = re.compile(r"""
826 range_re = re.compile(r"""
827 ((?P<startsess>~?\d+)/)?
827 ((?P<startsess>~?\d+)/)?
828 (?P<start>\d+)?
828 (?P<start>\d+)?
829 ((?P<sep>[\-:])
829 ((?P<sep>[\-:])
830 ((?P<endsess>~?\d+)/)?
830 ((?P<endsess>~?\d+)/)?
831 (?P<end>\d+))?
831 (?P<end>\d+))?
832 $""", re.VERBOSE)
832 $""", re.VERBOSE)
833
833
834
834
835 def extract_hist_ranges(ranges_str):
835 def extract_hist_ranges(ranges_str):
836 """Turn a string of history ranges into 3-tuples of (session, start, stop).
836 """Turn a string of history ranges into 3-tuples of (session, start, stop).
837
837
838 Examples
838 Examples
839 --------
839 --------
840 >>> list(extract_hist_ranges("~8/5-~7/4 2"))
840 >>> list(extract_hist_ranges("~8/5-~7/4 2"))
841 [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
841 [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
842 """
842 """
843 for range_str in ranges_str.split():
843 for range_str in ranges_str.split():
844 rmatch = range_re.match(range_str)
844 rmatch = range_re.match(range_str)
845 if not rmatch:
845 if not rmatch:
846 continue
846 continue
847 start = rmatch.group("start")
847 start = rmatch.group("start")
848 if start:
848 if start:
849 start = int(start)
849 start = int(start)
850 end = rmatch.group("end")
850 end = rmatch.group("end")
851 # If no end specified, get (a, a + 1)
851 # If no end specified, get (a, a + 1)
852 end = int(end) if end else start + 1
852 end = int(end) if end else start + 1
853 else: # start not specified
853 else: # start not specified
854 if not rmatch.group('startsess'): # no startsess
854 if not rmatch.group('startsess'): # no startsess
855 continue
855 continue
856 start = 1
856 start = 1
857 end = None # provide the entire session hist
857 end = None # provide the entire session hist
858
858
859 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
859 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
860 end += 1
860 end += 1
861 startsess = rmatch.group("startsess") or "0"
861 startsess = rmatch.group("startsess") or "0"
862 endsess = rmatch.group("endsess") or startsess
862 endsess = rmatch.group("endsess") or startsess
863 startsess = int(startsess.replace("~","-"))
863 startsess = int(startsess.replace("~","-"))
864 endsess = int(endsess.replace("~","-"))
864 endsess = int(endsess.replace("~","-"))
865 assert endsess >= startsess, "start session must be earlier than end session"
865 assert endsess >= startsess, "start session must be earlier than end session"
866
866
867 if endsess == startsess:
867 if endsess == startsess:
868 yield (startsess, start, end)
868 yield (startsess, start, end)
869 continue
869 continue
870 # Multiple sessions in one range:
870 # Multiple sessions in one range:
871 yield (startsess, start, None)
871 yield (startsess, start, None)
872 for sess in range(startsess+1, endsess):
872 for sess in range(startsess+1, endsess):
873 yield (sess, 1, None)
873 yield (sess, 1, None)
874 yield (endsess, 1, end)
874 yield (endsess, 1, end)
875
875
876
876
877 def _format_lineno(session, line):
877 def _format_lineno(session, line):
878 """Helper function to format line numbers properly."""
878 """Helper function to format line numbers properly."""
879 if session == 0:
879 if session == 0:
880 return str(line)
880 return str(line)
881 return "%s#%s" % (session, line)
881 return "%s#%s" % (session, line)
882
883
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,703 +1,703 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Magic functions for InteractiveShell.
2 """Magic functions for InteractiveShell.
3 """
3 """
4 from __future__ import print_function
4 from __future__ import print_function
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
8 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
9 # Copyright (C) 2008 The IPython Development Team
9 # Copyright (C) 2008 The IPython Development Team
10
10
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Stdlib
18 # Stdlib
19 import os
19 import os
20 import re
20 import re
21 import sys
21 import sys
22 import types
22 import types
23 from getopt import getopt, GetoptError
23 from getopt import getopt, GetoptError
24
24
25 # Our own
25 # Our own
26 from traitlets.config.configurable import Configurable
26 from traitlets.config.configurable import Configurable
27 from IPython.core import oinspect
27 from IPython.core import oinspect
28 from IPython.core.error import UsageError
28 from IPython.core.error import UsageError
29 from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2
29 from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2
30 from decorator import decorator
30 from decorator import decorator
31 from IPython.utils.ipstruct import Struct
31 from IPython.utils.ipstruct import Struct
32 from IPython.utils.process import arg_split
32 from IPython.utils.process import arg_split
33 from IPython.utils.py3compat import string_types, iteritems
33 from IPython.utils.py3compat import string_types, iteritems
34 from IPython.utils.text import dedent
34 from IPython.utils.text import dedent
35 from traitlets import Bool, Dict, Instance
35 from traitlets import Bool, Dict, Instance
36 from IPython.utils.warn import error
36 from logging import error
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Globals
39 # Globals
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 # A dict we'll use for each class that has magics, used as temporary storage to
42 # A dict we'll use for each class that has magics, used as temporary storage to
43 # pass information between the @line/cell_magic method decorators and the
43 # pass information between the @line/cell_magic method decorators and the
44 # @magics_class class decorator, because the method decorators have no
44 # @magics_class class decorator, because the method decorators have no
45 # access to the class when they run. See for more details:
45 # access to the class when they run. See for more details:
46 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
46 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
47
47
48 magics = dict(line={}, cell={})
48 magics = dict(line={}, cell={})
49
49
50 magic_kinds = ('line', 'cell')
50 magic_kinds = ('line', 'cell')
51 magic_spec = ('line', 'cell', 'line_cell')
51 magic_spec = ('line', 'cell', 'line_cell')
52 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
52 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
53
53
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55 # Utility classes and functions
55 # Utility classes and functions
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57
57
58 class Bunch: pass
58 class Bunch: pass
59
59
60
60
61 def on_off(tag):
61 def on_off(tag):
62 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
62 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
63 return ['OFF','ON'][tag]
63 return ['OFF','ON'][tag]
64
64
65
65
66 def compress_dhist(dh):
66 def compress_dhist(dh):
67 """Compress a directory history into a new one with at most 20 entries.
67 """Compress a directory history into a new one with at most 20 entries.
68
68
69 Return a new list made from the first and last 10 elements of dhist after
69 Return a new list made from the first and last 10 elements of dhist after
70 removal of duplicates.
70 removal of duplicates.
71 """
71 """
72 head, tail = dh[:-10], dh[-10:]
72 head, tail = dh[:-10], dh[-10:]
73
73
74 newhead = []
74 newhead = []
75 done = set()
75 done = set()
76 for h in head:
76 for h in head:
77 if h in done:
77 if h in done:
78 continue
78 continue
79 newhead.append(h)
79 newhead.append(h)
80 done.add(h)
80 done.add(h)
81
81
82 return newhead + tail
82 return newhead + tail
83
83
84
84
85 def needs_local_scope(func):
85 def needs_local_scope(func):
86 """Decorator to mark magic functions which need to local scope to run."""
86 """Decorator to mark magic functions which need to local scope to run."""
87 func.needs_local_scope = True
87 func.needs_local_scope = True
88 return func
88 return func
89
89
90 #-----------------------------------------------------------------------------
90 #-----------------------------------------------------------------------------
91 # Class and method decorators for registering magics
91 # Class and method decorators for registering magics
92 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
93
93
94 def magics_class(cls):
94 def magics_class(cls):
95 """Class decorator for all subclasses of the main Magics class.
95 """Class decorator for all subclasses of the main Magics class.
96
96
97 Any class that subclasses Magics *must* also apply this decorator, to
97 Any class that subclasses Magics *must* also apply this decorator, to
98 ensure that all the methods that have been decorated as line/cell magics
98 ensure that all the methods that have been decorated as line/cell magics
99 get correctly registered in the class instance. This is necessary because
99 get correctly registered in the class instance. This is necessary because
100 when method decorators run, the class does not exist yet, so they
100 when method decorators run, the class does not exist yet, so they
101 temporarily store their information into a module global. Application of
101 temporarily store their information into a module global. Application of
102 this class decorator copies that global data to the class instance and
102 this class decorator copies that global data to the class instance and
103 clears the global.
103 clears the global.
104
104
105 Obviously, this mechanism is not thread-safe, which means that the
105 Obviously, this mechanism is not thread-safe, which means that the
106 *creation* of subclasses of Magic should only be done in a single-thread
106 *creation* of subclasses of Magic should only be done in a single-thread
107 context. Instantiation of the classes has no restrictions. Given that
107 context. Instantiation of the classes has no restrictions. Given that
108 these classes are typically created at IPython startup time and before user
108 these classes are typically created at IPython startup time and before user
109 application code becomes active, in practice this should not pose any
109 application code becomes active, in practice this should not pose any
110 problems.
110 problems.
111 """
111 """
112 cls.registered = True
112 cls.registered = True
113 cls.magics = dict(line = magics['line'],
113 cls.magics = dict(line = magics['line'],
114 cell = magics['cell'])
114 cell = magics['cell'])
115 magics['line'] = {}
115 magics['line'] = {}
116 magics['cell'] = {}
116 magics['cell'] = {}
117 return cls
117 return cls
118
118
119
119
120 def record_magic(dct, magic_kind, magic_name, func):
120 def record_magic(dct, magic_kind, magic_name, func):
121 """Utility function to store a function as a magic of a specific kind.
121 """Utility function to store a function as a magic of a specific kind.
122
122
123 Parameters
123 Parameters
124 ----------
124 ----------
125 dct : dict
125 dct : dict
126 A dictionary with 'line' and 'cell' subdicts.
126 A dictionary with 'line' and 'cell' subdicts.
127
127
128 magic_kind : str
128 magic_kind : str
129 Kind of magic to be stored.
129 Kind of magic to be stored.
130
130
131 magic_name : str
131 magic_name : str
132 Key to store the magic as.
132 Key to store the magic as.
133
133
134 func : function
134 func : function
135 Callable object to store.
135 Callable object to store.
136 """
136 """
137 if magic_kind == 'line_cell':
137 if magic_kind == 'line_cell':
138 dct['line'][magic_name] = dct['cell'][magic_name] = func
138 dct['line'][magic_name] = dct['cell'][magic_name] = func
139 else:
139 else:
140 dct[magic_kind][magic_name] = func
140 dct[magic_kind][magic_name] = func
141
141
142
142
143 def validate_type(magic_kind):
143 def validate_type(magic_kind):
144 """Ensure that the given magic_kind is valid.
144 """Ensure that the given magic_kind is valid.
145
145
146 Check that the given magic_kind is one of the accepted spec types (stored
146 Check that the given magic_kind is one of the accepted spec types (stored
147 in the global `magic_spec`), raise ValueError otherwise.
147 in the global `magic_spec`), raise ValueError otherwise.
148 """
148 """
149 if magic_kind not in magic_spec:
149 if magic_kind not in magic_spec:
150 raise ValueError('magic_kind must be one of %s, %s given' %
150 raise ValueError('magic_kind must be one of %s, %s given' %
151 magic_kinds, magic_kind)
151 magic_kinds, magic_kind)
152
152
153
153
154 # The docstrings for the decorator below will be fairly similar for the two
154 # The docstrings for the decorator below will be fairly similar for the two
155 # types (method and function), so we generate them here once and reuse the
155 # types (method and function), so we generate them here once and reuse the
156 # templates below.
156 # templates below.
157 _docstring_template = \
157 _docstring_template = \
158 """Decorate the given {0} as {1} magic.
158 """Decorate the given {0} as {1} magic.
159
159
160 The decorator can be used with or without arguments, as follows.
160 The decorator can be used with or without arguments, as follows.
161
161
162 i) without arguments: it will create a {1} magic named as the {0} being
162 i) without arguments: it will create a {1} magic named as the {0} being
163 decorated::
163 decorated::
164
164
165 @deco
165 @deco
166 def foo(...)
166 def foo(...)
167
167
168 will create a {1} magic named `foo`.
168 will create a {1} magic named `foo`.
169
169
170 ii) with one string argument: which will be used as the actual name of the
170 ii) with one string argument: which will be used as the actual name of the
171 resulting magic::
171 resulting magic::
172
172
173 @deco('bar')
173 @deco('bar')
174 def foo(...)
174 def foo(...)
175
175
176 will create a {1} magic named `bar`.
176 will create a {1} magic named `bar`.
177 """
177 """
178
178
179 # These two are decorator factories. While they are conceptually very similar,
179 # These two are decorator factories. While they are conceptually very similar,
180 # there are enough differences in the details that it's simpler to have them
180 # there are enough differences in the details that it's simpler to have them
181 # written as completely standalone functions rather than trying to share code
181 # written as completely standalone functions rather than trying to share code
182 # and make a single one with convoluted logic.
182 # and make a single one with convoluted logic.
183
183
184 def _method_magic_marker(magic_kind):
184 def _method_magic_marker(magic_kind):
185 """Decorator factory for methods in Magics subclasses.
185 """Decorator factory for methods in Magics subclasses.
186 """
186 """
187
187
188 validate_type(magic_kind)
188 validate_type(magic_kind)
189
189
190 # This is a closure to capture the magic_kind. We could also use a class,
190 # This is a closure to capture the magic_kind. We could also use a class,
191 # but it's overkill for just that one bit of state.
191 # but it's overkill for just that one bit of state.
192 def magic_deco(arg):
192 def magic_deco(arg):
193 call = lambda f, *a, **k: f(*a, **k)
193 call = lambda f, *a, **k: f(*a, **k)
194
194
195 if callable(arg):
195 if callable(arg):
196 # "Naked" decorator call (just @foo, no args)
196 # "Naked" decorator call (just @foo, no args)
197 func = arg
197 func = arg
198 name = func.__name__
198 name = func.__name__
199 retval = decorator(call, func)
199 retval = decorator(call, func)
200 record_magic(magics, magic_kind, name, name)
200 record_magic(magics, magic_kind, name, name)
201 elif isinstance(arg, string_types):
201 elif isinstance(arg, string_types):
202 # Decorator called with arguments (@foo('bar'))
202 # Decorator called with arguments (@foo('bar'))
203 name = arg
203 name = arg
204 def mark(func, *a, **kw):
204 def mark(func, *a, **kw):
205 record_magic(magics, magic_kind, name, func.__name__)
205 record_magic(magics, magic_kind, name, func.__name__)
206 return decorator(call, func)
206 return decorator(call, func)
207 retval = mark
207 retval = mark
208 else:
208 else:
209 raise TypeError("Decorator can only be called with "
209 raise TypeError("Decorator can only be called with "
210 "string or function")
210 "string or function")
211 return retval
211 return retval
212
212
213 # Ensure the resulting decorator has a usable docstring
213 # Ensure the resulting decorator has a usable docstring
214 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
214 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
215 return magic_deco
215 return magic_deco
216
216
217
217
218 def _function_magic_marker(magic_kind):
218 def _function_magic_marker(magic_kind):
219 """Decorator factory for standalone functions.
219 """Decorator factory for standalone functions.
220 """
220 """
221 validate_type(magic_kind)
221 validate_type(magic_kind)
222
222
223 # This is a closure to capture the magic_kind. We could also use a class,
223 # This is a closure to capture the magic_kind. We could also use a class,
224 # but it's overkill for just that one bit of state.
224 # but it's overkill for just that one bit of state.
225 def magic_deco(arg):
225 def magic_deco(arg):
226 call = lambda f, *a, **k: f(*a, **k)
226 call = lambda f, *a, **k: f(*a, **k)
227
227
228 # Find get_ipython() in the caller's namespace
228 # Find get_ipython() in the caller's namespace
229 caller = sys._getframe(1)
229 caller = sys._getframe(1)
230 for ns in ['f_locals', 'f_globals', 'f_builtins']:
230 for ns in ['f_locals', 'f_globals', 'f_builtins']:
231 get_ipython = getattr(caller, ns).get('get_ipython')
231 get_ipython = getattr(caller, ns).get('get_ipython')
232 if get_ipython is not None:
232 if get_ipython is not None:
233 break
233 break
234 else:
234 else:
235 raise NameError('Decorator can only run in context where '
235 raise NameError('Decorator can only run in context where '
236 '`get_ipython` exists')
236 '`get_ipython` exists')
237
237
238 ip = get_ipython()
238 ip = get_ipython()
239
239
240 if callable(arg):
240 if callable(arg):
241 # "Naked" decorator call (just @foo, no args)
241 # "Naked" decorator call (just @foo, no args)
242 func = arg
242 func = arg
243 name = func.__name__
243 name = func.__name__
244 ip.register_magic_function(func, magic_kind, name)
244 ip.register_magic_function(func, magic_kind, name)
245 retval = decorator(call, func)
245 retval = decorator(call, func)
246 elif isinstance(arg, string_types):
246 elif isinstance(arg, string_types):
247 # Decorator called with arguments (@foo('bar'))
247 # Decorator called with arguments (@foo('bar'))
248 name = arg
248 name = arg
249 def mark(func, *a, **kw):
249 def mark(func, *a, **kw):
250 ip.register_magic_function(func, magic_kind, name)
250 ip.register_magic_function(func, magic_kind, name)
251 return decorator(call, func)
251 return decorator(call, func)
252 retval = mark
252 retval = mark
253 else:
253 else:
254 raise TypeError("Decorator can only be called with "
254 raise TypeError("Decorator can only be called with "
255 "string or function")
255 "string or function")
256 return retval
256 return retval
257
257
258 # Ensure the resulting decorator has a usable docstring
258 # Ensure the resulting decorator has a usable docstring
259 ds = _docstring_template.format('function', magic_kind)
259 ds = _docstring_template.format('function', magic_kind)
260
260
261 ds += dedent("""
261 ds += dedent("""
262 Note: this decorator can only be used in a context where IPython is already
262 Note: this decorator can only be used in a context where IPython is already
263 active, so that the `get_ipython()` call succeeds. You can therefore use
263 active, so that the `get_ipython()` call succeeds. You can therefore use
264 it in your startup files loaded after IPython initializes, but *not* in the
264 it in your startup files loaded after IPython initializes, but *not* in the
265 IPython configuration file itself, which is executed before IPython is
265 IPython configuration file itself, which is executed before IPython is
266 fully up and running. Any file located in the `startup` subdirectory of
266 fully up and running. Any file located in the `startup` subdirectory of
267 your configuration profile will be OK in this sense.
267 your configuration profile will be OK in this sense.
268 """)
268 """)
269
269
270 magic_deco.__doc__ = ds
270 magic_deco.__doc__ = ds
271 return magic_deco
271 return magic_deco
272
272
273
273
274 # Create the actual decorators for public use
274 # Create the actual decorators for public use
275
275
276 # These three are used to decorate methods in class definitions
276 # These three are used to decorate methods in class definitions
277 line_magic = _method_magic_marker('line')
277 line_magic = _method_magic_marker('line')
278 cell_magic = _method_magic_marker('cell')
278 cell_magic = _method_magic_marker('cell')
279 line_cell_magic = _method_magic_marker('line_cell')
279 line_cell_magic = _method_magic_marker('line_cell')
280
280
281 # These three decorate standalone functions and perform the decoration
281 # These three decorate standalone functions and perform the decoration
282 # immediately. They can only run where get_ipython() works
282 # immediately. They can only run where get_ipython() works
283 register_line_magic = _function_magic_marker('line')
283 register_line_magic = _function_magic_marker('line')
284 register_cell_magic = _function_magic_marker('cell')
284 register_cell_magic = _function_magic_marker('cell')
285 register_line_cell_magic = _function_magic_marker('line_cell')
285 register_line_cell_magic = _function_magic_marker('line_cell')
286
286
287 #-----------------------------------------------------------------------------
287 #-----------------------------------------------------------------------------
288 # Core Magic classes
288 # Core Magic classes
289 #-----------------------------------------------------------------------------
289 #-----------------------------------------------------------------------------
290
290
291 class MagicsManager(Configurable):
291 class MagicsManager(Configurable):
292 """Object that handles all magic-related functionality for IPython.
292 """Object that handles all magic-related functionality for IPython.
293 """
293 """
294 # Non-configurable class attributes
294 # Non-configurable class attributes
295
295
296 # A two-level dict, first keyed by magic type, then by magic function, and
296 # A two-level dict, first keyed by magic type, then by magic function, and
297 # holding the actual callable object as value. This is the dict used for
297 # holding the actual callable object as value. This is the dict used for
298 # magic function dispatch
298 # magic function dispatch
299 magics = Dict()
299 magics = Dict()
300
300
301 # A registry of the original objects that we've been given holding magics.
301 # A registry of the original objects that we've been given holding magics.
302 registry = Dict()
302 registry = Dict()
303
303
304 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
304 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
305
305
306 auto_magic = Bool(True, config=True, help=
306 auto_magic = Bool(True, config=True, help=
307 "Automatically call line magics without requiring explicit % prefix")
307 "Automatically call line magics without requiring explicit % prefix")
308
308
309 def _auto_magic_changed(self, name, value):
309 def _auto_magic_changed(self, name, value):
310 self.shell.automagic = value
310 self.shell.automagic = value
311
311
312 _auto_status = [
312 _auto_status = [
313 'Automagic is OFF, % prefix IS needed for line magics.',
313 'Automagic is OFF, % prefix IS needed for line magics.',
314 'Automagic is ON, % prefix IS NOT needed for line magics.']
314 'Automagic is ON, % prefix IS NOT needed for line magics.']
315
315
316 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
316 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
317
317
318 def __init__(self, shell=None, config=None, user_magics=None, **traits):
318 def __init__(self, shell=None, config=None, user_magics=None, **traits):
319
319
320 super(MagicsManager, self).__init__(shell=shell, config=config,
320 super(MagicsManager, self).__init__(shell=shell, config=config,
321 user_magics=user_magics, **traits)
321 user_magics=user_magics, **traits)
322 self.magics = dict(line={}, cell={})
322 self.magics = dict(line={}, cell={})
323 # Let's add the user_magics to the registry for uniformity, so *all*
323 # Let's add the user_magics to the registry for uniformity, so *all*
324 # registered magic containers can be found there.
324 # registered magic containers can be found there.
325 self.registry[user_magics.__class__.__name__] = user_magics
325 self.registry[user_magics.__class__.__name__] = user_magics
326
326
327 def auto_status(self):
327 def auto_status(self):
328 """Return descriptive string with automagic status."""
328 """Return descriptive string with automagic status."""
329 return self._auto_status[self.auto_magic]
329 return self._auto_status[self.auto_magic]
330
330
331 def lsmagic(self):
331 def lsmagic(self):
332 """Return a dict of currently available magic functions.
332 """Return a dict of currently available magic functions.
333
333
334 The return dict has the keys 'line' and 'cell', corresponding to the
334 The return dict has the keys 'line' and 'cell', corresponding to the
335 two types of magics we support. Each value is a list of names.
335 two types of magics we support. Each value is a list of names.
336 """
336 """
337 return self.magics
337 return self.magics
338
338
339 def lsmagic_docs(self, brief=False, missing=''):
339 def lsmagic_docs(self, brief=False, missing=''):
340 """Return dict of documentation of magic functions.
340 """Return dict of documentation of magic functions.
341
341
342 The return dict has the keys 'line' and 'cell', corresponding to the
342 The return dict has the keys 'line' and 'cell', corresponding to the
343 two types of magics we support. Each value is a dict keyed by magic
343 two types of magics we support. Each value is a dict keyed by magic
344 name whose value is the function docstring. If a docstring is
344 name whose value is the function docstring. If a docstring is
345 unavailable, the value of `missing` is used instead.
345 unavailable, the value of `missing` is used instead.
346
346
347 If brief is True, only the first line of each docstring will be returned.
347 If brief is True, only the first line of each docstring will be returned.
348 """
348 """
349 docs = {}
349 docs = {}
350 for m_type in self.magics:
350 for m_type in self.magics:
351 m_docs = {}
351 m_docs = {}
352 for m_name, m_func in iteritems(self.magics[m_type]):
352 for m_name, m_func in iteritems(self.magics[m_type]):
353 if m_func.__doc__:
353 if m_func.__doc__:
354 if brief:
354 if brief:
355 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
355 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
356 else:
356 else:
357 m_docs[m_name] = m_func.__doc__.rstrip()
357 m_docs[m_name] = m_func.__doc__.rstrip()
358 else:
358 else:
359 m_docs[m_name] = missing
359 m_docs[m_name] = missing
360 docs[m_type] = m_docs
360 docs[m_type] = m_docs
361 return docs
361 return docs
362
362
363 def register(self, *magic_objects):
363 def register(self, *magic_objects):
364 """Register one or more instances of Magics.
364 """Register one or more instances of Magics.
365
365
366 Take one or more classes or instances of classes that subclass the main
366 Take one or more classes or instances of classes that subclass the main
367 `core.Magic` class, and register them with IPython to use the magic
367 `core.Magic` class, and register them with IPython to use the magic
368 functions they provide. The registration process will then ensure that
368 functions they provide. The registration process will then ensure that
369 any methods that have decorated to provide line and/or cell magics will
369 any methods that have decorated to provide line and/or cell magics will
370 be recognized with the `%x`/`%%x` syntax as a line/cell magic
370 be recognized with the `%x`/`%%x` syntax as a line/cell magic
371 respectively.
371 respectively.
372
372
373 If classes are given, they will be instantiated with the default
373 If classes are given, they will be instantiated with the default
374 constructor. If your classes need a custom constructor, you should
374 constructor. If your classes need a custom constructor, you should
375 instanitate them first and pass the instance.
375 instanitate them first and pass the instance.
376
376
377 The provided arguments can be an arbitrary mix of classes and instances.
377 The provided arguments can be an arbitrary mix of classes and instances.
378
378
379 Parameters
379 Parameters
380 ----------
380 ----------
381 magic_objects : one or more classes or instances
381 magic_objects : one or more classes or instances
382 """
382 """
383 # Start by validating them to ensure they have all had their magic
383 # Start by validating them to ensure they have all had their magic
384 # methods registered at the instance level
384 # methods registered at the instance level
385 for m in magic_objects:
385 for m in magic_objects:
386 if not m.registered:
386 if not m.registered:
387 raise ValueError("Class of magics %r was constructed without "
387 raise ValueError("Class of magics %r was constructed without "
388 "the @register_magics class decorator")
388 "the @register_magics class decorator")
389 if isinstance(m, type):
389 if isinstance(m, type):
390 # If we're given an uninstantiated class
390 # If we're given an uninstantiated class
391 m = m(shell=self.shell)
391 m = m(shell=self.shell)
392
392
393 # Now that we have an instance, we can register it and update the
393 # Now that we have an instance, we can register it and update the
394 # table of callables
394 # table of callables
395 self.registry[m.__class__.__name__] = m
395 self.registry[m.__class__.__name__] = m
396 for mtype in magic_kinds:
396 for mtype in magic_kinds:
397 self.magics[mtype].update(m.magics[mtype])
397 self.magics[mtype].update(m.magics[mtype])
398
398
399 def register_function(self, func, magic_kind='line', magic_name=None):
399 def register_function(self, func, magic_kind='line', magic_name=None):
400 """Expose a standalone function as magic function for IPython.
400 """Expose a standalone function as magic function for IPython.
401
401
402 This will create an IPython magic (line, cell or both) from a
402 This will create an IPython magic (line, cell or both) from a
403 standalone function. The functions should have the following
403 standalone function. The functions should have the following
404 signatures:
404 signatures:
405
405
406 * For line magics: `def f(line)`
406 * For line magics: `def f(line)`
407 * For cell magics: `def f(line, cell)`
407 * For cell magics: `def f(line, cell)`
408 * For a function that does both: `def f(line, cell=None)`
408 * For a function that does both: `def f(line, cell=None)`
409
409
410 In the latter case, the function will be called with `cell==None` when
410 In the latter case, the function will be called with `cell==None` when
411 invoked as `%f`, and with cell as a string when invoked as `%%f`.
411 invoked as `%f`, and with cell as a string when invoked as `%%f`.
412
412
413 Parameters
413 Parameters
414 ----------
414 ----------
415 func : callable
415 func : callable
416 Function to be registered as a magic.
416 Function to be registered as a magic.
417
417
418 magic_kind : str
418 magic_kind : str
419 Kind of magic, one of 'line', 'cell' or 'line_cell'
419 Kind of magic, one of 'line', 'cell' or 'line_cell'
420
420
421 magic_name : optional str
421 magic_name : optional str
422 If given, the name the magic will have in the IPython namespace. By
422 If given, the name the magic will have in the IPython namespace. By
423 default, the name of the function itself is used.
423 default, the name of the function itself is used.
424 """
424 """
425
425
426 # Create the new method in the user_magics and register it in the
426 # Create the new method in the user_magics and register it in the
427 # global table
427 # global table
428 validate_type(magic_kind)
428 validate_type(magic_kind)
429 magic_name = func.__name__ if magic_name is None else magic_name
429 magic_name = func.__name__ if magic_name is None else magic_name
430 setattr(self.user_magics, magic_name, func)
430 setattr(self.user_magics, magic_name, func)
431 record_magic(self.magics, magic_kind, magic_name, func)
431 record_magic(self.magics, magic_kind, magic_name, func)
432
432
433 def define_magic(self, name, func):
433 def define_magic(self, name, func):
434 """[Deprecated] Expose own function as magic function for IPython.
434 """[Deprecated] Expose own function as magic function for IPython.
435
435
436 Will be removed in IPython 5.0
436 Will be removed in IPython 5.0
437
437
438 Example::
438 Example::
439
439
440 def foo_impl(self, parameter_s=''):
440 def foo_impl(self, parameter_s=''):
441 'My very own magic!. (Use docstrings, IPython reads them).'
441 'My very own magic!. (Use docstrings, IPython reads them).'
442 print 'Magic function. Passed parameter is between < >:'
442 print 'Magic function. Passed parameter is between < >:'
443 print '<%s>' % parameter_s
443 print '<%s>' % parameter_s
444 print 'The self object is:', self
444 print 'The self object is:', self
445
445
446 ip.define_magic('foo',foo_impl)
446 ip.define_magic('foo',foo_impl)
447 """
447 """
448 meth = types.MethodType(func, self.user_magics)
448 meth = types.MethodType(func, self.user_magics)
449 setattr(self.user_magics, name, meth)
449 setattr(self.user_magics, name, meth)
450 record_magic(self.magics, 'line', name, meth)
450 record_magic(self.magics, 'line', name, meth)
451
451
452 def register_alias(self, alias_name, magic_name, magic_kind='line'):
452 def register_alias(self, alias_name, magic_name, magic_kind='line'):
453 """Register an alias to a magic function.
453 """Register an alias to a magic function.
454
454
455 The alias is an instance of :class:`MagicAlias`, which holds the
455 The alias is an instance of :class:`MagicAlias`, which holds the
456 name and kind of the magic it should call. Binding is done at
456 name and kind of the magic it should call. Binding is done at
457 call time, so if the underlying magic function is changed the alias
457 call time, so if the underlying magic function is changed the alias
458 will call the new function.
458 will call the new function.
459
459
460 Parameters
460 Parameters
461 ----------
461 ----------
462 alias_name : str
462 alias_name : str
463 The name of the magic to be registered.
463 The name of the magic to be registered.
464
464
465 magic_name : str
465 magic_name : str
466 The name of an existing magic.
466 The name of an existing magic.
467
467
468 magic_kind : str
468 magic_kind : str
469 Kind of magic, one of 'line' or 'cell'
469 Kind of magic, one of 'line' or 'cell'
470 """
470 """
471
471
472 # `validate_type` is too permissive, as it allows 'line_cell'
472 # `validate_type` is too permissive, as it allows 'line_cell'
473 # which we do not handle.
473 # which we do not handle.
474 if magic_kind not in magic_kinds:
474 if magic_kind not in magic_kinds:
475 raise ValueError('magic_kind must be one of %s, %s given' %
475 raise ValueError('magic_kind must be one of %s, %s given' %
476 magic_kinds, magic_kind)
476 magic_kinds, magic_kind)
477
477
478 alias = MagicAlias(self.shell, magic_name, magic_kind)
478 alias = MagicAlias(self.shell, magic_name, magic_kind)
479 setattr(self.user_magics, alias_name, alias)
479 setattr(self.user_magics, alias_name, alias)
480 record_magic(self.magics, magic_kind, alias_name, alias)
480 record_magic(self.magics, magic_kind, alias_name, alias)
481
481
482 # Key base class that provides the central functionality for magics.
482 # Key base class that provides the central functionality for magics.
483
483
484
484
485 class Magics(Configurable):
485 class Magics(Configurable):
486 """Base class for implementing magic functions.
486 """Base class for implementing magic functions.
487
487
488 Shell functions which can be reached as %function_name. All magic
488 Shell functions which can be reached as %function_name. All magic
489 functions should accept a string, which they can parse for their own
489 functions should accept a string, which they can parse for their own
490 needs. This can make some functions easier to type, eg `%cd ../`
490 needs. This can make some functions easier to type, eg `%cd ../`
491 vs. `%cd("../")`
491 vs. `%cd("../")`
492
492
493 Classes providing magic functions need to subclass this class, and they
493 Classes providing magic functions need to subclass this class, and they
494 MUST:
494 MUST:
495
495
496 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
496 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
497 individual methods as magic functions, AND
497 individual methods as magic functions, AND
498
498
499 - Use the class decorator `@magics_class` to ensure that the magic
499 - Use the class decorator `@magics_class` to ensure that the magic
500 methods are properly registered at the instance level upon instance
500 methods are properly registered at the instance level upon instance
501 initialization.
501 initialization.
502
502
503 See :mod:`magic_functions` for examples of actual implementation classes.
503 See :mod:`magic_functions` for examples of actual implementation classes.
504 """
504 """
505 # Dict holding all command-line options for each magic.
505 # Dict holding all command-line options for each magic.
506 options_table = None
506 options_table = None
507 # Dict for the mapping of magic names to methods, set by class decorator
507 # Dict for the mapping of magic names to methods, set by class decorator
508 magics = None
508 magics = None
509 # Flag to check that the class decorator was properly applied
509 # Flag to check that the class decorator was properly applied
510 registered = False
510 registered = False
511 # Instance of IPython shell
511 # Instance of IPython shell
512 shell = None
512 shell = None
513
513
514 def __init__(self, shell=None, **kwargs):
514 def __init__(self, shell=None, **kwargs):
515 if not(self.__class__.registered):
515 if not(self.__class__.registered):
516 raise ValueError('Magics subclass without registration - '
516 raise ValueError('Magics subclass without registration - '
517 'did you forget to apply @magics_class?')
517 'did you forget to apply @magics_class?')
518 if shell is not None:
518 if shell is not None:
519 if hasattr(shell, 'configurables'):
519 if hasattr(shell, 'configurables'):
520 shell.configurables.append(self)
520 shell.configurables.append(self)
521 if hasattr(shell, 'config'):
521 if hasattr(shell, 'config'):
522 kwargs.setdefault('parent', shell)
522 kwargs.setdefault('parent', shell)
523
523
524 self.shell = shell
524 self.shell = shell
525 self.options_table = {}
525 self.options_table = {}
526 # The method decorators are run when the instance doesn't exist yet, so
526 # The method decorators are run when the instance doesn't exist yet, so
527 # they can only record the names of the methods they are supposed to
527 # they can only record the names of the methods they are supposed to
528 # grab. Only now, that the instance exists, can we create the proper
528 # grab. Only now, that the instance exists, can we create the proper
529 # mapping to bound methods. So we read the info off the original names
529 # mapping to bound methods. So we read the info off the original names
530 # table and replace each method name by the actual bound method.
530 # table and replace each method name by the actual bound method.
531 # But we mustn't clobber the *class* mapping, in case of multiple instances.
531 # But we mustn't clobber the *class* mapping, in case of multiple instances.
532 class_magics = self.magics
532 class_magics = self.magics
533 self.magics = {}
533 self.magics = {}
534 for mtype in magic_kinds:
534 for mtype in magic_kinds:
535 tab = self.magics[mtype] = {}
535 tab = self.magics[mtype] = {}
536 cls_tab = class_magics[mtype]
536 cls_tab = class_magics[mtype]
537 for magic_name, meth_name in iteritems(cls_tab):
537 for magic_name, meth_name in iteritems(cls_tab):
538 if isinstance(meth_name, string_types):
538 if isinstance(meth_name, string_types):
539 # it's a method name, grab it
539 # it's a method name, grab it
540 tab[magic_name] = getattr(self, meth_name)
540 tab[magic_name] = getattr(self, meth_name)
541 else:
541 else:
542 # it's the real thing
542 # it's the real thing
543 tab[magic_name] = meth_name
543 tab[magic_name] = meth_name
544 # Configurable **needs** to be initiated at the end or the config
544 # Configurable **needs** to be initiated at the end or the config
545 # magics get screwed up.
545 # magics get screwed up.
546 super(Magics, self).__init__(**kwargs)
546 super(Magics, self).__init__(**kwargs)
547
547
548 def arg_err(self,func):
548 def arg_err(self,func):
549 """Print docstring if incorrect arguments were passed"""
549 """Print docstring if incorrect arguments were passed"""
550 print('Error in arguments:')
550 print('Error in arguments:')
551 print(oinspect.getdoc(func))
551 print(oinspect.getdoc(func))
552
552
553 def format_latex(self, strng):
553 def format_latex(self, strng):
554 """Format a string for latex inclusion."""
554 """Format a string for latex inclusion."""
555
555
556 # Characters that need to be escaped for latex:
556 # Characters that need to be escaped for latex:
557 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
557 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
558 # Magic command names as headers:
558 # Magic command names as headers:
559 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
559 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
560 re.MULTILINE)
560 re.MULTILINE)
561 # Magic commands
561 # Magic commands
562 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
562 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
563 re.MULTILINE)
563 re.MULTILINE)
564 # Paragraph continue
564 # Paragraph continue
565 par_re = re.compile(r'\\$',re.MULTILINE)
565 par_re = re.compile(r'\\$',re.MULTILINE)
566
566
567 # The "\n" symbol
567 # The "\n" symbol
568 newline_re = re.compile(r'\\n')
568 newline_re = re.compile(r'\\n')
569
569
570 # Now build the string for output:
570 # Now build the string for output:
571 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
571 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
572 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
572 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
573 strng)
573 strng)
574 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
574 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
575 strng = par_re.sub(r'\\\\',strng)
575 strng = par_re.sub(r'\\\\',strng)
576 strng = escape_re.sub(r'\\\1',strng)
576 strng = escape_re.sub(r'\\\1',strng)
577 strng = newline_re.sub(r'\\textbackslash{}n',strng)
577 strng = newline_re.sub(r'\\textbackslash{}n',strng)
578 return strng
578 return strng
579
579
580 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
580 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
581 """Parse options passed to an argument string.
581 """Parse options passed to an argument string.
582
582
583 The interface is similar to that of :func:`getopt.getopt`, but it
583 The interface is similar to that of :func:`getopt.getopt`, but it
584 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
584 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
585 and the stripped argument string still as a string.
585 and the stripped argument string still as a string.
586
586
587 arg_str is quoted as a true sys.argv vector by using shlex.split.
587 arg_str is quoted as a true sys.argv vector by using shlex.split.
588 This allows us to easily expand variables, glob files, quote
588 This allows us to easily expand variables, glob files, quote
589 arguments, etc.
589 arguments, etc.
590
590
591 Parameters
591 Parameters
592 ----------
592 ----------
593
593
594 arg_str : str
594 arg_str : str
595 The arguments to parse.
595 The arguments to parse.
596
596
597 opt_str : str
597 opt_str : str
598 The options specification.
598 The options specification.
599
599
600 mode : str, default 'string'
600 mode : str, default 'string'
601 If given as 'list', the argument string is returned as a list (split
601 If given as 'list', the argument string is returned as a list (split
602 on whitespace) instead of a string.
602 on whitespace) instead of a string.
603
603
604 list_all : bool, default False
604 list_all : bool, default False
605 Put all option values in lists. Normally only options
605 Put all option values in lists. Normally only options
606 appearing more than once are put in a list.
606 appearing more than once are put in a list.
607
607
608 posix : bool, default True
608 posix : bool, default True
609 Whether to split the input line in POSIX mode or not, as per the
609 Whether to split the input line in POSIX mode or not, as per the
610 conventions outlined in the :mod:`shlex` module from the standard
610 conventions outlined in the :mod:`shlex` module from the standard
611 library.
611 library.
612 """
612 """
613
613
614 # inject default options at the beginning of the input line
614 # inject default options at the beginning of the input line
615 caller = sys._getframe(1).f_code.co_name
615 caller = sys._getframe(1).f_code.co_name
616 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
616 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
617
617
618 mode = kw.get('mode','string')
618 mode = kw.get('mode','string')
619 if mode not in ['string','list']:
619 if mode not in ['string','list']:
620 raise ValueError('incorrect mode given: %s' % mode)
620 raise ValueError('incorrect mode given: %s' % mode)
621 # Get options
621 # Get options
622 list_all = kw.get('list_all',0)
622 list_all = kw.get('list_all',0)
623 posix = kw.get('posix', os.name == 'posix')
623 posix = kw.get('posix', os.name == 'posix')
624 strict = kw.get('strict', True)
624 strict = kw.get('strict', True)
625
625
626 # Check if we have more than one argument to warrant extra processing:
626 # Check if we have more than one argument to warrant extra processing:
627 odict = {} # Dictionary with options
627 odict = {} # Dictionary with options
628 args = arg_str.split()
628 args = arg_str.split()
629 if len(args) >= 1:
629 if len(args) >= 1:
630 # If the list of inputs only has 0 or 1 thing in it, there's no
630 # If the list of inputs only has 0 or 1 thing in it, there's no
631 # need to look for options
631 # need to look for options
632 argv = arg_split(arg_str, posix, strict)
632 argv = arg_split(arg_str, posix, strict)
633 # Do regular option processing
633 # Do regular option processing
634 try:
634 try:
635 opts,args = getopt(argv, opt_str, long_opts)
635 opts,args = getopt(argv, opt_str, long_opts)
636 except GetoptError as e:
636 except GetoptError as e:
637 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
637 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
638 " ".join(long_opts)))
638 " ".join(long_opts)))
639 for o,a in opts:
639 for o,a in opts:
640 if o.startswith('--'):
640 if o.startswith('--'):
641 o = o[2:]
641 o = o[2:]
642 else:
642 else:
643 o = o[1:]
643 o = o[1:]
644 try:
644 try:
645 odict[o].append(a)
645 odict[o].append(a)
646 except AttributeError:
646 except AttributeError:
647 odict[o] = [odict[o],a]
647 odict[o] = [odict[o],a]
648 except KeyError:
648 except KeyError:
649 if list_all:
649 if list_all:
650 odict[o] = [a]
650 odict[o] = [a]
651 else:
651 else:
652 odict[o] = a
652 odict[o] = a
653
653
654 # Prepare opts,args for return
654 # Prepare opts,args for return
655 opts = Struct(odict)
655 opts = Struct(odict)
656 if mode == 'string':
656 if mode == 'string':
657 args = ' '.join(args)
657 args = ' '.join(args)
658
658
659 return opts,args
659 return opts,args
660
660
661 def default_option(self, fn, optstr):
661 def default_option(self, fn, optstr):
662 """Make an entry in the options_table for fn, with value optstr"""
662 """Make an entry in the options_table for fn, with value optstr"""
663
663
664 if fn not in self.lsmagic():
664 if fn not in self.lsmagic():
665 error("%s is not a magic function" % fn)
665 error("%s is not a magic function" % fn)
666 self.options_table[fn] = optstr
666 self.options_table[fn] = optstr
667
667
668
668
669 class MagicAlias(object):
669 class MagicAlias(object):
670 """An alias to another magic function.
670 """An alias to another magic function.
671
671
672 An alias is determined by its magic name and magic kind. Lookup
672 An alias is determined by its magic name and magic kind. Lookup
673 is done at call time, so if the underlying magic changes the alias
673 is done at call time, so if the underlying magic changes the alias
674 will call the new function.
674 will call the new function.
675
675
676 Use the :meth:`MagicsManager.register_alias` method or the
676 Use the :meth:`MagicsManager.register_alias` method or the
677 `%alias_magic` magic function to create and register a new alias.
677 `%alias_magic` magic function to create and register a new alias.
678 """
678 """
679 def __init__(self, shell, magic_name, magic_kind):
679 def __init__(self, shell, magic_name, magic_kind):
680 self.shell = shell
680 self.shell = shell
681 self.magic_name = magic_name
681 self.magic_name = magic_name
682 self.magic_kind = magic_kind
682 self.magic_kind = magic_kind
683
683
684 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
684 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
685 self.__doc__ = "Alias for `%s`." % self.pretty_target
685 self.__doc__ = "Alias for `%s`." % self.pretty_target
686
686
687 self._in_call = False
687 self._in_call = False
688
688
689 def __call__(self, *args, **kwargs):
689 def __call__(self, *args, **kwargs):
690 """Call the magic alias."""
690 """Call the magic alias."""
691 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
691 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
692 if fn is None:
692 if fn is None:
693 raise UsageError("Magic `%s` not found." % self.pretty_target)
693 raise UsageError("Magic `%s` not found." % self.pretty_target)
694
694
695 # Protect against infinite recursion.
695 # Protect against infinite recursion.
696 if self._in_call:
696 if self._in_call:
697 raise UsageError("Infinite recursion detected; "
697 raise UsageError("Infinite recursion detected; "
698 "magic aliases cannot call themselves.")
698 "magic aliases cannot call themselves.")
699 self._in_call = True
699 self._in_call = True
700 try:
700 try:
701 return fn(*args, **kwargs)
701 return fn(*args, **kwargs)
702 finally:
702 finally:
703 self._in_call = False
703 self._in_call = False
@@ -1,129 +1,129 b''
1 """Implementation of magic functions that control various automatic behaviors.
1 """Implementation of magic functions that control various automatic behaviors.
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 # Our own packages
16 # Our own packages
17 from IPython.core.magic import Bunch, Magics, magics_class, line_magic
17 from IPython.core.magic import Bunch, Magics, magics_class, line_magic
18 from IPython.testing.skipdoctest import skip_doctest
18 from IPython.testing.skipdoctest import skip_doctest
19 from IPython.utils.warn import error
19 from logging import error
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Magic implementation classes
22 # Magic implementation classes
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 @magics_class
25 @magics_class
26 class AutoMagics(Magics):
26 class AutoMagics(Magics):
27 """Magics that control various autoX behaviors."""
27 """Magics that control various autoX behaviors."""
28
28
29 def __init__(self, shell):
29 def __init__(self, shell):
30 super(AutoMagics, self).__init__(shell)
30 super(AutoMagics, self).__init__(shell)
31 # namespace for holding state we may need
31 # namespace for holding state we may need
32 self._magic_state = Bunch()
32 self._magic_state = Bunch()
33
33
34 @line_magic
34 @line_magic
35 def automagic(self, parameter_s=''):
35 def automagic(self, parameter_s=''):
36 """Make magic functions callable without having to type the initial %.
36 """Make magic functions callable without having to type the initial %.
37
37
38 Without argumentsl toggles on/off (when off, you must call it as
38 Without argumentsl toggles on/off (when off, you must call it as
39 %automagic, of course). With arguments it sets the value, and you can
39 %automagic, of course). With arguments it sets the value, and you can
40 use any of (case insensitive):
40 use any of (case insensitive):
41
41
42 - on, 1, True: to activate
42 - on, 1, True: to activate
43
43
44 - off, 0, False: to deactivate.
44 - off, 0, False: to deactivate.
45
45
46 Note that magic functions have lowest priority, so if there's a
46 Note that magic functions have lowest priority, so if there's a
47 variable whose name collides with that of a magic fn, automagic won't
47 variable whose name collides with that of a magic fn, automagic won't
48 work for that function (you get the variable instead). However, if you
48 work for that function (you get the variable instead). However, if you
49 delete the variable (del var), the previously shadowed magic function
49 delete the variable (del var), the previously shadowed magic function
50 becomes visible to automagic again."""
50 becomes visible to automagic again."""
51
51
52 arg = parameter_s.lower()
52 arg = parameter_s.lower()
53 mman = self.shell.magics_manager
53 mman = self.shell.magics_manager
54 if arg in ('on', '1', 'true'):
54 if arg in ('on', '1', 'true'):
55 val = True
55 val = True
56 elif arg in ('off', '0', 'false'):
56 elif arg in ('off', '0', 'false'):
57 val = False
57 val = False
58 else:
58 else:
59 val = not mman.auto_magic
59 val = not mman.auto_magic
60 mman.auto_magic = val
60 mman.auto_magic = val
61 print('\n' + self.shell.magics_manager.auto_status())
61 print('\n' + self.shell.magics_manager.auto_status())
62
62
63 @skip_doctest
63 @skip_doctest
64 @line_magic
64 @line_magic
65 def autocall(self, parameter_s=''):
65 def autocall(self, parameter_s=''):
66 """Make functions callable without having to type parentheses.
66 """Make functions callable without having to type parentheses.
67
67
68 Usage:
68 Usage:
69
69
70 %autocall [mode]
70 %autocall [mode]
71
71
72 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
72 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
73 value is toggled on and off (remembering the previous state).
73 value is toggled on and off (remembering the previous state).
74
74
75 In more detail, these values mean:
75 In more detail, these values mean:
76
76
77 0 -> fully disabled
77 0 -> fully disabled
78
78
79 1 -> active, but do not apply if there are no arguments on the line.
79 1 -> active, but do not apply if there are no arguments on the line.
80
80
81 In this mode, you get::
81 In this mode, you get::
82
82
83 In [1]: callable
83 In [1]: callable
84 Out[1]: <built-in function callable>
84 Out[1]: <built-in function callable>
85
85
86 In [2]: callable 'hello'
86 In [2]: callable 'hello'
87 ------> callable('hello')
87 ------> callable('hello')
88 Out[2]: False
88 Out[2]: False
89
89
90 2 -> Active always. Even if no arguments are present, the callable
90 2 -> Active always. Even if no arguments are present, the callable
91 object is called::
91 object is called::
92
92
93 In [2]: float
93 In [2]: float
94 ------> float()
94 ------> float()
95 Out[2]: 0.0
95 Out[2]: 0.0
96
96
97 Note that even with autocall off, you can still use '/' at the start of
97 Note that even with autocall off, you can still use '/' at the start of
98 a line to treat the first argument on the command line as a function
98 a line to treat the first argument on the command line as a function
99 and add parentheses to it::
99 and add parentheses to it::
100
100
101 In [8]: /str 43
101 In [8]: /str 43
102 ------> str(43)
102 ------> str(43)
103 Out[8]: '43'
103 Out[8]: '43'
104
104
105 # all-random (note for auto-testing)
105 # all-random (note for auto-testing)
106 """
106 """
107
107
108 if parameter_s:
108 if parameter_s:
109 arg = int(parameter_s)
109 arg = int(parameter_s)
110 else:
110 else:
111 arg = 'toggle'
111 arg = 'toggle'
112
112
113 if not arg in (0, 1, 2, 'toggle'):
113 if not arg in (0, 1, 2, 'toggle'):
114 error('Valid modes: (0->Off, 1->Smart, 2->Full')
114 error('Valid modes: (0->Off, 1->Smart, 2->Full')
115 return
115 return
116
116
117 if arg in (0, 1, 2):
117 if arg in (0, 1, 2):
118 self.shell.autocall = arg
118 self.shell.autocall = arg
119 else: # toggle
119 else: # toggle
120 if self.shell.autocall:
120 if self.shell.autocall:
121 self._magic_state.autocall_save = self.shell.autocall
121 self._magic_state.autocall_save = self.shell.autocall
122 self.shell.autocall = 0
122 self.shell.autocall = 0
123 else:
123 else:
124 try:
124 try:
125 self.shell.autocall = self._magic_state.autocall_save
125 self.shell.autocall = self._magic_state.autocall_save
126 except AttributeError:
126 except AttributeError:
127 self.shell.autocall = self._magic_state.autocall_save = 1
127 self.shell.autocall = self._magic_state.autocall_save = 1
128
128
129 print("Automatic calling is:",['OFF','Smart','Full'][self.shell.autocall])
129 print("Automatic calling is:",['OFF','Smart','Full'][self.shell.autocall])
@@ -1,612 +1,613 b''
1 """Implementation of basic magic functions."""
1 """Implementation of basic magic functions."""
2
2
3 from __future__ import print_function
3 from __future__ import print_function
4
4
5 import io
5 import io
6 import sys
6 import sys
7 from pprint import pformat
7 from pprint import pformat
8
8
9 from IPython.core import magic_arguments, page
9 from IPython.core import magic_arguments, page
10 from IPython.core.error import UsageError
10 from IPython.core.error import UsageError
11 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
11 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
12 from IPython.utils.text import format_screen, dedent, indent
12 from IPython.utils.text import format_screen, dedent, indent
13 from IPython.testing.skipdoctest import skip_doctest
13 from IPython.testing.skipdoctest import skip_doctest
14 from IPython.utils.ipstruct import Struct
14 from IPython.utils.ipstruct import Struct
15 from IPython.utils.path import unquote_filename
15 from IPython.utils.path import unquote_filename
16 from IPython.utils.py3compat import unicode_type
16 from IPython.utils.py3compat import unicode_type
17 from IPython.utils.warn import warn, error
17 from warnings import warn
18 from logging import error
18
19
19
20
20 class MagicsDisplay(object):
21 class MagicsDisplay(object):
21 def __init__(self, magics_manager):
22 def __init__(self, magics_manager):
22 self.magics_manager = magics_manager
23 self.magics_manager = magics_manager
23
24
24 def _lsmagic(self):
25 def _lsmagic(self):
25 """The main implementation of the %lsmagic"""
26 """The main implementation of the %lsmagic"""
26 mesc = magic_escapes['line']
27 mesc = magic_escapes['line']
27 cesc = magic_escapes['cell']
28 cesc = magic_escapes['cell']
28 mman = self.magics_manager
29 mman = self.magics_manager
29 magics = mman.lsmagic()
30 magics = mman.lsmagic()
30 out = ['Available line magics:',
31 out = ['Available line magics:',
31 mesc + (' '+mesc).join(sorted(magics['line'])),
32 mesc + (' '+mesc).join(sorted(magics['line'])),
32 '',
33 '',
33 'Available cell magics:',
34 'Available cell magics:',
34 cesc + (' '+cesc).join(sorted(magics['cell'])),
35 cesc + (' '+cesc).join(sorted(magics['cell'])),
35 '',
36 '',
36 mman.auto_status()]
37 mman.auto_status()]
37 return '\n'.join(out)
38 return '\n'.join(out)
38
39
39 def _repr_pretty_(self, p, cycle):
40 def _repr_pretty_(self, p, cycle):
40 p.text(self._lsmagic())
41 p.text(self._lsmagic())
41
42
42 def __str__(self):
43 def __str__(self):
43 return self._lsmagic()
44 return self._lsmagic()
44
45
45 def _jsonable(self):
46 def _jsonable(self):
46 """turn magics dict into jsonable dict of the same structure
47 """turn magics dict into jsonable dict of the same structure
47
48
48 replaces object instances with their class names as strings
49 replaces object instances with their class names as strings
49 """
50 """
50 magic_dict = {}
51 magic_dict = {}
51 mman = self.magics_manager
52 mman = self.magics_manager
52 magics = mman.lsmagic()
53 magics = mman.lsmagic()
53 for key, subdict in magics.items():
54 for key, subdict in magics.items():
54 d = {}
55 d = {}
55 magic_dict[key] = d
56 magic_dict[key] = d
56 for name, obj in subdict.items():
57 for name, obj in subdict.items():
57 try:
58 try:
58 classname = obj.__self__.__class__.__name__
59 classname = obj.__self__.__class__.__name__
59 except AttributeError:
60 except AttributeError:
60 classname = 'Other'
61 classname = 'Other'
61
62
62 d[name] = classname
63 d[name] = classname
63 return magic_dict
64 return magic_dict
64
65
65 def _repr_json_(self):
66 def _repr_json_(self):
66 return self._jsonable()
67 return self._jsonable()
67
68
68
69
69 @magics_class
70 @magics_class
70 class BasicMagics(Magics):
71 class BasicMagics(Magics):
71 """Magics that provide central IPython functionality.
72 """Magics that provide central IPython functionality.
72
73
73 These are various magics that don't fit into specific categories but that
74 These are various magics that don't fit into specific categories but that
74 are all part of the base 'IPython experience'."""
75 are all part of the base 'IPython experience'."""
75
76
76 @magic_arguments.magic_arguments()
77 @magic_arguments.magic_arguments()
77 @magic_arguments.argument(
78 @magic_arguments.argument(
78 '-l', '--line', action='store_true',
79 '-l', '--line', action='store_true',
79 help="""Create a line magic alias."""
80 help="""Create a line magic alias."""
80 )
81 )
81 @magic_arguments.argument(
82 @magic_arguments.argument(
82 '-c', '--cell', action='store_true',
83 '-c', '--cell', action='store_true',
83 help="""Create a cell magic alias."""
84 help="""Create a cell magic alias."""
84 )
85 )
85 @magic_arguments.argument(
86 @magic_arguments.argument(
86 'name',
87 'name',
87 help="""Name of the magic to be created."""
88 help="""Name of the magic to be created."""
88 )
89 )
89 @magic_arguments.argument(
90 @magic_arguments.argument(
90 'target',
91 'target',
91 help="""Name of the existing line or cell magic."""
92 help="""Name of the existing line or cell magic."""
92 )
93 )
93 @line_magic
94 @line_magic
94 def alias_magic(self, line=''):
95 def alias_magic(self, line=''):
95 """Create an alias for an existing line or cell magic.
96 """Create an alias for an existing line or cell magic.
96
97
97 Examples
98 Examples
98 --------
99 --------
99 ::
100 ::
100
101
101 In [1]: %alias_magic t timeit
102 In [1]: %alias_magic t timeit
102 Created `%t` as an alias for `%timeit`.
103 Created `%t` as an alias for `%timeit`.
103 Created `%%t` as an alias for `%%timeit`.
104 Created `%%t` as an alias for `%%timeit`.
104
105
105 In [2]: %t -n1 pass
106 In [2]: %t -n1 pass
106 1 loops, best of 3: 954 ns per loop
107 1 loops, best of 3: 954 ns per loop
107
108
108 In [3]: %%t -n1
109 In [3]: %%t -n1
109 ...: pass
110 ...: pass
110 ...:
111 ...:
111 1 loops, best of 3: 954 ns per loop
112 1 loops, best of 3: 954 ns per loop
112
113
113 In [4]: %alias_magic --cell whereami pwd
114 In [4]: %alias_magic --cell whereami pwd
114 UsageError: Cell magic function `%%pwd` not found.
115 UsageError: Cell magic function `%%pwd` not found.
115 In [5]: %alias_magic --line whereami pwd
116 In [5]: %alias_magic --line whereami pwd
116 Created `%whereami` as an alias for `%pwd`.
117 Created `%whereami` as an alias for `%pwd`.
117
118
118 In [6]: %whereami
119 In [6]: %whereami
119 Out[6]: u'/home/testuser'
120 Out[6]: u'/home/testuser'
120 """
121 """
121 args = magic_arguments.parse_argstring(self.alias_magic, line)
122 args = magic_arguments.parse_argstring(self.alias_magic, line)
122 shell = self.shell
123 shell = self.shell
123 mman = self.shell.magics_manager
124 mman = self.shell.magics_manager
124 escs = ''.join(magic_escapes.values())
125 escs = ''.join(magic_escapes.values())
125
126
126 target = args.target.lstrip(escs)
127 target = args.target.lstrip(escs)
127 name = args.name.lstrip(escs)
128 name = args.name.lstrip(escs)
128
129
129 # Find the requested magics.
130 # Find the requested magics.
130 m_line = shell.find_magic(target, 'line')
131 m_line = shell.find_magic(target, 'line')
131 m_cell = shell.find_magic(target, 'cell')
132 m_cell = shell.find_magic(target, 'cell')
132 if args.line and m_line is None:
133 if args.line and m_line is None:
133 raise UsageError('Line magic function `%s%s` not found.' %
134 raise UsageError('Line magic function `%s%s` not found.' %
134 (magic_escapes['line'], target))
135 (magic_escapes['line'], target))
135 if args.cell and m_cell is None:
136 if args.cell and m_cell is None:
136 raise UsageError('Cell magic function `%s%s` not found.' %
137 raise UsageError('Cell magic function `%s%s` not found.' %
137 (magic_escapes['cell'], target))
138 (magic_escapes['cell'], target))
138
139
139 # If --line and --cell are not specified, default to the ones
140 # If --line and --cell are not specified, default to the ones
140 # that are available.
141 # that are available.
141 if not args.line and not args.cell:
142 if not args.line and not args.cell:
142 if not m_line and not m_cell:
143 if not m_line and not m_cell:
143 raise UsageError(
144 raise UsageError(
144 'No line or cell magic with name `%s` found.' % target
145 'No line or cell magic with name `%s` found.' % target
145 )
146 )
146 args.line = bool(m_line)
147 args.line = bool(m_line)
147 args.cell = bool(m_cell)
148 args.cell = bool(m_cell)
148
149
149 if args.line:
150 if args.line:
150 mman.register_alias(name, target, 'line')
151 mman.register_alias(name, target, 'line')
151 print('Created `%s%s` as an alias for `%s%s`.' % (
152 print('Created `%s%s` as an alias for `%s%s`.' % (
152 magic_escapes['line'], name,
153 magic_escapes['line'], name,
153 magic_escapes['line'], target))
154 magic_escapes['line'], target))
154
155
155 if args.cell:
156 if args.cell:
156 mman.register_alias(name, target, 'cell')
157 mman.register_alias(name, target, 'cell')
157 print('Created `%s%s` as an alias for `%s%s`.' % (
158 print('Created `%s%s` as an alias for `%s%s`.' % (
158 magic_escapes['cell'], name,
159 magic_escapes['cell'], name,
159 magic_escapes['cell'], target))
160 magic_escapes['cell'], target))
160
161
161 @line_magic
162 @line_magic
162 def lsmagic(self, parameter_s=''):
163 def lsmagic(self, parameter_s=''):
163 """List currently available magic functions."""
164 """List currently available magic functions."""
164 return MagicsDisplay(self.shell.magics_manager)
165 return MagicsDisplay(self.shell.magics_manager)
165
166
166 def _magic_docs(self, brief=False, rest=False):
167 def _magic_docs(self, brief=False, rest=False):
167 """Return docstrings from magic functions."""
168 """Return docstrings from magic functions."""
168 mman = self.shell.magics_manager
169 mman = self.shell.magics_manager
169 docs = mman.lsmagic_docs(brief, missing='No documentation')
170 docs = mman.lsmagic_docs(brief, missing='No documentation')
170
171
171 if rest:
172 if rest:
172 format_string = '**%s%s**::\n\n%s\n\n'
173 format_string = '**%s%s**::\n\n%s\n\n'
173 else:
174 else:
174 format_string = '%s%s:\n%s\n'
175 format_string = '%s%s:\n%s\n'
175
176
176 return ''.join(
177 return ''.join(
177 [format_string % (magic_escapes['line'], fname,
178 [format_string % (magic_escapes['line'], fname,
178 indent(dedent(fndoc)))
179 indent(dedent(fndoc)))
179 for fname, fndoc in sorted(docs['line'].items())]
180 for fname, fndoc in sorted(docs['line'].items())]
180 +
181 +
181 [format_string % (magic_escapes['cell'], fname,
182 [format_string % (magic_escapes['cell'], fname,
182 indent(dedent(fndoc)))
183 indent(dedent(fndoc)))
183 for fname, fndoc in sorted(docs['cell'].items())]
184 for fname, fndoc in sorted(docs['cell'].items())]
184 )
185 )
185
186
186 @line_magic
187 @line_magic
187 def magic(self, parameter_s=''):
188 def magic(self, parameter_s=''):
188 """Print information about the magic function system.
189 """Print information about the magic function system.
189
190
190 Supported formats: -latex, -brief, -rest
191 Supported formats: -latex, -brief, -rest
191 """
192 """
192
193
193 mode = ''
194 mode = ''
194 try:
195 try:
195 mode = parameter_s.split()[0][1:]
196 mode = parameter_s.split()[0][1:]
196 except IndexError:
197 except IndexError:
197 pass
198 pass
198
199
199 brief = (mode == 'brief')
200 brief = (mode == 'brief')
200 rest = (mode == 'rest')
201 rest = (mode == 'rest')
201 magic_docs = self._magic_docs(brief, rest)
202 magic_docs = self._magic_docs(brief, rest)
202
203
203 if mode == 'latex':
204 if mode == 'latex':
204 print(self.format_latex(magic_docs))
205 print(self.format_latex(magic_docs))
205 return
206 return
206 else:
207 else:
207 magic_docs = format_screen(magic_docs)
208 magic_docs = format_screen(magic_docs)
208
209
209 out = ["""
210 out = ["""
210 IPython's 'magic' functions
211 IPython's 'magic' functions
211 ===========================
212 ===========================
212
213
213 The magic function system provides a series of functions which allow you to
214 The magic function system provides a series of functions which allow you to
214 control the behavior of IPython itself, plus a lot of system-type
215 control the behavior of IPython itself, plus a lot of system-type
215 features. There are two kinds of magics, line-oriented and cell-oriented.
216 features. There are two kinds of magics, line-oriented and cell-oriented.
216
217
217 Line magics are prefixed with the % character and work much like OS
218 Line magics are prefixed with the % character and work much like OS
218 command-line calls: they get as an argument the rest of the line, where
219 command-line calls: they get as an argument the rest of the line, where
219 arguments are passed without parentheses or quotes. For example, this will
220 arguments are passed without parentheses or quotes. For example, this will
220 time the given statement::
221 time the given statement::
221
222
222 %timeit range(1000)
223 %timeit range(1000)
223
224
224 Cell magics are prefixed with a double %%, and they are functions that get as
225 Cell magics are prefixed with a double %%, and they are functions that get as
225 an argument not only the rest of the line, but also the lines below it in a
226 an argument not only the rest of the line, but also the lines below it in a
226 separate argument. These magics are called with two arguments: the rest of the
227 separate argument. These magics are called with two arguments: the rest of the
227 call line and the body of the cell, consisting of the lines below the first.
228 call line and the body of the cell, consisting of the lines below the first.
228 For example::
229 For example::
229
230
230 %%timeit x = numpy.random.randn((100, 100))
231 %%timeit x = numpy.random.randn((100, 100))
231 numpy.linalg.svd(x)
232 numpy.linalg.svd(x)
232
233
233 will time the execution of the numpy svd routine, running the assignment of x
234 will time the execution of the numpy svd routine, running the assignment of x
234 as part of the setup phase, which is not timed.
235 as part of the setup phase, which is not timed.
235
236
236 In a line-oriented client (the terminal or Qt console IPython), starting a new
237 In a line-oriented client (the terminal or Qt console IPython), starting a new
237 input with %% will automatically enter cell mode, and IPython will continue
238 input with %% will automatically enter cell mode, and IPython will continue
238 reading input until a blank line is given. In the notebook, simply type the
239 reading input until a blank line is given. In the notebook, simply type the
239 whole cell as one entity, but keep in mind that the %% escape can only be at
240 whole cell as one entity, but keep in mind that the %% escape can only be at
240 the very start of the cell.
241 the very start of the cell.
241
242
242 NOTE: If you have 'automagic' enabled (via the command line option or with the
243 NOTE: If you have 'automagic' enabled (via the command line option or with the
243 %automagic function), you don't need to type in the % explicitly for line
244 %automagic function), you don't need to type in the % explicitly for line
244 magics; cell magics always require an explicit '%%' escape. By default,
245 magics; cell magics always require an explicit '%%' escape. By default,
245 IPython ships with automagic on, so you should only rarely need the % escape.
246 IPython ships with automagic on, so you should only rarely need the % escape.
246
247
247 Example: typing '%cd mydir' (without the quotes) changes your working directory
248 Example: typing '%cd mydir' (without the quotes) changes your working directory
248 to 'mydir', if it exists.
249 to 'mydir', if it exists.
249
250
250 For a list of the available magic functions, use %lsmagic. For a description
251 For a list of the available magic functions, use %lsmagic. For a description
251 of any of them, type %magic_name?, e.g. '%cd?'.
252 of any of them, type %magic_name?, e.g. '%cd?'.
252
253
253 Currently the magic system has the following functions:""",
254 Currently the magic system has the following functions:""",
254 magic_docs,
255 magic_docs,
255 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
256 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
256 str(self.lsmagic()),
257 str(self.lsmagic()),
257 ]
258 ]
258 page.page('\n'.join(out))
259 page.page('\n'.join(out))
259
260
260
261
261 @line_magic
262 @line_magic
262 def page(self, parameter_s=''):
263 def page(self, parameter_s=''):
263 """Pretty print the object and display it through a pager.
264 """Pretty print the object and display it through a pager.
264
265
265 %page [options] OBJECT
266 %page [options] OBJECT
266
267
267 If no object is given, use _ (last output).
268 If no object is given, use _ (last output).
268
269
269 Options:
270 Options:
270
271
271 -r: page str(object), don't pretty-print it."""
272 -r: page str(object), don't pretty-print it."""
272
273
273 # After a function contributed by Olivier Aubert, slightly modified.
274 # After a function contributed by Olivier Aubert, slightly modified.
274
275
275 # Process options/args
276 # Process options/args
276 opts, args = self.parse_options(parameter_s, 'r')
277 opts, args = self.parse_options(parameter_s, 'r')
277 raw = 'r' in opts
278 raw = 'r' in opts
278
279
279 oname = args and args or '_'
280 oname = args and args or '_'
280 info = self.shell._ofind(oname)
281 info = self.shell._ofind(oname)
281 if info['found']:
282 if info['found']:
282 txt = (raw and str or pformat)( info['obj'] )
283 txt = (raw and str or pformat)( info['obj'] )
283 page.page(txt)
284 page.page(txt)
284 else:
285 else:
285 print('Object `%s` not found' % oname)
286 print('Object `%s` not found' % oname)
286
287
287 @line_magic
288 @line_magic
288 def profile(self, parameter_s=''):
289 def profile(self, parameter_s=''):
289 """Print your currently active IPython profile.
290 """Print your currently active IPython profile.
290
291
291 See Also
292 See Also
292 --------
293 --------
293 prun : run code using the Python profiler
294 prun : run code using the Python profiler
294 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
295 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
295 """
296 """
296 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
297 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
297 from IPython.core.application import BaseIPythonApplication
298 from IPython.core.application import BaseIPythonApplication
298 if BaseIPythonApplication.initialized():
299 if BaseIPythonApplication.initialized():
299 print(BaseIPythonApplication.instance().profile)
300 print(BaseIPythonApplication.instance().profile)
300 else:
301 else:
301 error("profile is an application-level value, but you don't appear to be in an IPython application")
302 error("profile is an application-level value, but you don't appear to be in an IPython application")
302
303
303 @line_magic
304 @line_magic
304 def pprint(self, parameter_s=''):
305 def pprint(self, parameter_s=''):
305 """Toggle pretty printing on/off."""
306 """Toggle pretty printing on/off."""
306 ptformatter = self.shell.display_formatter.formatters['text/plain']
307 ptformatter = self.shell.display_formatter.formatters['text/plain']
307 ptformatter.pprint = bool(1 - ptformatter.pprint)
308 ptformatter.pprint = bool(1 - ptformatter.pprint)
308 print('Pretty printing has been turned',
309 print('Pretty printing has been turned',
309 ['OFF','ON'][ptformatter.pprint])
310 ['OFF','ON'][ptformatter.pprint])
310
311
311 @line_magic
312 @line_magic
312 def colors(self, parameter_s=''):
313 def colors(self, parameter_s=''):
313 """Switch color scheme for prompts, info system and exception handlers.
314 """Switch color scheme for prompts, info system and exception handlers.
314
315
315 Currently implemented schemes: NoColor, Linux, LightBG.
316 Currently implemented schemes: NoColor, Linux, LightBG.
316
317
317 Color scheme names are not case-sensitive.
318 Color scheme names are not case-sensitive.
318
319
319 Examples
320 Examples
320 --------
321 --------
321 To get a plain black and white terminal::
322 To get a plain black and white terminal::
322
323
323 %colors nocolor
324 %colors nocolor
324 """
325 """
325 def color_switch_err(name):
326 def color_switch_err(name):
326 warn('Error changing %s color schemes.\n%s' %
327 warn('Error changing %s color schemes.\n%s' %
327 (name, sys.exc_info()[1]))
328 (name, sys.exc_info()[1]))
328
329
329
330
330 new_scheme = parameter_s.strip()
331 new_scheme = parameter_s.strip()
331 if not new_scheme:
332 if not new_scheme:
332 raise UsageError(
333 raise UsageError(
333 "%colors: you must specify a color scheme. See '%colors?'")
334 "%colors: you must specify a color scheme. See '%colors?'")
334 # local shortcut
335 # local shortcut
335 shell = self.shell
336 shell = self.shell
336
337
337
338
338
339
339 if not shell.colors_force:
340 if not shell.colors_force:
340 if sys.platform in {'win32', 'cli'}:
341 if sys.platform in {'win32', 'cli'}:
341 import IPython.utils.rlineimpl as readline
342 import IPython.utils.rlineimpl as readline
342 if not readline.have_readline:
343 if not readline.have_readline:
343 msg = """\
344 msg = """\
344 Proper color support under MS Windows requires the pyreadline library.
345 Proper color support under MS Windows requires the pyreadline library.
345 You can find it at:
346 You can find it at:
346 http://ipython.org/pyreadline.html
347 http://ipython.org/pyreadline.html
347
348
348 Defaulting color scheme to 'NoColor'"""
349 Defaulting color scheme to 'NoColor'"""
349 new_scheme = 'NoColor'
350 new_scheme = 'NoColor'
350 warn(msg)
351 warn(msg)
351
352
352 elif not shell.has_readline:
353 elif not shell.has_readline:
353 # Coloured prompts get messed up without readline
354 # Coloured prompts get messed up without readline
354 # Will remove this check after switching to prompt_toolkit
355 # Will remove this check after switching to prompt_toolkit
355 new_scheme = 'NoColor'
356 new_scheme = 'NoColor'
356
357
357 # Set prompt colors
358 # Set prompt colors
358 try:
359 try:
359 shell.prompt_manager.color_scheme = new_scheme
360 shell.prompt_manager.color_scheme = new_scheme
360 except:
361 except:
361 color_switch_err('prompt')
362 color_switch_err('prompt')
362 else:
363 else:
363 shell.colors = \
364 shell.colors = \
364 shell.prompt_manager.color_scheme_table.active_scheme_name
365 shell.prompt_manager.color_scheme_table.active_scheme_name
365 # Set exception colors
366 # Set exception colors
366 try:
367 try:
367 shell.InteractiveTB.set_colors(scheme = new_scheme)
368 shell.InteractiveTB.set_colors(scheme = new_scheme)
368 shell.SyntaxTB.set_colors(scheme = new_scheme)
369 shell.SyntaxTB.set_colors(scheme = new_scheme)
369 except:
370 except:
370 color_switch_err('exception')
371 color_switch_err('exception')
371
372
372 # Set info (for 'object?') colors
373 # Set info (for 'object?') colors
373 if shell.color_info:
374 if shell.color_info:
374 try:
375 try:
375 shell.inspector.set_active_scheme(new_scheme)
376 shell.inspector.set_active_scheme(new_scheme)
376 except:
377 except:
377 color_switch_err('object inspector')
378 color_switch_err('object inspector')
378 else:
379 else:
379 shell.inspector.set_active_scheme('NoColor')
380 shell.inspector.set_active_scheme('NoColor')
380
381
381 @line_magic
382 @line_magic
382 def xmode(self, parameter_s=''):
383 def xmode(self, parameter_s=''):
383 """Switch modes for the exception handlers.
384 """Switch modes for the exception handlers.
384
385
385 Valid modes: Plain, Context and Verbose.
386 Valid modes: Plain, Context and Verbose.
386
387
387 If called without arguments, acts as a toggle."""
388 If called without arguments, acts as a toggle."""
388
389
389 def xmode_switch_err(name):
390 def xmode_switch_err(name):
390 warn('Error changing %s exception modes.\n%s' %
391 warn('Error changing %s exception modes.\n%s' %
391 (name,sys.exc_info()[1]))
392 (name,sys.exc_info()[1]))
392
393
393 shell = self.shell
394 shell = self.shell
394 new_mode = parameter_s.strip().capitalize()
395 new_mode = parameter_s.strip().capitalize()
395 try:
396 try:
396 shell.InteractiveTB.set_mode(mode=new_mode)
397 shell.InteractiveTB.set_mode(mode=new_mode)
397 print('Exception reporting mode:',shell.InteractiveTB.mode)
398 print('Exception reporting mode:',shell.InteractiveTB.mode)
398 except:
399 except:
399 xmode_switch_err('user')
400 xmode_switch_err('user')
400
401
401 @line_magic
402 @line_magic
402 def quickref(self,arg):
403 def quickref(self,arg):
403 """ Show a quick reference sheet """
404 """ Show a quick reference sheet """
404 from IPython.core.usage import quick_reference
405 from IPython.core.usage import quick_reference
405 qr = quick_reference + self._magic_docs(brief=True)
406 qr = quick_reference + self._magic_docs(brief=True)
406 page.page(qr)
407 page.page(qr)
407
408
408 @line_magic
409 @line_magic
409 def doctest_mode(self, parameter_s=''):
410 def doctest_mode(self, parameter_s=''):
410 """Toggle doctest mode on and off.
411 """Toggle doctest mode on and off.
411
412
412 This mode is intended to make IPython behave as much as possible like a
413 This mode is intended to make IPython behave as much as possible like a
413 plain Python shell, from the perspective of how its prompts, exceptions
414 plain Python shell, from the perspective of how its prompts, exceptions
414 and output look. This makes it easy to copy and paste parts of a
415 and output look. This makes it easy to copy and paste parts of a
415 session into doctests. It does so by:
416 session into doctests. It does so by:
416
417
417 - Changing the prompts to the classic ``>>>`` ones.
418 - Changing the prompts to the classic ``>>>`` ones.
418 - Changing the exception reporting mode to 'Plain'.
419 - Changing the exception reporting mode to 'Plain'.
419 - Disabling pretty-printing of output.
420 - Disabling pretty-printing of output.
420
421
421 Note that IPython also supports the pasting of code snippets that have
422 Note that IPython also supports the pasting of code snippets that have
422 leading '>>>' and '...' prompts in them. This means that you can paste
423 leading '>>>' and '...' prompts in them. This means that you can paste
423 doctests from files or docstrings (even if they have leading
424 doctests from files or docstrings (even if they have leading
424 whitespace), and the code will execute correctly. You can then use
425 whitespace), and the code will execute correctly. You can then use
425 '%history -t' to see the translated history; this will give you the
426 '%history -t' to see the translated history; this will give you the
426 input after removal of all the leading prompts and whitespace, which
427 input after removal of all the leading prompts and whitespace, which
427 can be pasted back into an editor.
428 can be pasted back into an editor.
428
429
429 With these features, you can switch into this mode easily whenever you
430 With these features, you can switch into this mode easily whenever you
430 need to do testing and changes to doctests, without having to leave
431 need to do testing and changes to doctests, without having to leave
431 your existing IPython session.
432 your existing IPython session.
432 """
433 """
433
434
434 # Shorthands
435 # Shorthands
435 shell = self.shell
436 shell = self.shell
436 pm = shell.prompt_manager
437 pm = shell.prompt_manager
437 meta = shell.meta
438 meta = shell.meta
438 disp_formatter = self.shell.display_formatter
439 disp_formatter = self.shell.display_formatter
439 ptformatter = disp_formatter.formatters['text/plain']
440 ptformatter = disp_formatter.formatters['text/plain']
440 # dstore is a data store kept in the instance metadata bag to track any
441 # dstore is a data store kept in the instance metadata bag to track any
441 # changes we make, so we can undo them later.
442 # changes we make, so we can undo them later.
442 dstore = meta.setdefault('doctest_mode',Struct())
443 dstore = meta.setdefault('doctest_mode',Struct())
443 save_dstore = dstore.setdefault
444 save_dstore = dstore.setdefault
444
445
445 # save a few values we'll need to recover later
446 # save a few values we'll need to recover later
446 mode = save_dstore('mode',False)
447 mode = save_dstore('mode',False)
447 save_dstore('rc_pprint',ptformatter.pprint)
448 save_dstore('rc_pprint',ptformatter.pprint)
448 save_dstore('xmode',shell.InteractiveTB.mode)
449 save_dstore('xmode',shell.InteractiveTB.mode)
449 save_dstore('rc_separate_out',shell.separate_out)
450 save_dstore('rc_separate_out',shell.separate_out)
450 save_dstore('rc_separate_out2',shell.separate_out2)
451 save_dstore('rc_separate_out2',shell.separate_out2)
451 save_dstore('rc_prompts_pad_left',pm.justify)
452 save_dstore('rc_prompts_pad_left',pm.justify)
452 save_dstore('rc_separate_in',shell.separate_in)
453 save_dstore('rc_separate_in',shell.separate_in)
453 save_dstore('rc_active_types',disp_formatter.active_types)
454 save_dstore('rc_active_types',disp_formatter.active_types)
454 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
455 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
455
456
456 if not mode:
457 if not mode:
457 # turn on
458 # turn on
458 pm.in_template = '>>> '
459 pm.in_template = '>>> '
459 pm.in2_template = '... '
460 pm.in2_template = '... '
460 pm.out_template = ''
461 pm.out_template = ''
461
462
462 # Prompt separators like plain python
463 # Prompt separators like plain python
463 shell.separate_in = ''
464 shell.separate_in = ''
464 shell.separate_out = ''
465 shell.separate_out = ''
465 shell.separate_out2 = ''
466 shell.separate_out2 = ''
466
467
467 pm.justify = False
468 pm.justify = False
468
469
469 ptformatter.pprint = False
470 ptformatter.pprint = False
470 disp_formatter.active_types = ['text/plain']
471 disp_formatter.active_types = ['text/plain']
471
472
472 shell.magic('xmode Plain')
473 shell.magic('xmode Plain')
473 else:
474 else:
474 # turn off
475 # turn off
475 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
476 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
476
477
477 shell.separate_in = dstore.rc_separate_in
478 shell.separate_in = dstore.rc_separate_in
478
479
479 shell.separate_out = dstore.rc_separate_out
480 shell.separate_out = dstore.rc_separate_out
480 shell.separate_out2 = dstore.rc_separate_out2
481 shell.separate_out2 = dstore.rc_separate_out2
481
482
482 pm.justify = dstore.rc_prompts_pad_left
483 pm.justify = dstore.rc_prompts_pad_left
483
484
484 ptformatter.pprint = dstore.rc_pprint
485 ptformatter.pprint = dstore.rc_pprint
485 disp_formatter.active_types = dstore.rc_active_types
486 disp_formatter.active_types = dstore.rc_active_types
486
487
487 shell.magic('xmode ' + dstore.xmode)
488 shell.magic('xmode ' + dstore.xmode)
488
489
489 # Store new mode and inform
490 # Store new mode and inform
490 dstore.mode = bool(1-int(mode))
491 dstore.mode = bool(1-int(mode))
491 mode_label = ['OFF','ON'][dstore.mode]
492 mode_label = ['OFF','ON'][dstore.mode]
492 print('Doctest mode is:', mode_label)
493 print('Doctest mode is:', mode_label)
493
494
494 @line_magic
495 @line_magic
495 def gui(self, parameter_s=''):
496 def gui(self, parameter_s=''):
496 """Enable or disable IPython GUI event loop integration.
497 """Enable or disable IPython GUI event loop integration.
497
498
498 %gui [GUINAME]
499 %gui [GUINAME]
499
500
500 This magic replaces IPython's threaded shells that were activated
501 This magic replaces IPython's threaded shells that were activated
501 using the (pylab/wthread/etc.) command line flags. GUI toolkits
502 using the (pylab/wthread/etc.) command line flags. GUI toolkits
502 can now be enabled at runtime and keyboard
503 can now be enabled at runtime and keyboard
503 interrupts should work without any problems. The following toolkits
504 interrupts should work without any problems. The following toolkits
504 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
505 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
505
506
506 %gui wx # enable wxPython event loop integration
507 %gui wx # enable wxPython event loop integration
507 %gui qt4|qt # enable PyQt4 event loop integration
508 %gui qt4|qt # enable PyQt4 event loop integration
508 %gui qt5 # enable PyQt5 event loop integration
509 %gui qt5 # enable PyQt5 event loop integration
509 %gui gtk # enable PyGTK event loop integration
510 %gui gtk # enable PyGTK event loop integration
510 %gui gtk3 # enable Gtk3 event loop integration
511 %gui gtk3 # enable Gtk3 event loop integration
511 %gui tk # enable Tk event loop integration
512 %gui tk # enable Tk event loop integration
512 %gui osx # enable Cocoa event loop integration
513 %gui osx # enable Cocoa event loop integration
513 # (requires %matplotlib 1.1)
514 # (requires %matplotlib 1.1)
514 %gui # disable all event loop integration
515 %gui # disable all event loop integration
515
516
516 WARNING: after any of these has been called you can simply create
517 WARNING: after any of these has been called you can simply create
517 an application object, but DO NOT start the event loop yourself, as
518 an application object, but DO NOT start the event loop yourself, as
518 we have already handled that.
519 we have already handled that.
519 """
520 """
520 opts, arg = self.parse_options(parameter_s, '')
521 opts, arg = self.parse_options(parameter_s, '')
521 if arg=='': arg = None
522 if arg=='': arg = None
522 try:
523 try:
523 return self.shell.enable_gui(arg)
524 return self.shell.enable_gui(arg)
524 except Exception as e:
525 except Exception as e:
525 # print simple error message, rather than traceback if we can't
526 # print simple error message, rather than traceback if we can't
526 # hook up the GUI
527 # hook up the GUI
527 error(str(e))
528 error(str(e))
528
529
529 @skip_doctest
530 @skip_doctest
530 @line_magic
531 @line_magic
531 def precision(self, s=''):
532 def precision(self, s=''):
532 """Set floating point precision for pretty printing.
533 """Set floating point precision for pretty printing.
533
534
534 Can set either integer precision or a format string.
535 Can set either integer precision or a format string.
535
536
536 If numpy has been imported and precision is an int,
537 If numpy has been imported and precision is an int,
537 numpy display precision will also be set, via ``numpy.set_printoptions``.
538 numpy display precision will also be set, via ``numpy.set_printoptions``.
538
539
539 If no argument is given, defaults will be restored.
540 If no argument is given, defaults will be restored.
540
541
541 Examples
542 Examples
542 --------
543 --------
543 ::
544 ::
544
545
545 In [1]: from math import pi
546 In [1]: from math import pi
546
547
547 In [2]: %precision 3
548 In [2]: %precision 3
548 Out[2]: u'%.3f'
549 Out[2]: u'%.3f'
549
550
550 In [3]: pi
551 In [3]: pi
551 Out[3]: 3.142
552 Out[3]: 3.142
552
553
553 In [4]: %precision %i
554 In [4]: %precision %i
554 Out[4]: u'%i'
555 Out[4]: u'%i'
555
556
556 In [5]: pi
557 In [5]: pi
557 Out[5]: 3
558 Out[5]: 3
558
559
559 In [6]: %precision %e
560 In [6]: %precision %e
560 Out[6]: u'%e'
561 Out[6]: u'%e'
561
562
562 In [7]: pi**10
563 In [7]: pi**10
563 Out[7]: 9.364805e+04
564 Out[7]: 9.364805e+04
564
565
565 In [8]: %precision
566 In [8]: %precision
566 Out[8]: u'%r'
567 Out[8]: u'%r'
567
568
568 In [9]: pi**10
569 In [9]: pi**10
569 Out[9]: 93648.047476082982
570 Out[9]: 93648.047476082982
570 """
571 """
571 ptformatter = self.shell.display_formatter.formatters['text/plain']
572 ptformatter = self.shell.display_formatter.formatters['text/plain']
572 ptformatter.float_precision = s
573 ptformatter.float_precision = s
573 return ptformatter.float_format
574 return ptformatter.float_format
574
575
575 @magic_arguments.magic_arguments()
576 @magic_arguments.magic_arguments()
576 @magic_arguments.argument(
577 @magic_arguments.argument(
577 '-e', '--export', action='store_true', default=False,
578 '-e', '--export', action='store_true', default=False,
578 help='Export IPython history as a notebook. The filename argument '
579 help='Export IPython history as a notebook. The filename argument '
579 'is used to specify the notebook name and format. For example '
580 'is used to specify the notebook name and format. For example '
580 'a filename of notebook.ipynb will result in a notebook name '
581 'a filename of notebook.ipynb will result in a notebook name '
581 'of "notebook" and a format of "json". Likewise using a ".py" '
582 'of "notebook" and a format of "json". Likewise using a ".py" '
582 'file extension will write the notebook as a Python script'
583 'file extension will write the notebook as a Python script'
583 )
584 )
584 @magic_arguments.argument(
585 @magic_arguments.argument(
585 'filename', type=unicode_type,
586 'filename', type=unicode_type,
586 help='Notebook name or filename'
587 help='Notebook name or filename'
587 )
588 )
588 @line_magic
589 @line_magic
589 def notebook(self, s):
590 def notebook(self, s):
590 """Export and convert IPython notebooks.
591 """Export and convert IPython notebooks.
591
592
592 This function can export the current IPython history to a notebook file.
593 This function can export the current IPython history to a notebook file.
593 For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
594 For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
594 To export the history to "foo.py" do "%notebook -e foo.py".
595 To export the history to "foo.py" do "%notebook -e foo.py".
595 """
596 """
596 args = magic_arguments.parse_argstring(self.notebook, s)
597 args = magic_arguments.parse_argstring(self.notebook, s)
597
598
598 from nbformat import write, v4
599 from nbformat import write, v4
599 args.filename = unquote_filename(args.filename)
600 args.filename = unquote_filename(args.filename)
600 if args.export:
601 if args.export:
601 cells = []
602 cells = []
602 hist = list(self.shell.history_manager.get_range())
603 hist = list(self.shell.history_manager.get_range())
603 if(len(hist)<=1):
604 if(len(hist)<=1):
604 raise ValueError('History is empty, cannot export')
605 raise ValueError('History is empty, cannot export')
605 for session, execution_count, source in hist[:-1]:
606 for session, execution_count, source in hist[:-1]:
606 cells.append(v4.new_code_cell(
607 cells.append(v4.new_code_cell(
607 execution_count=execution_count,
608 execution_count=execution_count,
608 source=source
609 source=source
609 ))
610 ))
610 nb = v4.new_notebook(cells=cells)
611 nb = v4.new_notebook(cells=cells)
611 with io.open(args.filename, 'w', encoding='utf-8') as f:
612 with io.open(args.filename, 'w', encoding='utf-8') as f:
612 write(nb, f, version=4)
613 write(nb, f, version=4)
@@ -1,715 +1,716 b''
1 """Implementation of code management magic functions.
1 """Implementation of code management 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 inspect
17 import inspect
18 import io
18 import io
19 import os
19 import os
20 import re
20 import re
21 import sys
21 import sys
22 import ast
22 import ast
23 from itertools import chain
23 from itertools import chain
24
24
25 # Our own packages
25 # Our own packages
26 from IPython.core.error import TryNext, StdinNotImplementedError, UsageError
26 from IPython.core.error import TryNext, StdinNotImplementedError, UsageError
27 from IPython.core.macro import Macro
27 from IPython.core.macro import Macro
28 from IPython.core.magic import Magics, magics_class, line_magic
28 from IPython.core.magic import Magics, magics_class, line_magic
29 from IPython.core.oinspect import find_file, find_source_lines
29 from IPython.core.oinspect import find_file, find_source_lines
30 from IPython.testing.skipdoctest import skip_doctest
30 from IPython.testing.skipdoctest import skip_doctest
31 from IPython.utils import py3compat
31 from IPython.utils import py3compat
32 from IPython.utils.py3compat import string_types
32 from IPython.utils.py3compat import string_types
33 from IPython.utils.contexts import preserve_keys
33 from IPython.utils.contexts import preserve_keys
34 from IPython.utils.path import get_py_filename, unquote_filename
34 from IPython.utils.path import get_py_filename, unquote_filename
35 from IPython.utils.warn import warn, error
35 from warnings import warn
36 from logging import error
36 from IPython.utils.text import get_text_list
37 from IPython.utils.text import get_text_list
37
38
38 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
39 # Magic implementation classes
40 # Magic implementation classes
40 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
41
42
42 # Used for exception handling in magic_edit
43 # Used for exception handling in magic_edit
43 class MacroToEdit(ValueError): pass
44 class MacroToEdit(ValueError): pass
44
45
45 ipython_input_pat = re.compile(r"<ipython\-input\-(\d+)-[a-z\d]+>$")
46 ipython_input_pat = re.compile(r"<ipython\-input\-(\d+)-[a-z\d]+>$")
46
47
47 # To match, e.g. 8-10 1:5 :10 3-
48 # To match, e.g. 8-10 1:5 :10 3-
48 range_re = re.compile(r"""
49 range_re = re.compile(r"""
49 (?P<start>\d+)?
50 (?P<start>\d+)?
50 ((?P<sep>[\-:])
51 ((?P<sep>[\-:])
51 (?P<end>\d+)?)?
52 (?P<end>\d+)?)?
52 $""", re.VERBOSE)
53 $""", re.VERBOSE)
53
54
54
55
55 def extract_code_ranges(ranges_str):
56 def extract_code_ranges(ranges_str):
56 """Turn a string of range for %%load into 2-tuples of (start, stop)
57 """Turn a string of range for %%load into 2-tuples of (start, stop)
57 ready to use as a slice of the content splitted by lines.
58 ready to use as a slice of the content splitted by lines.
58
59
59 Examples
60 Examples
60 --------
61 --------
61 list(extract_input_ranges("5-10 2"))
62 list(extract_input_ranges("5-10 2"))
62 [(4, 10), (1, 2)]
63 [(4, 10), (1, 2)]
63 """
64 """
64 for range_str in ranges_str.split():
65 for range_str in ranges_str.split():
65 rmatch = range_re.match(range_str)
66 rmatch = range_re.match(range_str)
66 if not rmatch:
67 if not rmatch:
67 continue
68 continue
68 sep = rmatch.group("sep")
69 sep = rmatch.group("sep")
69 start = rmatch.group("start")
70 start = rmatch.group("start")
70 end = rmatch.group("end")
71 end = rmatch.group("end")
71
72
72 if sep == '-':
73 if sep == '-':
73 start = int(start) - 1 if start else None
74 start = int(start) - 1 if start else None
74 end = int(end) if end else None
75 end = int(end) if end else None
75 elif sep == ':':
76 elif sep == ':':
76 start = int(start) - 1 if start else None
77 start = int(start) - 1 if start else None
77 end = int(end) - 1 if end else None
78 end = int(end) - 1 if end else None
78 else:
79 else:
79 end = int(start)
80 end = int(start)
80 start = int(start) - 1
81 start = int(start) - 1
81 yield (start, end)
82 yield (start, end)
82
83
83
84
84 @skip_doctest
85 @skip_doctest
85 def extract_symbols(code, symbols):
86 def extract_symbols(code, symbols):
86 """
87 """
87 Return a tuple (blocks, not_found)
88 Return a tuple (blocks, not_found)
88 where ``blocks`` is a list of code fragments
89 where ``blocks`` is a list of code fragments
89 for each symbol parsed from code, and ``not_found`` are
90 for each symbol parsed from code, and ``not_found`` are
90 symbols not found in the code.
91 symbols not found in the code.
91
92
92 For example::
93 For example::
93
94
94 >>> code = '''a = 10
95 >>> code = '''a = 10
95
96
96 def b(): return 42
97 def b(): return 42
97
98
98 class A: pass'''
99 class A: pass'''
99
100
100 >>> extract_symbols(code, 'A,b,z')
101 >>> extract_symbols(code, 'A,b,z')
101 (["class A: pass", "def b(): return 42"], ['z'])
102 (["class A: pass", "def b(): return 42"], ['z'])
102 """
103 """
103 symbols = symbols.split(',')
104 symbols = symbols.split(',')
104
105
105 # this will raise SyntaxError if code isn't valid Python
106 # this will raise SyntaxError if code isn't valid Python
106 py_code = ast.parse(code)
107 py_code = ast.parse(code)
107
108
108 marks = [(getattr(s, 'name', None), s.lineno) for s in py_code.body]
109 marks = [(getattr(s, 'name', None), s.lineno) for s in py_code.body]
109 code = code.split('\n')
110 code = code.split('\n')
110
111
111 symbols_lines = {}
112 symbols_lines = {}
112
113
113 # we already know the start_lineno of each symbol (marks).
114 # we already know the start_lineno of each symbol (marks).
114 # To find each end_lineno, we traverse in reverse order until each
115 # To find each end_lineno, we traverse in reverse order until each
115 # non-blank line
116 # non-blank line
116 end = len(code)
117 end = len(code)
117 for name, start in reversed(marks):
118 for name, start in reversed(marks):
118 while not code[end - 1].strip():
119 while not code[end - 1].strip():
119 end -= 1
120 end -= 1
120 if name:
121 if name:
121 symbols_lines[name] = (start - 1, end)
122 symbols_lines[name] = (start - 1, end)
122 end = start - 1
123 end = start - 1
123
124
124 # Now symbols_lines is a map
125 # Now symbols_lines is a map
125 # {'symbol_name': (start_lineno, end_lineno), ...}
126 # {'symbol_name': (start_lineno, end_lineno), ...}
126
127
127 # fill a list with chunks of codes for each requested symbol
128 # fill a list with chunks of codes for each requested symbol
128 blocks = []
129 blocks = []
129 not_found = []
130 not_found = []
130 for symbol in symbols:
131 for symbol in symbols:
131 if symbol in symbols_lines:
132 if symbol in symbols_lines:
132 start, end = symbols_lines[symbol]
133 start, end = symbols_lines[symbol]
133 blocks.append('\n'.join(code[start:end]) + '\n')
134 blocks.append('\n'.join(code[start:end]) + '\n')
134 else:
135 else:
135 not_found.append(symbol)
136 not_found.append(symbol)
136
137
137 return blocks, not_found
138 return blocks, not_found
138
139
139
140
140 class InteractivelyDefined(Exception):
141 class InteractivelyDefined(Exception):
141 """Exception for interactively defined variable in magic_edit"""
142 """Exception for interactively defined variable in magic_edit"""
142 def __init__(self, index):
143 def __init__(self, index):
143 self.index = index
144 self.index = index
144
145
145
146
146 @magics_class
147 @magics_class
147 class CodeMagics(Magics):
148 class CodeMagics(Magics):
148 """Magics related to code management (loading, saving, editing, ...)."""
149 """Magics related to code management (loading, saving, editing, ...)."""
149
150
150 def __init__(self, *args, **kwargs):
151 def __init__(self, *args, **kwargs):
151 self._knowntemps = set()
152 self._knowntemps = set()
152 super(CodeMagics, self).__init__(*args, **kwargs)
153 super(CodeMagics, self).__init__(*args, **kwargs)
153
154
154 @line_magic
155 @line_magic
155 def save(self, parameter_s=''):
156 def save(self, parameter_s=''):
156 """Save a set of lines or a macro to a given filename.
157 """Save a set of lines or a macro to a given filename.
157
158
158 Usage:\\
159 Usage:\\
159 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
160 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
160
161
161 Options:
162 Options:
162
163
163 -r: use 'raw' input. By default, the 'processed' history is used,
164 -r: use 'raw' input. By default, the 'processed' history is used,
164 so that magics are loaded in their transformed version to valid
165 so that magics are loaded in their transformed version to valid
165 Python. If this option is given, the raw input as typed as the
166 Python. If this option is given, the raw input as typed as the
166 command line is used instead.
167 command line is used instead.
167
168
168 -f: force overwrite. If file exists, %save will prompt for overwrite
169 -f: force overwrite. If file exists, %save will prompt for overwrite
169 unless -f is given.
170 unless -f is given.
170
171
171 -a: append to the file instead of overwriting it.
172 -a: append to the file instead of overwriting it.
172
173
173 This function uses the same syntax as %history for input ranges,
174 This function uses the same syntax as %history for input ranges,
174 then saves the lines to the filename you specify.
175 then saves the lines to the filename you specify.
175
176
176 It adds a '.py' extension to the file if you don't do so yourself, and
177 It adds a '.py' extension to the file if you don't do so yourself, and
177 it asks for confirmation before overwriting existing files.
178 it asks for confirmation before overwriting existing files.
178
179
179 If `-r` option is used, the default extension is `.ipy`.
180 If `-r` option is used, the default extension is `.ipy`.
180 """
181 """
181
182
182 opts,args = self.parse_options(parameter_s,'fra',mode='list')
183 opts,args = self.parse_options(parameter_s,'fra',mode='list')
183 if not args:
184 if not args:
184 raise UsageError('Missing filename.')
185 raise UsageError('Missing filename.')
185 raw = 'r' in opts
186 raw = 'r' in opts
186 force = 'f' in opts
187 force = 'f' in opts
187 append = 'a' in opts
188 append = 'a' in opts
188 mode = 'a' if append else 'w'
189 mode = 'a' if append else 'w'
189 ext = u'.ipy' if raw else u'.py'
190 ext = u'.ipy' if raw else u'.py'
190 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
191 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
191 if not fname.endswith((u'.py',u'.ipy')):
192 if not fname.endswith((u'.py',u'.ipy')):
192 fname += ext
193 fname += ext
193 file_exists = os.path.isfile(fname)
194 file_exists = os.path.isfile(fname)
194 if file_exists and not force and not append:
195 if file_exists and not force and not append:
195 try:
196 try:
196 overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
197 overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
197 except StdinNotImplementedError:
198 except StdinNotImplementedError:
198 print("File `%s` exists. Use `%%save -f %s` to force overwrite" % (fname, parameter_s))
199 print("File `%s` exists. Use `%%save -f %s` to force overwrite" % (fname, parameter_s))
199 return
200 return
200 if not overwrite :
201 if not overwrite :
201 print('Operation cancelled.')
202 print('Operation cancelled.')
202 return
203 return
203 try:
204 try:
204 cmds = self.shell.find_user_code(codefrom,raw)
205 cmds = self.shell.find_user_code(codefrom,raw)
205 except (TypeError, ValueError) as e:
206 except (TypeError, ValueError) as e:
206 print(e.args[0])
207 print(e.args[0])
207 return
208 return
208 out = py3compat.cast_unicode(cmds)
209 out = py3compat.cast_unicode(cmds)
209 with io.open(fname, mode, encoding="utf-8") as f:
210 with io.open(fname, mode, encoding="utf-8") as f:
210 if not file_exists or not append:
211 if not file_exists or not append:
211 f.write(u"# coding: utf-8\n")
212 f.write(u"# coding: utf-8\n")
212 f.write(out)
213 f.write(out)
213 # make sure we end on a newline
214 # make sure we end on a newline
214 if not out.endswith(u'\n'):
215 if not out.endswith(u'\n'):
215 f.write(u'\n')
216 f.write(u'\n')
216 print('The following commands were written to file `%s`:' % fname)
217 print('The following commands were written to file `%s`:' % fname)
217 print(cmds)
218 print(cmds)
218
219
219 @line_magic
220 @line_magic
220 def pastebin(self, parameter_s=''):
221 def pastebin(self, parameter_s=''):
221 """Upload code to Github's Gist paste bin, returning the URL.
222 """Upload code to Github's Gist paste bin, returning the URL.
222
223
223 Usage:\\
224 Usage:\\
224 %pastebin [-d "Custom description"] 1-7
225 %pastebin [-d "Custom description"] 1-7
225
226
226 The argument can be an input history range, a filename, or the name of a
227 The argument can be an input history range, a filename, or the name of a
227 string or macro.
228 string or macro.
228
229
229 Options:
230 Options:
230
231
231 -d: Pass a custom description for the gist. The default will say
232 -d: Pass a custom description for the gist. The default will say
232 "Pasted from IPython".
233 "Pasted from IPython".
233 """
234 """
234 opts, args = self.parse_options(parameter_s, 'd:')
235 opts, args = self.parse_options(parameter_s, 'd:')
235
236
236 try:
237 try:
237 code = self.shell.find_user_code(args)
238 code = self.shell.find_user_code(args)
238 except (ValueError, TypeError) as e:
239 except (ValueError, TypeError) as e:
239 print(e.args[0])
240 print(e.args[0])
240 return
241 return
241
242
242 # Deferred import
243 # Deferred import
243 try:
244 try:
244 from urllib.request import urlopen # Py 3
245 from urllib.request import urlopen # Py 3
245 except ImportError:
246 except ImportError:
246 from urllib2 import urlopen
247 from urllib2 import urlopen
247 import json
248 import json
248 post_data = json.dumps({
249 post_data = json.dumps({
249 "description": opts.get('d', "Pasted from IPython"),
250 "description": opts.get('d', "Pasted from IPython"),
250 "public": True,
251 "public": True,
251 "files": {
252 "files": {
252 "file1.py": {
253 "file1.py": {
253 "content": code
254 "content": code
254 }
255 }
255 }
256 }
256 }).encode('utf-8')
257 }).encode('utf-8')
257
258
258 response = urlopen("https://api.github.com/gists", post_data)
259 response = urlopen("https://api.github.com/gists", post_data)
259 response_data = json.loads(response.read().decode('utf-8'))
260 response_data = json.loads(response.read().decode('utf-8'))
260 return response_data['html_url']
261 return response_data['html_url']
261
262
262 @line_magic
263 @line_magic
263 def loadpy(self, arg_s):
264 def loadpy(self, arg_s):
264 """Alias of `%load`
265 """Alias of `%load`
265
266
266 `%loadpy` has gained some flexibility and dropped the requirement of a `.py`
267 `%loadpy` has gained some flexibility and dropped the requirement of a `.py`
267 extension. So it has been renamed simply into %load. You can look at
268 extension. So it has been renamed simply into %load. You can look at
268 `%load`'s docstring for more info.
269 `%load`'s docstring for more info.
269 """
270 """
270 self.load(arg_s)
271 self.load(arg_s)
271
272
272 @line_magic
273 @line_magic
273 def load(self, arg_s):
274 def load(self, arg_s):
274 """Load code into the current frontend.
275 """Load code into the current frontend.
275
276
276 Usage:\\
277 Usage:\\
277 %load [options] source
278 %load [options] source
278
279
279 where source can be a filename, URL, input history range, macro, or
280 where source can be a filename, URL, input history range, macro, or
280 element in the user namespace
281 element in the user namespace
281
282
282 Options:
283 Options:
283
284
284 -r <lines>: Specify lines or ranges of lines to load from the source.
285 -r <lines>: Specify lines or ranges of lines to load from the source.
285 Ranges could be specified as x-y (x..y) or in python-style x:y
286 Ranges could be specified as x-y (x..y) or in python-style x:y
286 (x..(y-1)). Both limits x and y can be left blank (meaning the
287 (x..(y-1)). Both limits x and y can be left blank (meaning the
287 beginning and end of the file, respectively).
288 beginning and end of the file, respectively).
288
289
289 -s <symbols>: Specify function or classes to load from python source.
290 -s <symbols>: Specify function or classes to load from python source.
290
291
291 -y : Don't ask confirmation for loading source above 200 000 characters.
292 -y : Don't ask confirmation for loading source above 200 000 characters.
292
293
293 -n : Include the user's namespace when searching for source code.
294 -n : Include the user's namespace when searching for source code.
294
295
295 This magic command can either take a local filename, a URL, an history
296 This magic command can either take a local filename, a URL, an history
296 range (see %history) or a macro as argument, it will prompt for
297 range (see %history) or a macro as argument, it will prompt for
297 confirmation before loading source with more than 200 000 characters, unless
298 confirmation before loading source with more than 200 000 characters, unless
298 -y flag is passed or if the frontend does not support raw_input::
299 -y flag is passed or if the frontend does not support raw_input::
299
300
300 %load myscript.py
301 %load myscript.py
301 %load 7-27
302 %load 7-27
302 %load myMacro
303 %load myMacro
303 %load http://www.example.com/myscript.py
304 %load http://www.example.com/myscript.py
304 %load -r 5-10 myscript.py
305 %load -r 5-10 myscript.py
305 %load -r 10-20,30,40: foo.py
306 %load -r 10-20,30,40: foo.py
306 %load -s MyClass,wonder_function myscript.py
307 %load -s MyClass,wonder_function myscript.py
307 %load -n MyClass
308 %load -n MyClass
308 %load -n my_module.wonder_function
309 %load -n my_module.wonder_function
309 """
310 """
310 opts,args = self.parse_options(arg_s,'yns:r:')
311 opts,args = self.parse_options(arg_s,'yns:r:')
311
312
312 if not args:
313 if not args:
313 raise UsageError('Missing filename, URL, input history range, '
314 raise UsageError('Missing filename, URL, input history range, '
314 'macro, or element in the user namespace.')
315 'macro, or element in the user namespace.')
315
316
316 search_ns = 'n' in opts
317 search_ns = 'n' in opts
317
318
318 contents = self.shell.find_user_code(args, search_ns=search_ns)
319 contents = self.shell.find_user_code(args, search_ns=search_ns)
319
320
320 if 's' in opts:
321 if 's' in opts:
321 try:
322 try:
322 blocks, not_found = extract_symbols(contents, opts['s'])
323 blocks, not_found = extract_symbols(contents, opts['s'])
323 except SyntaxError:
324 except SyntaxError:
324 # non python code
325 # non python code
325 error("Unable to parse the input as valid Python code")
326 error("Unable to parse the input as valid Python code")
326 return
327 return
327
328
328 if len(not_found) == 1:
329 if len(not_found) == 1:
329 warn('The symbol `%s` was not found' % not_found[0])
330 warn('The symbol `%s` was not found' % not_found[0])
330 elif len(not_found) > 1:
331 elif len(not_found) > 1:
331 warn('The symbols %s were not found' % get_text_list(not_found,
332 warn('The symbols %s were not found' % get_text_list(not_found,
332 wrap_item_with='`')
333 wrap_item_with='`')
333 )
334 )
334
335
335 contents = '\n'.join(blocks)
336 contents = '\n'.join(blocks)
336
337
337 if 'r' in opts:
338 if 'r' in opts:
338 ranges = opts['r'].replace(',', ' ')
339 ranges = opts['r'].replace(',', ' ')
339 lines = contents.split('\n')
340 lines = contents.split('\n')
340 slices = extract_code_ranges(ranges)
341 slices = extract_code_ranges(ranges)
341 contents = [lines[slice(*slc)] for slc in slices]
342 contents = [lines[slice(*slc)] for slc in slices]
342 contents = '\n'.join(chain.from_iterable(contents))
343 contents = '\n'.join(chain.from_iterable(contents))
343
344
344 l = len(contents)
345 l = len(contents)
345
346
346 # 200 000 is ~ 2500 full 80 caracter lines
347 # 200 000 is ~ 2500 full 80 caracter lines
347 # so in average, more than 5000 lines
348 # so in average, more than 5000 lines
348 if l > 200000 and 'y' not in opts:
349 if l > 200000 and 'y' not in opts:
349 try:
350 try:
350 ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\
351 ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\
351 " (%d characters). Continue (y/[N]) ?" % l), default='n' )
352 " (%d characters). Continue (y/[N]) ?" % l), default='n' )
352 except StdinNotImplementedError:
353 except StdinNotImplementedError:
353 #asume yes if raw input not implemented
354 #asume yes if raw input not implemented
354 ans = True
355 ans = True
355
356
356 if ans is False :
357 if ans is False :
357 print('Operation cancelled.')
358 print('Operation cancelled.')
358 return
359 return
359
360
360 contents = "# %load {}\n".format(arg_s) + contents
361 contents = "# %load {}\n".format(arg_s) + contents
361
362
362 self.shell.set_next_input(contents, replace=True)
363 self.shell.set_next_input(contents, replace=True)
363
364
364 @staticmethod
365 @staticmethod
365 def _find_edit_target(shell, args, opts, last_call):
366 def _find_edit_target(shell, args, opts, last_call):
366 """Utility method used by magic_edit to find what to edit."""
367 """Utility method used by magic_edit to find what to edit."""
367
368
368 def make_filename(arg):
369 def make_filename(arg):
369 "Make a filename from the given args"
370 "Make a filename from the given args"
370 arg = unquote_filename(arg)
371 arg = unquote_filename(arg)
371 try:
372 try:
372 filename = get_py_filename(arg)
373 filename = get_py_filename(arg)
373 except IOError:
374 except IOError:
374 # If it ends with .py but doesn't already exist, assume we want
375 # If it ends with .py but doesn't already exist, assume we want
375 # a new file.
376 # a new file.
376 if arg.endswith('.py'):
377 if arg.endswith('.py'):
377 filename = arg
378 filename = arg
378 else:
379 else:
379 filename = None
380 filename = None
380 return filename
381 return filename
381
382
382 # Set a few locals from the options for convenience:
383 # Set a few locals from the options for convenience:
383 opts_prev = 'p' in opts
384 opts_prev = 'p' in opts
384 opts_raw = 'r' in opts
385 opts_raw = 'r' in opts
385
386
386 # custom exceptions
387 # custom exceptions
387 class DataIsObject(Exception): pass
388 class DataIsObject(Exception): pass
388
389
389 # Default line number value
390 # Default line number value
390 lineno = opts.get('n',None)
391 lineno = opts.get('n',None)
391
392
392 if opts_prev:
393 if opts_prev:
393 args = '_%s' % last_call[0]
394 args = '_%s' % last_call[0]
394 if args not in shell.user_ns:
395 if args not in shell.user_ns:
395 args = last_call[1]
396 args = last_call[1]
396
397
397 # by default this is done with temp files, except when the given
398 # by default this is done with temp files, except when the given
398 # arg is a filename
399 # arg is a filename
399 use_temp = True
400 use_temp = True
400
401
401 data = ''
402 data = ''
402
403
403 # First, see if the arguments should be a filename.
404 # First, see if the arguments should be a filename.
404 filename = make_filename(args)
405 filename = make_filename(args)
405 if filename:
406 if filename:
406 use_temp = False
407 use_temp = False
407 elif args:
408 elif args:
408 # Mode where user specifies ranges of lines, like in %macro.
409 # Mode where user specifies ranges of lines, like in %macro.
409 data = shell.extract_input_lines(args, opts_raw)
410 data = shell.extract_input_lines(args, opts_raw)
410 if not data:
411 if not data:
411 try:
412 try:
412 # Load the parameter given as a variable. If not a string,
413 # Load the parameter given as a variable. If not a string,
413 # process it as an object instead (below)
414 # process it as an object instead (below)
414
415
415 #print '*** args',args,'type',type(args) # dbg
416 #print '*** args',args,'type',type(args) # dbg
416 data = eval(args, shell.user_ns)
417 data = eval(args, shell.user_ns)
417 if not isinstance(data, string_types):
418 if not isinstance(data, string_types):
418 raise DataIsObject
419 raise DataIsObject
419
420
420 except (NameError,SyntaxError):
421 except (NameError,SyntaxError):
421 # given argument is not a variable, try as a filename
422 # given argument is not a variable, try as a filename
422 filename = make_filename(args)
423 filename = make_filename(args)
423 if filename is None:
424 if filename is None:
424 warn("Argument given (%s) can't be found as a variable "
425 warn("Argument given (%s) can't be found as a variable "
425 "or as a filename." % args)
426 "or as a filename." % args)
426 return (None, None, None)
427 return (None, None, None)
427 use_temp = False
428 use_temp = False
428
429
429 except DataIsObject:
430 except DataIsObject:
430 # macros have a special edit function
431 # macros have a special edit function
431 if isinstance(data, Macro):
432 if isinstance(data, Macro):
432 raise MacroToEdit(data)
433 raise MacroToEdit(data)
433
434
434 # For objects, try to edit the file where they are defined
435 # For objects, try to edit the file where they are defined
435 filename = find_file(data)
436 filename = find_file(data)
436 if filename:
437 if filename:
437 if 'fakemodule' in filename.lower() and \
438 if 'fakemodule' in filename.lower() and \
438 inspect.isclass(data):
439 inspect.isclass(data):
439 # class created by %edit? Try to find source
440 # class created by %edit? Try to find source
440 # by looking for method definitions instead, the
441 # by looking for method definitions instead, the
441 # __module__ in those classes is FakeModule.
442 # __module__ in those classes is FakeModule.
442 attrs = [getattr(data, aname) for aname in dir(data)]
443 attrs = [getattr(data, aname) for aname in dir(data)]
443 for attr in attrs:
444 for attr in attrs:
444 if not inspect.ismethod(attr):
445 if not inspect.ismethod(attr):
445 continue
446 continue
446 filename = find_file(attr)
447 filename = find_file(attr)
447 if filename and \
448 if filename and \
448 'fakemodule' not in filename.lower():
449 'fakemodule' not in filename.lower():
449 # change the attribute to be the edit
450 # change the attribute to be the edit
450 # target instead
451 # target instead
451 data = attr
452 data = attr
452 break
453 break
453
454
454 m = ipython_input_pat.match(os.path.basename(filename))
455 m = ipython_input_pat.match(os.path.basename(filename))
455 if m:
456 if m:
456 raise InteractivelyDefined(int(m.groups()[0]))
457 raise InteractivelyDefined(int(m.groups()[0]))
457
458
458 datafile = 1
459 datafile = 1
459 if filename is None:
460 if filename is None:
460 filename = make_filename(args)
461 filename = make_filename(args)
461 datafile = 1
462 datafile = 1
462 if filename is not None:
463 if filename is not None:
463 # only warn about this if we get a real name
464 # only warn about this if we get a real name
464 warn('Could not find file where `%s` is defined.\n'
465 warn('Could not find file where `%s` is defined.\n'
465 'Opening a file named `%s`' % (args, filename))
466 'Opening a file named `%s`' % (args, filename))
466 # Now, make sure we can actually read the source (if it was
467 # Now, make sure we can actually read the source (if it was
467 # in a temp file it's gone by now).
468 # in a temp file it's gone by now).
468 if datafile:
469 if datafile:
469 if lineno is None:
470 if lineno is None:
470 lineno = find_source_lines(data)
471 lineno = find_source_lines(data)
471 if lineno is None:
472 if lineno is None:
472 filename = make_filename(args)
473 filename = make_filename(args)
473 if filename is None:
474 if filename is None:
474 warn('The file where `%s` was defined '
475 warn('The file where `%s` was defined '
475 'cannot be read or found.' % data)
476 'cannot be read or found.' % data)
476 return (None, None, None)
477 return (None, None, None)
477 use_temp = False
478 use_temp = False
478
479
479 if use_temp:
480 if use_temp:
480 filename = shell.mktempfile(data)
481 filename = shell.mktempfile(data)
481 print('IPython will make a temporary file named:',filename)
482 print('IPython will make a temporary file named:',filename)
482
483
483 # use last_call to remember the state of the previous call, but don't
484 # use last_call to remember the state of the previous call, but don't
484 # let it be clobbered by successive '-p' calls.
485 # let it be clobbered by successive '-p' calls.
485 try:
486 try:
486 last_call[0] = shell.displayhook.prompt_count
487 last_call[0] = shell.displayhook.prompt_count
487 if not opts_prev:
488 if not opts_prev:
488 last_call[1] = args
489 last_call[1] = args
489 except:
490 except:
490 pass
491 pass
491
492
492
493
493 return filename, lineno, use_temp
494 return filename, lineno, use_temp
494
495
495 def _edit_macro(self,mname,macro):
496 def _edit_macro(self,mname,macro):
496 """open an editor with the macro data in a file"""
497 """open an editor with the macro data in a file"""
497 filename = self.shell.mktempfile(macro.value)
498 filename = self.shell.mktempfile(macro.value)
498 self.shell.hooks.editor(filename)
499 self.shell.hooks.editor(filename)
499
500
500 # and make a new macro object, to replace the old one
501 # and make a new macro object, to replace the old one
501 with open(filename) as mfile:
502 with open(filename) as mfile:
502 mvalue = mfile.read()
503 mvalue = mfile.read()
503 self.shell.user_ns[mname] = Macro(mvalue)
504 self.shell.user_ns[mname] = Macro(mvalue)
504
505
505 @skip_doctest
506 @skip_doctest
506 @line_magic
507 @line_magic
507 def edit(self, parameter_s='',last_call=['','']):
508 def edit(self, parameter_s='',last_call=['','']):
508 """Bring up an editor and execute the resulting code.
509 """Bring up an editor and execute the resulting code.
509
510
510 Usage:
511 Usage:
511 %edit [options] [args]
512 %edit [options] [args]
512
513
513 %edit runs IPython's editor hook. The default version of this hook is
514 %edit runs IPython's editor hook. The default version of this hook is
514 set to call the editor specified by your $EDITOR environment variable.
515 set to call the editor specified by your $EDITOR environment variable.
515 If this isn't found, it will default to vi under Linux/Unix and to
516 If this isn't found, it will default to vi under Linux/Unix and to
516 notepad under Windows. See the end of this docstring for how to change
517 notepad under Windows. See the end of this docstring for how to change
517 the editor hook.
518 the editor hook.
518
519
519 You can also set the value of this editor via the
520 You can also set the value of this editor via the
520 ``TerminalInteractiveShell.editor`` option in your configuration file.
521 ``TerminalInteractiveShell.editor`` option in your configuration file.
521 This is useful if you wish to use a different editor from your typical
522 This is useful if you wish to use a different editor from your typical
522 default with IPython (and for Windows users who typically don't set
523 default with IPython (and for Windows users who typically don't set
523 environment variables).
524 environment variables).
524
525
525 This command allows you to conveniently edit multi-line code right in
526 This command allows you to conveniently edit multi-line code right in
526 your IPython session.
527 your IPython session.
527
528
528 If called without arguments, %edit opens up an empty editor with a
529 If called without arguments, %edit opens up an empty editor with a
529 temporary file and will execute the contents of this file when you
530 temporary file and will execute the contents of this file when you
530 close it (don't forget to save it!).
531 close it (don't forget to save it!).
531
532
532
533
533 Options:
534 Options:
534
535
535 -n <number>: open the editor at a specified line number. By default,
536 -n <number>: open the editor at a specified line number. By default,
536 the IPython editor hook uses the unix syntax 'editor +N filename', but
537 the IPython editor hook uses the unix syntax 'editor +N filename', but
537 you can configure this by providing your own modified hook if your
538 you can configure this by providing your own modified hook if your
538 favorite editor supports line-number specifications with a different
539 favorite editor supports line-number specifications with a different
539 syntax.
540 syntax.
540
541
541 -p: this will call the editor with the same data as the previous time
542 -p: this will call the editor with the same data as the previous time
542 it was used, regardless of how long ago (in your current session) it
543 it was used, regardless of how long ago (in your current session) it
543 was.
544 was.
544
545
545 -r: use 'raw' input. This option only applies to input taken from the
546 -r: use 'raw' input. This option only applies to input taken from the
546 user's history. By default, the 'processed' history is used, so that
547 user's history. By default, the 'processed' history is used, so that
547 magics are loaded in their transformed version to valid Python. If
548 magics are loaded in their transformed version to valid Python. If
548 this option is given, the raw input as typed as the command line is
549 this option is given, the raw input as typed as the command line is
549 used instead. When you exit the editor, it will be executed by
550 used instead. When you exit the editor, it will be executed by
550 IPython's own processor.
551 IPython's own processor.
551
552
552 -x: do not execute the edited code immediately upon exit. This is
553 -x: do not execute the edited code immediately upon exit. This is
553 mainly useful if you are editing programs which need to be called with
554 mainly useful if you are editing programs which need to be called with
554 command line arguments, which you can then do using %run.
555 command line arguments, which you can then do using %run.
555
556
556
557
557 Arguments:
558 Arguments:
558
559
559 If arguments are given, the following possibilities exist:
560 If arguments are given, the following possibilities exist:
560
561
561 - If the argument is a filename, IPython will load that into the
562 - If the argument is a filename, IPython will load that into the
562 editor. It will execute its contents with execfile() when you exit,
563 editor. It will execute its contents with execfile() when you exit,
563 loading any code in the file into your interactive namespace.
564 loading any code in the file into your interactive namespace.
564
565
565 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
566 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
566 The syntax is the same as in the %history magic.
567 The syntax is the same as in the %history magic.
567
568
568 - If the argument is a string variable, its contents are loaded
569 - If the argument is a string variable, its contents are loaded
569 into the editor. You can thus edit any string which contains
570 into the editor. You can thus edit any string which contains
570 python code (including the result of previous edits).
571 python code (including the result of previous edits).
571
572
572 - If the argument is the name of an object (other than a string),
573 - If the argument is the name of an object (other than a string),
573 IPython will try to locate the file where it was defined and open the
574 IPython will try to locate the file where it was defined and open the
574 editor at the point where it is defined. You can use `%edit function`
575 editor at the point where it is defined. You can use `%edit function`
575 to load an editor exactly at the point where 'function' is defined,
576 to load an editor exactly at the point where 'function' is defined,
576 edit it and have the file be executed automatically.
577 edit it and have the file be executed automatically.
577
578
578 - If the object is a macro (see %macro for details), this opens up your
579 - If the object is a macro (see %macro for details), this opens up your
579 specified editor with a temporary file containing the macro's data.
580 specified editor with a temporary file containing the macro's data.
580 Upon exit, the macro is reloaded with the contents of the file.
581 Upon exit, the macro is reloaded with the contents of the file.
581
582
582 Note: opening at an exact line is only supported under Unix, and some
583 Note: opening at an exact line is only supported under Unix, and some
583 editors (like kedit and gedit up to Gnome 2.8) do not understand the
584 editors (like kedit and gedit up to Gnome 2.8) do not understand the
584 '+NUMBER' parameter necessary for this feature. Good editors like
585 '+NUMBER' parameter necessary for this feature. Good editors like
585 (X)Emacs, vi, jed, pico and joe all do.
586 (X)Emacs, vi, jed, pico and joe all do.
586
587
587 After executing your code, %edit will return as output the code you
588 After executing your code, %edit will return as output the code you
588 typed in the editor (except when it was an existing file). This way
589 typed in the editor (except when it was an existing file). This way
589 you can reload the code in further invocations of %edit as a variable,
590 you can reload the code in further invocations of %edit as a variable,
590 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
591 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
591 the output.
592 the output.
592
593
593 Note that %edit is also available through the alias %ed.
594 Note that %edit is also available through the alias %ed.
594
595
595 This is an example of creating a simple function inside the editor and
596 This is an example of creating a simple function inside the editor and
596 then modifying it. First, start up the editor::
597 then modifying it. First, start up the editor::
597
598
598 In [1]: edit
599 In [1]: edit
599 Editing... done. Executing edited code...
600 Editing... done. Executing edited code...
600 Out[1]: 'def foo():\\n print "foo() was defined in an editing
601 Out[1]: 'def foo():\\n print "foo() was defined in an editing
601 session"\\n'
602 session"\\n'
602
603
603 We can then call the function foo()::
604 We can then call the function foo()::
604
605
605 In [2]: foo()
606 In [2]: foo()
606 foo() was defined in an editing session
607 foo() was defined in an editing session
607
608
608 Now we edit foo. IPython automatically loads the editor with the
609 Now we edit foo. IPython automatically loads the editor with the
609 (temporary) file where foo() was previously defined::
610 (temporary) file where foo() was previously defined::
610
611
611 In [3]: edit foo
612 In [3]: edit foo
612 Editing... done. Executing edited code...
613 Editing... done. Executing edited code...
613
614
614 And if we call foo() again we get the modified version::
615 And if we call foo() again we get the modified version::
615
616
616 In [4]: foo()
617 In [4]: foo()
617 foo() has now been changed!
618 foo() has now been changed!
618
619
619 Here is an example of how to edit a code snippet successive
620 Here is an example of how to edit a code snippet successive
620 times. First we call the editor::
621 times. First we call the editor::
621
622
622 In [5]: edit
623 In [5]: edit
623 Editing... done. Executing edited code...
624 Editing... done. Executing edited code...
624 hello
625 hello
625 Out[5]: "print 'hello'\\n"
626 Out[5]: "print 'hello'\\n"
626
627
627 Now we call it again with the previous output (stored in _)::
628 Now we call it again with the previous output (stored in _)::
628
629
629 In [6]: edit _
630 In [6]: edit _
630 Editing... done. Executing edited code...
631 Editing... done. Executing edited code...
631 hello world
632 hello world
632 Out[6]: "print 'hello world'\\n"
633 Out[6]: "print 'hello world'\\n"
633
634
634 Now we call it with the output #8 (stored in _8, also as Out[8])::
635 Now we call it with the output #8 (stored in _8, also as Out[8])::
635
636
636 In [7]: edit _8
637 In [7]: edit _8
637 Editing... done. Executing edited code...
638 Editing... done. Executing edited code...
638 hello again
639 hello again
639 Out[7]: "print 'hello again'\\n"
640 Out[7]: "print 'hello again'\\n"
640
641
641
642
642 Changing the default editor hook:
643 Changing the default editor hook:
643
644
644 If you wish to write your own editor hook, you can put it in a
645 If you wish to write your own editor hook, you can put it in a
645 configuration file which you load at startup time. The default hook
646 configuration file which you load at startup time. The default hook
646 is defined in the IPython.core.hooks module, and you can use that as a
647 is defined in the IPython.core.hooks module, and you can use that as a
647 starting example for further modifications. That file also has
648 starting example for further modifications. That file also has
648 general instructions on how to set a new hook for use once you've
649 general instructions on how to set a new hook for use once you've
649 defined it."""
650 defined it."""
650 opts,args = self.parse_options(parameter_s,'prxn:')
651 opts,args = self.parse_options(parameter_s,'prxn:')
651
652
652 try:
653 try:
653 filename, lineno, is_temp = self._find_edit_target(self.shell,
654 filename, lineno, is_temp = self._find_edit_target(self.shell,
654 args, opts, last_call)
655 args, opts, last_call)
655 except MacroToEdit as e:
656 except MacroToEdit as e:
656 self._edit_macro(args, e.args[0])
657 self._edit_macro(args, e.args[0])
657 return
658 return
658 except InteractivelyDefined as e:
659 except InteractivelyDefined as e:
659 print("Editing In[%i]" % e.index)
660 print("Editing In[%i]" % e.index)
660 args = str(e.index)
661 args = str(e.index)
661 filename, lineno, is_temp = self._find_edit_target(self.shell,
662 filename, lineno, is_temp = self._find_edit_target(self.shell,
662 args, opts, last_call)
663 args, opts, last_call)
663 if filename is None:
664 if filename is None:
664 # nothing was found, warnings have already been issued,
665 # nothing was found, warnings have already been issued,
665 # just give up.
666 # just give up.
666 return
667 return
667
668
668 if is_temp:
669 if is_temp:
669 self._knowntemps.add(filename)
670 self._knowntemps.add(filename)
670 elif (filename in self._knowntemps):
671 elif (filename in self._knowntemps):
671 is_temp = True
672 is_temp = True
672
673
673
674
674 # do actual editing here
675 # do actual editing here
675 print('Editing...', end=' ')
676 print('Editing...', end=' ')
676 sys.stdout.flush()
677 sys.stdout.flush()
677 try:
678 try:
678 # Quote filenames that may have spaces in them
679 # Quote filenames that may have spaces in them
679 if ' ' in filename:
680 if ' ' in filename:
680 filename = "'%s'" % filename
681 filename = "'%s'" % filename
681 self.shell.hooks.editor(filename,lineno)
682 self.shell.hooks.editor(filename,lineno)
682 except TryNext:
683 except TryNext:
683 warn('Could not open editor')
684 warn('Could not open editor')
684 return
685 return
685
686
686 # XXX TODO: should this be generalized for all string vars?
687 # XXX TODO: should this be generalized for all string vars?
687 # For now, this is special-cased to blocks created by cpaste
688 # For now, this is special-cased to blocks created by cpaste
688 if args.strip() == 'pasted_block':
689 if args.strip() == 'pasted_block':
689 with open(filename, 'r') as f:
690 with open(filename, 'r') as f:
690 self.shell.user_ns['pasted_block'] = f.read()
691 self.shell.user_ns['pasted_block'] = f.read()
691
692
692 if 'x' in opts: # -x prevents actual execution
693 if 'x' in opts: # -x prevents actual execution
693 print()
694 print()
694 else:
695 else:
695 print('done. Executing edited code...')
696 print('done. Executing edited code...')
696 with preserve_keys(self.shell.user_ns, '__file__'):
697 with preserve_keys(self.shell.user_ns, '__file__'):
697 if not is_temp:
698 if not is_temp:
698 self.shell.user_ns['__file__'] = filename
699 self.shell.user_ns['__file__'] = filename
699 if 'r' in opts: # Untranslated IPython code
700 if 'r' in opts: # Untranslated IPython code
700 with open(filename, 'r') as f:
701 with open(filename, 'r') as f:
701 source = f.read()
702 source = f.read()
702 self.shell.run_cell(source, store_history=False)
703 self.shell.run_cell(source, store_history=False)
703 else:
704 else:
704 self.shell.safe_execfile(filename, self.shell.user_ns,
705 self.shell.safe_execfile(filename, self.shell.user_ns,
705 self.shell.user_ns)
706 self.shell.user_ns)
706
707
707 if is_temp:
708 if is_temp:
708 try:
709 try:
709 return open(filename).read()
710 return open(filename).read()
710 except IOError as msg:
711 except IOError as msg:
711 if msg.filename == filename:
712 if msg.filename == filename:
712 warn('File not found. Did you forget to save?')
713 warn('File not found. Did you forget to save?')
713 return
714 return
714 else:
715 else:
715 self.shell.showtraceback()
716 self.shell.showtraceback()
@@ -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 logging 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 traitlets.config.loader import Config
109 from traitlets.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, 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,1362 +1,1363 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 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 import ast
9 import ast
10 import bdb
10 import bdb
11 import gc
11 import gc
12 import itertools
12 import itertools
13 import os
13 import os
14 import sys
14 import sys
15 import time
15 import time
16 import timeit
16 import timeit
17 from pdb import Restart
17 from pdb import Restart
18
18
19 # cProfile was added in Python2.5
19 # cProfile was added in Python2.5
20 try:
20 try:
21 import cProfile as profile
21 import cProfile as profile
22 import pstats
22 import pstats
23 except ImportError:
23 except ImportError:
24 # profile isn't bundled by default in Debian for license reasons
24 # profile isn't bundled by default in Debian for license reasons
25 try:
25 try:
26 import profile, pstats
26 import profile, pstats
27 except ImportError:
27 except ImportError:
28 profile = pstats = None
28 profile = pstats = None
29
29
30 from IPython.core import debugger, oinspect
30 from IPython.core import debugger, oinspect
31 from IPython.core import magic_arguments
31 from IPython.core import magic_arguments
32 from IPython.core import page
32 from IPython.core import page
33 from IPython.core.error import UsageError
33 from IPython.core.error import UsageError
34 from IPython.core.macro import Macro
34 from IPython.core.macro import Macro
35 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
35 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
36 line_cell_magic, on_off, needs_local_scope)
36 line_cell_magic, on_off, needs_local_scope)
37 from IPython.testing.skipdoctest import skip_doctest
37 from IPython.testing.skipdoctest import skip_doctest
38 from IPython.utils import py3compat
38 from IPython.utils import py3compat
39 from IPython.utils.py3compat import builtin_mod, iteritems, PY3
39 from IPython.utils.py3compat import builtin_mod, iteritems, PY3
40 from IPython.utils.contexts import preserve_keys
40 from IPython.utils.contexts import preserve_keys
41 from IPython.utils.capture import capture_output
41 from IPython.utils.capture import capture_output
42 from IPython.utils.ipstruct import Struct
42 from IPython.utils.ipstruct import Struct
43 from IPython.utils.module_paths import find_mod
43 from IPython.utils.module_paths import find_mod
44 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
44 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
45 from IPython.utils.timing import clock, clock2
45 from IPython.utils.timing import clock, clock2
46 from IPython.utils.warn import warn, error
46 from warnings import warn
47 from logging import error
47
48
48 if PY3:
49 if PY3:
49 from io import StringIO
50 from io import StringIO
50 else:
51 else:
51 from StringIO import StringIO
52 from StringIO import StringIO
52
53
53 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
54 # Magic implementation classes
55 # Magic implementation classes
55 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
56
57
57
58
58 class TimeitResult(object):
59 class TimeitResult(object):
59 """
60 """
60 Object returned by the timeit magic with info about the run.
61 Object returned by the timeit magic with info about the run.
61
62
62 Contain the following attributes :
63 Contain the following attributes :
63
64
64 loops: (int) number of loop done per measurement
65 loops: (int) number of loop done per measurement
65 repeat: (int) number of time the mesurement has been repeated
66 repeat: (int) number of time the mesurement has been repeated
66 best: (float) best execusion time / number
67 best: (float) best execusion time / number
67 all_runs: (list of float) execusion time of each run (in s)
68 all_runs: (list of float) execusion time of each run (in s)
68 compile_time: (float) time of statement compilation (s)
69 compile_time: (float) time of statement compilation (s)
69
70
70 """
71 """
71
72
72 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
73 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
73 self.loops = loops
74 self.loops = loops
74 self.repeat = repeat
75 self.repeat = repeat
75 self.best = best
76 self.best = best
76 self.worst = worst
77 self.worst = worst
77 self.all_runs = all_runs
78 self.all_runs = all_runs
78 self.compile_time = compile_time
79 self.compile_time = compile_time
79 self._precision = precision
80 self._precision = precision
80
81
81 def _repr_pretty_(self, p , cycle):
82 def _repr_pretty_(self, p , cycle):
82 if self.loops == 1: # No s at "loops" if only one loop
83 if self.loops == 1: # No s at "loops" if only one loop
83 unic = u"%d loop, best of %d: %s per loop" % (self.loops, self.repeat,
84 unic = u"%d loop, best of %d: %s per loop" % (self.loops, self.repeat,
84 _format_time(self.best, self._precision))
85 _format_time(self.best, self._precision))
85 else:
86 else:
86 unic = u"%d loops, best of %d: %s per loop" % (self.loops, self.repeat,
87 unic = u"%d loops, best of %d: %s per loop" % (self.loops, self.repeat,
87 _format_time(self.best, self._precision))
88 _format_time(self.best, self._precision))
88 p.text(u'<TimeitResult : '+unic+u'>')
89 p.text(u'<TimeitResult : '+unic+u'>')
89
90
90
91
91 class TimeitTemplateFiller(ast.NodeTransformer):
92 class TimeitTemplateFiller(ast.NodeTransformer):
92 """Fill in the AST template for timing execution.
93 """Fill in the AST template for timing execution.
93
94
94 This is quite closely tied to the template definition, which is in
95 This is quite closely tied to the template definition, which is in
95 :meth:`ExecutionMagics.timeit`.
96 :meth:`ExecutionMagics.timeit`.
96 """
97 """
97 def __init__(self, ast_setup, ast_stmt):
98 def __init__(self, ast_setup, ast_stmt):
98 self.ast_setup = ast_setup
99 self.ast_setup = ast_setup
99 self.ast_stmt = ast_stmt
100 self.ast_stmt = ast_stmt
100
101
101 def visit_FunctionDef(self, node):
102 def visit_FunctionDef(self, node):
102 "Fill in the setup statement"
103 "Fill in the setup statement"
103 self.generic_visit(node)
104 self.generic_visit(node)
104 if node.name == "inner":
105 if node.name == "inner":
105 node.body[:1] = self.ast_setup.body
106 node.body[:1] = self.ast_setup.body
106
107
107 return node
108 return node
108
109
109 def visit_For(self, node):
110 def visit_For(self, node):
110 "Fill in the statement to be timed"
111 "Fill in the statement to be timed"
111 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
112 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
112 node.body = self.ast_stmt.body
113 node.body = self.ast_stmt.body
113 return node
114 return node
114
115
115
116
116 class Timer(timeit.Timer):
117 class Timer(timeit.Timer):
117 """Timer class that explicitly uses self.inner
118 """Timer class that explicitly uses self.inner
118
119
119 which is an undocumented implementation detail of CPython,
120 which is an undocumented implementation detail of CPython,
120 not shared by PyPy.
121 not shared by PyPy.
121 """
122 """
122 # Timer.timeit copied from CPython 3.4.2
123 # Timer.timeit copied from CPython 3.4.2
123 def timeit(self, number=timeit.default_number):
124 def timeit(self, number=timeit.default_number):
124 """Time 'number' executions of the main statement.
125 """Time 'number' executions of the main statement.
125
126
126 To be precise, this executes the setup statement once, and
127 To be precise, this executes the setup statement once, and
127 then returns the time it takes to execute the main statement
128 then returns the time it takes to execute the main statement
128 a number of times, as a float measured in seconds. The
129 a number of times, as a float measured in seconds. The
129 argument is the number of times through the loop, defaulting
130 argument is the number of times through the loop, defaulting
130 to one million. The main statement, the setup statement and
131 to one million. The main statement, the setup statement and
131 the timer function to be used are passed to the constructor.
132 the timer function to be used are passed to the constructor.
132 """
133 """
133 it = itertools.repeat(None, number)
134 it = itertools.repeat(None, number)
134 gcold = gc.isenabled()
135 gcold = gc.isenabled()
135 gc.disable()
136 gc.disable()
136 try:
137 try:
137 timing = self.inner(it, self.timer)
138 timing = self.inner(it, self.timer)
138 finally:
139 finally:
139 if gcold:
140 if gcold:
140 gc.enable()
141 gc.enable()
141 return timing
142 return timing
142
143
143
144
144 @magics_class
145 @magics_class
145 class ExecutionMagics(Magics):
146 class ExecutionMagics(Magics):
146 """Magics related to code execution, debugging, profiling, etc.
147 """Magics related to code execution, debugging, profiling, etc.
147
148
148 """
149 """
149
150
150 def __init__(self, shell):
151 def __init__(self, shell):
151 super(ExecutionMagics, self).__init__(shell)
152 super(ExecutionMagics, self).__init__(shell)
152 if profile is None:
153 if profile is None:
153 self.prun = self.profile_missing_notice
154 self.prun = self.profile_missing_notice
154 # Default execution function used to actually run user code.
155 # Default execution function used to actually run user code.
155 self.default_runner = None
156 self.default_runner = None
156
157
157 def profile_missing_notice(self, *args, **kwargs):
158 def profile_missing_notice(self, *args, **kwargs):
158 error("""\
159 error("""\
159 The profile module could not be found. It has been removed from the standard
160 The profile module could not be found. It has been removed from the standard
160 python packages because of its non-free license. To use profiling, install the
161 python packages because of its non-free license. To use profiling, install the
161 python-profiler package from non-free.""")
162 python-profiler package from non-free.""")
162
163
163 @skip_doctest
164 @skip_doctest
164 @line_cell_magic
165 @line_cell_magic
165 def prun(self, parameter_s='', cell=None):
166 def prun(self, parameter_s='', cell=None):
166
167
167 """Run a statement through the python code profiler.
168 """Run a statement through the python code profiler.
168
169
169 Usage, in line mode:
170 Usage, in line mode:
170 %prun [options] statement
171 %prun [options] statement
171
172
172 Usage, in cell mode:
173 Usage, in cell mode:
173 %%prun [options] [statement]
174 %%prun [options] [statement]
174 code...
175 code...
175 code...
176 code...
176
177
177 In cell mode, the additional code lines are appended to the (possibly
178 In cell mode, the additional code lines are appended to the (possibly
178 empty) statement in the first line. Cell mode allows you to easily
179 empty) statement in the first line. Cell mode allows you to easily
179 profile multiline blocks without having to put them in a separate
180 profile multiline blocks without having to put them in a separate
180 function.
181 function.
181
182
182 The given statement (which doesn't require quote marks) is run via the
183 The given statement (which doesn't require quote marks) is run via the
183 python profiler in a manner similar to the profile.run() function.
184 python profiler in a manner similar to the profile.run() function.
184 Namespaces are internally managed to work correctly; profile.run
185 Namespaces are internally managed to work correctly; profile.run
185 cannot be used in IPython because it makes certain assumptions about
186 cannot be used in IPython because it makes certain assumptions about
186 namespaces which do not hold under IPython.
187 namespaces which do not hold under IPython.
187
188
188 Options:
189 Options:
189
190
190 -l <limit>
191 -l <limit>
191 you can place restrictions on what or how much of the
192 you can place restrictions on what or how much of the
192 profile gets printed. The limit value can be:
193 profile gets printed. The limit value can be:
193
194
194 * A string: only information for function names containing this string
195 * A string: only information for function names containing this string
195 is printed.
196 is printed.
196
197
197 * An integer: only these many lines are printed.
198 * An integer: only these many lines are printed.
198
199
199 * A float (between 0 and 1): this fraction of the report is printed
200 * A float (between 0 and 1): this fraction of the report is printed
200 (for example, use a limit of 0.4 to see the topmost 40% only).
201 (for example, use a limit of 0.4 to see the topmost 40% only).
201
202
202 You can combine several limits with repeated use of the option. For
203 You can combine several limits with repeated use of the option. For
203 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
204 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
204 information about class constructors.
205 information about class constructors.
205
206
206 -r
207 -r
207 return the pstats.Stats object generated by the profiling. This
208 return the pstats.Stats object generated by the profiling. This
208 object has all the information about the profile in it, and you can
209 object has all the information about the profile in it, and you can
209 later use it for further analysis or in other functions.
210 later use it for further analysis or in other functions.
210
211
211 -s <key>
212 -s <key>
212 sort profile by given key. You can provide more than one key
213 sort profile by given key. You can provide more than one key
213 by using the option several times: '-s key1 -s key2 -s key3...'. The
214 by using the option several times: '-s key1 -s key2 -s key3...'. The
214 default sorting key is 'time'.
215 default sorting key is 'time'.
215
216
216 The following is copied verbatim from the profile documentation
217 The following is copied verbatim from the profile documentation
217 referenced below:
218 referenced below:
218
219
219 When more than one key is provided, additional keys are used as
220 When more than one key is provided, additional keys are used as
220 secondary criteria when the there is equality in all keys selected
221 secondary criteria when the there is equality in all keys selected
221 before them.
222 before them.
222
223
223 Abbreviations can be used for any key names, as long as the
224 Abbreviations can be used for any key names, as long as the
224 abbreviation is unambiguous. The following are the keys currently
225 abbreviation is unambiguous. The following are the keys currently
225 defined:
226 defined:
226
227
227 ============ =====================
228 ============ =====================
228 Valid Arg Meaning
229 Valid Arg Meaning
229 ============ =====================
230 ============ =====================
230 "calls" call count
231 "calls" call count
231 "cumulative" cumulative time
232 "cumulative" cumulative time
232 "file" file name
233 "file" file name
233 "module" file name
234 "module" file name
234 "pcalls" primitive call count
235 "pcalls" primitive call count
235 "line" line number
236 "line" line number
236 "name" function name
237 "name" function name
237 "nfl" name/file/line
238 "nfl" name/file/line
238 "stdname" standard name
239 "stdname" standard name
239 "time" internal time
240 "time" internal time
240 ============ =====================
241 ============ =====================
241
242
242 Note that all sorts on statistics are in descending order (placing
243 Note that all sorts on statistics are in descending order (placing
243 most time consuming items first), where as name, file, and line number
244 most time consuming items first), where as name, file, and line number
244 searches are in ascending order (i.e., alphabetical). The subtle
245 searches are in ascending order (i.e., alphabetical). The subtle
245 distinction between "nfl" and "stdname" is that the standard name is a
246 distinction between "nfl" and "stdname" is that the standard name is a
246 sort of the name as printed, which means that the embedded line
247 sort of the name as printed, which means that the embedded line
247 numbers get compared in an odd way. For example, lines 3, 20, and 40
248 numbers get compared in an odd way. For example, lines 3, 20, and 40
248 would (if the file names were the same) appear in the string order
249 would (if the file names were the same) appear in the string order
249 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
250 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
250 line numbers. In fact, sort_stats("nfl") is the same as
251 line numbers. In fact, sort_stats("nfl") is the same as
251 sort_stats("name", "file", "line").
252 sort_stats("name", "file", "line").
252
253
253 -T <filename>
254 -T <filename>
254 save profile results as shown on screen to a text
255 save profile results as shown on screen to a text
255 file. The profile is still shown on screen.
256 file. The profile is still shown on screen.
256
257
257 -D <filename>
258 -D <filename>
258 save (via dump_stats) profile statistics to given
259 save (via dump_stats) profile statistics to given
259 filename. This data is in a format understood by the pstats module, and
260 filename. This data is in a format understood by the pstats module, and
260 is generated by a call to the dump_stats() method of profile
261 is generated by a call to the dump_stats() method of profile
261 objects. The profile is still shown on screen.
262 objects. The profile is still shown on screen.
262
263
263 -q
264 -q
264 suppress output to the pager. Best used with -T and/or -D above.
265 suppress output to the pager. Best used with -T and/or -D above.
265
266
266 If you want to run complete programs under the profiler's control, use
267 If you want to run complete programs under the profiler's control, use
267 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
268 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
268 contains profiler specific options as described here.
269 contains profiler specific options as described here.
269
270
270 You can read the complete documentation for the profile module with::
271 You can read the complete documentation for the profile module with::
271
272
272 In [1]: import profile; profile.help()
273 In [1]: import profile; profile.help()
273 """
274 """
274 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
275 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
275 list_all=True, posix=False)
276 list_all=True, posix=False)
276 if cell is not None:
277 if cell is not None:
277 arg_str += '\n' + cell
278 arg_str += '\n' + cell
278 arg_str = self.shell.input_splitter.transform_cell(arg_str)
279 arg_str = self.shell.input_splitter.transform_cell(arg_str)
279 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
280 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
280
281
281 def _run_with_profiler(self, code, opts, namespace):
282 def _run_with_profiler(self, code, opts, namespace):
282 """
283 """
283 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
284 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
284
285
285 Parameters
286 Parameters
286 ----------
287 ----------
287 code : str
288 code : str
288 Code to be executed.
289 Code to be executed.
289 opts : Struct
290 opts : Struct
290 Options parsed by `self.parse_options`.
291 Options parsed by `self.parse_options`.
291 namespace : dict
292 namespace : dict
292 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
293 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
293
294
294 """
295 """
295
296
296 # Fill default values for unspecified options:
297 # Fill default values for unspecified options:
297 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
298 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
298
299
299 prof = profile.Profile()
300 prof = profile.Profile()
300 try:
301 try:
301 prof = prof.runctx(code, namespace, namespace)
302 prof = prof.runctx(code, namespace, namespace)
302 sys_exit = ''
303 sys_exit = ''
303 except SystemExit:
304 except SystemExit:
304 sys_exit = """*** SystemExit exception caught in code being profiled."""
305 sys_exit = """*** SystemExit exception caught in code being profiled."""
305
306
306 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
307 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
307
308
308 lims = opts.l
309 lims = opts.l
309 if lims:
310 if lims:
310 lims = [] # rebuild lims with ints/floats/strings
311 lims = [] # rebuild lims with ints/floats/strings
311 for lim in opts.l:
312 for lim in opts.l:
312 try:
313 try:
313 lims.append(int(lim))
314 lims.append(int(lim))
314 except ValueError:
315 except ValueError:
315 try:
316 try:
316 lims.append(float(lim))
317 lims.append(float(lim))
317 except ValueError:
318 except ValueError:
318 lims.append(lim)
319 lims.append(lim)
319
320
320 # Trap output.
321 # Trap output.
321 stdout_trap = StringIO()
322 stdout_trap = StringIO()
322 stats_stream = stats.stream
323 stats_stream = stats.stream
323 try:
324 try:
324 stats.stream = stdout_trap
325 stats.stream = stdout_trap
325 stats.print_stats(*lims)
326 stats.print_stats(*lims)
326 finally:
327 finally:
327 stats.stream = stats_stream
328 stats.stream = stats_stream
328
329
329 output = stdout_trap.getvalue()
330 output = stdout_trap.getvalue()
330 output = output.rstrip()
331 output = output.rstrip()
331
332
332 if 'q' not in opts:
333 if 'q' not in opts:
333 page.page(output)
334 page.page(output)
334 print(sys_exit, end=' ')
335 print(sys_exit, end=' ')
335
336
336 dump_file = opts.D[0]
337 dump_file = opts.D[0]
337 text_file = opts.T[0]
338 text_file = opts.T[0]
338 if dump_file:
339 if dump_file:
339 dump_file = unquote_filename(dump_file)
340 dump_file = unquote_filename(dump_file)
340 prof.dump_stats(dump_file)
341 prof.dump_stats(dump_file)
341 print('\n*** Profile stats marshalled to file',\
342 print('\n*** Profile stats marshalled to file',\
342 repr(dump_file)+'.',sys_exit)
343 repr(dump_file)+'.',sys_exit)
343 if text_file:
344 if text_file:
344 text_file = unquote_filename(text_file)
345 text_file = unquote_filename(text_file)
345 pfile = open(text_file,'w')
346 pfile = open(text_file,'w')
346 pfile.write(output)
347 pfile.write(output)
347 pfile.close()
348 pfile.close()
348 print('\n*** Profile printout saved to text file',\
349 print('\n*** Profile printout saved to text file',\
349 repr(text_file)+'.',sys_exit)
350 repr(text_file)+'.',sys_exit)
350
351
351 if 'r' in opts:
352 if 'r' in opts:
352 return stats
353 return stats
353 else:
354 else:
354 return None
355 return None
355
356
356 @line_magic
357 @line_magic
357 def pdb(self, parameter_s=''):
358 def pdb(self, parameter_s=''):
358 """Control the automatic calling of the pdb interactive debugger.
359 """Control the automatic calling of the pdb interactive debugger.
359
360
360 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
361 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
361 argument it works as a toggle.
362 argument it works as a toggle.
362
363
363 When an exception is triggered, IPython can optionally call the
364 When an exception is triggered, IPython can optionally call the
364 interactive pdb debugger after the traceback printout. %pdb toggles
365 interactive pdb debugger after the traceback printout. %pdb toggles
365 this feature on and off.
366 this feature on and off.
366
367
367 The initial state of this feature is set in your configuration
368 The initial state of this feature is set in your configuration
368 file (the option is ``InteractiveShell.pdb``).
369 file (the option is ``InteractiveShell.pdb``).
369
370
370 If you want to just activate the debugger AFTER an exception has fired,
371 If you want to just activate the debugger AFTER an exception has fired,
371 without having to type '%pdb on' and rerunning your code, you can use
372 without having to type '%pdb on' and rerunning your code, you can use
372 the %debug magic."""
373 the %debug magic."""
373
374
374 par = parameter_s.strip().lower()
375 par = parameter_s.strip().lower()
375
376
376 if par:
377 if par:
377 try:
378 try:
378 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
379 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
379 except KeyError:
380 except KeyError:
380 print ('Incorrect argument. Use on/1, off/0, '
381 print ('Incorrect argument. Use on/1, off/0, '
381 'or nothing for a toggle.')
382 'or nothing for a toggle.')
382 return
383 return
383 else:
384 else:
384 # toggle
385 # toggle
385 new_pdb = not self.shell.call_pdb
386 new_pdb = not self.shell.call_pdb
386
387
387 # set on the shell
388 # set on the shell
388 self.shell.call_pdb = new_pdb
389 self.shell.call_pdb = new_pdb
389 print('Automatic pdb calling has been turned',on_off(new_pdb))
390 print('Automatic pdb calling has been turned',on_off(new_pdb))
390
391
391 @skip_doctest
392 @skip_doctest
392 @magic_arguments.magic_arguments()
393 @magic_arguments.magic_arguments()
393 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
394 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
394 help="""
395 help="""
395 Set break point at LINE in FILE.
396 Set break point at LINE in FILE.
396 """
397 """
397 )
398 )
398 @magic_arguments.argument('statement', nargs='*',
399 @magic_arguments.argument('statement', nargs='*',
399 help="""
400 help="""
400 Code to run in debugger.
401 Code to run in debugger.
401 You can omit this in cell magic mode.
402 You can omit this in cell magic mode.
402 """
403 """
403 )
404 )
404 @line_cell_magic
405 @line_cell_magic
405 def debug(self, line='', cell=None):
406 def debug(self, line='', cell=None):
406 """Activate the interactive debugger.
407 """Activate the interactive debugger.
407
408
408 This magic command support two ways of activating debugger.
409 This magic command support two ways of activating debugger.
409 One is to activate debugger before executing code. This way, you
410 One is to activate debugger before executing code. This way, you
410 can set a break point, to step through the code from the point.
411 can set a break point, to step through the code from the point.
411 You can use this mode by giving statements to execute and optionally
412 You can use this mode by giving statements to execute and optionally
412 a breakpoint.
413 a breakpoint.
413
414
414 The other one is to activate debugger in post-mortem mode. You can
415 The other one is to activate debugger in post-mortem mode. You can
415 activate this mode simply running %debug without any argument.
416 activate this mode simply running %debug without any argument.
416 If an exception has just occurred, this lets you inspect its stack
417 If an exception has just occurred, this lets you inspect its stack
417 frames interactively. Note that this will always work only on the last
418 frames interactively. Note that this will always work only on the last
418 traceback that occurred, so you must call this quickly after an
419 traceback that occurred, so you must call this quickly after an
419 exception that you wish to inspect has fired, because if another one
420 exception that you wish to inspect has fired, because if another one
420 occurs, it clobbers the previous one.
421 occurs, it clobbers the previous one.
421
422
422 If you want IPython to automatically do this on every exception, see
423 If you want IPython to automatically do this on every exception, see
423 the %pdb magic for more details.
424 the %pdb magic for more details.
424 """
425 """
425 args = magic_arguments.parse_argstring(self.debug, line)
426 args = magic_arguments.parse_argstring(self.debug, line)
426
427
427 if not (args.breakpoint or args.statement or cell):
428 if not (args.breakpoint or args.statement or cell):
428 self._debug_post_mortem()
429 self._debug_post_mortem()
429 else:
430 else:
430 code = "\n".join(args.statement)
431 code = "\n".join(args.statement)
431 if cell:
432 if cell:
432 code += "\n" + cell
433 code += "\n" + cell
433 self._debug_exec(code, args.breakpoint)
434 self._debug_exec(code, args.breakpoint)
434
435
435 def _debug_post_mortem(self):
436 def _debug_post_mortem(self):
436 self.shell.debugger(force=True)
437 self.shell.debugger(force=True)
437
438
438 def _debug_exec(self, code, breakpoint):
439 def _debug_exec(self, code, breakpoint):
439 if breakpoint:
440 if breakpoint:
440 (filename, bp_line) = breakpoint.split(':', 1)
441 (filename, bp_line) = breakpoint.split(':', 1)
441 bp_line = int(bp_line)
442 bp_line = int(bp_line)
442 else:
443 else:
443 (filename, bp_line) = (None, None)
444 (filename, bp_line) = (None, None)
444 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
445 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
445
446
446 @line_magic
447 @line_magic
447 def tb(self, s):
448 def tb(self, s):
448 """Print the last traceback with the currently active exception mode.
449 """Print the last traceback with the currently active exception mode.
449
450
450 See %xmode for changing exception reporting modes."""
451 See %xmode for changing exception reporting modes."""
451 self.shell.showtraceback()
452 self.shell.showtraceback()
452
453
453 @skip_doctest
454 @skip_doctest
454 @line_magic
455 @line_magic
455 def run(self, parameter_s='', runner=None,
456 def run(self, parameter_s='', runner=None,
456 file_finder=get_py_filename):
457 file_finder=get_py_filename):
457 """Run the named file inside IPython as a program.
458 """Run the named file inside IPython as a program.
458
459
459 Usage::
460 Usage::
460
461
461 %run [-n -i -e -G]
462 %run [-n -i -e -G]
462 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
463 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
463 ( -m mod | file ) [args]
464 ( -m mod | file ) [args]
464
465
465 Parameters after the filename are passed as command-line arguments to
466 Parameters after the filename are passed as command-line arguments to
466 the program (put in sys.argv). Then, control returns to IPython's
467 the program (put in sys.argv). Then, control returns to IPython's
467 prompt.
468 prompt.
468
469
469 This is similar to running at a system prompt ``python file args``,
470 This is similar to running at a system prompt ``python file args``,
470 but with the advantage of giving you IPython's tracebacks, and of
471 but with the advantage of giving you IPython's tracebacks, and of
471 loading all variables into your interactive namespace for further use
472 loading all variables into your interactive namespace for further use
472 (unless -p is used, see below).
473 (unless -p is used, see below).
473
474
474 The file is executed in a namespace initially consisting only of
475 The file is executed in a namespace initially consisting only of
475 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
476 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
476 sees its environment as if it were being run as a stand-alone program
477 sees its environment as if it were being run as a stand-alone program
477 (except for sharing global objects such as previously imported
478 (except for sharing global objects such as previously imported
478 modules). But after execution, the IPython interactive namespace gets
479 modules). But after execution, the IPython interactive namespace gets
479 updated with all variables defined in the program (except for __name__
480 updated with all variables defined in the program (except for __name__
480 and sys.argv). This allows for very convenient loading of code for
481 and sys.argv). This allows for very convenient loading of code for
481 interactive work, while giving each program a 'clean sheet' to run in.
482 interactive work, while giving each program a 'clean sheet' to run in.
482
483
483 Arguments are expanded using shell-like glob match. Patterns
484 Arguments are expanded using shell-like glob match. Patterns
484 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
485 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
485 tilde '~' will be expanded into user's home directory. Unlike
486 tilde '~' will be expanded into user's home directory. Unlike
486 real shells, quotation does not suppress expansions. Use
487 real shells, quotation does not suppress expansions. Use
487 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
488 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
488 To completely disable these expansions, you can use -G flag.
489 To completely disable these expansions, you can use -G flag.
489
490
490 Options:
491 Options:
491
492
492 -n
493 -n
493 __name__ is NOT set to '__main__', but to the running file's name
494 __name__ is NOT set to '__main__', but to the running file's name
494 without extension (as python does under import). This allows running
495 without extension (as python does under import). This allows running
495 scripts and reloading the definitions in them without calling code
496 scripts and reloading the definitions in them without calling code
496 protected by an ``if __name__ == "__main__"`` clause.
497 protected by an ``if __name__ == "__main__"`` clause.
497
498
498 -i
499 -i
499 run the file in IPython's namespace instead of an empty one. This
500 run the file in IPython's namespace instead of an empty one. This
500 is useful if you are experimenting with code written in a text editor
501 is useful if you are experimenting with code written in a text editor
501 which depends on variables defined interactively.
502 which depends on variables defined interactively.
502
503
503 -e
504 -e
504 ignore sys.exit() calls or SystemExit exceptions in the script
505 ignore sys.exit() calls or SystemExit exceptions in the script
505 being run. This is particularly useful if IPython is being used to
506 being run. This is particularly useful if IPython is being used to
506 run unittests, which always exit with a sys.exit() call. In such
507 run unittests, which always exit with a sys.exit() call. In such
507 cases you are interested in the output of the test results, not in
508 cases you are interested in the output of the test results, not in
508 seeing a traceback of the unittest module.
509 seeing a traceback of the unittest module.
509
510
510 -t
511 -t
511 print timing information at the end of the run. IPython will give
512 print timing information at the end of the run. IPython will give
512 you an estimated CPU time consumption for your script, which under
513 you an estimated CPU time consumption for your script, which under
513 Unix uses the resource module to avoid the wraparound problems of
514 Unix uses the resource module to avoid the wraparound problems of
514 time.clock(). Under Unix, an estimate of time spent on system tasks
515 time.clock(). Under Unix, an estimate of time spent on system tasks
515 is also given (for Windows platforms this is reported as 0.0).
516 is also given (for Windows platforms this is reported as 0.0).
516
517
517 If -t is given, an additional ``-N<N>`` option can be given, where <N>
518 If -t is given, an additional ``-N<N>`` option can be given, where <N>
518 must be an integer indicating how many times you want the script to
519 must be an integer indicating how many times you want the script to
519 run. The final timing report will include total and per run results.
520 run. The final timing report will include total and per run results.
520
521
521 For example (testing the script uniq_stable.py)::
522 For example (testing the script uniq_stable.py)::
522
523
523 In [1]: run -t uniq_stable
524 In [1]: run -t uniq_stable
524
525
525 IPython CPU timings (estimated):
526 IPython CPU timings (estimated):
526 User : 0.19597 s.
527 User : 0.19597 s.
527 System: 0.0 s.
528 System: 0.0 s.
528
529
529 In [2]: run -t -N5 uniq_stable
530 In [2]: run -t -N5 uniq_stable
530
531
531 IPython CPU timings (estimated):
532 IPython CPU timings (estimated):
532 Total runs performed: 5
533 Total runs performed: 5
533 Times : Total Per run
534 Times : Total Per run
534 User : 0.910862 s, 0.1821724 s.
535 User : 0.910862 s, 0.1821724 s.
535 System: 0.0 s, 0.0 s.
536 System: 0.0 s, 0.0 s.
536
537
537 -d
538 -d
538 run your program under the control of pdb, the Python debugger.
539 run your program under the control of pdb, the Python debugger.
539 This allows you to execute your program step by step, watch variables,
540 This allows you to execute your program step by step, watch variables,
540 etc. Internally, what IPython does is similar to calling::
541 etc. Internally, what IPython does is similar to calling::
541
542
542 pdb.run('execfile("YOURFILENAME")')
543 pdb.run('execfile("YOURFILENAME")')
543
544
544 with a breakpoint set on line 1 of your file. You can change the line
545 with a breakpoint set on line 1 of your file. You can change the line
545 number for this automatic breakpoint to be <N> by using the -bN option
546 number for this automatic breakpoint to be <N> by using the -bN option
546 (where N must be an integer). For example::
547 (where N must be an integer). For example::
547
548
548 %run -d -b40 myscript
549 %run -d -b40 myscript
549
550
550 will set the first breakpoint at line 40 in myscript.py. Note that
551 will set the first breakpoint at line 40 in myscript.py. Note that
551 the first breakpoint must be set on a line which actually does
552 the first breakpoint must be set on a line which actually does
552 something (not a comment or docstring) for it to stop execution.
553 something (not a comment or docstring) for it to stop execution.
553
554
554 Or you can specify a breakpoint in a different file::
555 Or you can specify a breakpoint in a different file::
555
556
556 %run -d -b myotherfile.py:20 myscript
557 %run -d -b myotherfile.py:20 myscript
557
558
558 When the pdb debugger starts, you will see a (Pdb) prompt. You must
559 When the pdb debugger starts, you will see a (Pdb) prompt. You must
559 first enter 'c' (without quotes) to start execution up to the first
560 first enter 'c' (without quotes) to start execution up to the first
560 breakpoint.
561 breakpoint.
561
562
562 Entering 'help' gives information about the use of the debugger. You
563 Entering 'help' gives information about the use of the debugger. You
563 can easily see pdb's full documentation with "import pdb;pdb.help()"
564 can easily see pdb's full documentation with "import pdb;pdb.help()"
564 at a prompt.
565 at a prompt.
565
566
566 -p
567 -p
567 run program under the control of the Python profiler module (which
568 run program under the control of the Python profiler module (which
568 prints a detailed report of execution times, function calls, etc).
569 prints a detailed report of execution times, function calls, etc).
569
570
570 You can pass other options after -p which affect the behavior of the
571 You can pass other options after -p which affect the behavior of the
571 profiler itself. See the docs for %prun for details.
572 profiler itself. See the docs for %prun for details.
572
573
573 In this mode, the program's variables do NOT propagate back to the
574 In this mode, the program's variables do NOT propagate back to the
574 IPython interactive namespace (because they remain in the namespace
575 IPython interactive namespace (because they remain in the namespace
575 where the profiler executes them).
576 where the profiler executes them).
576
577
577 Internally this triggers a call to %prun, see its documentation for
578 Internally this triggers a call to %prun, see its documentation for
578 details on the options available specifically for profiling.
579 details on the options available specifically for profiling.
579
580
580 There is one special usage for which the text above doesn't apply:
581 There is one special usage for which the text above doesn't apply:
581 if the filename ends with .ipy[nb], the file is run as ipython script,
582 if the filename ends with .ipy[nb], the file is run as ipython script,
582 just as if the commands were written on IPython prompt.
583 just as if the commands were written on IPython prompt.
583
584
584 -m
585 -m
585 specify module name to load instead of script path. Similar to
586 specify module name to load instead of script path. Similar to
586 the -m option for the python interpreter. Use this option last if you
587 the -m option for the python interpreter. Use this option last if you
587 want to combine with other %run options. Unlike the python interpreter
588 want to combine with other %run options. Unlike the python interpreter
588 only source modules are allowed no .pyc or .pyo files.
589 only source modules are allowed no .pyc or .pyo files.
589 For example::
590 For example::
590
591
591 %run -m example
592 %run -m example
592
593
593 will run the example module.
594 will run the example module.
594
595
595 -G
596 -G
596 disable shell-like glob expansion of arguments.
597 disable shell-like glob expansion of arguments.
597
598
598 """
599 """
599
600
600 # get arguments and set sys.argv for program to be run.
601 # get arguments and set sys.argv for program to be run.
601 opts, arg_lst = self.parse_options(parameter_s,
602 opts, arg_lst = self.parse_options(parameter_s,
602 'nidtN:b:pD:l:rs:T:em:G',
603 'nidtN:b:pD:l:rs:T:em:G',
603 mode='list', list_all=1)
604 mode='list', list_all=1)
604 if "m" in opts:
605 if "m" in opts:
605 modulename = opts["m"][0]
606 modulename = opts["m"][0]
606 modpath = find_mod(modulename)
607 modpath = find_mod(modulename)
607 if modpath is None:
608 if modpath is None:
608 warn('%r is not a valid modulename on sys.path'%modulename)
609 warn('%r is not a valid modulename on sys.path'%modulename)
609 return
610 return
610 arg_lst = [modpath] + arg_lst
611 arg_lst = [modpath] + arg_lst
611 try:
612 try:
612 filename = file_finder(arg_lst[0])
613 filename = file_finder(arg_lst[0])
613 except IndexError:
614 except IndexError:
614 warn('you must provide at least a filename.')
615 warn('you must provide at least a filename.')
615 print('\n%run:\n', oinspect.getdoc(self.run))
616 print('\n%run:\n', oinspect.getdoc(self.run))
616 return
617 return
617 except IOError as e:
618 except IOError as e:
618 try:
619 try:
619 msg = str(e)
620 msg = str(e)
620 except UnicodeError:
621 except UnicodeError:
621 msg = e.message
622 msg = e.message
622 error(msg)
623 error(msg)
623 return
624 return
624
625
625 if filename.lower().endswith(('.ipy', '.ipynb')):
626 if filename.lower().endswith(('.ipy', '.ipynb')):
626 with preserve_keys(self.shell.user_ns, '__file__'):
627 with preserve_keys(self.shell.user_ns, '__file__'):
627 self.shell.user_ns['__file__'] = filename
628 self.shell.user_ns['__file__'] = filename
628 self.shell.safe_execfile_ipy(filename)
629 self.shell.safe_execfile_ipy(filename)
629 return
630 return
630
631
631 # Control the response to exit() calls made by the script being run
632 # Control the response to exit() calls made by the script being run
632 exit_ignore = 'e' in opts
633 exit_ignore = 'e' in opts
633
634
634 # Make sure that the running script gets a proper sys.argv as if it
635 # Make sure that the running script gets a proper sys.argv as if it
635 # were run from a system shell.
636 # were run from a system shell.
636 save_argv = sys.argv # save it for later restoring
637 save_argv = sys.argv # save it for later restoring
637
638
638 if 'G' in opts:
639 if 'G' in opts:
639 args = arg_lst[1:]
640 args = arg_lst[1:]
640 else:
641 else:
641 # tilde and glob expansion
642 # tilde and glob expansion
642 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
643 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
643
644
644 sys.argv = [filename] + args # put in the proper filename
645 sys.argv = [filename] + args # put in the proper filename
645 # protect sys.argv from potential unicode strings on Python 2:
646 # protect sys.argv from potential unicode strings on Python 2:
646 if not py3compat.PY3:
647 if not py3compat.PY3:
647 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
648 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
648
649
649 if 'i' in opts:
650 if 'i' in opts:
650 # Run in user's interactive namespace
651 # Run in user's interactive namespace
651 prog_ns = self.shell.user_ns
652 prog_ns = self.shell.user_ns
652 __name__save = self.shell.user_ns['__name__']
653 __name__save = self.shell.user_ns['__name__']
653 prog_ns['__name__'] = '__main__'
654 prog_ns['__name__'] = '__main__'
654 main_mod = self.shell.user_module
655 main_mod = self.shell.user_module
655
656
656 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
657 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
657 # set the __file__ global in the script's namespace
658 # set the __file__ global in the script's namespace
658 # TK: Is this necessary in interactive mode?
659 # TK: Is this necessary in interactive mode?
659 prog_ns['__file__'] = filename
660 prog_ns['__file__'] = filename
660 else:
661 else:
661 # Run in a fresh, empty namespace
662 # Run in a fresh, empty namespace
662 if 'n' in opts:
663 if 'n' in opts:
663 name = os.path.splitext(os.path.basename(filename))[0]
664 name = os.path.splitext(os.path.basename(filename))[0]
664 else:
665 else:
665 name = '__main__'
666 name = '__main__'
666
667
667 # The shell MUST hold a reference to prog_ns so after %run
668 # The shell MUST hold a reference to prog_ns so after %run
668 # exits, the python deletion mechanism doesn't zero it out
669 # exits, the python deletion mechanism doesn't zero it out
669 # (leaving dangling references). See interactiveshell for details
670 # (leaving dangling references). See interactiveshell for details
670 main_mod = self.shell.new_main_mod(filename, name)
671 main_mod = self.shell.new_main_mod(filename, name)
671 prog_ns = main_mod.__dict__
672 prog_ns = main_mod.__dict__
672
673
673 # pickle fix. See interactiveshell for an explanation. But we need to
674 # pickle fix. See interactiveshell for an explanation. But we need to
674 # make sure that, if we overwrite __main__, we replace it at the end
675 # make sure that, if we overwrite __main__, we replace it at the end
675 main_mod_name = prog_ns['__name__']
676 main_mod_name = prog_ns['__name__']
676
677
677 if main_mod_name == '__main__':
678 if main_mod_name == '__main__':
678 restore_main = sys.modules['__main__']
679 restore_main = sys.modules['__main__']
679 else:
680 else:
680 restore_main = False
681 restore_main = False
681
682
682 # This needs to be undone at the end to prevent holding references to
683 # This needs to be undone at the end to prevent holding references to
683 # every single object ever created.
684 # every single object ever created.
684 sys.modules[main_mod_name] = main_mod
685 sys.modules[main_mod_name] = main_mod
685
686
686 if 'p' in opts or 'd' in opts:
687 if 'p' in opts or 'd' in opts:
687 if 'm' in opts:
688 if 'm' in opts:
688 code = 'run_module(modulename, prog_ns)'
689 code = 'run_module(modulename, prog_ns)'
689 code_ns = {
690 code_ns = {
690 'run_module': self.shell.safe_run_module,
691 'run_module': self.shell.safe_run_module,
691 'prog_ns': prog_ns,
692 'prog_ns': prog_ns,
692 'modulename': modulename,
693 'modulename': modulename,
693 }
694 }
694 else:
695 else:
695 if 'd' in opts:
696 if 'd' in opts:
696 # allow exceptions to raise in debug mode
697 # allow exceptions to raise in debug mode
697 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
698 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
698 else:
699 else:
699 code = 'execfile(filename, prog_ns)'
700 code = 'execfile(filename, prog_ns)'
700 code_ns = {
701 code_ns = {
701 'execfile': self.shell.safe_execfile,
702 'execfile': self.shell.safe_execfile,
702 'prog_ns': prog_ns,
703 'prog_ns': prog_ns,
703 'filename': get_py_filename(filename),
704 'filename': get_py_filename(filename),
704 }
705 }
705
706
706 try:
707 try:
707 stats = None
708 stats = None
708 with self.shell.readline_no_record:
709 with self.shell.readline_no_record:
709 if 'p' in opts:
710 if 'p' in opts:
710 stats = self._run_with_profiler(code, opts, code_ns)
711 stats = self._run_with_profiler(code, opts, code_ns)
711 else:
712 else:
712 if 'd' in opts:
713 if 'd' in opts:
713 bp_file, bp_line = parse_breakpoint(
714 bp_file, bp_line = parse_breakpoint(
714 opts.get('b', ['1'])[0], filename)
715 opts.get('b', ['1'])[0], filename)
715 self._run_with_debugger(
716 self._run_with_debugger(
716 code, code_ns, filename, bp_line, bp_file)
717 code, code_ns, filename, bp_line, bp_file)
717 else:
718 else:
718 if 'm' in opts:
719 if 'm' in opts:
719 def run():
720 def run():
720 self.shell.safe_run_module(modulename, prog_ns)
721 self.shell.safe_run_module(modulename, prog_ns)
721 else:
722 else:
722 if runner is None:
723 if runner is None:
723 runner = self.default_runner
724 runner = self.default_runner
724 if runner is None:
725 if runner is None:
725 runner = self.shell.safe_execfile
726 runner = self.shell.safe_execfile
726
727
727 def run():
728 def run():
728 runner(filename, prog_ns, prog_ns,
729 runner(filename, prog_ns, prog_ns,
729 exit_ignore=exit_ignore)
730 exit_ignore=exit_ignore)
730
731
731 if 't' in opts:
732 if 't' in opts:
732 # timed execution
733 # timed execution
733 try:
734 try:
734 nruns = int(opts['N'][0])
735 nruns = int(opts['N'][0])
735 if nruns < 1:
736 if nruns < 1:
736 error('Number of runs must be >=1')
737 error('Number of runs must be >=1')
737 return
738 return
738 except (KeyError):
739 except (KeyError):
739 nruns = 1
740 nruns = 1
740 self._run_with_timing(run, nruns)
741 self._run_with_timing(run, nruns)
741 else:
742 else:
742 # regular execution
743 # regular execution
743 run()
744 run()
744
745
745 if 'i' in opts:
746 if 'i' in opts:
746 self.shell.user_ns['__name__'] = __name__save
747 self.shell.user_ns['__name__'] = __name__save
747 else:
748 else:
748 # update IPython interactive namespace
749 # update IPython interactive namespace
749
750
750 # Some forms of read errors on the file may mean the
751 # Some forms of read errors on the file may mean the
751 # __name__ key was never set; using pop we don't have to
752 # __name__ key was never set; using pop we don't have to
752 # worry about a possible KeyError.
753 # worry about a possible KeyError.
753 prog_ns.pop('__name__', None)
754 prog_ns.pop('__name__', None)
754
755
755 with preserve_keys(self.shell.user_ns, '__file__'):
756 with preserve_keys(self.shell.user_ns, '__file__'):
756 self.shell.user_ns.update(prog_ns)
757 self.shell.user_ns.update(prog_ns)
757 finally:
758 finally:
758 # It's a bit of a mystery why, but __builtins__ can change from
759 # It's a bit of a mystery why, but __builtins__ can change from
759 # being a module to becoming a dict missing some key data after
760 # being a module to becoming a dict missing some key data after
760 # %run. As best I can see, this is NOT something IPython is doing
761 # %run. As best I can see, this is NOT something IPython is doing
761 # at all, and similar problems have been reported before:
762 # at all, and similar problems have been reported before:
762 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
763 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
763 # Since this seems to be done by the interpreter itself, the best
764 # Since this seems to be done by the interpreter itself, the best
764 # we can do is to at least restore __builtins__ for the user on
765 # we can do is to at least restore __builtins__ for the user on
765 # exit.
766 # exit.
766 self.shell.user_ns['__builtins__'] = builtin_mod
767 self.shell.user_ns['__builtins__'] = builtin_mod
767
768
768 # Ensure key global structures are restored
769 # Ensure key global structures are restored
769 sys.argv = save_argv
770 sys.argv = save_argv
770 if restore_main:
771 if restore_main:
771 sys.modules['__main__'] = restore_main
772 sys.modules['__main__'] = restore_main
772 else:
773 else:
773 # Remove from sys.modules the reference to main_mod we'd
774 # Remove from sys.modules the reference to main_mod we'd
774 # added. Otherwise it will trap references to objects
775 # added. Otherwise it will trap references to objects
775 # contained therein.
776 # contained therein.
776 del sys.modules[main_mod_name]
777 del sys.modules[main_mod_name]
777
778
778 return stats
779 return stats
779
780
780 def _run_with_debugger(self, code, code_ns, filename=None,
781 def _run_with_debugger(self, code, code_ns, filename=None,
781 bp_line=None, bp_file=None):
782 bp_line=None, bp_file=None):
782 """
783 """
783 Run `code` in debugger with a break point.
784 Run `code` in debugger with a break point.
784
785
785 Parameters
786 Parameters
786 ----------
787 ----------
787 code : str
788 code : str
788 Code to execute.
789 Code to execute.
789 code_ns : dict
790 code_ns : dict
790 A namespace in which `code` is executed.
791 A namespace in which `code` is executed.
791 filename : str
792 filename : str
792 `code` is ran as if it is in `filename`.
793 `code` is ran as if it is in `filename`.
793 bp_line : int, optional
794 bp_line : int, optional
794 Line number of the break point.
795 Line number of the break point.
795 bp_file : str, optional
796 bp_file : str, optional
796 Path to the file in which break point is specified.
797 Path to the file in which break point is specified.
797 `filename` is used if not given.
798 `filename` is used if not given.
798
799
799 Raises
800 Raises
800 ------
801 ------
801 UsageError
802 UsageError
802 If the break point given by `bp_line` is not valid.
803 If the break point given by `bp_line` is not valid.
803
804
804 """
805 """
805 deb = debugger.Pdb(self.shell.colors)
806 deb = debugger.Pdb(self.shell.colors)
806 # reset Breakpoint state, which is moronically kept
807 # reset Breakpoint state, which is moronically kept
807 # in a class
808 # in a class
808 bdb.Breakpoint.next = 1
809 bdb.Breakpoint.next = 1
809 bdb.Breakpoint.bplist = {}
810 bdb.Breakpoint.bplist = {}
810 bdb.Breakpoint.bpbynumber = [None]
811 bdb.Breakpoint.bpbynumber = [None]
811 if bp_line is not None:
812 if bp_line is not None:
812 # Set an initial breakpoint to stop execution
813 # Set an initial breakpoint to stop execution
813 maxtries = 10
814 maxtries = 10
814 bp_file = bp_file or filename
815 bp_file = bp_file or filename
815 checkline = deb.checkline(bp_file, bp_line)
816 checkline = deb.checkline(bp_file, bp_line)
816 if not checkline:
817 if not checkline:
817 for bp in range(bp_line + 1, bp_line + maxtries + 1):
818 for bp in range(bp_line + 1, bp_line + maxtries + 1):
818 if deb.checkline(bp_file, bp):
819 if deb.checkline(bp_file, bp):
819 break
820 break
820 else:
821 else:
821 msg = ("\nI failed to find a valid line to set "
822 msg = ("\nI failed to find a valid line to set "
822 "a breakpoint\n"
823 "a breakpoint\n"
823 "after trying up to line: %s.\n"
824 "after trying up to line: %s.\n"
824 "Please set a valid breakpoint manually "
825 "Please set a valid breakpoint manually "
825 "with the -b option." % bp)
826 "with the -b option." % bp)
826 raise UsageError(msg)
827 raise UsageError(msg)
827 # if we find a good linenumber, set the breakpoint
828 # if we find a good linenumber, set the breakpoint
828 deb.do_break('%s:%s' % (bp_file, bp_line))
829 deb.do_break('%s:%s' % (bp_file, bp_line))
829
830
830 if filename:
831 if filename:
831 # Mimic Pdb._runscript(...)
832 # Mimic Pdb._runscript(...)
832 deb._wait_for_mainpyfile = True
833 deb._wait_for_mainpyfile = True
833 deb.mainpyfile = deb.canonic(filename)
834 deb.mainpyfile = deb.canonic(filename)
834
835
835 # Start file run
836 # Start file run
836 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
837 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
837 try:
838 try:
838 if filename:
839 if filename:
839 # save filename so it can be used by methods on the deb object
840 # save filename so it can be used by methods on the deb object
840 deb._exec_filename = filename
841 deb._exec_filename = filename
841 while True:
842 while True:
842 try:
843 try:
843 deb.run(code, code_ns)
844 deb.run(code, code_ns)
844 except Restart:
845 except Restart:
845 print("Restarting")
846 print("Restarting")
846 if filename:
847 if filename:
847 deb._wait_for_mainpyfile = True
848 deb._wait_for_mainpyfile = True
848 deb.mainpyfile = deb.canonic(filename)
849 deb.mainpyfile = deb.canonic(filename)
849 continue
850 continue
850 else:
851 else:
851 break
852 break
852
853
853
854
854 except:
855 except:
855 etype, value, tb = sys.exc_info()
856 etype, value, tb = sys.exc_info()
856 # Skip three frames in the traceback: the %run one,
857 # Skip three frames in the traceback: the %run one,
857 # one inside bdb.py, and the command-line typed by the
858 # one inside bdb.py, and the command-line typed by the
858 # user (run by exec in pdb itself).
859 # user (run by exec in pdb itself).
859 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
860 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
860
861
861 @staticmethod
862 @staticmethod
862 def _run_with_timing(run, nruns):
863 def _run_with_timing(run, nruns):
863 """
864 """
864 Run function `run` and print timing information.
865 Run function `run` and print timing information.
865
866
866 Parameters
867 Parameters
867 ----------
868 ----------
868 run : callable
869 run : callable
869 Any callable object which takes no argument.
870 Any callable object which takes no argument.
870 nruns : int
871 nruns : int
871 Number of times to execute `run`.
872 Number of times to execute `run`.
872
873
873 """
874 """
874 twall0 = time.time()
875 twall0 = time.time()
875 if nruns == 1:
876 if nruns == 1:
876 t0 = clock2()
877 t0 = clock2()
877 run()
878 run()
878 t1 = clock2()
879 t1 = clock2()
879 t_usr = t1[0] - t0[0]
880 t_usr = t1[0] - t0[0]
880 t_sys = t1[1] - t0[1]
881 t_sys = t1[1] - t0[1]
881 print("\nIPython CPU timings (estimated):")
882 print("\nIPython CPU timings (estimated):")
882 print(" User : %10.2f s." % t_usr)
883 print(" User : %10.2f s." % t_usr)
883 print(" System : %10.2f s." % t_sys)
884 print(" System : %10.2f s." % t_sys)
884 else:
885 else:
885 runs = range(nruns)
886 runs = range(nruns)
886 t0 = clock2()
887 t0 = clock2()
887 for nr in runs:
888 for nr in runs:
888 run()
889 run()
889 t1 = clock2()
890 t1 = clock2()
890 t_usr = t1[0] - t0[0]
891 t_usr = t1[0] - t0[0]
891 t_sys = t1[1] - t0[1]
892 t_sys = t1[1] - t0[1]
892 print("\nIPython CPU timings (estimated):")
893 print("\nIPython CPU timings (estimated):")
893 print("Total runs performed:", nruns)
894 print("Total runs performed:", nruns)
894 print(" Times : %10s %10s" % ('Total', 'Per run'))
895 print(" Times : %10s %10s" % ('Total', 'Per run'))
895 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
896 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
896 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
897 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
897 twall1 = time.time()
898 twall1 = time.time()
898 print("Wall time: %10.2f s." % (twall1 - twall0))
899 print("Wall time: %10.2f s." % (twall1 - twall0))
899
900
900 @skip_doctest
901 @skip_doctest
901 @line_cell_magic
902 @line_cell_magic
902 def timeit(self, line='', cell=None):
903 def timeit(self, line='', cell=None):
903 """Time execution of a Python statement or expression
904 """Time execution of a Python statement or expression
904
905
905 Usage, in line mode:
906 Usage, in line mode:
906 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
907 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
907 or in cell mode:
908 or in cell mode:
908 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
909 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
909 code
910 code
910 code...
911 code...
911
912
912 Time execution of a Python statement or expression using the timeit
913 Time execution of a Python statement or expression using the timeit
913 module. This function can be used both as a line and cell magic:
914 module. This function can be used both as a line and cell magic:
914
915
915 - In line mode you can time a single-line statement (though multiple
916 - In line mode you can time a single-line statement (though multiple
916 ones can be chained with using semicolons).
917 ones can be chained with using semicolons).
917
918
918 - In cell mode, the statement in the first line is used as setup code
919 - In cell mode, the statement in the first line is used as setup code
919 (executed but not timed) and the body of the cell is timed. The cell
920 (executed but not timed) and the body of the cell is timed. The cell
920 body has access to any variables created in the setup code.
921 body has access to any variables created in the setup code.
921
922
922 Options:
923 Options:
923 -n<N>: execute the given statement <N> times in a loop. If this value
924 -n<N>: execute the given statement <N> times in a loop. If this value
924 is not given, a fitting value is chosen.
925 is not given, a fitting value is chosen.
925
926
926 -r<R>: repeat the loop iteration <R> times and take the best result.
927 -r<R>: repeat the loop iteration <R> times and take the best result.
927 Default: 3
928 Default: 3
928
929
929 -t: use time.time to measure the time, which is the default on Unix.
930 -t: use time.time to measure the time, which is the default on Unix.
930 This function measures wall time.
931 This function measures wall time.
931
932
932 -c: use time.clock to measure the time, which is the default on
933 -c: use time.clock to measure the time, which is the default on
933 Windows and measures wall time. On Unix, resource.getrusage is used
934 Windows and measures wall time. On Unix, resource.getrusage is used
934 instead and returns the CPU user time.
935 instead and returns the CPU user time.
935
936
936 -p<P>: use a precision of <P> digits to display the timing result.
937 -p<P>: use a precision of <P> digits to display the timing result.
937 Default: 3
938 Default: 3
938
939
939 -q: Quiet, do not print result.
940 -q: Quiet, do not print result.
940
941
941 -o: return a TimeitResult that can be stored in a variable to inspect
942 -o: return a TimeitResult that can be stored in a variable to inspect
942 the result in more details.
943 the result in more details.
943
944
944
945
945 Examples
946 Examples
946 --------
947 --------
947 ::
948 ::
948
949
949 In [1]: %timeit pass
950 In [1]: %timeit pass
950 10000000 loops, best of 3: 53.3 ns per loop
951 10000000 loops, best of 3: 53.3 ns per loop
951
952
952 In [2]: u = None
953 In [2]: u = None
953
954
954 In [3]: %timeit u is None
955 In [3]: %timeit u is None
955 10000000 loops, best of 3: 184 ns per loop
956 10000000 loops, best of 3: 184 ns per loop
956
957
957 In [4]: %timeit -r 4 u == None
958 In [4]: %timeit -r 4 u == None
958 1000000 loops, best of 4: 242 ns per loop
959 1000000 loops, best of 4: 242 ns per loop
959
960
960 In [5]: import time
961 In [5]: import time
961
962
962 In [6]: %timeit -n1 time.sleep(2)
963 In [6]: %timeit -n1 time.sleep(2)
963 1 loop, best of 3: 2 s per loop
964 1 loop, best of 3: 2 s per loop
964
965
965
966
966 The times reported by %timeit will be slightly higher than those
967 The times reported by %timeit will be slightly higher than those
967 reported by the timeit.py script when variables are accessed. This is
968 reported by the timeit.py script when variables are accessed. This is
968 due to the fact that %timeit executes the statement in the namespace
969 due to the fact that %timeit executes the statement in the namespace
969 of the shell, compared with timeit.py, which uses a single setup
970 of the shell, compared with timeit.py, which uses a single setup
970 statement to import function or create variables. Generally, the bias
971 statement to import function or create variables. Generally, the bias
971 does not matter as long as results from timeit.py are not mixed with
972 does not matter as long as results from timeit.py are not mixed with
972 those from %timeit."""
973 those from %timeit."""
973
974
974 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
975 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
975 posix=False, strict=False)
976 posix=False, strict=False)
976 if stmt == "" and cell is None:
977 if stmt == "" and cell is None:
977 return
978 return
978
979
979 timefunc = timeit.default_timer
980 timefunc = timeit.default_timer
980 number = int(getattr(opts, "n", 0))
981 number = int(getattr(opts, "n", 0))
981 repeat = int(getattr(opts, "r", timeit.default_repeat))
982 repeat = int(getattr(opts, "r", timeit.default_repeat))
982 precision = int(getattr(opts, "p", 3))
983 precision = int(getattr(opts, "p", 3))
983 quiet = 'q' in opts
984 quiet = 'q' in opts
984 return_result = 'o' in opts
985 return_result = 'o' in opts
985 if hasattr(opts, "t"):
986 if hasattr(opts, "t"):
986 timefunc = time.time
987 timefunc = time.time
987 if hasattr(opts, "c"):
988 if hasattr(opts, "c"):
988 timefunc = clock
989 timefunc = clock
989
990
990 timer = Timer(timer=timefunc)
991 timer = Timer(timer=timefunc)
991 # this code has tight coupling to the inner workings of timeit.Timer,
992 # this code has tight coupling to the inner workings of timeit.Timer,
992 # but is there a better way to achieve that the code stmt has access
993 # but is there a better way to achieve that the code stmt has access
993 # to the shell namespace?
994 # to the shell namespace?
994 transform = self.shell.input_splitter.transform_cell
995 transform = self.shell.input_splitter.transform_cell
995
996
996 if cell is None:
997 if cell is None:
997 # called as line magic
998 # called as line magic
998 ast_setup = self.shell.compile.ast_parse("pass")
999 ast_setup = self.shell.compile.ast_parse("pass")
999 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1000 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1000 else:
1001 else:
1001 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1002 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1002 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1003 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1003
1004
1004 ast_setup = self.shell.transform_ast(ast_setup)
1005 ast_setup = self.shell.transform_ast(ast_setup)
1005 ast_stmt = self.shell.transform_ast(ast_stmt)
1006 ast_stmt = self.shell.transform_ast(ast_stmt)
1006
1007
1007 # This codestring is taken from timeit.template - we fill it in as an
1008 # This codestring is taken from timeit.template - we fill it in as an
1008 # AST, so that we can apply our AST transformations to the user code
1009 # AST, so that we can apply our AST transformations to the user code
1009 # without affecting the timing code.
1010 # without affecting the timing code.
1010 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1011 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1011 ' setup\n'
1012 ' setup\n'
1012 ' _t0 = _timer()\n'
1013 ' _t0 = _timer()\n'
1013 ' for _i in _it:\n'
1014 ' for _i in _it:\n'
1014 ' stmt\n'
1015 ' stmt\n'
1015 ' _t1 = _timer()\n'
1016 ' _t1 = _timer()\n'
1016 ' return _t1 - _t0\n')
1017 ' return _t1 - _t0\n')
1017
1018
1018 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1019 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1019 timeit_ast = ast.fix_missing_locations(timeit_ast)
1020 timeit_ast = ast.fix_missing_locations(timeit_ast)
1020
1021
1021 # Track compilation time so it can be reported if too long
1022 # Track compilation time so it can be reported if too long
1022 # Minimum time above which compilation time will be reported
1023 # Minimum time above which compilation time will be reported
1023 tc_min = 0.1
1024 tc_min = 0.1
1024
1025
1025 t0 = clock()
1026 t0 = clock()
1026 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1027 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1027 tc = clock()-t0
1028 tc = clock()-t0
1028
1029
1029 ns = {}
1030 ns = {}
1030 exec(code, self.shell.user_ns, ns)
1031 exec(code, self.shell.user_ns, ns)
1031 timer.inner = ns["inner"]
1032 timer.inner = ns["inner"]
1032
1033
1033 # This is used to check if there is a huge difference between the
1034 # This is used to check if there is a huge difference between the
1034 # best and worst timings.
1035 # best and worst timings.
1035 # Issue: https://github.com/ipython/ipython/issues/6471
1036 # Issue: https://github.com/ipython/ipython/issues/6471
1036 worst_tuning = 0
1037 worst_tuning = 0
1037 if number == 0:
1038 if number == 0:
1038 # determine number so that 0.2 <= total time < 2.0
1039 # determine number so that 0.2 <= total time < 2.0
1039 number = 1
1040 number = 1
1040 for _ in range(1, 10):
1041 for _ in range(1, 10):
1041 time_number = timer.timeit(number)
1042 time_number = timer.timeit(number)
1042 worst_tuning = max(worst_tuning, time_number / number)
1043 worst_tuning = max(worst_tuning, time_number / number)
1043 if time_number >= 0.2:
1044 if time_number >= 0.2:
1044 break
1045 break
1045 number *= 10
1046 number *= 10
1046 all_runs = timer.repeat(repeat, number)
1047 all_runs = timer.repeat(repeat, number)
1047 best = min(all_runs) / number
1048 best = min(all_runs) / number
1048
1049
1049 worst = max(all_runs) / number
1050 worst = max(all_runs) / number
1050 if worst_tuning:
1051 if worst_tuning:
1051 worst = max(worst, worst_tuning)
1052 worst = max(worst, worst_tuning)
1052
1053
1053 if not quiet :
1054 if not quiet :
1054 # Check best timing is greater than zero to avoid a
1055 # Check best timing is greater than zero to avoid a
1055 # ZeroDivisionError.
1056 # ZeroDivisionError.
1056 # In cases where the slowest timing is lesser than a micosecond
1057 # In cases where the slowest timing is lesser than a micosecond
1057 # we assume that it does not really matter if the fastest
1058 # we assume that it does not really matter if the fastest
1058 # timing is 4 times faster than the slowest timing or not.
1059 # timing is 4 times faster than the slowest timing or not.
1059 if worst > 4 * best and best > 0 and worst > 1e-6:
1060 if worst > 4 * best and best > 0 and worst > 1e-6:
1060 print("The slowest run took %0.2f times longer than the "
1061 print("The slowest run took %0.2f times longer than the "
1061 "fastest. This could mean that an intermediate result "
1062 "fastest. This could mean that an intermediate result "
1062 "is being cached." % (worst / best))
1063 "is being cached." % (worst / best))
1063 if number == 1: # No s at "loops" if only one loop
1064 if number == 1: # No s at "loops" if only one loop
1064 print(u"%d loop, best of %d: %s per loop" % (number, repeat,
1065 print(u"%d loop, best of %d: %s per loop" % (number, repeat,
1065 _format_time(best, precision)))
1066 _format_time(best, precision)))
1066 else:
1067 else:
1067 print(u"%d loops, best of %d: %s per loop" % (number, repeat,
1068 print(u"%d loops, best of %d: %s per loop" % (number, repeat,
1068 _format_time(best, precision)))
1069 _format_time(best, precision)))
1069 if tc > tc_min:
1070 if tc > tc_min:
1070 print("Compiler time: %.2f s" % tc)
1071 print("Compiler time: %.2f s" % tc)
1071 if return_result:
1072 if return_result:
1072 return TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1073 return TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1073
1074
1074 @skip_doctest
1075 @skip_doctest
1075 @needs_local_scope
1076 @needs_local_scope
1076 @line_cell_magic
1077 @line_cell_magic
1077 def time(self,line='', cell=None, local_ns=None):
1078 def time(self,line='', cell=None, local_ns=None):
1078 """Time execution of a Python statement or expression.
1079 """Time execution of a Python statement or expression.
1079
1080
1080 The CPU and wall clock times are printed, and the value of the
1081 The CPU and wall clock times are printed, and the value of the
1081 expression (if any) is returned. Note that under Win32, system time
1082 expression (if any) is returned. Note that under Win32, system time
1082 is always reported as 0, since it can not be measured.
1083 is always reported as 0, since it can not be measured.
1083
1084
1084 This function can be used both as a line and cell magic:
1085 This function can be used both as a line and cell magic:
1085
1086
1086 - In line mode you can time a single-line statement (though multiple
1087 - In line mode you can time a single-line statement (though multiple
1087 ones can be chained with using semicolons).
1088 ones can be chained with using semicolons).
1088
1089
1089 - In cell mode, you can time the cell body (a directly
1090 - In cell mode, you can time the cell body (a directly
1090 following statement raises an error).
1091 following statement raises an error).
1091
1092
1092 This function provides very basic timing functionality. Use the timeit
1093 This function provides very basic timing functionality. Use the timeit
1093 magic for more control over the measurement.
1094 magic for more control over the measurement.
1094
1095
1095 Examples
1096 Examples
1096 --------
1097 --------
1097 ::
1098 ::
1098
1099
1099 In [1]: %time 2**128
1100 In [1]: %time 2**128
1100 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1101 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1101 Wall time: 0.00
1102 Wall time: 0.00
1102 Out[1]: 340282366920938463463374607431768211456L
1103 Out[1]: 340282366920938463463374607431768211456L
1103
1104
1104 In [2]: n = 1000000
1105 In [2]: n = 1000000
1105
1106
1106 In [3]: %time sum(range(n))
1107 In [3]: %time sum(range(n))
1107 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1108 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1108 Wall time: 1.37
1109 Wall time: 1.37
1109 Out[3]: 499999500000L
1110 Out[3]: 499999500000L
1110
1111
1111 In [4]: %time print 'hello world'
1112 In [4]: %time print 'hello world'
1112 hello world
1113 hello world
1113 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1114 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1114 Wall time: 0.00
1115 Wall time: 0.00
1115
1116
1116 Note that the time needed by Python to compile the given expression
1117 Note that the time needed by Python to compile the given expression
1117 will be reported if it is more than 0.1s. In this example, the
1118 will be reported if it is more than 0.1s. In this example, the
1118 actual exponentiation is done by Python at compilation time, so while
1119 actual exponentiation is done by Python at compilation time, so while
1119 the expression can take a noticeable amount of time to compute, that
1120 the expression can take a noticeable amount of time to compute, that
1120 time is purely due to the compilation:
1121 time is purely due to the compilation:
1121
1122
1122 In [5]: %time 3**9999;
1123 In [5]: %time 3**9999;
1123 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1124 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1124 Wall time: 0.00 s
1125 Wall time: 0.00 s
1125
1126
1126 In [6]: %time 3**999999;
1127 In [6]: %time 3**999999;
1127 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1128 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1128 Wall time: 0.00 s
1129 Wall time: 0.00 s
1129 Compiler : 0.78 s
1130 Compiler : 0.78 s
1130 """
1131 """
1131
1132
1132 # fail immediately if the given expression can't be compiled
1133 # fail immediately if the given expression can't be compiled
1133
1134
1134 if line and cell:
1135 if line and cell:
1135 raise UsageError("Can't use statement directly after '%%time'!")
1136 raise UsageError("Can't use statement directly after '%%time'!")
1136
1137
1137 if cell:
1138 if cell:
1138 expr = self.shell.input_transformer_manager.transform_cell(cell)
1139 expr = self.shell.input_transformer_manager.transform_cell(cell)
1139 else:
1140 else:
1140 expr = self.shell.input_transformer_manager.transform_cell(line)
1141 expr = self.shell.input_transformer_manager.transform_cell(line)
1141
1142
1142 # Minimum time above which parse time will be reported
1143 # Minimum time above which parse time will be reported
1143 tp_min = 0.1
1144 tp_min = 0.1
1144
1145
1145 t0 = clock()
1146 t0 = clock()
1146 expr_ast = self.shell.compile.ast_parse(expr)
1147 expr_ast = self.shell.compile.ast_parse(expr)
1147 tp = clock()-t0
1148 tp = clock()-t0
1148
1149
1149 # Apply AST transformations
1150 # Apply AST transformations
1150 expr_ast = self.shell.transform_ast(expr_ast)
1151 expr_ast = self.shell.transform_ast(expr_ast)
1151
1152
1152 # Minimum time above which compilation time will be reported
1153 # Minimum time above which compilation time will be reported
1153 tc_min = 0.1
1154 tc_min = 0.1
1154
1155
1155 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1156 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1156 mode = 'eval'
1157 mode = 'eval'
1157 source = '<timed eval>'
1158 source = '<timed eval>'
1158 expr_ast = ast.Expression(expr_ast.body[0].value)
1159 expr_ast = ast.Expression(expr_ast.body[0].value)
1159 else:
1160 else:
1160 mode = 'exec'
1161 mode = 'exec'
1161 source = '<timed exec>'
1162 source = '<timed exec>'
1162 t0 = clock()
1163 t0 = clock()
1163 code = self.shell.compile(expr_ast, source, mode)
1164 code = self.shell.compile(expr_ast, source, mode)
1164 tc = clock()-t0
1165 tc = clock()-t0
1165
1166
1166 # skew measurement as little as possible
1167 # skew measurement as little as possible
1167 glob = self.shell.user_ns
1168 glob = self.shell.user_ns
1168 wtime = time.time
1169 wtime = time.time
1169 # time execution
1170 # time execution
1170 wall_st = wtime()
1171 wall_st = wtime()
1171 if mode=='eval':
1172 if mode=='eval':
1172 st = clock2()
1173 st = clock2()
1173 out = eval(code, glob, local_ns)
1174 out = eval(code, glob, local_ns)
1174 end = clock2()
1175 end = clock2()
1175 else:
1176 else:
1176 st = clock2()
1177 st = clock2()
1177 exec(code, glob, local_ns)
1178 exec(code, glob, local_ns)
1178 end = clock2()
1179 end = clock2()
1179 out = None
1180 out = None
1180 wall_end = wtime()
1181 wall_end = wtime()
1181 # Compute actual times and report
1182 # Compute actual times and report
1182 wall_time = wall_end-wall_st
1183 wall_time = wall_end-wall_st
1183 cpu_user = end[0]-st[0]
1184 cpu_user = end[0]-st[0]
1184 cpu_sys = end[1]-st[1]
1185 cpu_sys = end[1]-st[1]
1185 cpu_tot = cpu_user+cpu_sys
1186 cpu_tot = cpu_user+cpu_sys
1186 # On windows cpu_sys is always zero, so no new information to the next print
1187 # On windows cpu_sys is always zero, so no new information to the next print
1187 if sys.platform != 'win32':
1188 if sys.platform != 'win32':
1188 print("CPU times: user %s, sys: %s, total: %s" % \
1189 print("CPU times: user %s, sys: %s, total: %s" % \
1189 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1190 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1190 print("Wall time: %s" % _format_time(wall_time))
1191 print("Wall time: %s" % _format_time(wall_time))
1191 if tc > tc_min:
1192 if tc > tc_min:
1192 print("Compiler : %s" % _format_time(tc))
1193 print("Compiler : %s" % _format_time(tc))
1193 if tp > tp_min:
1194 if tp > tp_min:
1194 print("Parser : %s" % _format_time(tp))
1195 print("Parser : %s" % _format_time(tp))
1195 return out
1196 return out
1196
1197
1197 @skip_doctest
1198 @skip_doctest
1198 @line_magic
1199 @line_magic
1199 def macro(self, parameter_s=''):
1200 def macro(self, parameter_s=''):
1200 """Define a macro for future re-execution. It accepts ranges of history,
1201 """Define a macro for future re-execution. It accepts ranges of history,
1201 filenames or string objects.
1202 filenames or string objects.
1202
1203
1203 Usage:\\
1204 Usage:\\
1204 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1205 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1205
1206
1206 Options:
1207 Options:
1207
1208
1208 -r: use 'raw' input. By default, the 'processed' history is used,
1209 -r: use 'raw' input. By default, the 'processed' history is used,
1209 so that magics are loaded in their transformed version to valid
1210 so that magics are loaded in their transformed version to valid
1210 Python. If this option is given, the raw input as typed at the
1211 Python. If this option is given, the raw input as typed at the
1211 command line is used instead.
1212 command line is used instead.
1212
1213
1213 -q: quiet macro definition. By default, a tag line is printed
1214 -q: quiet macro definition. By default, a tag line is printed
1214 to indicate the macro has been created, and then the contents of
1215 to indicate the macro has been created, and then the contents of
1215 the macro are printed. If this option is given, then no printout
1216 the macro are printed. If this option is given, then no printout
1216 is produced once the macro is created.
1217 is produced once the macro is created.
1217
1218
1218 This will define a global variable called `name` which is a string
1219 This will define a global variable called `name` which is a string
1219 made of joining the slices and lines you specify (n1,n2,... numbers
1220 made of joining the slices and lines you specify (n1,n2,... numbers
1220 above) from your input history into a single string. This variable
1221 above) from your input history into a single string. This variable
1221 acts like an automatic function which re-executes those lines as if
1222 acts like an automatic function which re-executes those lines as if
1222 you had typed them. You just type 'name' at the prompt and the code
1223 you had typed them. You just type 'name' at the prompt and the code
1223 executes.
1224 executes.
1224
1225
1225 The syntax for indicating input ranges is described in %history.
1226 The syntax for indicating input ranges is described in %history.
1226
1227
1227 Note: as a 'hidden' feature, you can also use traditional python slice
1228 Note: as a 'hidden' feature, you can also use traditional python slice
1228 notation, where N:M means numbers N through M-1.
1229 notation, where N:M means numbers N through M-1.
1229
1230
1230 For example, if your history contains (print using %hist -n )::
1231 For example, if your history contains (print using %hist -n )::
1231
1232
1232 44: x=1
1233 44: x=1
1233 45: y=3
1234 45: y=3
1234 46: z=x+y
1235 46: z=x+y
1235 47: print x
1236 47: print x
1236 48: a=5
1237 48: a=5
1237 49: print 'x',x,'y',y
1238 49: print 'x',x,'y',y
1238
1239
1239 you can create a macro with lines 44 through 47 (included) and line 49
1240 you can create a macro with lines 44 through 47 (included) and line 49
1240 called my_macro with::
1241 called my_macro with::
1241
1242
1242 In [55]: %macro my_macro 44-47 49
1243 In [55]: %macro my_macro 44-47 49
1243
1244
1244 Now, typing `my_macro` (without quotes) will re-execute all this code
1245 Now, typing `my_macro` (without quotes) will re-execute all this code
1245 in one pass.
1246 in one pass.
1246
1247
1247 You don't need to give the line-numbers in order, and any given line
1248 You don't need to give the line-numbers in order, and any given line
1248 number can appear multiple times. You can assemble macros with any
1249 number can appear multiple times. You can assemble macros with any
1249 lines from your input history in any order.
1250 lines from your input history in any order.
1250
1251
1251 The macro is a simple object which holds its value in an attribute,
1252 The macro is a simple object which holds its value in an attribute,
1252 but IPython's display system checks for macros and executes them as
1253 but IPython's display system checks for macros and executes them as
1253 code instead of printing them when you type their name.
1254 code instead of printing them when you type their name.
1254
1255
1255 You can view a macro's contents by explicitly printing it with::
1256 You can view a macro's contents by explicitly printing it with::
1256
1257
1257 print macro_name
1258 print macro_name
1258
1259
1259 """
1260 """
1260 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1261 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1261 if not args: # List existing macros
1262 if not args: # List existing macros
1262 return sorted(k for k,v in iteritems(self.shell.user_ns) if\
1263 return sorted(k for k,v in iteritems(self.shell.user_ns) if\
1263 isinstance(v, Macro))
1264 isinstance(v, Macro))
1264 if len(args) == 1:
1265 if len(args) == 1:
1265 raise UsageError(
1266 raise UsageError(
1266 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1267 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1267 name, codefrom = args[0], " ".join(args[1:])
1268 name, codefrom = args[0], " ".join(args[1:])
1268
1269
1269 #print 'rng',ranges # dbg
1270 #print 'rng',ranges # dbg
1270 try:
1271 try:
1271 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1272 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1272 except (ValueError, TypeError) as e:
1273 except (ValueError, TypeError) as e:
1273 print(e.args[0])
1274 print(e.args[0])
1274 return
1275 return
1275 macro = Macro(lines)
1276 macro = Macro(lines)
1276 self.shell.define_macro(name, macro)
1277 self.shell.define_macro(name, macro)
1277 if not ( 'q' in opts) :
1278 if not ( 'q' in opts) :
1278 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1279 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1279 print('=== Macro contents: ===')
1280 print('=== Macro contents: ===')
1280 print(macro, end=' ')
1281 print(macro, end=' ')
1281
1282
1282 @magic_arguments.magic_arguments()
1283 @magic_arguments.magic_arguments()
1283 @magic_arguments.argument('output', type=str, default='', nargs='?',
1284 @magic_arguments.argument('output', type=str, default='', nargs='?',
1284 help="""The name of the variable in which to store output.
1285 help="""The name of the variable in which to store output.
1285 This is a utils.io.CapturedIO object with stdout/err attributes
1286 This is a utils.io.CapturedIO object with stdout/err attributes
1286 for the text of the captured output.
1287 for the text of the captured output.
1287
1288
1288 CapturedOutput also has a show() method for displaying the output,
1289 CapturedOutput also has a show() method for displaying the output,
1289 and __call__ as well, so you can use that to quickly display the
1290 and __call__ as well, so you can use that to quickly display the
1290 output.
1291 output.
1291
1292
1292 If unspecified, captured output is discarded.
1293 If unspecified, captured output is discarded.
1293 """
1294 """
1294 )
1295 )
1295 @magic_arguments.argument('--no-stderr', action="store_true",
1296 @magic_arguments.argument('--no-stderr', action="store_true",
1296 help="""Don't capture stderr."""
1297 help="""Don't capture stderr."""
1297 )
1298 )
1298 @magic_arguments.argument('--no-stdout', action="store_true",
1299 @magic_arguments.argument('--no-stdout', action="store_true",
1299 help="""Don't capture stdout."""
1300 help="""Don't capture stdout."""
1300 )
1301 )
1301 @magic_arguments.argument('--no-display', action="store_true",
1302 @magic_arguments.argument('--no-display', action="store_true",
1302 help="""Don't capture IPython's rich display."""
1303 help="""Don't capture IPython's rich display."""
1303 )
1304 )
1304 @cell_magic
1305 @cell_magic
1305 def capture(self, line, cell):
1306 def capture(self, line, cell):
1306 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1307 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1307 args = magic_arguments.parse_argstring(self.capture, line)
1308 args = magic_arguments.parse_argstring(self.capture, line)
1308 out = not args.no_stdout
1309 out = not args.no_stdout
1309 err = not args.no_stderr
1310 err = not args.no_stderr
1310 disp = not args.no_display
1311 disp = not args.no_display
1311 with capture_output(out, err, disp) as io:
1312 with capture_output(out, err, disp) as io:
1312 self.shell.run_cell(cell)
1313 self.shell.run_cell(cell)
1313 if args.output:
1314 if args.output:
1314 self.shell.user_ns[args.output] = io
1315 self.shell.user_ns[args.output] = io
1315
1316
1316 def parse_breakpoint(text, current_file):
1317 def parse_breakpoint(text, current_file):
1317 '''Returns (file, line) for file:line and (current_file, line) for line'''
1318 '''Returns (file, line) for file:line and (current_file, line) for line'''
1318 colon = text.find(':')
1319 colon = text.find(':')
1319 if colon == -1:
1320 if colon == -1:
1320 return current_file, int(text)
1321 return current_file, int(text)
1321 else:
1322 else:
1322 return text[:colon], int(text[colon+1:])
1323 return text[:colon], int(text[colon+1:])
1323
1324
1324 def _format_time(timespan, precision=3):
1325 def _format_time(timespan, precision=3):
1325 """Formats the timespan in a human readable form"""
1326 """Formats the timespan in a human readable form"""
1326 import math
1327 import math
1327
1328
1328 if timespan >= 60.0:
1329 if timespan >= 60.0:
1329 # we have more than a minute, format that in a human readable form
1330 # we have more than a minute, format that in a human readable form
1330 # Idea from http://snipplr.com/view/5713/
1331 # Idea from http://snipplr.com/view/5713/
1331 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1332 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1332 time = []
1333 time = []
1333 leftover = timespan
1334 leftover = timespan
1334 for suffix, length in parts:
1335 for suffix, length in parts:
1335 value = int(leftover / length)
1336 value = int(leftover / length)
1336 if value > 0:
1337 if value > 0:
1337 leftover = leftover % length
1338 leftover = leftover % length
1338 time.append(u'%s%s' % (str(value), suffix))
1339 time.append(u'%s%s' % (str(value), suffix))
1339 if leftover < 1:
1340 if leftover < 1:
1340 break
1341 break
1341 return " ".join(time)
1342 return " ".join(time)
1342
1343
1343
1344
1344 # Unfortunately the unicode 'micro' symbol can cause problems in
1345 # Unfortunately the unicode 'micro' symbol can cause problems in
1345 # certain terminals.
1346 # certain terminals.
1346 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1347 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1347 # Try to prevent crashes by being more secure than it needs to
1348 # Try to prevent crashes by being more secure than it needs to
1348 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1349 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1349 units = [u"s", u"ms",u'us',"ns"] # the save value
1350 units = [u"s", u"ms",u'us',"ns"] # the save value
1350 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1351 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1351 try:
1352 try:
1352 u'\xb5'.encode(sys.stdout.encoding)
1353 u'\xb5'.encode(sys.stdout.encoding)
1353 units = [u"s", u"ms",u'\xb5s',"ns"]
1354 units = [u"s", u"ms",u'\xb5s',"ns"]
1354 except:
1355 except:
1355 pass
1356 pass
1356 scaling = [1, 1e3, 1e6, 1e9]
1357 scaling = [1, 1e3, 1e6, 1e9]
1357
1358
1358 if timespan > 0.0:
1359 if timespan > 0.0:
1359 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1360 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1360 else:
1361 else:
1361 order = 3
1362 order = 3
1362 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1363 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,184 +1,184 b''
1 """Implementation of magic functions for IPython's own logging.
1 """Implementation of magic functions for IPython's own logging.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The 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 # Stdlib
15 # Stdlib
16 import os
16 import os
17 import sys
17 import sys
18
18
19 # Our own packages
19 # Our own packages
20 from IPython.core.magic import Magics, magics_class, line_magic
20 from IPython.core.magic import Magics, magics_class, line_magic
21 from IPython.utils.warn import warn
21 from warnings import warn
22 from IPython.utils.py3compat import str_to_unicode
22 from IPython.utils.py3compat import str_to_unicode
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Magic implementation classes
25 # Magic implementation classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 @magics_class
28 @magics_class
29 class LoggingMagics(Magics):
29 class LoggingMagics(Magics):
30 """Magics related to all logging machinery."""
30 """Magics related to all logging machinery."""
31
31
32 @line_magic
32 @line_magic
33 def logstart(self, parameter_s=''):
33 def logstart(self, parameter_s=''):
34 """Start logging anywhere in a session.
34 """Start logging anywhere in a session.
35
35
36 %logstart [-o|-r|-t] [log_name [log_mode]]
36 %logstart [-o|-r|-t] [log_name [log_mode]]
37
37
38 If no name is given, it defaults to a file named 'ipython_log.py' in your
38 If no name is given, it defaults to a file named 'ipython_log.py' in your
39 current directory, in 'rotate' mode (see below).
39 current directory, in 'rotate' mode (see below).
40
40
41 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
41 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
42 history up to that point and then continues logging.
42 history up to that point and then continues logging.
43
43
44 %logstart takes a second optional parameter: logging mode. This can be one
44 %logstart takes a second optional parameter: logging mode. This can be one
45 of (note that the modes are given unquoted):
45 of (note that the modes are given unquoted):
46
46
47 append
47 append
48 Keep logging at the end of any existing file.
48 Keep logging at the end of any existing file.
49
49
50 backup
50 backup
51 Rename any existing file to name~ and start name.
51 Rename any existing file to name~ and start name.
52
52
53 global
53 global
54 Append to a single logfile in your home directory.
54 Append to a single logfile in your home directory.
55
55
56 over
56 over
57 Overwrite any existing log.
57 Overwrite any existing log.
58
58
59 rotate
59 rotate
60 Create rotating logs: name.1~, name.2~, etc.
60 Create rotating logs: name.1~, name.2~, etc.
61
61
62 Options:
62 Options:
63
63
64 -o
64 -o
65 log also IPython's output. In this mode, all commands which
65 log also IPython's output. In this mode, all commands which
66 generate an Out[NN] prompt are recorded to the logfile, right after
66 generate an Out[NN] prompt are recorded to the logfile, right after
67 their corresponding input line. The output lines are always
67 their corresponding input line. The output lines are always
68 prepended with a '#[Out]# ' marker, so that the log remains valid
68 prepended with a '#[Out]# ' marker, so that the log remains valid
69 Python code.
69 Python code.
70
70
71 Since this marker is always the same, filtering only the output from
71 Since this marker is always the same, filtering only the output from
72 a log is very easy, using for example a simple awk call::
72 a log is very easy, using for example a simple awk call::
73
73
74 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
74 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
75
75
76 -r
76 -r
77 log 'raw' input. Normally, IPython's logs contain the processed
77 log 'raw' input. Normally, IPython's logs contain the processed
78 input, so that user lines are logged in their final form, converted
78 input, so that user lines are logged in their final form, converted
79 into valid Python. For example, %Exit is logged as
79 into valid Python. For example, %Exit is logged as
80 _ip.magic("Exit"). If the -r flag is given, all input is logged
80 _ip.magic("Exit"). If the -r flag is given, all input is logged
81 exactly as typed, with no transformations applied.
81 exactly as typed, with no transformations applied.
82
82
83 -t
83 -t
84 put timestamps before each input line logged (these are put in
84 put timestamps before each input line logged (these are put in
85 comments).
85 comments).
86 """
86 """
87
87
88 opts,par = self.parse_options(parameter_s,'ort')
88 opts,par = self.parse_options(parameter_s,'ort')
89 log_output = 'o' in opts
89 log_output = 'o' in opts
90 log_raw_input = 'r' in opts
90 log_raw_input = 'r' in opts
91 timestamp = 't' in opts
91 timestamp = 't' in opts
92
92
93 logger = self.shell.logger
93 logger = self.shell.logger
94
94
95 # if no args are given, the defaults set in the logger constructor by
95 # if no args are given, the defaults set in the logger constructor by
96 # ipython remain valid
96 # ipython remain valid
97 if par:
97 if par:
98 try:
98 try:
99 logfname,logmode = par.split()
99 logfname,logmode = par.split()
100 except:
100 except:
101 logfname = par
101 logfname = par
102 logmode = 'backup'
102 logmode = 'backup'
103 else:
103 else:
104 logfname = logger.logfname
104 logfname = logger.logfname
105 logmode = logger.logmode
105 logmode = logger.logmode
106 # put logfname into rc struct as if it had been called on the command
106 # put logfname into rc struct as if it had been called on the command
107 # line, so it ends up saved in the log header Save it in case we need
107 # line, so it ends up saved in the log header Save it in case we need
108 # to restore it...
108 # to restore it...
109 old_logfile = self.shell.logfile
109 old_logfile = self.shell.logfile
110 if logfname:
110 if logfname:
111 logfname = os.path.expanduser(logfname)
111 logfname = os.path.expanduser(logfname)
112 self.shell.logfile = logfname
112 self.shell.logfile = logfname
113
113
114 loghead = u'# IPython log file\n\n'
114 loghead = u'# IPython log file\n\n'
115 try:
115 try:
116 logger.logstart(logfname, loghead, logmode, log_output, timestamp,
116 logger.logstart(logfname, loghead, logmode, log_output, timestamp,
117 log_raw_input)
117 log_raw_input)
118 except:
118 except:
119 self.shell.logfile = old_logfile
119 self.shell.logfile = old_logfile
120 warn("Couldn't start log: %s" % sys.exc_info()[1])
120 warn("Couldn't start log: %s" % sys.exc_info()[1])
121 else:
121 else:
122 # log input history up to this point, optionally interleaving
122 # log input history up to this point, optionally interleaving
123 # output if requested
123 # output if requested
124
124
125 if timestamp:
125 if timestamp:
126 # disable timestamping for the previous history, since we've
126 # disable timestamping for the previous history, since we've
127 # lost those already (no time machine here).
127 # lost those already (no time machine here).
128 logger.timestamp = False
128 logger.timestamp = False
129
129
130 if log_raw_input:
130 if log_raw_input:
131 input_hist = self.shell.history_manager.input_hist_raw
131 input_hist = self.shell.history_manager.input_hist_raw
132 else:
132 else:
133 input_hist = self.shell.history_manager.input_hist_parsed
133 input_hist = self.shell.history_manager.input_hist_parsed
134
134
135 if log_output:
135 if log_output:
136 log_write = logger.log_write
136 log_write = logger.log_write
137 output_hist = self.shell.history_manager.output_hist
137 output_hist = self.shell.history_manager.output_hist
138 for n in range(1,len(input_hist)-1):
138 for n in range(1,len(input_hist)-1):
139 log_write(input_hist[n].rstrip() + u'\n')
139 log_write(input_hist[n].rstrip() + u'\n')
140 if n in output_hist:
140 if n in output_hist:
141 log_write(str_to_unicode(repr(output_hist[n])),'output')
141 log_write(str_to_unicode(repr(output_hist[n])),'output')
142 else:
142 else:
143 logger.log_write(u'\n'.join(input_hist[1:]))
143 logger.log_write(u'\n'.join(input_hist[1:]))
144 logger.log_write(u'\n')
144 logger.log_write(u'\n')
145 if timestamp:
145 if timestamp:
146 # re-enable timestamping
146 # re-enable timestamping
147 logger.timestamp = True
147 logger.timestamp = True
148
148
149 print ('Activating auto-logging. '
149 print ('Activating auto-logging. '
150 'Current session state plus future input saved.')
150 'Current session state plus future input saved.')
151 logger.logstate()
151 logger.logstate()
152
152
153 @line_magic
153 @line_magic
154 def logstop(self, parameter_s=''):
154 def logstop(self, parameter_s=''):
155 """Fully stop logging and close log file.
155 """Fully stop logging and close log file.
156
156
157 In order to start logging again, a new %logstart call needs to be made,
157 In order to start logging again, a new %logstart call needs to be made,
158 possibly (though not necessarily) with a new filename, mode and other
158 possibly (though not necessarily) with a new filename, mode and other
159 options."""
159 options."""
160 self.shell.logger.logstop()
160 self.shell.logger.logstop()
161
161
162 @line_magic
162 @line_magic
163 def logoff(self, parameter_s=''):
163 def logoff(self, parameter_s=''):
164 """Temporarily stop logging.
164 """Temporarily stop logging.
165
165
166 You must have previously started logging."""
166 You must have previously started logging."""
167 self.shell.logger.switch_log(0)
167 self.shell.logger.switch_log(0)
168
168
169 @line_magic
169 @line_magic
170 def logon(self, parameter_s=''):
170 def logon(self, parameter_s=''):
171 """Restart logging.
171 """Restart logging.
172
172
173 This function is for restarting logging which you've temporarily
173 This function is for restarting logging which you've temporarily
174 stopped with %logoff. For starting logging for the first time, you
174 stopped with %logoff. For starting logging for the first time, you
175 must use the %logstart function, which allows you to specify an
175 must use the %logstart function, which allows you to specify an
176 optional log filename."""
176 optional log filename."""
177
177
178 self.shell.logger.switch_log(1)
178 self.shell.logger.switch_log(1)
179
179
180 @line_magic
180 @line_magic
181 def logstate(self, parameter_s=''):
181 def logstate(self, parameter_s=''):
182 """Print the status of the logging system."""
182 """Print the status of the logging system."""
183
183
184 self.shell.logger.logstate()
184 self.shell.logger.logstate()
@@ -1,167 +1,167 b''
1 """Implementation of magic functions for matplotlib/pylab support.
1 """Implementation of magic functions for matplotlib/pylab support.
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 # Our own packages
16 # Our own packages
17 from traitlets.config.application import Application
17 from traitlets.config.application import Application
18 from IPython.core import magic_arguments
18 from IPython.core import magic_arguments
19 from IPython.core.magic import Magics, magics_class, line_magic
19 from IPython.core.magic import Magics, magics_class, line_magic
20 from IPython.testing.skipdoctest import skip_doctest
20 from IPython.testing.skipdoctest import skip_doctest
21 from IPython.utils.warn import warn
21 from warnings import warn
22 from IPython.core.pylabtools import backends
22 from IPython.core.pylabtools import backends
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Magic implementation classes
25 # Magic implementation classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 magic_gui_arg = magic_arguments.argument(
28 magic_gui_arg = magic_arguments.argument(
29 'gui', nargs='?',
29 'gui', nargs='?',
30 help="""Name of the matplotlib backend to use %s.
30 help="""Name of the matplotlib backend to use %s.
31 If given, the corresponding matplotlib backend is used,
31 If given, the corresponding matplotlib backend is used,
32 otherwise it will be matplotlib's default
32 otherwise it will be matplotlib's default
33 (which you can set in your matplotlib config file).
33 (which you can set in your matplotlib config file).
34 """ % str(tuple(sorted(backends.keys())))
34 """ % str(tuple(sorted(backends.keys())))
35 )
35 )
36
36
37
37
38 @magics_class
38 @magics_class
39 class PylabMagics(Magics):
39 class PylabMagics(Magics):
40 """Magics related to matplotlib's pylab support"""
40 """Magics related to matplotlib's pylab support"""
41
41
42 @skip_doctest
42 @skip_doctest
43 @line_magic
43 @line_magic
44 @magic_arguments.magic_arguments()
44 @magic_arguments.magic_arguments()
45 @magic_arguments.argument('-l', '--list', action='store_true',
45 @magic_arguments.argument('-l', '--list', action='store_true',
46 help='Show available matplotlib backends')
46 help='Show available matplotlib backends')
47 @magic_gui_arg
47 @magic_gui_arg
48 def matplotlib(self, line=''):
48 def matplotlib(self, line=''):
49 """Set up matplotlib to work interactively.
49 """Set up matplotlib to work interactively.
50
50
51 This function lets you activate matplotlib interactive support
51 This function lets you activate matplotlib interactive support
52 at any point during an IPython session. It does not import anything
52 at any point during an IPython session. It does not import anything
53 into the interactive namespace.
53 into the interactive namespace.
54
54
55 If you are using the inline matplotlib backend in the IPython Notebook
55 If you are using the inline matplotlib backend in the IPython Notebook
56 you can set which figure formats are enabled using the following::
56 you can set which figure formats are enabled using the following::
57
57
58 In [1]: from IPython.display import set_matplotlib_formats
58 In [1]: from IPython.display import set_matplotlib_formats
59
59
60 In [2]: set_matplotlib_formats('pdf', 'svg')
60 In [2]: set_matplotlib_formats('pdf', 'svg')
61
61
62 The default for inline figures sets `bbox_inches` to 'tight'. This can
62 The default for inline figures sets `bbox_inches` to 'tight'. This can
63 cause discrepancies between the displayed image and the identical
63 cause discrepancies between the displayed image and the identical
64 image created using `savefig`. This behavior can be disabled using the
64 image created using `savefig`. This behavior can be disabled using the
65 `%config` magic::
65 `%config` magic::
66
66
67 In [3]: %config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
67 In [3]: %config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
68
68
69 In addition, see the docstring of
69 In addition, see the docstring of
70 `IPython.display.set_matplotlib_formats` and
70 `IPython.display.set_matplotlib_formats` and
71 `IPython.display.set_matplotlib_close` for more information on
71 `IPython.display.set_matplotlib_close` for more information on
72 changing additional behaviors of the inline backend.
72 changing additional behaviors of the inline backend.
73
73
74 Examples
74 Examples
75 --------
75 --------
76 To enable the inline backend for usage with the IPython Notebook::
76 To enable the inline backend for usage with the IPython Notebook::
77
77
78 In [1]: %matplotlib inline
78 In [1]: %matplotlib inline
79
79
80 In this case, where the matplotlib default is TkAgg::
80 In this case, where the matplotlib default is TkAgg::
81
81
82 In [2]: %matplotlib
82 In [2]: %matplotlib
83 Using matplotlib backend: TkAgg
83 Using matplotlib backend: TkAgg
84
84
85 But you can explicitly request a different GUI backend::
85 But you can explicitly request a different GUI backend::
86
86
87 In [3]: %matplotlib qt
87 In [3]: %matplotlib qt
88
88
89 You can list the available backends using the -l/--list option::
89 You can list the available backends using the -l/--list option::
90
90
91 In [4]: %matplotlib --list
91 In [4]: %matplotlib --list
92 Available matplotlib backends: ['osx', 'qt4', 'qt5', 'gtk3', 'notebook', 'wx', 'qt', 'nbagg',
92 Available matplotlib backends: ['osx', 'qt4', 'qt5', 'gtk3', 'notebook', 'wx', 'qt', 'nbagg',
93 'gtk', 'tk', 'inline']
93 'gtk', 'tk', 'inline']
94 """
94 """
95 args = magic_arguments.parse_argstring(self.matplotlib, line)
95 args = magic_arguments.parse_argstring(self.matplotlib, line)
96 if args.list:
96 if args.list:
97 backends_list = list(backends.keys())
97 backends_list = list(backends.keys())
98 print("Available matplotlib backends: %s" % backends_list)
98 print("Available matplotlib backends: %s" % backends_list)
99 else:
99 else:
100 gui, backend = self.shell.enable_matplotlib(args.gui)
100 gui, backend = self.shell.enable_matplotlib(args.gui)
101 self._show_matplotlib_backend(args.gui, backend)
101 self._show_matplotlib_backend(args.gui, backend)
102
102
103 @skip_doctest
103 @skip_doctest
104 @line_magic
104 @line_magic
105 @magic_arguments.magic_arguments()
105 @magic_arguments.magic_arguments()
106 @magic_arguments.argument(
106 @magic_arguments.argument(
107 '--no-import-all', action='store_true', default=None,
107 '--no-import-all', action='store_true', default=None,
108 help="""Prevent IPython from performing ``import *`` into the interactive namespace.
108 help="""Prevent IPython from performing ``import *`` into the interactive namespace.
109
109
110 You can govern the default behavior of this flag with the
110 You can govern the default behavior of this flag with the
111 InteractiveShellApp.pylab_import_all configurable.
111 InteractiveShellApp.pylab_import_all configurable.
112 """
112 """
113 )
113 )
114 @magic_gui_arg
114 @magic_gui_arg
115 def pylab(self, line=''):
115 def pylab(self, line=''):
116 """Load numpy and matplotlib to work interactively.
116 """Load numpy and matplotlib to work interactively.
117
117
118 This function lets you activate pylab (matplotlib, numpy and
118 This function lets you activate pylab (matplotlib, numpy and
119 interactive support) at any point during an IPython session.
119 interactive support) at any point during an IPython session.
120
120
121 %pylab makes the following imports::
121 %pylab makes the following imports::
122
122
123 import numpy
123 import numpy
124 import matplotlib
124 import matplotlib
125 from matplotlib import pylab, mlab, pyplot
125 from matplotlib import pylab, mlab, pyplot
126 np = numpy
126 np = numpy
127 plt = pyplot
127 plt = pyplot
128
128
129 from IPython.display import display
129 from IPython.display import display
130 from IPython.core.pylabtools import figsize, getfigs
130 from IPython.core.pylabtools import figsize, getfigs
131
131
132 from pylab import *
132 from pylab import *
133 from numpy import *
133 from numpy import *
134
134
135 If you pass `--no-import-all`, the last two `*` imports will be excluded.
135 If you pass `--no-import-all`, the last two `*` imports will be excluded.
136
136
137 See the %matplotlib magic for more details about activating matplotlib
137 See the %matplotlib magic for more details about activating matplotlib
138 without affecting the interactive namespace.
138 without affecting the interactive namespace.
139 """
139 """
140 args = magic_arguments.parse_argstring(self.pylab, line)
140 args = magic_arguments.parse_argstring(self.pylab, line)
141 if args.no_import_all is None:
141 if args.no_import_all is None:
142 # get default from Application
142 # get default from Application
143 if Application.initialized():
143 if Application.initialized():
144 app = Application.instance()
144 app = Application.instance()
145 try:
145 try:
146 import_all = app.pylab_import_all
146 import_all = app.pylab_import_all
147 except AttributeError:
147 except AttributeError:
148 import_all = True
148 import_all = True
149 else:
149 else:
150 # nothing specified, no app - default True
150 # nothing specified, no app - default True
151 import_all = True
151 import_all = True
152 else:
152 else:
153 # invert no-import flag
153 # invert no-import flag
154 import_all = not args.no_import_all
154 import_all = not args.no_import_all
155
155
156 gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all)
156 gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all)
157 self._show_matplotlib_backend(args.gui, backend)
157 self._show_matplotlib_backend(args.gui, backend)
158 print ("Populating the interactive namespace from numpy and matplotlib")
158 print ("Populating the interactive namespace from numpy and matplotlib")
159 if clobbered:
159 if clobbered:
160 warn("pylab import has clobbered these variables: %s" % clobbered +
160 warn("pylab import has clobbered these variables: %s" % clobbered +
161 "\n`%matplotlib` prevents importing * from pylab and numpy"
161 "\n`%matplotlib` prevents importing * from pylab and numpy"
162 )
162 )
163
163
164 def _show_matplotlib_backend(self, gui, backend):
164 def _show_matplotlib_backend(self, gui, backend):
165 """show matplotlib message backend message"""
165 """show matplotlib message backend message"""
166 if not gui or gui == 'auto':
166 if not gui or gui == 'auto':
167 print("Using matplotlib backend: %s" % backend)
167 print("Using matplotlib backend: %s" % backend)
@@ -1,1471 +1,1471 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Verbose and colourful traceback formatting.
3 Verbose and colourful traceback formatting.
4
4
5 **ColorTB**
5 **ColorTB**
6
6
7 I've always found it a bit hard to visually parse tracebacks in Python. The
7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 ColorTB class is a solution to that problem. It colors the different parts of a
8 ColorTB class is a solution to that problem. It colors the different parts of a
9 traceback in a manner similar to what you would expect from a syntax-highlighting
9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 text editor.
10 text editor.
11
11
12 Installation instructions for ColorTB::
12 Installation instructions for ColorTB::
13
13
14 import sys,ultratb
14 import sys,ultratb
15 sys.excepthook = ultratb.ColorTB()
15 sys.excepthook = ultratb.ColorTB()
16
16
17 **VerboseTB**
17 **VerboseTB**
18
18
19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 of useful info when a traceback occurs. Ping originally had it spit out HTML
20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 and intended it for CGI programmers, but why should they have all the fun? I
21 and intended it for CGI programmers, but why should they have all the fun? I
22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 but kind of neat, and maybe useful for long-running programs that you believe
23 but kind of neat, and maybe useful for long-running programs that you believe
24 are bug-free. If a crash *does* occur in that type of program you want details.
24 are bug-free. If a crash *does* occur in that type of program you want details.
25 Give it a shot--you'll love it or you'll hate it.
25 Give it a shot--you'll love it or you'll hate it.
26
26
27 .. note::
27 .. note::
28
28
29 The Verbose mode prints the variables currently visible where the exception
29 The Verbose mode prints the variables currently visible where the exception
30 happened (shortening their strings if too long). This can potentially be
30 happened (shortening their strings if too long). This can potentially be
31 very slow, if you happen to have a huge data structure whose string
31 very slow, if you happen to have a huge data structure whose string
32 representation is complex to compute. Your computer may appear to freeze for
32 representation is complex to compute. Your computer may appear to freeze for
33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 with Ctrl-C (maybe hitting it more than once).
34 with Ctrl-C (maybe hitting it more than once).
35
35
36 If you encounter this kind of situation often, you may want to use the
36 If you encounter this kind of situation often, you may want to use the
37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 variables (but otherwise includes the information and context given by
38 variables (but otherwise includes the information and context given by
39 Verbose).
39 Verbose).
40
40
41
41
42 Installation instructions for VerboseTB::
42 Installation instructions for VerboseTB::
43
43
44 import sys,ultratb
44 import sys,ultratb
45 sys.excepthook = ultratb.VerboseTB()
45 sys.excepthook = ultratb.VerboseTB()
46
46
47 Note: Much of the code in this module was lifted verbatim from the standard
47 Note: Much of the code in this module was lifted verbatim from the standard
48 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
48 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
49
49
50 Color schemes
50 Color schemes
51 -------------
51 -------------
52
52
53 The colors are defined in the class TBTools through the use of the
53 The colors are defined in the class TBTools through the use of the
54 ColorSchemeTable class. Currently the following exist:
54 ColorSchemeTable class. Currently the following exist:
55
55
56 - NoColor: allows all of this module to be used in any terminal (the color
56 - NoColor: allows all of this module to be used in any terminal (the color
57 escapes are just dummy blank strings).
57 escapes are just dummy blank strings).
58
58
59 - Linux: is meant to look good in a terminal like the Linux console (black
59 - Linux: is meant to look good in a terminal like the Linux console (black
60 or very dark background).
60 or very dark background).
61
61
62 - LightBG: similar to Linux but swaps dark/light colors to be more readable
62 - LightBG: similar to Linux but swaps dark/light colors to be more readable
63 in light background terminals.
63 in light background terminals.
64
64
65 You can implement other color schemes easily, the syntax is fairly
65 You can implement other color schemes easily, the syntax is fairly
66 self-explanatory. Please send back new schemes you develop to the author for
66 self-explanatory. Please send back new schemes you develop to the author for
67 possible inclusion in future releases.
67 possible inclusion in future releases.
68
68
69 Inheritance diagram:
69 Inheritance diagram:
70
70
71 .. inheritance-diagram:: IPython.core.ultratb
71 .. inheritance-diagram:: IPython.core.ultratb
72 :parts: 3
72 :parts: 3
73 """
73 """
74
74
75 #*****************************************************************************
75 #*****************************************************************************
76 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
76 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
77 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
77 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
78 #
78 #
79 # Distributed under the terms of the BSD License. The full license is in
79 # Distributed under the terms of the BSD License. The full license is in
80 # the file COPYING, distributed as part of this software.
80 # the file COPYING, distributed as part of this software.
81 #*****************************************************************************
81 #*****************************************************************************
82
82
83 from __future__ import unicode_literals
83 from __future__ import unicode_literals
84 from __future__ import print_function
84 from __future__ import print_function
85
85
86 import dis
86 import dis
87 import inspect
87 import inspect
88 import keyword
88 import keyword
89 import linecache
89 import linecache
90 import os
90 import os
91 import pydoc
91 import pydoc
92 import re
92 import re
93 import sys
93 import sys
94 import time
94 import time
95 import tokenize
95 import tokenize
96 import traceback
96 import traceback
97 import types
97 import types
98
98
99 try: # Python 2
99 try: # Python 2
100 generate_tokens = tokenize.generate_tokens
100 generate_tokens = tokenize.generate_tokens
101 except AttributeError: # Python 3
101 except AttributeError: # Python 3
102 generate_tokens = tokenize.tokenize
102 generate_tokens = tokenize.tokenize
103
103
104 # For purposes of monkeypatching inspect to fix a bug in it.
104 # For purposes of monkeypatching inspect to fix a bug in it.
105 from inspect import getsourcefile, getfile, getmodule, \
105 from inspect import getsourcefile, getfile, getmodule, \
106 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
106 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
107
107
108 # IPython's own modules
108 # IPython's own modules
109 # Modified pdb which doesn't damage IPython's readline handling
109 # Modified pdb which doesn't damage IPython's readline handling
110 from IPython import get_ipython
110 from IPython import get_ipython
111 from IPython.core import debugger
111 from IPython.core import debugger
112 from IPython.core.display_trap import DisplayTrap
112 from IPython.core.display_trap import DisplayTrap
113 from IPython.core.excolors import exception_colors
113 from IPython.core.excolors import exception_colors
114 from IPython.utils import PyColorize
114 from IPython.utils import PyColorize
115 from IPython.utils import io
115 from IPython.utils import io
116 from IPython.utils import openpy
116 from IPython.utils import openpy
117 from IPython.utils import path as util_path
117 from IPython.utils import path as util_path
118 from IPython.utils import py3compat
118 from IPython.utils import py3compat
119 from IPython.utils import ulinecache
119 from IPython.utils import ulinecache
120 from IPython.utils.data import uniq_stable
120 from IPython.utils.data import uniq_stable
121 from IPython.utils.warn import info, error
121 from logging import info, error
122
122
123 # Globals
123 # Globals
124 # amount of space to put line numbers before verbose tracebacks
124 # amount of space to put line numbers before verbose tracebacks
125 INDENT_SIZE = 8
125 INDENT_SIZE = 8
126
126
127 # Default color scheme. This is used, for example, by the traceback
127 # Default color scheme. This is used, for example, by the traceback
128 # formatter. When running in an actual IPython instance, the user's rc.colors
128 # formatter. When running in an actual IPython instance, the user's rc.colors
129 # value is used, but having a module global makes this functionality available
129 # value is used, but having a module global makes this functionality available
130 # to users of ultratb who are NOT running inside ipython.
130 # to users of ultratb who are NOT running inside ipython.
131 DEFAULT_SCHEME = 'NoColor'
131 DEFAULT_SCHEME = 'NoColor'
132
132
133 # ---------------------------------------------------------------------------
133 # ---------------------------------------------------------------------------
134 # Code begins
134 # Code begins
135
135
136 # Utility functions
136 # Utility functions
137 def inspect_error():
137 def inspect_error():
138 """Print a message about internal inspect errors.
138 """Print a message about internal inspect errors.
139
139
140 These are unfortunately quite common."""
140 These are unfortunately quite common."""
141
141
142 error('Internal Python error in the inspect module.\n'
142 error('Internal Python error in the inspect module.\n'
143 'Below is the traceback from this internal error.\n')
143 'Below is the traceback from this internal error.\n')
144
144
145
145
146 # This function is a monkeypatch we apply to the Python inspect module. We have
146 # This function is a monkeypatch we apply to the Python inspect module. We have
147 # now found when it's needed (see discussion on issue gh-1456), and we have a
147 # now found when it's needed (see discussion on issue gh-1456), and we have a
148 # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
148 # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
149 # the monkeypatch is not applied. TK, Aug 2012.
149 # the monkeypatch is not applied. TK, Aug 2012.
150 def findsource(object):
150 def findsource(object):
151 """Return the entire source file and starting line number for an object.
151 """Return the entire source file and starting line number for an object.
152
152
153 The argument may be a module, class, method, function, traceback, frame,
153 The argument may be a module, class, method, function, traceback, frame,
154 or code object. The source code is returned as a list of all the lines
154 or code object. The source code is returned as a list of all the lines
155 in the file and the line number indexes a line in that list. An IOError
155 in the file and the line number indexes a line in that list. An IOError
156 is raised if the source code cannot be retrieved.
156 is raised if the source code cannot be retrieved.
157
157
158 FIXED version with which we monkeypatch the stdlib to work around a bug."""
158 FIXED version with which we monkeypatch the stdlib to work around a bug."""
159
159
160 file = getsourcefile(object) or getfile(object)
160 file = getsourcefile(object) or getfile(object)
161 # If the object is a frame, then trying to get the globals dict from its
161 # If the object is a frame, then trying to get the globals dict from its
162 # module won't work. Instead, the frame object itself has the globals
162 # module won't work. Instead, the frame object itself has the globals
163 # dictionary.
163 # dictionary.
164 globals_dict = None
164 globals_dict = None
165 if inspect.isframe(object):
165 if inspect.isframe(object):
166 # XXX: can this ever be false?
166 # XXX: can this ever be false?
167 globals_dict = object.f_globals
167 globals_dict = object.f_globals
168 else:
168 else:
169 module = getmodule(object, file)
169 module = getmodule(object, file)
170 if module:
170 if module:
171 globals_dict = module.__dict__
171 globals_dict = module.__dict__
172 lines = linecache.getlines(file, globals_dict)
172 lines = linecache.getlines(file, globals_dict)
173 if not lines:
173 if not lines:
174 raise IOError('could not get source code')
174 raise IOError('could not get source code')
175
175
176 if ismodule(object):
176 if ismodule(object):
177 return lines, 0
177 return lines, 0
178
178
179 if isclass(object):
179 if isclass(object):
180 name = object.__name__
180 name = object.__name__
181 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
181 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
182 # make some effort to find the best matching class definition:
182 # make some effort to find the best matching class definition:
183 # use the one with the least indentation, which is the one
183 # use the one with the least indentation, which is the one
184 # that's most probably not inside a function definition.
184 # that's most probably not inside a function definition.
185 candidates = []
185 candidates = []
186 for i in range(len(lines)):
186 for i in range(len(lines)):
187 match = pat.match(lines[i])
187 match = pat.match(lines[i])
188 if match:
188 if match:
189 # if it's at toplevel, it's already the best one
189 # if it's at toplevel, it's already the best one
190 if lines[i][0] == 'c':
190 if lines[i][0] == 'c':
191 return lines, i
191 return lines, i
192 # else add whitespace to candidate list
192 # else add whitespace to candidate list
193 candidates.append((match.group(1), i))
193 candidates.append((match.group(1), i))
194 if candidates:
194 if candidates:
195 # this will sort by whitespace, and by line number,
195 # this will sort by whitespace, and by line number,
196 # less whitespace first
196 # less whitespace first
197 candidates.sort()
197 candidates.sort()
198 return lines, candidates[0][1]
198 return lines, candidates[0][1]
199 else:
199 else:
200 raise IOError('could not find class definition')
200 raise IOError('could not find class definition')
201
201
202 if ismethod(object):
202 if ismethod(object):
203 object = object.__func__
203 object = object.__func__
204 if isfunction(object):
204 if isfunction(object):
205 object = object.__code__
205 object = object.__code__
206 if istraceback(object):
206 if istraceback(object):
207 object = object.tb_frame
207 object = object.tb_frame
208 if isframe(object):
208 if isframe(object):
209 object = object.f_code
209 object = object.f_code
210 if iscode(object):
210 if iscode(object):
211 if not hasattr(object, 'co_firstlineno'):
211 if not hasattr(object, 'co_firstlineno'):
212 raise IOError('could not find function definition')
212 raise IOError('could not find function definition')
213 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
213 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
214 pmatch = pat.match
214 pmatch = pat.match
215 # fperez - fix: sometimes, co_firstlineno can give a number larger than
215 # fperez - fix: sometimes, co_firstlineno can give a number larger than
216 # the length of lines, which causes an error. Safeguard against that.
216 # the length of lines, which causes an error. Safeguard against that.
217 lnum = min(object.co_firstlineno, len(lines)) - 1
217 lnum = min(object.co_firstlineno, len(lines)) - 1
218 while lnum > 0:
218 while lnum > 0:
219 if pmatch(lines[lnum]): break
219 if pmatch(lines[lnum]): break
220 lnum -= 1
220 lnum -= 1
221
221
222 return lines, lnum
222 return lines, lnum
223 raise IOError('could not find code object')
223 raise IOError('could not find code object')
224
224
225
225
226 # This is a patched version of inspect.getargs that applies the (unmerged)
226 # This is a patched version of inspect.getargs that applies the (unmerged)
227 # patch for http://bugs.python.org/issue14611 by Stefano Taschini. This fixes
227 # patch for http://bugs.python.org/issue14611 by Stefano Taschini. This fixes
228 # https://github.com/ipython/ipython/issues/8205 and
228 # https://github.com/ipython/ipython/issues/8205 and
229 # https://github.com/ipython/ipython/issues/8293
229 # https://github.com/ipython/ipython/issues/8293
230 def getargs(co):
230 def getargs(co):
231 """Get information about the arguments accepted by a code object.
231 """Get information about the arguments accepted by a code object.
232
232
233 Three things are returned: (args, varargs, varkw), where 'args' is
233 Three things are returned: (args, varargs, varkw), where 'args' is
234 a list of argument names (possibly containing nested lists), and
234 a list of argument names (possibly containing nested lists), and
235 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
235 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
236 if not iscode(co):
236 if not iscode(co):
237 raise TypeError('{!r} is not a code object'.format(co))
237 raise TypeError('{!r} is not a code object'.format(co))
238
238
239 nargs = co.co_argcount
239 nargs = co.co_argcount
240 names = co.co_varnames
240 names = co.co_varnames
241 args = list(names[:nargs])
241 args = list(names[:nargs])
242 step = 0
242 step = 0
243
243
244 # The following acrobatics are for anonymous (tuple) arguments.
244 # The following acrobatics are for anonymous (tuple) arguments.
245 for i in range(nargs):
245 for i in range(nargs):
246 if args[i][:1] in ('', '.'):
246 if args[i][:1] in ('', '.'):
247 stack, remain, count = [], [], []
247 stack, remain, count = [], [], []
248 while step < len(co.co_code):
248 while step < len(co.co_code):
249 op = ord(co.co_code[step])
249 op = ord(co.co_code[step])
250 step = step + 1
250 step = step + 1
251 if op >= dis.HAVE_ARGUMENT:
251 if op >= dis.HAVE_ARGUMENT:
252 opname = dis.opname[op]
252 opname = dis.opname[op]
253 value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
253 value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
254 step = step + 2
254 step = step + 2
255 if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
255 if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
256 remain.append(value)
256 remain.append(value)
257 count.append(value)
257 count.append(value)
258 elif opname in ('STORE_FAST', 'STORE_DEREF'):
258 elif opname in ('STORE_FAST', 'STORE_DEREF'):
259 if op in dis.haslocal:
259 if op in dis.haslocal:
260 stack.append(co.co_varnames[value])
260 stack.append(co.co_varnames[value])
261 elif op in dis.hasfree:
261 elif op in dis.hasfree:
262 stack.append((co.co_cellvars + co.co_freevars)[value])
262 stack.append((co.co_cellvars + co.co_freevars)[value])
263 # Special case for sublists of length 1: def foo((bar))
263 # Special case for sublists of length 1: def foo((bar))
264 # doesn't generate the UNPACK_TUPLE bytecode, so if
264 # doesn't generate the UNPACK_TUPLE bytecode, so if
265 # `remain` is empty here, we have such a sublist.
265 # `remain` is empty here, we have such a sublist.
266 if not remain:
266 if not remain:
267 stack[0] = [stack[0]]
267 stack[0] = [stack[0]]
268 break
268 break
269 else:
269 else:
270 remain[-1] = remain[-1] - 1
270 remain[-1] = remain[-1] - 1
271 while remain[-1] == 0:
271 while remain[-1] == 0:
272 remain.pop()
272 remain.pop()
273 size = count.pop()
273 size = count.pop()
274 stack[-size:] = [stack[-size:]]
274 stack[-size:] = [stack[-size:]]
275 if not remain: break
275 if not remain: break
276 remain[-1] = remain[-1] - 1
276 remain[-1] = remain[-1] - 1
277 if not remain: break
277 if not remain: break
278 args[i] = stack[0]
278 args[i] = stack[0]
279
279
280 varargs = None
280 varargs = None
281 if co.co_flags & inspect.CO_VARARGS:
281 if co.co_flags & inspect.CO_VARARGS:
282 varargs = co.co_varnames[nargs]
282 varargs = co.co_varnames[nargs]
283 nargs = nargs + 1
283 nargs = nargs + 1
284 varkw = None
284 varkw = None
285 if co.co_flags & inspect.CO_VARKEYWORDS:
285 if co.co_flags & inspect.CO_VARKEYWORDS:
286 varkw = co.co_varnames[nargs]
286 varkw = co.co_varnames[nargs]
287 return inspect.Arguments(args, varargs, varkw)
287 return inspect.Arguments(args, varargs, varkw)
288
288
289
289
290 # Monkeypatch inspect to apply our bugfix.
290 # Monkeypatch inspect to apply our bugfix.
291 def with_patch_inspect(f):
291 def with_patch_inspect(f):
292 """decorator for monkeypatching inspect.findsource"""
292 """decorator for monkeypatching inspect.findsource"""
293
293
294 def wrapped(*args, **kwargs):
294 def wrapped(*args, **kwargs):
295 save_findsource = inspect.findsource
295 save_findsource = inspect.findsource
296 save_getargs = inspect.getargs
296 save_getargs = inspect.getargs
297 inspect.findsource = findsource
297 inspect.findsource = findsource
298 inspect.getargs = getargs
298 inspect.getargs = getargs
299 try:
299 try:
300 return f(*args, **kwargs)
300 return f(*args, **kwargs)
301 finally:
301 finally:
302 inspect.findsource = save_findsource
302 inspect.findsource = save_findsource
303 inspect.getargs = save_getargs
303 inspect.getargs = save_getargs
304
304
305 return wrapped
305 return wrapped
306
306
307
307
308 if py3compat.PY3:
308 if py3compat.PY3:
309 fixed_getargvalues = inspect.getargvalues
309 fixed_getargvalues = inspect.getargvalues
310 else:
310 else:
311 # Fixes for https://github.com/ipython/ipython/issues/8293
311 # Fixes for https://github.com/ipython/ipython/issues/8293
312 # and https://github.com/ipython/ipython/issues/8205.
312 # and https://github.com/ipython/ipython/issues/8205.
313 # The relevant bug is caused by failure to correctly handle anonymous tuple
313 # The relevant bug is caused by failure to correctly handle anonymous tuple
314 # unpacking, which only exists in Python 2.
314 # unpacking, which only exists in Python 2.
315 fixed_getargvalues = with_patch_inspect(inspect.getargvalues)
315 fixed_getargvalues = with_patch_inspect(inspect.getargvalues)
316
316
317
317
318 def fix_frame_records_filenames(records):
318 def fix_frame_records_filenames(records):
319 """Try to fix the filenames in each record from inspect.getinnerframes().
319 """Try to fix the filenames in each record from inspect.getinnerframes().
320
320
321 Particularly, modules loaded from within zip files have useless filenames
321 Particularly, modules loaded from within zip files have useless filenames
322 attached to their code object, and inspect.getinnerframes() just uses it.
322 attached to their code object, and inspect.getinnerframes() just uses it.
323 """
323 """
324 fixed_records = []
324 fixed_records = []
325 for frame, filename, line_no, func_name, lines, index in records:
325 for frame, filename, line_no, func_name, lines, index in records:
326 # Look inside the frame's globals dictionary for __file__,
326 # Look inside the frame's globals dictionary for __file__,
327 # which should be better. However, keep Cython filenames since
327 # which should be better. However, keep Cython filenames since
328 # we prefer the source filenames over the compiled .so file.
328 # we prefer the source filenames over the compiled .so file.
329 filename = py3compat.cast_unicode_py2(filename, "utf-8")
329 filename = py3compat.cast_unicode_py2(filename, "utf-8")
330 if not filename.endswith(('.pyx', '.pxd', '.pxi')):
330 if not filename.endswith(('.pyx', '.pxd', '.pxi')):
331 better_fn = frame.f_globals.get('__file__', None)
331 better_fn = frame.f_globals.get('__file__', None)
332 if isinstance(better_fn, str):
332 if isinstance(better_fn, str):
333 # Check the type just in case someone did something weird with
333 # Check the type just in case someone did something weird with
334 # __file__. It might also be None if the error occurred during
334 # __file__. It might also be None if the error occurred during
335 # import.
335 # import.
336 filename = better_fn
336 filename = better_fn
337 fixed_records.append((frame, filename, line_no, func_name, lines, index))
337 fixed_records.append((frame, filename, line_no, func_name, lines, index))
338 return fixed_records
338 return fixed_records
339
339
340
340
341 @with_patch_inspect
341 @with_patch_inspect
342 def _fixed_getinnerframes(etb, context=1, tb_offset=0):
342 def _fixed_getinnerframes(etb, context=1, tb_offset=0):
343 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
343 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
344
344
345 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
345 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
346 # If the error is at the console, don't build any context, since it would
346 # If the error is at the console, don't build any context, since it would
347 # otherwise produce 5 blank lines printed out (there is no file at the
347 # otherwise produce 5 blank lines printed out (there is no file at the
348 # console)
348 # console)
349 rec_check = records[tb_offset:]
349 rec_check = records[tb_offset:]
350 try:
350 try:
351 rname = rec_check[0][1]
351 rname = rec_check[0][1]
352 if rname == '<ipython console>' or rname.endswith('<string>'):
352 if rname == '<ipython console>' or rname.endswith('<string>'):
353 return rec_check
353 return rec_check
354 except IndexError:
354 except IndexError:
355 pass
355 pass
356
356
357 aux = traceback.extract_tb(etb)
357 aux = traceback.extract_tb(etb)
358 assert len(records) == len(aux)
358 assert len(records) == len(aux)
359 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
359 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
360 maybeStart = lnum - 1 - context // 2
360 maybeStart = lnum - 1 - context // 2
361 start = max(maybeStart, 0)
361 start = max(maybeStart, 0)
362 end = start + context
362 end = start + context
363 lines = ulinecache.getlines(file)[start:end]
363 lines = ulinecache.getlines(file)[start:end]
364 buf = list(records[i])
364 buf = list(records[i])
365 buf[LNUM_POS] = lnum
365 buf[LNUM_POS] = lnum
366 buf[INDEX_POS] = lnum - 1 - start
366 buf[INDEX_POS] = lnum - 1 - start
367 buf[LINES_POS] = lines
367 buf[LINES_POS] = lines
368 records[i] = tuple(buf)
368 records[i] = tuple(buf)
369 return records[tb_offset:]
369 return records[tb_offset:]
370
370
371 # Helper function -- largely belongs to VerboseTB, but we need the same
371 # Helper function -- largely belongs to VerboseTB, but we need the same
372 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
372 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
373 # can be recognized properly by ipython.el's py-traceback-line-re
373 # can be recognized properly by ipython.el's py-traceback-line-re
374 # (SyntaxErrors have to be treated specially because they have no traceback)
374 # (SyntaxErrors have to be treated specially because they have no traceback)
375
375
376 _parser = PyColorize.Parser()
376 _parser = PyColorize.Parser()
377
377
378
378
379 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, scheme=None):
379 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, scheme=None):
380 numbers_width = INDENT_SIZE - 1
380 numbers_width = INDENT_SIZE - 1
381 res = []
381 res = []
382 i = lnum - index
382 i = lnum - index
383
383
384 # This lets us get fully syntax-highlighted tracebacks.
384 # This lets us get fully syntax-highlighted tracebacks.
385 if scheme is None:
385 if scheme is None:
386 ipinst = get_ipython()
386 ipinst = get_ipython()
387 if ipinst is not None:
387 if ipinst is not None:
388 scheme = ipinst.colors
388 scheme = ipinst.colors
389 else:
389 else:
390 scheme = DEFAULT_SCHEME
390 scheme = DEFAULT_SCHEME
391
391
392 _line_format = _parser.format2
392 _line_format = _parser.format2
393
393
394 for line in lines:
394 for line in lines:
395 line = py3compat.cast_unicode(line)
395 line = py3compat.cast_unicode(line)
396
396
397 new_line, err = _line_format(line, 'str', scheme)
397 new_line, err = _line_format(line, 'str', scheme)
398 if not err: line = new_line
398 if not err: line = new_line
399
399
400 if i == lnum:
400 if i == lnum:
401 # This is the line with the error
401 # This is the line with the error
402 pad = numbers_width - len(str(i))
402 pad = numbers_width - len(str(i))
403 num = '%s%s' % (debugger.make_arrow(pad), str(lnum))
403 num = '%s%s' % (debugger.make_arrow(pad), str(lnum))
404 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
404 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
405 Colors.line, line, Colors.Normal)
405 Colors.line, line, Colors.Normal)
406 else:
406 else:
407 num = '%*s' % (numbers_width, i)
407 num = '%*s' % (numbers_width, i)
408 line = '%s%s%s %s' % (Colors.lineno, num,
408 line = '%s%s%s %s' % (Colors.lineno, num,
409 Colors.Normal, line)
409 Colors.Normal, line)
410
410
411 res.append(line)
411 res.append(line)
412 if lvals and i == lnum:
412 if lvals and i == lnum:
413 res.append(lvals + '\n')
413 res.append(lvals + '\n')
414 i = i + 1
414 i = i + 1
415 return res
415 return res
416
416
417 def is_recursion_error(etype, value, records):
417 def is_recursion_error(etype, value, records):
418 try:
418 try:
419 # RecursionError is new in Python 3.5
419 # RecursionError is new in Python 3.5
420 recursion_error_type = RecursionError
420 recursion_error_type = RecursionError
421 except NameError:
421 except NameError:
422 recursion_error_type = RuntimeError
422 recursion_error_type = RuntimeError
423
423
424 # The default recursion limit is 1000, but some of that will be taken up
424 # The default recursion limit is 1000, but some of that will be taken up
425 # by stack frames in IPython itself. >500 frames probably indicates
425 # by stack frames in IPython itself. >500 frames probably indicates
426 # a recursion error.
426 # a recursion error.
427 return (etype is recursion_error_type) \
427 return (etype is recursion_error_type) \
428 and "recursion" in str(value).lower() \
428 and "recursion" in str(value).lower() \
429 and len(records) > 500
429 and len(records) > 500
430
430
431 def find_recursion(etype, value, records):
431 def find_recursion(etype, value, records):
432 """Identify the repeating stack frames from a RecursionError traceback
432 """Identify the repeating stack frames from a RecursionError traceback
433
433
434 'records' is a list as returned by VerboseTB.get_records()
434 'records' is a list as returned by VerboseTB.get_records()
435
435
436 Returns (last_unique, repeat_length)
436 Returns (last_unique, repeat_length)
437 """
437 """
438 # This involves a bit of guesswork - we want to show enough of the traceback
438 # This involves a bit of guesswork - we want to show enough of the traceback
439 # to indicate where the recursion is occurring. We guess that the innermost
439 # to indicate where the recursion is occurring. We guess that the innermost
440 # quarter of the traceback (250 frames by default) is repeats, and find the
440 # quarter of the traceback (250 frames by default) is repeats, and find the
441 # first frame (from in to out) that looks different.
441 # first frame (from in to out) that looks different.
442 if not is_recursion_error(etype, value, records):
442 if not is_recursion_error(etype, value, records):
443 return len(records), 0
443 return len(records), 0
444
444
445 # Select filename, lineno, func_name to track frames with
445 # Select filename, lineno, func_name to track frames with
446 records = [r[1:4] for r in records]
446 records = [r[1:4] for r in records]
447 inner_frames = records[-(len(records)//4):]
447 inner_frames = records[-(len(records)//4):]
448 frames_repeated = set(inner_frames)
448 frames_repeated = set(inner_frames)
449
449
450 last_seen_at = {}
450 last_seen_at = {}
451 longest_repeat = 0
451 longest_repeat = 0
452 i = len(records)
452 i = len(records)
453 for frame in reversed(records):
453 for frame in reversed(records):
454 i -= 1
454 i -= 1
455 if frame not in frames_repeated:
455 if frame not in frames_repeated:
456 last_unique = i
456 last_unique = i
457 break
457 break
458
458
459 if frame in last_seen_at:
459 if frame in last_seen_at:
460 distance = last_seen_at[frame] - i
460 distance = last_seen_at[frame] - i
461 longest_repeat = max(longest_repeat, distance)
461 longest_repeat = max(longest_repeat, distance)
462
462
463 last_seen_at[frame] = i
463 last_seen_at[frame] = i
464 else:
464 else:
465 last_unique = 0 # The whole traceback was recursion
465 last_unique = 0 # The whole traceback was recursion
466
466
467 return last_unique, longest_repeat
467 return last_unique, longest_repeat
468
468
469 #---------------------------------------------------------------------------
469 #---------------------------------------------------------------------------
470 # Module classes
470 # Module classes
471 class TBTools(object):
471 class TBTools(object):
472 """Basic tools used by all traceback printer classes."""
472 """Basic tools used by all traceback printer classes."""
473
473
474 # Number of frames to skip when reporting tracebacks
474 # Number of frames to skip when reporting tracebacks
475 tb_offset = 0
475 tb_offset = 0
476
476
477 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
477 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
478 # Whether to call the interactive pdb debugger after printing
478 # Whether to call the interactive pdb debugger after printing
479 # tracebacks or not
479 # tracebacks or not
480 self.call_pdb = call_pdb
480 self.call_pdb = call_pdb
481
481
482 # Output stream to write to. Note that we store the original value in
482 # Output stream to write to. Note that we store the original value in
483 # a private attribute and then make the public ostream a property, so
483 # a private attribute and then make the public ostream a property, so
484 # that we can delay accessing io.stdout until runtime. The way
484 # that we can delay accessing io.stdout until runtime. The way
485 # things are written now, the io.stdout object is dynamically managed
485 # things are written now, the io.stdout object is dynamically managed
486 # so a reference to it should NEVER be stored statically. This
486 # so a reference to it should NEVER be stored statically. This
487 # property approach confines this detail to a single location, and all
487 # property approach confines this detail to a single location, and all
488 # subclasses can simply access self.ostream for writing.
488 # subclasses can simply access self.ostream for writing.
489 self._ostream = ostream
489 self._ostream = ostream
490
490
491 # Create color table
491 # Create color table
492 self.color_scheme_table = exception_colors()
492 self.color_scheme_table = exception_colors()
493
493
494 self.set_colors(color_scheme)
494 self.set_colors(color_scheme)
495 self.old_scheme = color_scheme # save initial value for toggles
495 self.old_scheme = color_scheme # save initial value for toggles
496
496
497 if call_pdb:
497 if call_pdb:
498 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
498 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
499 else:
499 else:
500 self.pdb = None
500 self.pdb = None
501
501
502 def _get_ostream(self):
502 def _get_ostream(self):
503 """Output stream that exceptions are written to.
503 """Output stream that exceptions are written to.
504
504
505 Valid values are:
505 Valid values are:
506
506
507 - None: the default, which means that IPython will dynamically resolve
507 - None: the default, which means that IPython will dynamically resolve
508 to io.stdout. This ensures compatibility with most tools, including
508 to io.stdout. This ensures compatibility with most tools, including
509 Windows (where plain stdout doesn't recognize ANSI escapes).
509 Windows (where plain stdout doesn't recognize ANSI escapes).
510
510
511 - Any object with 'write' and 'flush' attributes.
511 - Any object with 'write' and 'flush' attributes.
512 """
512 """
513 return io.stdout if self._ostream is None else self._ostream
513 return io.stdout if self._ostream is None else self._ostream
514
514
515 def _set_ostream(self, val):
515 def _set_ostream(self, val):
516 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
516 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
517 self._ostream = val
517 self._ostream = val
518
518
519 ostream = property(_get_ostream, _set_ostream)
519 ostream = property(_get_ostream, _set_ostream)
520
520
521 def set_colors(self, *args, **kw):
521 def set_colors(self, *args, **kw):
522 """Shorthand access to the color table scheme selector method."""
522 """Shorthand access to the color table scheme selector method."""
523
523
524 # Set own color table
524 # Set own color table
525 self.color_scheme_table.set_active_scheme(*args, **kw)
525 self.color_scheme_table.set_active_scheme(*args, **kw)
526 # for convenience, set Colors to the active scheme
526 # for convenience, set Colors to the active scheme
527 self.Colors = self.color_scheme_table.active_colors
527 self.Colors = self.color_scheme_table.active_colors
528 # Also set colors of debugger
528 # Also set colors of debugger
529 if hasattr(self, 'pdb') and self.pdb is not None:
529 if hasattr(self, 'pdb') and self.pdb is not None:
530 self.pdb.set_colors(*args, **kw)
530 self.pdb.set_colors(*args, **kw)
531
531
532 def color_toggle(self):
532 def color_toggle(self):
533 """Toggle between the currently active color scheme and NoColor."""
533 """Toggle between the currently active color scheme and NoColor."""
534
534
535 if self.color_scheme_table.active_scheme_name == 'NoColor':
535 if self.color_scheme_table.active_scheme_name == 'NoColor':
536 self.color_scheme_table.set_active_scheme(self.old_scheme)
536 self.color_scheme_table.set_active_scheme(self.old_scheme)
537 self.Colors = self.color_scheme_table.active_colors
537 self.Colors = self.color_scheme_table.active_colors
538 else:
538 else:
539 self.old_scheme = self.color_scheme_table.active_scheme_name
539 self.old_scheme = self.color_scheme_table.active_scheme_name
540 self.color_scheme_table.set_active_scheme('NoColor')
540 self.color_scheme_table.set_active_scheme('NoColor')
541 self.Colors = self.color_scheme_table.active_colors
541 self.Colors = self.color_scheme_table.active_colors
542
542
543 def stb2text(self, stb):
543 def stb2text(self, stb):
544 """Convert a structured traceback (a list) to a string."""
544 """Convert a structured traceback (a list) to a string."""
545 return '\n'.join(stb)
545 return '\n'.join(stb)
546
546
547 def text(self, etype, value, tb, tb_offset=None, context=5):
547 def text(self, etype, value, tb, tb_offset=None, context=5):
548 """Return formatted traceback.
548 """Return formatted traceback.
549
549
550 Subclasses may override this if they add extra arguments.
550 Subclasses may override this if they add extra arguments.
551 """
551 """
552 tb_list = self.structured_traceback(etype, value, tb,
552 tb_list = self.structured_traceback(etype, value, tb,
553 tb_offset, context)
553 tb_offset, context)
554 return self.stb2text(tb_list)
554 return self.stb2text(tb_list)
555
555
556 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
556 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
557 context=5, mode=None):
557 context=5, mode=None):
558 """Return a list of traceback frames.
558 """Return a list of traceback frames.
559
559
560 Must be implemented by each class.
560 Must be implemented by each class.
561 """
561 """
562 raise NotImplementedError()
562 raise NotImplementedError()
563
563
564
564
565 #---------------------------------------------------------------------------
565 #---------------------------------------------------------------------------
566 class ListTB(TBTools):
566 class ListTB(TBTools):
567 """Print traceback information from a traceback list, with optional color.
567 """Print traceback information from a traceback list, with optional color.
568
568
569 Calling requires 3 arguments: (etype, evalue, elist)
569 Calling requires 3 arguments: (etype, evalue, elist)
570 as would be obtained by::
570 as would be obtained by::
571
571
572 etype, evalue, tb = sys.exc_info()
572 etype, evalue, tb = sys.exc_info()
573 if tb:
573 if tb:
574 elist = traceback.extract_tb(tb)
574 elist = traceback.extract_tb(tb)
575 else:
575 else:
576 elist = None
576 elist = None
577
577
578 It can thus be used by programs which need to process the traceback before
578 It can thus be used by programs which need to process the traceback before
579 printing (such as console replacements based on the code module from the
579 printing (such as console replacements based on the code module from the
580 standard library).
580 standard library).
581
581
582 Because they are meant to be called without a full traceback (only a
582 Because they are meant to be called without a full traceback (only a
583 list), instances of this class can't call the interactive pdb debugger."""
583 list), instances of this class can't call the interactive pdb debugger."""
584
584
585 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
585 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
586 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
586 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
587 ostream=ostream)
587 ostream=ostream)
588
588
589 def __call__(self, etype, value, elist):
589 def __call__(self, etype, value, elist):
590 self.ostream.flush()
590 self.ostream.flush()
591 self.ostream.write(self.text(etype, value, elist))
591 self.ostream.write(self.text(etype, value, elist))
592 self.ostream.write('\n')
592 self.ostream.write('\n')
593
593
594 def structured_traceback(self, etype, value, elist, tb_offset=None,
594 def structured_traceback(self, etype, value, elist, tb_offset=None,
595 context=5):
595 context=5):
596 """Return a color formatted string with the traceback info.
596 """Return a color formatted string with the traceback info.
597
597
598 Parameters
598 Parameters
599 ----------
599 ----------
600 etype : exception type
600 etype : exception type
601 Type of the exception raised.
601 Type of the exception raised.
602
602
603 value : object
603 value : object
604 Data stored in the exception
604 Data stored in the exception
605
605
606 elist : list
606 elist : list
607 List of frames, see class docstring for details.
607 List of frames, see class docstring for details.
608
608
609 tb_offset : int, optional
609 tb_offset : int, optional
610 Number of frames in the traceback to skip. If not given, the
610 Number of frames in the traceback to skip. If not given, the
611 instance value is used (set in constructor).
611 instance value is used (set in constructor).
612
612
613 context : int, optional
613 context : int, optional
614 Number of lines of context information to print.
614 Number of lines of context information to print.
615
615
616 Returns
616 Returns
617 -------
617 -------
618 String with formatted exception.
618 String with formatted exception.
619 """
619 """
620 tb_offset = self.tb_offset if tb_offset is None else tb_offset
620 tb_offset = self.tb_offset if tb_offset is None else tb_offset
621 Colors = self.Colors
621 Colors = self.Colors
622 out_list = []
622 out_list = []
623 if elist:
623 if elist:
624
624
625 if tb_offset and len(elist) > tb_offset:
625 if tb_offset and len(elist) > tb_offset:
626 elist = elist[tb_offset:]
626 elist = elist[tb_offset:]
627
627
628 out_list.append('Traceback %s(most recent call last)%s:' %
628 out_list.append('Traceback %s(most recent call last)%s:' %
629 (Colors.normalEm, Colors.Normal) + '\n')
629 (Colors.normalEm, Colors.Normal) + '\n')
630 out_list.extend(self._format_list(elist))
630 out_list.extend(self._format_list(elist))
631 # The exception info should be a single entry in the list.
631 # The exception info should be a single entry in the list.
632 lines = ''.join(self._format_exception_only(etype, value))
632 lines = ''.join(self._format_exception_only(etype, value))
633 out_list.append(lines)
633 out_list.append(lines)
634
634
635 # Note: this code originally read:
635 # Note: this code originally read:
636
636
637 ## for line in lines[:-1]:
637 ## for line in lines[:-1]:
638 ## out_list.append(" "+line)
638 ## out_list.append(" "+line)
639 ## out_list.append(lines[-1])
639 ## out_list.append(lines[-1])
640
640
641 # This means it was indenting everything but the last line by a little
641 # This means it was indenting everything but the last line by a little
642 # bit. I've disabled this for now, but if we see ugliness somewhere we
642 # bit. I've disabled this for now, but if we see ugliness somewhere we
643 # can restore it.
643 # can restore it.
644
644
645 return out_list
645 return out_list
646
646
647 def _format_list(self, extracted_list):
647 def _format_list(self, extracted_list):
648 """Format a list of traceback entry tuples for printing.
648 """Format a list of traceback entry tuples for printing.
649
649
650 Given a list of tuples as returned by extract_tb() or
650 Given a list of tuples as returned by extract_tb() or
651 extract_stack(), return a list of strings ready for printing.
651 extract_stack(), return a list of strings ready for printing.
652 Each string in the resulting list corresponds to the item with the
652 Each string in the resulting list corresponds to the item with the
653 same index in the argument list. Each string ends in a newline;
653 same index in the argument list. Each string ends in a newline;
654 the strings may contain internal newlines as well, for those items
654 the strings may contain internal newlines as well, for those items
655 whose source text line is not None.
655 whose source text line is not None.
656
656
657 Lifted almost verbatim from traceback.py
657 Lifted almost verbatim from traceback.py
658 """
658 """
659
659
660 Colors = self.Colors
660 Colors = self.Colors
661 list = []
661 list = []
662 for filename, lineno, name, line in extracted_list[:-1]:
662 for filename, lineno, name, line in extracted_list[:-1]:
663 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
663 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
664 (Colors.filename, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.Normal,
664 (Colors.filename, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.Normal,
665 Colors.lineno, lineno, Colors.Normal,
665 Colors.lineno, lineno, Colors.Normal,
666 Colors.name, py3compat.cast_unicode_py2(name, "utf-8"), Colors.Normal)
666 Colors.name, py3compat.cast_unicode_py2(name, "utf-8"), Colors.Normal)
667 if line:
667 if line:
668 item += ' %s\n' % line.strip()
668 item += ' %s\n' % line.strip()
669 list.append(item)
669 list.append(item)
670 # Emphasize the last entry
670 # Emphasize the last entry
671 filename, lineno, name, line = extracted_list[-1]
671 filename, lineno, name, line = extracted_list[-1]
672 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
672 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
673 (Colors.normalEm,
673 (Colors.normalEm,
674 Colors.filenameEm, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.normalEm,
674 Colors.filenameEm, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.normalEm,
675 Colors.linenoEm, lineno, Colors.normalEm,
675 Colors.linenoEm, lineno, Colors.normalEm,
676 Colors.nameEm, py3compat.cast_unicode_py2(name, "utf-8"), Colors.normalEm,
676 Colors.nameEm, py3compat.cast_unicode_py2(name, "utf-8"), Colors.normalEm,
677 Colors.Normal)
677 Colors.Normal)
678 if line:
678 if line:
679 item += '%s %s%s\n' % (Colors.line, line.strip(),
679 item += '%s %s%s\n' % (Colors.line, line.strip(),
680 Colors.Normal)
680 Colors.Normal)
681 list.append(item)
681 list.append(item)
682 return list
682 return list
683
683
684 def _format_exception_only(self, etype, value):
684 def _format_exception_only(self, etype, value):
685 """Format the exception part of a traceback.
685 """Format the exception part of a traceback.
686
686
687 The arguments are the exception type and value such as given by
687 The arguments are the exception type and value such as given by
688 sys.exc_info()[:2]. The return value is a list of strings, each ending
688 sys.exc_info()[:2]. The return value is a list of strings, each ending
689 in a newline. Normally, the list contains a single string; however,
689 in a newline. Normally, the list contains a single string; however,
690 for SyntaxError exceptions, it contains several lines that (when
690 for SyntaxError exceptions, it contains several lines that (when
691 printed) display detailed information about where the syntax error
691 printed) display detailed information about where the syntax error
692 occurred. The message indicating which exception occurred is the
692 occurred. The message indicating which exception occurred is the
693 always last string in the list.
693 always last string in the list.
694
694
695 Also lifted nearly verbatim from traceback.py
695 Also lifted nearly verbatim from traceback.py
696 """
696 """
697 have_filedata = False
697 have_filedata = False
698 Colors = self.Colors
698 Colors = self.Colors
699 list = []
699 list = []
700 stype = Colors.excName + etype.__name__ + Colors.Normal
700 stype = Colors.excName + etype.__name__ + Colors.Normal
701 if value is None:
701 if value is None:
702 # Not sure if this can still happen in Python 2.6 and above
702 # Not sure if this can still happen in Python 2.6 and above
703 list.append(py3compat.cast_unicode(stype) + '\n')
703 list.append(py3compat.cast_unicode(stype) + '\n')
704 else:
704 else:
705 if issubclass(etype, SyntaxError):
705 if issubclass(etype, SyntaxError):
706 have_filedata = True
706 have_filedata = True
707 if not value.filename: value.filename = "<string>"
707 if not value.filename: value.filename = "<string>"
708 if value.lineno:
708 if value.lineno:
709 lineno = value.lineno
709 lineno = value.lineno
710 textline = ulinecache.getline(value.filename, value.lineno)
710 textline = ulinecache.getline(value.filename, value.lineno)
711 else:
711 else:
712 lineno = 'unknown'
712 lineno = 'unknown'
713 textline = ''
713 textline = ''
714 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
714 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
715 (Colors.normalEm,
715 (Colors.normalEm,
716 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
716 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
717 Colors.linenoEm, lineno, Colors.Normal ))
717 Colors.linenoEm, lineno, Colors.Normal ))
718 if textline == '':
718 if textline == '':
719 textline = py3compat.cast_unicode(value.text, "utf-8")
719 textline = py3compat.cast_unicode(value.text, "utf-8")
720
720
721 if textline is not None:
721 if textline is not None:
722 i = 0
722 i = 0
723 while i < len(textline) and textline[i].isspace():
723 while i < len(textline) and textline[i].isspace():
724 i += 1
724 i += 1
725 list.append('%s %s%s\n' % (Colors.line,
725 list.append('%s %s%s\n' % (Colors.line,
726 textline.strip(),
726 textline.strip(),
727 Colors.Normal))
727 Colors.Normal))
728 if value.offset is not None:
728 if value.offset is not None:
729 s = ' '
729 s = ' '
730 for c in textline[i:value.offset - 1]:
730 for c in textline[i:value.offset - 1]:
731 if c.isspace():
731 if c.isspace():
732 s += c
732 s += c
733 else:
733 else:
734 s += ' '
734 s += ' '
735 list.append('%s%s^%s\n' % (Colors.caret, s,
735 list.append('%s%s^%s\n' % (Colors.caret, s,
736 Colors.Normal))
736 Colors.Normal))
737
737
738 try:
738 try:
739 s = value.msg
739 s = value.msg
740 except Exception:
740 except Exception:
741 s = self._some_str(value)
741 s = self._some_str(value)
742 if s:
742 if s:
743 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
743 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
744 Colors.Normal, s))
744 Colors.Normal, s))
745 else:
745 else:
746 list.append('%s\n' % str(stype))
746 list.append('%s\n' % str(stype))
747
747
748 # sync with user hooks
748 # sync with user hooks
749 if have_filedata:
749 if have_filedata:
750 ipinst = get_ipython()
750 ipinst = get_ipython()
751 if ipinst is not None:
751 if ipinst is not None:
752 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
752 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
753
753
754 return list
754 return list
755
755
756 def get_exception_only(self, etype, value):
756 def get_exception_only(self, etype, value):
757 """Only print the exception type and message, without a traceback.
757 """Only print the exception type and message, without a traceback.
758
758
759 Parameters
759 Parameters
760 ----------
760 ----------
761 etype : exception type
761 etype : exception type
762 value : exception value
762 value : exception value
763 """
763 """
764 return ListTB.structured_traceback(self, etype, value, [])
764 return ListTB.structured_traceback(self, etype, value, [])
765
765
766 def show_exception_only(self, etype, evalue):
766 def show_exception_only(self, etype, evalue):
767 """Only print the exception type and message, without a traceback.
767 """Only print the exception type and message, without a traceback.
768
768
769 Parameters
769 Parameters
770 ----------
770 ----------
771 etype : exception type
771 etype : exception type
772 value : exception value
772 value : exception value
773 """
773 """
774 # This method needs to use __call__ from *this* class, not the one from
774 # This method needs to use __call__ from *this* class, not the one from
775 # a subclass whose signature or behavior may be different
775 # a subclass whose signature or behavior may be different
776 ostream = self.ostream
776 ostream = self.ostream
777 ostream.flush()
777 ostream.flush()
778 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
778 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
779 ostream.flush()
779 ostream.flush()
780
780
781 def _some_str(self, value):
781 def _some_str(self, value):
782 # Lifted from traceback.py
782 # Lifted from traceback.py
783 try:
783 try:
784 return str(value)
784 return str(value)
785 except:
785 except:
786 return '<unprintable %s object>' % type(value).__name__
786 return '<unprintable %s object>' % type(value).__name__
787
787
788
788
789 #----------------------------------------------------------------------------
789 #----------------------------------------------------------------------------
790 class VerboseTB(TBTools):
790 class VerboseTB(TBTools):
791 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
791 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
792 of HTML. Requires inspect and pydoc. Crazy, man.
792 of HTML. Requires inspect and pydoc. Crazy, man.
793
793
794 Modified version which optionally strips the topmost entries from the
794 Modified version which optionally strips the topmost entries from the
795 traceback, to be used with alternate interpreters (because their own code
795 traceback, to be used with alternate interpreters (because their own code
796 would appear in the traceback)."""
796 would appear in the traceback)."""
797
797
798 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
798 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
799 tb_offset=0, long_header=False, include_vars=True,
799 tb_offset=0, long_header=False, include_vars=True,
800 check_cache=None):
800 check_cache=None):
801 """Specify traceback offset, headers and color scheme.
801 """Specify traceback offset, headers and color scheme.
802
802
803 Define how many frames to drop from the tracebacks. Calling it with
803 Define how many frames to drop from the tracebacks. Calling it with
804 tb_offset=1 allows use of this handler in interpreters which will have
804 tb_offset=1 allows use of this handler in interpreters which will have
805 their own code at the top of the traceback (VerboseTB will first
805 their own code at the top of the traceback (VerboseTB will first
806 remove that frame before printing the traceback info)."""
806 remove that frame before printing the traceback info)."""
807 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
807 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
808 ostream=ostream)
808 ostream=ostream)
809 self.tb_offset = tb_offset
809 self.tb_offset = tb_offset
810 self.long_header = long_header
810 self.long_header = long_header
811 self.include_vars = include_vars
811 self.include_vars = include_vars
812 # By default we use linecache.checkcache, but the user can provide a
812 # By default we use linecache.checkcache, but the user can provide a
813 # different check_cache implementation. This is used by the IPython
813 # different check_cache implementation. This is used by the IPython
814 # kernel to provide tracebacks for interactive code that is cached,
814 # kernel to provide tracebacks for interactive code that is cached,
815 # by a compiler instance that flushes the linecache but preserves its
815 # by a compiler instance that flushes the linecache but preserves its
816 # own code cache.
816 # own code cache.
817 if check_cache is None:
817 if check_cache is None:
818 check_cache = linecache.checkcache
818 check_cache = linecache.checkcache
819 self.check_cache = check_cache
819 self.check_cache = check_cache
820
820
821 def format_records(self, records, last_unique, recursion_repeat):
821 def format_records(self, records, last_unique, recursion_repeat):
822 """Format the stack frames of the traceback"""
822 """Format the stack frames of the traceback"""
823 frames = []
823 frames = []
824 for r in records[:last_unique+recursion_repeat+1]:
824 for r in records[:last_unique+recursion_repeat+1]:
825 #print '*** record:',file,lnum,func,lines,index # dbg
825 #print '*** record:',file,lnum,func,lines,index # dbg
826 frames.append(self.format_record(*r))
826 frames.append(self.format_record(*r))
827
827
828 if recursion_repeat:
828 if recursion_repeat:
829 frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat)
829 frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat)
830 frames.append(self.format_record(*records[last_unique+recursion_repeat+1]))
830 frames.append(self.format_record(*records[last_unique+recursion_repeat+1]))
831
831
832 return frames
832 return frames
833
833
834 def format_record(self, frame, file, lnum, func, lines, index):
834 def format_record(self, frame, file, lnum, func, lines, index):
835 """Format a single stack frame"""
835 """Format a single stack frame"""
836 Colors = self.Colors # just a shorthand + quicker name lookup
836 Colors = self.Colors # just a shorthand + quicker name lookup
837 ColorsNormal = Colors.Normal # used a lot
837 ColorsNormal = Colors.Normal # used a lot
838 col_scheme = self.color_scheme_table.active_scheme_name
838 col_scheme = self.color_scheme_table.active_scheme_name
839 indent = ' ' * INDENT_SIZE
839 indent = ' ' * INDENT_SIZE
840 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
840 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
841 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
841 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
842 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
842 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
843 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
843 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
844 ColorsNormal)
844 ColorsNormal)
845 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
845 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
846 (Colors.vName, Colors.valEm, ColorsNormal)
846 (Colors.vName, Colors.valEm, ColorsNormal)
847 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
847 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
848 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
848 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
849 Colors.vName, ColorsNormal)
849 Colors.vName, ColorsNormal)
850 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
850 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
851
851
852 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
852 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
853 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line,
853 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line,
854 ColorsNormal)
854 ColorsNormal)
855
855
856 abspath = os.path.abspath
856 abspath = os.path.abspath
857
857
858
858
859 if not file:
859 if not file:
860 file = '?'
860 file = '?'
861 elif file.startswith(str("<")) and file.endswith(str(">")):
861 elif file.startswith(str("<")) and file.endswith(str(">")):
862 # Not a real filename, no problem...
862 # Not a real filename, no problem...
863 pass
863 pass
864 elif not os.path.isabs(file):
864 elif not os.path.isabs(file):
865 # Try to make the filename absolute by trying all
865 # Try to make the filename absolute by trying all
866 # sys.path entries (which is also what linecache does)
866 # sys.path entries (which is also what linecache does)
867 for dirname in sys.path:
867 for dirname in sys.path:
868 try:
868 try:
869 fullname = os.path.join(dirname, file)
869 fullname = os.path.join(dirname, file)
870 if os.path.isfile(fullname):
870 if os.path.isfile(fullname):
871 file = os.path.abspath(fullname)
871 file = os.path.abspath(fullname)
872 break
872 break
873 except Exception:
873 except Exception:
874 # Just in case that sys.path contains very
874 # Just in case that sys.path contains very
875 # strange entries...
875 # strange entries...
876 pass
876 pass
877
877
878 file = py3compat.cast_unicode(file, util_path.fs_encoding)
878 file = py3compat.cast_unicode(file, util_path.fs_encoding)
879 link = tpl_link % file
879 link = tpl_link % file
880 args, varargs, varkw, locals = fixed_getargvalues(frame)
880 args, varargs, varkw, locals = fixed_getargvalues(frame)
881
881
882 if func == '?':
882 if func == '?':
883 call = ''
883 call = ''
884 else:
884 else:
885 # Decide whether to include variable details or not
885 # Decide whether to include variable details or not
886 var_repr = self.include_vars and eqrepr or nullrepr
886 var_repr = self.include_vars and eqrepr or nullrepr
887 try:
887 try:
888 call = tpl_call % (func, inspect.formatargvalues(args,
888 call = tpl_call % (func, inspect.formatargvalues(args,
889 varargs, varkw,
889 varargs, varkw,
890 locals, formatvalue=var_repr))
890 locals, formatvalue=var_repr))
891 except KeyError:
891 except KeyError:
892 # This happens in situations like errors inside generator
892 # This happens in situations like errors inside generator
893 # expressions, where local variables are listed in the
893 # expressions, where local variables are listed in the
894 # line, but can't be extracted from the frame. I'm not
894 # line, but can't be extracted from the frame. I'm not
895 # 100% sure this isn't actually a bug in inspect itself,
895 # 100% sure this isn't actually a bug in inspect itself,
896 # but since there's no info for us to compute with, the
896 # but since there's no info for us to compute with, the
897 # best we can do is report the failure and move on. Here
897 # best we can do is report the failure and move on. Here
898 # we must *not* call any traceback construction again,
898 # we must *not* call any traceback construction again,
899 # because that would mess up use of %debug later on. So we
899 # because that would mess up use of %debug later on. So we
900 # simply report the failure and move on. The only
900 # simply report the failure and move on. The only
901 # limitation will be that this frame won't have locals
901 # limitation will be that this frame won't have locals
902 # listed in the call signature. Quite subtle problem...
902 # listed in the call signature. Quite subtle problem...
903 # I can't think of a good way to validate this in a unit
903 # I can't think of a good way to validate this in a unit
904 # test, but running a script consisting of:
904 # test, but running a script consisting of:
905 # dict( (k,v.strip()) for (k,v) in range(10) )
905 # dict( (k,v.strip()) for (k,v) in range(10) )
906 # will illustrate the error, if this exception catch is
906 # will illustrate the error, if this exception catch is
907 # disabled.
907 # disabled.
908 call = tpl_call_fail % func
908 call = tpl_call_fail % func
909
909
910 # Don't attempt to tokenize binary files.
910 # Don't attempt to tokenize binary files.
911 if file.endswith(('.so', '.pyd', '.dll')):
911 if file.endswith(('.so', '.pyd', '.dll')):
912 return '%s %s\n' % (link, call)
912 return '%s %s\n' % (link, call)
913
913
914 elif file.endswith(('.pyc', '.pyo')):
914 elif file.endswith(('.pyc', '.pyo')):
915 # Look up the corresponding source file.
915 # Look up the corresponding source file.
916 file = openpy.source_from_cache(file)
916 file = openpy.source_from_cache(file)
917
917
918 def linereader(file=file, lnum=[lnum], getline=ulinecache.getline):
918 def linereader(file=file, lnum=[lnum], getline=ulinecache.getline):
919 line = getline(file, lnum[0])
919 line = getline(file, lnum[0])
920 lnum[0] += 1
920 lnum[0] += 1
921 return line
921 return line
922
922
923 # Build the list of names on this line of code where the exception
923 # Build the list of names on this line of code where the exception
924 # occurred.
924 # occurred.
925 try:
925 try:
926 names = []
926 names = []
927 name_cont = False
927 name_cont = False
928
928
929 for token_type, token, start, end, line in generate_tokens(linereader):
929 for token_type, token, start, end, line in generate_tokens(linereader):
930 # build composite names
930 # build composite names
931 if token_type == tokenize.NAME and token not in keyword.kwlist:
931 if token_type == tokenize.NAME and token not in keyword.kwlist:
932 if name_cont:
932 if name_cont:
933 # Continuation of a dotted name
933 # Continuation of a dotted name
934 try:
934 try:
935 names[-1].append(token)
935 names[-1].append(token)
936 except IndexError:
936 except IndexError:
937 names.append([token])
937 names.append([token])
938 name_cont = False
938 name_cont = False
939 else:
939 else:
940 # Regular new names. We append everything, the caller
940 # Regular new names. We append everything, the caller
941 # will be responsible for pruning the list later. It's
941 # will be responsible for pruning the list later. It's
942 # very tricky to try to prune as we go, b/c composite
942 # very tricky to try to prune as we go, b/c composite
943 # names can fool us. The pruning at the end is easy
943 # names can fool us. The pruning at the end is easy
944 # to do (or the caller can print a list with repeated
944 # to do (or the caller can print a list with repeated
945 # names if so desired.
945 # names if so desired.
946 names.append([token])
946 names.append([token])
947 elif token == '.':
947 elif token == '.':
948 name_cont = True
948 name_cont = True
949 elif token_type == tokenize.NEWLINE:
949 elif token_type == tokenize.NEWLINE:
950 break
950 break
951
951
952 except (IndexError, UnicodeDecodeError, SyntaxError):
952 except (IndexError, UnicodeDecodeError, SyntaxError):
953 # signals exit of tokenizer
953 # signals exit of tokenizer
954 # SyntaxError can occur if the file is not actually Python
954 # SyntaxError can occur if the file is not actually Python
955 # - see gh-6300
955 # - see gh-6300
956 pass
956 pass
957 except tokenize.TokenError as msg:
957 except tokenize.TokenError as msg:
958 _m = ("An unexpected error occurred while tokenizing input\n"
958 _m = ("An unexpected error occurred while tokenizing input\n"
959 "The following traceback may be corrupted or invalid\n"
959 "The following traceback may be corrupted or invalid\n"
960 "The error message is: %s\n" % msg)
960 "The error message is: %s\n" % msg)
961 error(_m)
961 error(_m)
962
962
963 # Join composite names (e.g. "dict.fromkeys")
963 # Join composite names (e.g. "dict.fromkeys")
964 names = ['.'.join(n) for n in names]
964 names = ['.'.join(n) for n in names]
965 # prune names list of duplicates, but keep the right order
965 # prune names list of duplicates, but keep the right order
966 unique_names = uniq_stable(names)
966 unique_names = uniq_stable(names)
967
967
968 # Start loop over vars
968 # Start loop over vars
969 lvals = []
969 lvals = []
970 if self.include_vars:
970 if self.include_vars:
971 for name_full in unique_names:
971 for name_full in unique_names:
972 name_base = name_full.split('.', 1)[0]
972 name_base = name_full.split('.', 1)[0]
973 if name_base in frame.f_code.co_varnames:
973 if name_base in frame.f_code.co_varnames:
974 if name_base in locals:
974 if name_base in locals:
975 try:
975 try:
976 value = repr(eval(name_full, locals))
976 value = repr(eval(name_full, locals))
977 except:
977 except:
978 value = undefined
978 value = undefined
979 else:
979 else:
980 value = undefined
980 value = undefined
981 name = tpl_local_var % name_full
981 name = tpl_local_var % name_full
982 else:
982 else:
983 if name_base in frame.f_globals:
983 if name_base in frame.f_globals:
984 try:
984 try:
985 value = repr(eval(name_full, frame.f_globals))
985 value = repr(eval(name_full, frame.f_globals))
986 except:
986 except:
987 value = undefined
987 value = undefined
988 else:
988 else:
989 value = undefined
989 value = undefined
990 name = tpl_global_var % name_full
990 name = tpl_global_var % name_full
991 lvals.append(tpl_name_val % (name, value))
991 lvals.append(tpl_name_val % (name, value))
992 if lvals:
992 if lvals:
993 lvals = '%s%s' % (indent, em_normal.join(lvals))
993 lvals = '%s%s' % (indent, em_normal.join(lvals))
994 else:
994 else:
995 lvals = ''
995 lvals = ''
996
996
997 level = '%s %s\n' % (link, call)
997 level = '%s %s\n' % (link, call)
998
998
999 if index is None:
999 if index is None:
1000 return level
1000 return level
1001 else:
1001 else:
1002 return '%s%s' % (level, ''.join(
1002 return '%s%s' % (level, ''.join(
1003 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1003 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1004 col_scheme)))
1004 col_scheme)))
1005
1005
1006 def prepare_chained_exception_message(self, cause):
1006 def prepare_chained_exception_message(self, cause):
1007 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1007 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1008 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1008 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1009
1009
1010 if cause:
1010 if cause:
1011 message = [[direct_cause]]
1011 message = [[direct_cause]]
1012 else:
1012 else:
1013 message = [[exception_during_handling]]
1013 message = [[exception_during_handling]]
1014 return message
1014 return message
1015
1015
1016 def prepare_header(self, etype, long_version=False):
1016 def prepare_header(self, etype, long_version=False):
1017 colors = self.Colors # just a shorthand + quicker name lookup
1017 colors = self.Colors # just a shorthand + quicker name lookup
1018 colorsnormal = colors.Normal # used a lot
1018 colorsnormal = colors.Normal # used a lot
1019 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
1019 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
1020 if long_version:
1020 if long_version:
1021 # Header with the exception type, python version, and date
1021 # Header with the exception type, python version, and date
1022 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
1022 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
1023 date = time.ctime(time.time())
1023 date = time.ctime(time.time())
1024
1024
1025 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * 75, colorsnormal,
1025 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * 75, colorsnormal,
1026 exc, ' ' * (75 - len(str(etype)) - len(pyver)),
1026 exc, ' ' * (75 - len(str(etype)) - len(pyver)),
1027 pyver, date.rjust(75) )
1027 pyver, date.rjust(75) )
1028 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
1028 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
1029 "\ncalls leading up to the error, with the most recent (innermost) call last."
1029 "\ncalls leading up to the error, with the most recent (innermost) call last."
1030 else:
1030 else:
1031 # Simplified header
1031 # Simplified header
1032 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
1032 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
1033 rjust(75 - len(str(etype))) )
1033 rjust(75 - len(str(etype))) )
1034
1034
1035 return head
1035 return head
1036
1036
1037 def format_exception(self, etype, evalue):
1037 def format_exception(self, etype, evalue):
1038 colors = self.Colors # just a shorthand + quicker name lookup
1038 colors = self.Colors # just a shorthand + quicker name lookup
1039 colorsnormal = colors.Normal # used a lot
1039 colorsnormal = colors.Normal # used a lot
1040 indent = ' ' * INDENT_SIZE
1040 indent = ' ' * INDENT_SIZE
1041 # Get (safely) a string form of the exception info
1041 # Get (safely) a string form of the exception info
1042 try:
1042 try:
1043 etype_str, evalue_str = map(str, (etype, evalue))
1043 etype_str, evalue_str = map(str, (etype, evalue))
1044 except:
1044 except:
1045 # User exception is improperly defined.
1045 # User exception is improperly defined.
1046 etype, evalue = str, sys.exc_info()[:2]
1046 etype, evalue = str, sys.exc_info()[:2]
1047 etype_str, evalue_str = map(str, (etype, evalue))
1047 etype_str, evalue_str = map(str, (etype, evalue))
1048 # ... and format it
1048 # ... and format it
1049 exception = ['%s%s%s: %s' % (colors.excName, etype_str,
1049 exception = ['%s%s%s: %s' % (colors.excName, etype_str,
1050 colorsnormal, py3compat.cast_unicode(evalue_str))]
1050 colorsnormal, py3compat.cast_unicode(evalue_str))]
1051
1051
1052 if (not py3compat.PY3) and type(evalue) is types.InstanceType:
1052 if (not py3compat.PY3) and type(evalue) is types.InstanceType:
1053 try:
1053 try:
1054 names = [w for w in dir(evalue) if isinstance(w, py3compat.string_types)]
1054 names = [w for w in dir(evalue) if isinstance(w, py3compat.string_types)]
1055 except:
1055 except:
1056 # Every now and then, an object with funny internals blows up
1056 # Every now and then, an object with funny internals blows up
1057 # when dir() is called on it. We do the best we can to report
1057 # when dir() is called on it. We do the best we can to report
1058 # the problem and continue
1058 # the problem and continue
1059 _m = '%sException reporting error (object with broken dir())%s:'
1059 _m = '%sException reporting error (object with broken dir())%s:'
1060 exception.append(_m % (colors.excName, colorsnormal))
1060 exception.append(_m % (colors.excName, colorsnormal))
1061 etype_str, evalue_str = map(str, sys.exc_info()[:2])
1061 etype_str, evalue_str = map(str, sys.exc_info()[:2])
1062 exception.append('%s%s%s: %s' % (colors.excName, etype_str,
1062 exception.append('%s%s%s: %s' % (colors.excName, etype_str,
1063 colorsnormal, py3compat.cast_unicode(evalue_str)))
1063 colorsnormal, py3compat.cast_unicode(evalue_str)))
1064 names = []
1064 names = []
1065 for name in names:
1065 for name in names:
1066 value = text_repr(getattr(evalue, name))
1066 value = text_repr(getattr(evalue, name))
1067 exception.append('\n%s%s = %s' % (indent, name, value))
1067 exception.append('\n%s%s = %s' % (indent, name, value))
1068
1068
1069 return exception
1069 return exception
1070
1070
1071 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
1071 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
1072 """Formats the header, traceback and exception message for a single exception.
1072 """Formats the header, traceback and exception message for a single exception.
1073
1073
1074 This may be called multiple times by Python 3 exception chaining
1074 This may be called multiple times by Python 3 exception chaining
1075 (PEP 3134).
1075 (PEP 3134).
1076 """
1076 """
1077 # some locals
1077 # some locals
1078 orig_etype = etype
1078 orig_etype = etype
1079 try:
1079 try:
1080 etype = etype.__name__
1080 etype = etype.__name__
1081 except AttributeError:
1081 except AttributeError:
1082 pass
1082 pass
1083
1083
1084 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1084 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1085 head = self.prepare_header(etype, self.long_header)
1085 head = self.prepare_header(etype, self.long_header)
1086 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
1086 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
1087
1087
1088 if records is None:
1088 if records is None:
1089 return ""
1089 return ""
1090
1090
1091 last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)
1091 last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)
1092
1092
1093 frames = self.format_records(records, last_unique, recursion_repeat)
1093 frames = self.format_records(records, last_unique, recursion_repeat)
1094
1094
1095 formatted_exception = self.format_exception(etype, evalue)
1095 formatted_exception = self.format_exception(etype, evalue)
1096 if records:
1096 if records:
1097 filepath, lnum = records[-1][1:3]
1097 filepath, lnum = records[-1][1:3]
1098 filepath = os.path.abspath(filepath)
1098 filepath = os.path.abspath(filepath)
1099 ipinst = get_ipython()
1099 ipinst = get_ipython()
1100 if ipinst is not None:
1100 if ipinst is not None:
1101 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
1101 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
1102
1102
1103 return [[head] + frames + [''.join(formatted_exception[0])]]
1103 return [[head] + frames + [''.join(formatted_exception[0])]]
1104
1104
1105 def get_records(self, etb, number_of_lines_of_context, tb_offset):
1105 def get_records(self, etb, number_of_lines_of_context, tb_offset):
1106 try:
1106 try:
1107 # Try the default getinnerframes and Alex's: Alex's fixes some
1107 # Try the default getinnerframes and Alex's: Alex's fixes some
1108 # problems, but it generates empty tracebacks for console errors
1108 # problems, but it generates empty tracebacks for console errors
1109 # (5 blanks lines) where none should be returned.
1109 # (5 blanks lines) where none should be returned.
1110 return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)
1110 return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)
1111 except:
1111 except:
1112 # FIXME: I've been getting many crash reports from python 2.3
1112 # FIXME: I've been getting many crash reports from python 2.3
1113 # users, traceable to inspect.py. If I can find a small test-case
1113 # users, traceable to inspect.py. If I can find a small test-case
1114 # to reproduce this, I should either write a better workaround or
1114 # to reproduce this, I should either write a better workaround or
1115 # file a bug report against inspect (if that's the real problem).
1115 # file a bug report against inspect (if that's the real problem).
1116 # So far, I haven't been able to find an isolated example to
1116 # So far, I haven't been able to find an isolated example to
1117 # reproduce the problem.
1117 # reproduce the problem.
1118 inspect_error()
1118 inspect_error()
1119 traceback.print_exc(file=self.ostream)
1119 traceback.print_exc(file=self.ostream)
1120 info('\nUnfortunately, your original traceback can not be constructed.\n')
1120 info('\nUnfortunately, your original traceback can not be constructed.\n')
1121 return None
1121 return None
1122
1122
1123 def get_parts_of_chained_exception(self, evalue):
1123 def get_parts_of_chained_exception(self, evalue):
1124 def get_chained_exception(exception_value):
1124 def get_chained_exception(exception_value):
1125 cause = getattr(exception_value, '__cause__', None)
1125 cause = getattr(exception_value, '__cause__', None)
1126 if cause:
1126 if cause:
1127 return cause
1127 return cause
1128 if getattr(exception_value, '__suppress_context__', False):
1128 if getattr(exception_value, '__suppress_context__', False):
1129 return None
1129 return None
1130 return getattr(exception_value, '__context__', None)
1130 return getattr(exception_value, '__context__', None)
1131
1131
1132 chained_evalue = get_chained_exception(evalue)
1132 chained_evalue = get_chained_exception(evalue)
1133
1133
1134 if chained_evalue:
1134 if chained_evalue:
1135 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1135 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1136
1136
1137 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1137 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1138 number_of_lines_of_context=5):
1138 number_of_lines_of_context=5):
1139 """Return a nice text document describing the traceback."""
1139 """Return a nice text document describing the traceback."""
1140
1140
1141 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1141 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1142 tb_offset)
1142 tb_offset)
1143
1143
1144 colors = self.Colors # just a shorthand + quicker name lookup
1144 colors = self.Colors # just a shorthand + quicker name lookup
1145 colorsnormal = colors.Normal # used a lot
1145 colorsnormal = colors.Normal # used a lot
1146 head = '%s%s%s' % (colors.topline, '-' * 75, colorsnormal)
1146 head = '%s%s%s' % (colors.topline, '-' * 75, colorsnormal)
1147 structured_traceback_parts = [head]
1147 structured_traceback_parts = [head]
1148 if py3compat.PY3:
1148 if py3compat.PY3:
1149 chained_exceptions_tb_offset = 0
1149 chained_exceptions_tb_offset = 0
1150 lines_of_context = 3
1150 lines_of_context = 3
1151 formatted_exceptions = formatted_exception
1151 formatted_exceptions = formatted_exception
1152 exception = self.get_parts_of_chained_exception(evalue)
1152 exception = self.get_parts_of_chained_exception(evalue)
1153 if exception:
1153 if exception:
1154 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1154 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1155 etype, evalue, etb = exception
1155 etype, evalue, etb = exception
1156 else:
1156 else:
1157 evalue = None
1157 evalue = None
1158 chained_exc_ids = set()
1158 chained_exc_ids = set()
1159 while evalue:
1159 while evalue:
1160 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1160 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1161 chained_exceptions_tb_offset)
1161 chained_exceptions_tb_offset)
1162 exception = self.get_parts_of_chained_exception(evalue)
1162 exception = self.get_parts_of_chained_exception(evalue)
1163
1163
1164 if exception and not id(exception[1]) in chained_exc_ids:
1164 if exception and not id(exception[1]) in chained_exc_ids:
1165 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1165 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1166 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1166 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1167 etype, evalue, etb = exception
1167 etype, evalue, etb = exception
1168 else:
1168 else:
1169 evalue = None
1169 evalue = None
1170
1170
1171 # we want to see exceptions in a reversed order:
1171 # we want to see exceptions in a reversed order:
1172 # the first exception should be on top
1172 # the first exception should be on top
1173 for formatted_exception in reversed(formatted_exceptions):
1173 for formatted_exception in reversed(formatted_exceptions):
1174 structured_traceback_parts += formatted_exception
1174 structured_traceback_parts += formatted_exception
1175 else:
1175 else:
1176 structured_traceback_parts += formatted_exception[0]
1176 structured_traceback_parts += formatted_exception[0]
1177
1177
1178 return structured_traceback_parts
1178 return structured_traceback_parts
1179
1179
1180 def debugger(self, force=False):
1180 def debugger(self, force=False):
1181 """Call up the pdb debugger if desired, always clean up the tb
1181 """Call up the pdb debugger if desired, always clean up the tb
1182 reference.
1182 reference.
1183
1183
1184 Keywords:
1184 Keywords:
1185
1185
1186 - force(False): by default, this routine checks the instance call_pdb
1186 - force(False): by default, this routine checks the instance call_pdb
1187 flag and does not actually invoke the debugger if the flag is false.
1187 flag and does not actually invoke the debugger if the flag is false.
1188 The 'force' option forces the debugger to activate even if the flag
1188 The 'force' option forces the debugger to activate even if the flag
1189 is false.
1189 is false.
1190
1190
1191 If the call_pdb flag is set, the pdb interactive debugger is
1191 If the call_pdb flag is set, the pdb interactive debugger is
1192 invoked. In all cases, the self.tb reference to the current traceback
1192 invoked. In all cases, the self.tb reference to the current traceback
1193 is deleted to prevent lingering references which hamper memory
1193 is deleted to prevent lingering references which hamper memory
1194 management.
1194 management.
1195
1195
1196 Note that each call to pdb() does an 'import readline', so if your app
1196 Note that each call to pdb() does an 'import readline', so if your app
1197 requires a special setup for the readline completers, you'll have to
1197 requires a special setup for the readline completers, you'll have to
1198 fix that by hand after invoking the exception handler."""
1198 fix that by hand after invoking the exception handler."""
1199
1199
1200 if force or self.call_pdb:
1200 if force or self.call_pdb:
1201 if self.pdb is None:
1201 if self.pdb is None:
1202 self.pdb = debugger.Pdb(
1202 self.pdb = debugger.Pdb(
1203 self.color_scheme_table.active_scheme_name)
1203 self.color_scheme_table.active_scheme_name)
1204 # the system displayhook may have changed, restore the original
1204 # the system displayhook may have changed, restore the original
1205 # for pdb
1205 # for pdb
1206 display_trap = DisplayTrap(hook=sys.__displayhook__)
1206 display_trap = DisplayTrap(hook=sys.__displayhook__)
1207 with display_trap:
1207 with display_trap:
1208 self.pdb.reset()
1208 self.pdb.reset()
1209 # Find the right frame so we don't pop up inside ipython itself
1209 # Find the right frame so we don't pop up inside ipython itself
1210 if hasattr(self, 'tb') and self.tb is not None:
1210 if hasattr(self, 'tb') and self.tb is not None:
1211 etb = self.tb
1211 etb = self.tb
1212 else:
1212 else:
1213 etb = self.tb = sys.last_traceback
1213 etb = self.tb = sys.last_traceback
1214 while self.tb is not None and self.tb.tb_next is not None:
1214 while self.tb is not None and self.tb.tb_next is not None:
1215 self.tb = self.tb.tb_next
1215 self.tb = self.tb.tb_next
1216 if etb and etb.tb_next:
1216 if etb and etb.tb_next:
1217 etb = etb.tb_next
1217 etb = etb.tb_next
1218 self.pdb.botframe = etb.tb_frame
1218 self.pdb.botframe = etb.tb_frame
1219 self.pdb.interaction(self.tb.tb_frame, self.tb)
1219 self.pdb.interaction(self.tb.tb_frame, self.tb)
1220
1220
1221 if hasattr(self, 'tb'):
1221 if hasattr(self, 'tb'):
1222 del self.tb
1222 del self.tb
1223
1223
1224 def handler(self, info=None):
1224 def handler(self, info=None):
1225 (etype, evalue, etb) = info or sys.exc_info()
1225 (etype, evalue, etb) = info or sys.exc_info()
1226 self.tb = etb
1226 self.tb = etb
1227 ostream = self.ostream
1227 ostream = self.ostream
1228 ostream.flush()
1228 ostream.flush()
1229 ostream.write(self.text(etype, evalue, etb))
1229 ostream.write(self.text(etype, evalue, etb))
1230 ostream.write('\n')
1230 ostream.write('\n')
1231 ostream.flush()
1231 ostream.flush()
1232
1232
1233 # Changed so an instance can just be called as VerboseTB_inst() and print
1233 # Changed so an instance can just be called as VerboseTB_inst() and print
1234 # out the right info on its own.
1234 # out the right info on its own.
1235 def __call__(self, etype=None, evalue=None, etb=None):
1235 def __call__(self, etype=None, evalue=None, etb=None):
1236 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1236 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1237 if etb is None:
1237 if etb is None:
1238 self.handler()
1238 self.handler()
1239 else:
1239 else:
1240 self.handler((etype, evalue, etb))
1240 self.handler((etype, evalue, etb))
1241 try:
1241 try:
1242 self.debugger()
1242 self.debugger()
1243 except KeyboardInterrupt:
1243 except KeyboardInterrupt:
1244 print("\nKeyboardInterrupt")
1244 print("\nKeyboardInterrupt")
1245
1245
1246
1246
1247 #----------------------------------------------------------------------------
1247 #----------------------------------------------------------------------------
1248 class FormattedTB(VerboseTB, ListTB):
1248 class FormattedTB(VerboseTB, ListTB):
1249 """Subclass ListTB but allow calling with a traceback.
1249 """Subclass ListTB but allow calling with a traceback.
1250
1250
1251 It can thus be used as a sys.excepthook for Python > 2.1.
1251 It can thus be used as a sys.excepthook for Python > 2.1.
1252
1252
1253 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1253 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1254
1254
1255 Allows a tb_offset to be specified. This is useful for situations where
1255 Allows a tb_offset to be specified. This is useful for situations where
1256 one needs to remove a number of topmost frames from the traceback (such as
1256 one needs to remove a number of topmost frames from the traceback (such as
1257 occurs with python programs that themselves execute other python code,
1257 occurs with python programs that themselves execute other python code,
1258 like Python shells). """
1258 like Python shells). """
1259
1259
1260 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1260 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1261 ostream=None,
1261 ostream=None,
1262 tb_offset=0, long_header=False, include_vars=False,
1262 tb_offset=0, long_header=False, include_vars=False,
1263 check_cache=None):
1263 check_cache=None):
1264
1264
1265 # NEVER change the order of this list. Put new modes at the end:
1265 # NEVER change the order of this list. Put new modes at the end:
1266 self.valid_modes = ['Plain', 'Context', 'Verbose']
1266 self.valid_modes = ['Plain', 'Context', 'Verbose']
1267 self.verbose_modes = self.valid_modes[1:3]
1267 self.verbose_modes = self.valid_modes[1:3]
1268
1268
1269 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1269 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1270 ostream=ostream, tb_offset=tb_offset,
1270 ostream=ostream, tb_offset=tb_offset,
1271 long_header=long_header, include_vars=include_vars,
1271 long_header=long_header, include_vars=include_vars,
1272 check_cache=check_cache)
1272 check_cache=check_cache)
1273
1273
1274 # Different types of tracebacks are joined with different separators to
1274 # Different types of tracebacks are joined with different separators to
1275 # form a single string. They are taken from this dict
1275 # form a single string. They are taken from this dict
1276 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1276 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1277 # set_mode also sets the tb_join_char attribute
1277 # set_mode also sets the tb_join_char attribute
1278 self.set_mode(mode)
1278 self.set_mode(mode)
1279
1279
1280 def _extract_tb(self, tb):
1280 def _extract_tb(self, tb):
1281 if tb:
1281 if tb:
1282 return traceback.extract_tb(tb)
1282 return traceback.extract_tb(tb)
1283 else:
1283 else:
1284 return None
1284 return None
1285
1285
1286 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1286 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1287 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1287 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1288 mode = self.mode
1288 mode = self.mode
1289 if mode in self.verbose_modes:
1289 if mode in self.verbose_modes:
1290 # Verbose modes need a full traceback
1290 # Verbose modes need a full traceback
1291 return VerboseTB.structured_traceback(
1291 return VerboseTB.structured_traceback(
1292 self, etype, value, tb, tb_offset, number_of_lines_of_context
1292 self, etype, value, tb, tb_offset, number_of_lines_of_context
1293 )
1293 )
1294 else:
1294 else:
1295 # We must check the source cache because otherwise we can print
1295 # We must check the source cache because otherwise we can print
1296 # out-of-date source code.
1296 # out-of-date source code.
1297 self.check_cache()
1297 self.check_cache()
1298 # Now we can extract and format the exception
1298 # Now we can extract and format the exception
1299 elist = self._extract_tb(tb)
1299 elist = self._extract_tb(tb)
1300 return ListTB.structured_traceback(
1300 return ListTB.structured_traceback(
1301 self, etype, value, elist, tb_offset, number_of_lines_of_context
1301 self, etype, value, elist, tb_offset, number_of_lines_of_context
1302 )
1302 )
1303
1303
1304 def stb2text(self, stb):
1304 def stb2text(self, stb):
1305 """Convert a structured traceback (a list) to a string."""
1305 """Convert a structured traceback (a list) to a string."""
1306 return self.tb_join_char.join(stb)
1306 return self.tb_join_char.join(stb)
1307
1307
1308
1308
1309 def set_mode(self, mode=None):
1309 def set_mode(self, mode=None):
1310 """Switch to the desired mode.
1310 """Switch to the desired mode.
1311
1311
1312 If mode is not specified, cycles through the available modes."""
1312 If mode is not specified, cycles through the available modes."""
1313
1313
1314 if not mode:
1314 if not mode:
1315 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1315 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1316 len(self.valid_modes)
1316 len(self.valid_modes)
1317 self.mode = self.valid_modes[new_idx]
1317 self.mode = self.valid_modes[new_idx]
1318 elif mode not in self.valid_modes:
1318 elif mode not in self.valid_modes:
1319 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
1319 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
1320 'Valid modes: ' + str(self.valid_modes))
1320 'Valid modes: ' + str(self.valid_modes))
1321 else:
1321 else:
1322 self.mode = mode
1322 self.mode = mode
1323 # include variable details only in 'Verbose' mode
1323 # include variable details only in 'Verbose' mode
1324 self.include_vars = (self.mode == self.valid_modes[2])
1324 self.include_vars = (self.mode == self.valid_modes[2])
1325 # Set the join character for generating text tracebacks
1325 # Set the join character for generating text tracebacks
1326 self.tb_join_char = self._join_chars[self.mode]
1326 self.tb_join_char = self._join_chars[self.mode]
1327
1327
1328 # some convenient shortcuts
1328 # some convenient shortcuts
1329 def plain(self):
1329 def plain(self):
1330 self.set_mode(self.valid_modes[0])
1330 self.set_mode(self.valid_modes[0])
1331
1331
1332 def context(self):
1332 def context(self):
1333 self.set_mode(self.valid_modes[1])
1333 self.set_mode(self.valid_modes[1])
1334
1334
1335 def verbose(self):
1335 def verbose(self):
1336 self.set_mode(self.valid_modes[2])
1336 self.set_mode(self.valid_modes[2])
1337
1337
1338
1338
1339 #----------------------------------------------------------------------------
1339 #----------------------------------------------------------------------------
1340 class AutoFormattedTB(FormattedTB):
1340 class AutoFormattedTB(FormattedTB):
1341 """A traceback printer which can be called on the fly.
1341 """A traceback printer which can be called on the fly.
1342
1342
1343 It will find out about exceptions by itself.
1343 It will find out about exceptions by itself.
1344
1344
1345 A brief example::
1345 A brief example::
1346
1346
1347 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1347 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1348 try:
1348 try:
1349 ...
1349 ...
1350 except:
1350 except:
1351 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1351 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1352 """
1352 """
1353
1353
1354 def __call__(self, etype=None, evalue=None, etb=None,
1354 def __call__(self, etype=None, evalue=None, etb=None,
1355 out=None, tb_offset=None):
1355 out=None, tb_offset=None):
1356 """Print out a formatted exception traceback.
1356 """Print out a formatted exception traceback.
1357
1357
1358 Optional arguments:
1358 Optional arguments:
1359 - out: an open file-like object to direct output to.
1359 - out: an open file-like object to direct output to.
1360
1360
1361 - tb_offset: the number of frames to skip over in the stack, on a
1361 - tb_offset: the number of frames to skip over in the stack, on a
1362 per-call basis (this overrides temporarily the instance's tb_offset
1362 per-call basis (this overrides temporarily the instance's tb_offset
1363 given at initialization time. """
1363 given at initialization time. """
1364
1364
1365 if out is None:
1365 if out is None:
1366 out = self.ostream
1366 out = self.ostream
1367 out.flush()
1367 out.flush()
1368 out.write(self.text(etype, evalue, etb, tb_offset))
1368 out.write(self.text(etype, evalue, etb, tb_offset))
1369 out.write('\n')
1369 out.write('\n')
1370 out.flush()
1370 out.flush()
1371 # FIXME: we should remove the auto pdb behavior from here and leave
1371 # FIXME: we should remove the auto pdb behavior from here and leave
1372 # that to the clients.
1372 # that to the clients.
1373 try:
1373 try:
1374 self.debugger()
1374 self.debugger()
1375 except KeyboardInterrupt:
1375 except KeyboardInterrupt:
1376 print("\nKeyboardInterrupt")
1376 print("\nKeyboardInterrupt")
1377
1377
1378 def structured_traceback(self, etype=None, value=None, tb=None,
1378 def structured_traceback(self, etype=None, value=None, tb=None,
1379 tb_offset=None, number_of_lines_of_context=5):
1379 tb_offset=None, number_of_lines_of_context=5):
1380 if etype is None:
1380 if etype is None:
1381 etype, value, tb = sys.exc_info()
1381 etype, value, tb = sys.exc_info()
1382 self.tb = tb
1382 self.tb = tb
1383 return FormattedTB.structured_traceback(
1383 return FormattedTB.structured_traceback(
1384 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1384 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1385
1385
1386
1386
1387 #---------------------------------------------------------------------------
1387 #---------------------------------------------------------------------------
1388
1388
1389 # A simple class to preserve Nathan's original functionality.
1389 # A simple class to preserve Nathan's original functionality.
1390 class ColorTB(FormattedTB):
1390 class ColorTB(FormattedTB):
1391 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1391 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1392
1392
1393 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1393 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1394 FormattedTB.__init__(self, color_scheme=color_scheme,
1394 FormattedTB.__init__(self, color_scheme=color_scheme,
1395 call_pdb=call_pdb, **kwargs)
1395 call_pdb=call_pdb, **kwargs)
1396
1396
1397
1397
1398 class SyntaxTB(ListTB):
1398 class SyntaxTB(ListTB):
1399 """Extension which holds some state: the last exception value"""
1399 """Extension which holds some state: the last exception value"""
1400
1400
1401 def __init__(self, color_scheme='NoColor'):
1401 def __init__(self, color_scheme='NoColor'):
1402 ListTB.__init__(self, color_scheme)
1402 ListTB.__init__(self, color_scheme)
1403 self.last_syntax_error = None
1403 self.last_syntax_error = None
1404
1404
1405 def __call__(self, etype, value, elist):
1405 def __call__(self, etype, value, elist):
1406 self.last_syntax_error = value
1406 self.last_syntax_error = value
1407
1407
1408 ListTB.__call__(self, etype, value, elist)
1408 ListTB.__call__(self, etype, value, elist)
1409
1409
1410 def structured_traceback(self, etype, value, elist, tb_offset=None,
1410 def structured_traceback(self, etype, value, elist, tb_offset=None,
1411 context=5):
1411 context=5):
1412 # If the source file has been edited, the line in the syntax error can
1412 # If the source file has been edited, the line in the syntax error can
1413 # be wrong (retrieved from an outdated cache). This replaces it with
1413 # be wrong (retrieved from an outdated cache). This replaces it with
1414 # the current value.
1414 # the current value.
1415 if isinstance(value, SyntaxError) \
1415 if isinstance(value, SyntaxError) \
1416 and isinstance(value.filename, py3compat.string_types) \
1416 and isinstance(value.filename, py3compat.string_types) \
1417 and isinstance(value.lineno, int):
1417 and isinstance(value.lineno, int):
1418 linecache.checkcache(value.filename)
1418 linecache.checkcache(value.filename)
1419 newtext = ulinecache.getline(value.filename, value.lineno)
1419 newtext = ulinecache.getline(value.filename, value.lineno)
1420 if newtext:
1420 if newtext:
1421 value.text = newtext
1421 value.text = newtext
1422 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1422 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1423 tb_offset=tb_offset, context=context)
1423 tb_offset=tb_offset, context=context)
1424
1424
1425 def clear_err_state(self):
1425 def clear_err_state(self):
1426 """Return the current error state and clear it"""
1426 """Return the current error state and clear it"""
1427 e = self.last_syntax_error
1427 e = self.last_syntax_error
1428 self.last_syntax_error = None
1428 self.last_syntax_error = None
1429 return e
1429 return e
1430
1430
1431 def stb2text(self, stb):
1431 def stb2text(self, stb):
1432 """Convert a structured traceback (a list) to a string."""
1432 """Convert a structured traceback (a list) to a string."""
1433 return ''.join(stb)
1433 return ''.join(stb)
1434
1434
1435
1435
1436 # some internal-use functions
1436 # some internal-use functions
1437 def text_repr(value):
1437 def text_repr(value):
1438 """Hopefully pretty robust repr equivalent."""
1438 """Hopefully pretty robust repr equivalent."""
1439 # this is pretty horrible but should always return *something*
1439 # this is pretty horrible but should always return *something*
1440 try:
1440 try:
1441 return pydoc.text.repr(value)
1441 return pydoc.text.repr(value)
1442 except KeyboardInterrupt:
1442 except KeyboardInterrupt:
1443 raise
1443 raise
1444 except:
1444 except:
1445 try:
1445 try:
1446 return repr(value)
1446 return repr(value)
1447 except KeyboardInterrupt:
1447 except KeyboardInterrupt:
1448 raise
1448 raise
1449 except:
1449 except:
1450 try:
1450 try:
1451 # all still in an except block so we catch
1451 # all still in an except block so we catch
1452 # getattr raising
1452 # getattr raising
1453 name = getattr(value, '__name__', None)
1453 name = getattr(value, '__name__', None)
1454 if name:
1454 if name:
1455 # ick, recursion
1455 # ick, recursion
1456 return text_repr(name)
1456 return text_repr(name)
1457 klass = getattr(value, '__class__', None)
1457 klass = getattr(value, '__class__', None)
1458 if klass:
1458 if klass:
1459 return '%s instance' % text_repr(klass)
1459 return '%s instance' % text_repr(klass)
1460 except KeyboardInterrupt:
1460 except KeyboardInterrupt:
1461 raise
1461 raise
1462 except:
1462 except:
1463 return 'UNRECOVERABLE REPR FAILURE'
1463 return 'UNRECOVERABLE REPR FAILURE'
1464
1464
1465
1465
1466 def eqrepr(value, repr=text_repr):
1466 def eqrepr(value, repr=text_repr):
1467 return '=%s' % repr(value)
1467 return '=%s' % repr(value)
1468
1468
1469
1469
1470 def nullrepr(value, repr=text_repr):
1470 def nullrepr(value, repr=text_repr):
1471 return ''
1471 return ''
@@ -1,491 +1,491 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Manage background (threaded) jobs conveniently from an interactive shell.
2 """Manage background (threaded) jobs conveniently from an interactive shell.
3
3
4 This module provides a BackgroundJobManager class. This is the main class
4 This module provides a BackgroundJobManager class. This is the main class
5 meant for public usage, it implements an object which can create and manage
5 meant for public usage, it implements an object which can create and manage
6 new background jobs.
6 new background jobs.
7
7
8 It also provides the actual job classes managed by these BackgroundJobManager
8 It also provides the actual job classes managed by these BackgroundJobManager
9 objects, see their docstrings below.
9 objects, see their docstrings below.
10
10
11
11
12 This system was inspired by discussions with B. Granger and the
12 This system was inspired by discussions with B. Granger and the
13 BackgroundCommand class described in the book Python Scripting for
13 BackgroundCommand class described in the book Python Scripting for
14 Computational Science, by H. P. Langtangen:
14 Computational Science, by H. P. Langtangen:
15
15
16 http://folk.uio.no/hpl/scripting
16 http://folk.uio.no/hpl/scripting
17
17
18 (although ultimately no code from this text was used, as IPython's system is a
18 (although ultimately no code from this text was used, as IPython's system is a
19 separate implementation).
19 separate implementation).
20
20
21 An example notebook is provided in our documentation illustrating interactive
21 An example notebook is provided in our documentation illustrating interactive
22 use of the system.
22 use of the system.
23 """
23 """
24 from __future__ import print_function
24 from __future__ import print_function
25
25
26 #*****************************************************************************
26 #*****************************************************************************
27 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
27 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
28 #
28 #
29 # Distributed under the terms of the BSD License. The full license is in
29 # Distributed under the terms of the BSD License. The full license is in
30 # the file COPYING, distributed as part of this software.
30 # the file COPYING, distributed as part of this software.
31 #*****************************************************************************
31 #*****************************************************************************
32
32
33 # Code begins
33 # Code begins
34 import sys
34 import sys
35 import threading
35 import threading
36
36
37 from IPython import get_ipython
37 from IPython import get_ipython
38 from IPython.core.ultratb import AutoFormattedTB
38 from IPython.core.ultratb import AutoFormattedTB
39 from IPython.utils.warn import error
39 from logging import error
40 from IPython.utils.py3compat import string_types
40 from IPython.utils.py3compat import string_types
41
41
42
42
43 class BackgroundJobManager(object):
43 class BackgroundJobManager(object):
44 """Class to manage a pool of backgrounded threaded jobs.
44 """Class to manage a pool of backgrounded threaded jobs.
45
45
46 Below, we assume that 'jobs' is a BackgroundJobManager instance.
46 Below, we assume that 'jobs' is a BackgroundJobManager instance.
47
47
48 Usage summary (see the method docstrings for details):
48 Usage summary (see the method docstrings for details):
49
49
50 jobs.new(...) -> start a new job
50 jobs.new(...) -> start a new job
51
51
52 jobs() or jobs.status() -> print status summary of all jobs
52 jobs() or jobs.status() -> print status summary of all jobs
53
53
54 jobs[N] -> returns job number N.
54 jobs[N] -> returns job number N.
55
55
56 foo = jobs[N].result -> assign to variable foo the result of job N
56 foo = jobs[N].result -> assign to variable foo the result of job N
57
57
58 jobs[N].traceback() -> print the traceback of dead job N
58 jobs[N].traceback() -> print the traceback of dead job N
59
59
60 jobs.remove(N) -> remove (finished) job N
60 jobs.remove(N) -> remove (finished) job N
61
61
62 jobs.flush() -> remove all finished jobs
62 jobs.flush() -> remove all finished jobs
63
63
64 As a convenience feature, BackgroundJobManager instances provide the
64 As a convenience feature, BackgroundJobManager instances provide the
65 utility result and traceback methods which retrieve the corresponding
65 utility result and traceback methods which retrieve the corresponding
66 information from the jobs list:
66 information from the jobs list:
67
67
68 jobs.result(N) <--> jobs[N].result
68 jobs.result(N) <--> jobs[N].result
69 jobs.traceback(N) <--> jobs[N].traceback()
69 jobs.traceback(N) <--> jobs[N].traceback()
70
70
71 While this appears minor, it allows you to use tab completion
71 While this appears minor, it allows you to use tab completion
72 interactively on the job manager instance.
72 interactively on the job manager instance.
73 """
73 """
74
74
75 def __init__(self):
75 def __init__(self):
76 # Lists for job management, accessed via a property to ensure they're
76 # Lists for job management, accessed via a property to ensure they're
77 # up to date.x
77 # up to date.x
78 self._running = []
78 self._running = []
79 self._completed = []
79 self._completed = []
80 self._dead = []
80 self._dead = []
81 # A dict of all jobs, so users can easily access any of them
81 # A dict of all jobs, so users can easily access any of them
82 self.all = {}
82 self.all = {}
83 # For reporting
83 # For reporting
84 self._comp_report = []
84 self._comp_report = []
85 self._dead_report = []
85 self._dead_report = []
86 # Store status codes locally for fast lookups
86 # Store status codes locally for fast lookups
87 self._s_created = BackgroundJobBase.stat_created_c
87 self._s_created = BackgroundJobBase.stat_created_c
88 self._s_running = BackgroundJobBase.stat_running_c
88 self._s_running = BackgroundJobBase.stat_running_c
89 self._s_completed = BackgroundJobBase.stat_completed_c
89 self._s_completed = BackgroundJobBase.stat_completed_c
90 self._s_dead = BackgroundJobBase.stat_dead_c
90 self._s_dead = BackgroundJobBase.stat_dead_c
91
91
92 @property
92 @property
93 def running(self):
93 def running(self):
94 self._update_status()
94 self._update_status()
95 return self._running
95 return self._running
96
96
97 @property
97 @property
98 def dead(self):
98 def dead(self):
99 self._update_status()
99 self._update_status()
100 return self._dead
100 return self._dead
101
101
102 @property
102 @property
103 def completed(self):
103 def completed(self):
104 self._update_status()
104 self._update_status()
105 return self._completed
105 return self._completed
106
106
107 def new(self, func_or_exp, *args, **kwargs):
107 def new(self, func_or_exp, *args, **kwargs):
108 """Add a new background job and start it in a separate thread.
108 """Add a new background job and start it in a separate thread.
109
109
110 There are two types of jobs which can be created:
110 There are two types of jobs which can be created:
111
111
112 1. Jobs based on expressions which can be passed to an eval() call.
112 1. Jobs based on expressions which can be passed to an eval() call.
113 The expression must be given as a string. For example:
113 The expression must be given as a string. For example:
114
114
115 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
115 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
116
116
117 The given expression is passed to eval(), along with the optional
117 The given expression is passed to eval(), along with the optional
118 global/local dicts provided. If no dicts are given, they are
118 global/local dicts provided. If no dicts are given, they are
119 extracted automatically from the caller's frame.
119 extracted automatically from the caller's frame.
120
120
121 A Python statement is NOT a valid eval() expression. Basically, you
121 A Python statement is NOT a valid eval() expression. Basically, you
122 can only use as an eval() argument something which can go on the right
122 can only use as an eval() argument something which can go on the right
123 of an '=' sign and be assigned to a variable.
123 of an '=' sign and be assigned to a variable.
124
124
125 For example,"print 'hello'" is not valid, but '2+3' is.
125 For example,"print 'hello'" is not valid, but '2+3' is.
126
126
127 2. Jobs given a function object, optionally passing additional
127 2. Jobs given a function object, optionally passing additional
128 positional arguments:
128 positional arguments:
129
129
130 job_manager.new(myfunc, x, y)
130 job_manager.new(myfunc, x, y)
131
131
132 The function is called with the given arguments.
132 The function is called with the given arguments.
133
133
134 If you need to pass keyword arguments to your function, you must
134 If you need to pass keyword arguments to your function, you must
135 supply them as a dict named kw:
135 supply them as a dict named kw:
136
136
137 job_manager.new(myfunc, x, y, kw=dict(z=1))
137 job_manager.new(myfunc, x, y, kw=dict(z=1))
138
138
139 The reason for this assymmetry is that the new() method needs to
139 The reason for this assymmetry is that the new() method needs to
140 maintain access to its own keywords, and this prevents name collisions
140 maintain access to its own keywords, and this prevents name collisions
141 between arguments to new() and arguments to your own functions.
141 between arguments to new() and arguments to your own functions.
142
142
143 In both cases, the result is stored in the job.result field of the
143 In both cases, the result is stored in the job.result field of the
144 background job object.
144 background job object.
145
145
146 You can set `daemon` attribute of the thread by giving the keyword
146 You can set `daemon` attribute of the thread by giving the keyword
147 argument `daemon`.
147 argument `daemon`.
148
148
149 Notes and caveats:
149 Notes and caveats:
150
150
151 1. All threads running share the same standard output. Thus, if your
151 1. All threads running share the same standard output. Thus, if your
152 background jobs generate output, it will come out on top of whatever
152 background jobs generate output, it will come out on top of whatever
153 you are currently writing. For this reason, background jobs are best
153 you are currently writing. For this reason, background jobs are best
154 used with silent functions which simply return their output.
154 used with silent functions which simply return their output.
155
155
156 2. Threads also all work within the same global namespace, and this
156 2. Threads also all work within the same global namespace, and this
157 system does not lock interactive variables. So if you send job to the
157 system does not lock interactive variables. So if you send job to the
158 background which operates on a mutable object for a long time, and
158 background which operates on a mutable object for a long time, and
159 start modifying that same mutable object interactively (or in another
159 start modifying that same mutable object interactively (or in another
160 backgrounded job), all sorts of bizarre behaviour will occur.
160 backgrounded job), all sorts of bizarre behaviour will occur.
161
161
162 3. If a background job is spending a lot of time inside a C extension
162 3. If a background job is spending a lot of time inside a C extension
163 module which does not release the Python Global Interpreter Lock
163 module which does not release the Python Global Interpreter Lock
164 (GIL), this will block the IPython prompt. This is simply because the
164 (GIL), this will block the IPython prompt. This is simply because the
165 Python interpreter can only switch between threads at Python
165 Python interpreter can only switch between threads at Python
166 bytecodes. While the execution is inside C code, the interpreter must
166 bytecodes. While the execution is inside C code, the interpreter must
167 simply wait unless the extension module releases the GIL.
167 simply wait unless the extension module releases the GIL.
168
168
169 4. There is no way, due to limitations in the Python threads library,
169 4. There is no way, due to limitations in the Python threads library,
170 to kill a thread once it has started."""
170 to kill a thread once it has started."""
171
171
172 if callable(func_or_exp):
172 if callable(func_or_exp):
173 kw = kwargs.get('kw',{})
173 kw = kwargs.get('kw',{})
174 job = BackgroundJobFunc(func_or_exp,*args,**kw)
174 job = BackgroundJobFunc(func_or_exp,*args,**kw)
175 elif isinstance(func_or_exp, string_types):
175 elif isinstance(func_or_exp, string_types):
176 if not args:
176 if not args:
177 frame = sys._getframe(1)
177 frame = sys._getframe(1)
178 glob, loc = frame.f_globals, frame.f_locals
178 glob, loc = frame.f_globals, frame.f_locals
179 elif len(args)==1:
179 elif len(args)==1:
180 glob = loc = args[0]
180 glob = loc = args[0]
181 elif len(args)==2:
181 elif len(args)==2:
182 glob,loc = args
182 glob,loc = args
183 else:
183 else:
184 raise ValueError(
184 raise ValueError(
185 'Expression jobs take at most 2 args (globals,locals)')
185 'Expression jobs take at most 2 args (globals,locals)')
186 job = BackgroundJobExpr(func_or_exp, glob, loc)
186 job = BackgroundJobExpr(func_or_exp, glob, loc)
187 else:
187 else:
188 raise TypeError('invalid args for new job')
188 raise TypeError('invalid args for new job')
189
189
190 if kwargs.get('daemon', False):
190 if kwargs.get('daemon', False):
191 job.daemon = True
191 job.daemon = True
192 job.num = len(self.all)+1 if self.all else 0
192 job.num = len(self.all)+1 if self.all else 0
193 self.running.append(job)
193 self.running.append(job)
194 self.all[job.num] = job
194 self.all[job.num] = job
195 print('Starting job # %s in a separate thread.' % job.num)
195 print('Starting job # %s in a separate thread.' % job.num)
196 job.start()
196 job.start()
197 return job
197 return job
198
198
199 def __getitem__(self, job_key):
199 def __getitem__(self, job_key):
200 num = job_key if isinstance(job_key, int) else job_key.num
200 num = job_key if isinstance(job_key, int) else job_key.num
201 return self.all[num]
201 return self.all[num]
202
202
203 def __call__(self):
203 def __call__(self):
204 """An alias to self.status(),
204 """An alias to self.status(),
205
205
206 This allows you to simply call a job manager instance much like the
206 This allows you to simply call a job manager instance much like the
207 Unix `jobs` shell command."""
207 Unix `jobs` shell command."""
208
208
209 return self.status()
209 return self.status()
210
210
211 def _update_status(self):
211 def _update_status(self):
212 """Update the status of the job lists.
212 """Update the status of the job lists.
213
213
214 This method moves finished jobs to one of two lists:
214 This method moves finished jobs to one of two lists:
215 - self.completed: jobs which completed successfully
215 - self.completed: jobs which completed successfully
216 - self.dead: jobs which finished but died.
216 - self.dead: jobs which finished but died.
217
217
218 It also copies those jobs to corresponding _report lists. These lists
218 It also copies those jobs to corresponding _report lists. These lists
219 are used to report jobs completed/dead since the last update, and are
219 are used to report jobs completed/dead since the last update, and are
220 then cleared by the reporting function after each call."""
220 then cleared by the reporting function after each call."""
221
221
222 # Status codes
222 # Status codes
223 srun, scomp, sdead = self._s_running, self._s_completed, self._s_dead
223 srun, scomp, sdead = self._s_running, self._s_completed, self._s_dead
224 # State lists, use the actual lists b/c the public names are properties
224 # State lists, use the actual lists b/c the public names are properties
225 # that call this very function on access
225 # that call this very function on access
226 running, completed, dead = self._running, self._completed, self._dead
226 running, completed, dead = self._running, self._completed, self._dead
227
227
228 # Now, update all state lists
228 # Now, update all state lists
229 for num, job in enumerate(running):
229 for num, job in enumerate(running):
230 stat = job.stat_code
230 stat = job.stat_code
231 if stat == srun:
231 if stat == srun:
232 continue
232 continue
233 elif stat == scomp:
233 elif stat == scomp:
234 completed.append(job)
234 completed.append(job)
235 self._comp_report.append(job)
235 self._comp_report.append(job)
236 running[num] = False
236 running[num] = False
237 elif stat == sdead:
237 elif stat == sdead:
238 dead.append(job)
238 dead.append(job)
239 self._dead_report.append(job)
239 self._dead_report.append(job)
240 running[num] = False
240 running[num] = False
241 # Remove dead/completed jobs from running list
241 # Remove dead/completed jobs from running list
242 running[:] = filter(None, running)
242 running[:] = filter(None, running)
243
243
244 def _group_report(self,group,name):
244 def _group_report(self,group,name):
245 """Report summary for a given job group.
245 """Report summary for a given job group.
246
246
247 Return True if the group had any elements."""
247 Return True if the group had any elements."""
248
248
249 if group:
249 if group:
250 print('%s jobs:' % name)
250 print('%s jobs:' % name)
251 for job in group:
251 for job in group:
252 print('%s : %s' % (job.num,job))
252 print('%s : %s' % (job.num,job))
253 print()
253 print()
254 return True
254 return True
255
255
256 def _group_flush(self,group,name):
256 def _group_flush(self,group,name):
257 """Flush a given job group
257 """Flush a given job group
258
258
259 Return True if the group had any elements."""
259 Return True if the group had any elements."""
260
260
261 njobs = len(group)
261 njobs = len(group)
262 if njobs:
262 if njobs:
263 plural = {1:''}.setdefault(njobs,'s')
263 plural = {1:''}.setdefault(njobs,'s')
264 print('Flushing %s %s job%s.' % (njobs,name,plural))
264 print('Flushing %s %s job%s.' % (njobs,name,plural))
265 group[:] = []
265 group[:] = []
266 return True
266 return True
267
267
268 def _status_new(self):
268 def _status_new(self):
269 """Print the status of newly finished jobs.
269 """Print the status of newly finished jobs.
270
270
271 Return True if any new jobs are reported.
271 Return True if any new jobs are reported.
272
272
273 This call resets its own state every time, so it only reports jobs
273 This call resets its own state every time, so it only reports jobs
274 which have finished since the last time it was called."""
274 which have finished since the last time it was called."""
275
275
276 self._update_status()
276 self._update_status()
277 new_comp = self._group_report(self._comp_report, 'Completed')
277 new_comp = self._group_report(self._comp_report, 'Completed')
278 new_dead = self._group_report(self._dead_report,
278 new_dead = self._group_report(self._dead_report,
279 'Dead, call jobs.traceback() for details')
279 'Dead, call jobs.traceback() for details')
280 self._comp_report[:] = []
280 self._comp_report[:] = []
281 self._dead_report[:] = []
281 self._dead_report[:] = []
282 return new_comp or new_dead
282 return new_comp or new_dead
283
283
284 def status(self,verbose=0):
284 def status(self,verbose=0):
285 """Print a status of all jobs currently being managed."""
285 """Print a status of all jobs currently being managed."""
286
286
287 self._update_status()
287 self._update_status()
288 self._group_report(self.running,'Running')
288 self._group_report(self.running,'Running')
289 self._group_report(self.completed,'Completed')
289 self._group_report(self.completed,'Completed')
290 self._group_report(self.dead,'Dead')
290 self._group_report(self.dead,'Dead')
291 # Also flush the report queues
291 # Also flush the report queues
292 self._comp_report[:] = []
292 self._comp_report[:] = []
293 self._dead_report[:] = []
293 self._dead_report[:] = []
294
294
295 def remove(self,num):
295 def remove(self,num):
296 """Remove a finished (completed or dead) job."""
296 """Remove a finished (completed or dead) job."""
297
297
298 try:
298 try:
299 job = self.all[num]
299 job = self.all[num]
300 except KeyError:
300 except KeyError:
301 error('Job #%s not found' % num)
301 error('Job #%s not found' % num)
302 else:
302 else:
303 stat_code = job.stat_code
303 stat_code = job.stat_code
304 if stat_code == self._s_running:
304 if stat_code == self._s_running:
305 error('Job #%s is still running, it can not be removed.' % num)
305 error('Job #%s is still running, it can not be removed.' % num)
306 return
306 return
307 elif stat_code == self._s_completed:
307 elif stat_code == self._s_completed:
308 self.completed.remove(job)
308 self.completed.remove(job)
309 elif stat_code == self._s_dead:
309 elif stat_code == self._s_dead:
310 self.dead.remove(job)
310 self.dead.remove(job)
311
311
312 def flush(self):
312 def flush(self):
313 """Flush all finished jobs (completed and dead) from lists.
313 """Flush all finished jobs (completed and dead) from lists.
314
314
315 Running jobs are never flushed.
315 Running jobs are never flushed.
316
316
317 It first calls _status_new(), to update info. If any jobs have
317 It first calls _status_new(), to update info. If any jobs have
318 completed since the last _status_new() call, the flush operation
318 completed since the last _status_new() call, the flush operation
319 aborts."""
319 aborts."""
320
320
321 # Remove the finished jobs from the master dict
321 # Remove the finished jobs from the master dict
322 alljobs = self.all
322 alljobs = self.all
323 for job in self.completed+self.dead:
323 for job in self.completed+self.dead:
324 del(alljobs[job.num])
324 del(alljobs[job.num])
325
325
326 # Now flush these lists completely
326 # Now flush these lists completely
327 fl_comp = self._group_flush(self.completed, 'Completed')
327 fl_comp = self._group_flush(self.completed, 'Completed')
328 fl_dead = self._group_flush(self.dead, 'Dead')
328 fl_dead = self._group_flush(self.dead, 'Dead')
329 if not (fl_comp or fl_dead):
329 if not (fl_comp or fl_dead):
330 print('No jobs to flush.')
330 print('No jobs to flush.')
331
331
332 def result(self,num):
332 def result(self,num):
333 """result(N) -> return the result of job N."""
333 """result(N) -> return the result of job N."""
334 try:
334 try:
335 return self.all[num].result
335 return self.all[num].result
336 except KeyError:
336 except KeyError:
337 error('Job #%s not found' % num)
337 error('Job #%s not found' % num)
338
338
339 def _traceback(self, job):
339 def _traceback(self, job):
340 num = job if isinstance(job, int) else job.num
340 num = job if isinstance(job, int) else job.num
341 try:
341 try:
342 self.all[num].traceback()
342 self.all[num].traceback()
343 except KeyError:
343 except KeyError:
344 error('Job #%s not found' % num)
344 error('Job #%s not found' % num)
345
345
346 def traceback(self, job=None):
346 def traceback(self, job=None):
347 if job is None:
347 if job is None:
348 self._update_status()
348 self._update_status()
349 for deadjob in self.dead:
349 for deadjob in self.dead:
350 print("Traceback for: %r" % deadjob)
350 print("Traceback for: %r" % deadjob)
351 self._traceback(deadjob)
351 self._traceback(deadjob)
352 print()
352 print()
353 else:
353 else:
354 self._traceback(job)
354 self._traceback(job)
355
355
356
356
357 class BackgroundJobBase(threading.Thread):
357 class BackgroundJobBase(threading.Thread):
358 """Base class to build BackgroundJob classes.
358 """Base class to build BackgroundJob classes.
359
359
360 The derived classes must implement:
360 The derived classes must implement:
361
361
362 - Their own __init__, since the one here raises NotImplementedError. The
362 - Their own __init__, since the one here raises NotImplementedError. The
363 derived constructor must call self._init() at the end, to provide common
363 derived constructor must call self._init() at the end, to provide common
364 initialization.
364 initialization.
365
365
366 - A strform attribute used in calls to __str__.
366 - A strform attribute used in calls to __str__.
367
367
368 - A call() method, which will make the actual execution call and must
368 - A call() method, which will make the actual execution call and must
369 return a value to be held in the 'result' field of the job object.
369 return a value to be held in the 'result' field of the job object.
370 """
370 """
371
371
372 # Class constants for status, in string and as numerical codes (when
372 # Class constants for status, in string and as numerical codes (when
373 # updating jobs lists, we don't want to do string comparisons). This will
373 # updating jobs lists, we don't want to do string comparisons). This will
374 # be done at every user prompt, so it has to be as fast as possible
374 # be done at every user prompt, so it has to be as fast as possible
375 stat_created = 'Created'; stat_created_c = 0
375 stat_created = 'Created'; stat_created_c = 0
376 stat_running = 'Running'; stat_running_c = 1
376 stat_running = 'Running'; stat_running_c = 1
377 stat_completed = 'Completed'; stat_completed_c = 2
377 stat_completed = 'Completed'; stat_completed_c = 2
378 stat_dead = 'Dead (Exception), call jobs.traceback() for details'
378 stat_dead = 'Dead (Exception), call jobs.traceback() for details'
379 stat_dead_c = -1
379 stat_dead_c = -1
380
380
381 def __init__(self):
381 def __init__(self):
382 """Must be implemented in subclasses.
382 """Must be implemented in subclasses.
383
383
384 Subclasses must call :meth:`_init` for standard initialisation.
384 Subclasses must call :meth:`_init` for standard initialisation.
385 """
385 """
386 raise NotImplementedError("This class can not be instantiated directly.")
386 raise NotImplementedError("This class can not be instantiated directly.")
387
387
388 def _init(self):
388 def _init(self):
389 """Common initialization for all BackgroundJob objects"""
389 """Common initialization for all BackgroundJob objects"""
390
390
391 for attr in ['call','strform']:
391 for attr in ['call','strform']:
392 assert hasattr(self,attr), "Missing attribute <%s>" % attr
392 assert hasattr(self,attr), "Missing attribute <%s>" % attr
393
393
394 # The num tag can be set by an external job manager
394 # The num tag can be set by an external job manager
395 self.num = None
395 self.num = None
396
396
397 self.status = BackgroundJobBase.stat_created
397 self.status = BackgroundJobBase.stat_created
398 self.stat_code = BackgroundJobBase.stat_created_c
398 self.stat_code = BackgroundJobBase.stat_created_c
399 self.finished = False
399 self.finished = False
400 self.result = '<BackgroundJob has not completed>'
400 self.result = '<BackgroundJob has not completed>'
401
401
402 # reuse the ipython traceback handler if we can get to it, otherwise
402 # reuse the ipython traceback handler if we can get to it, otherwise
403 # make a new one
403 # make a new one
404 try:
404 try:
405 make_tb = get_ipython().InteractiveTB.text
405 make_tb = get_ipython().InteractiveTB.text
406 except:
406 except:
407 make_tb = AutoFormattedTB(mode = 'Context',
407 make_tb = AutoFormattedTB(mode = 'Context',
408 color_scheme='NoColor',
408 color_scheme='NoColor',
409 tb_offset = 1).text
409 tb_offset = 1).text
410 # Note that the actual API for text() requires the three args to be
410 # Note that the actual API for text() requires the three args to be
411 # passed in, so we wrap it in a simple lambda.
411 # passed in, so we wrap it in a simple lambda.
412 self._make_tb = lambda : make_tb(None, None, None)
412 self._make_tb = lambda : make_tb(None, None, None)
413
413
414 # Hold a formatted traceback if one is generated.
414 # Hold a formatted traceback if one is generated.
415 self._tb = None
415 self._tb = None
416
416
417 threading.Thread.__init__(self)
417 threading.Thread.__init__(self)
418
418
419 def __str__(self):
419 def __str__(self):
420 return self.strform
420 return self.strform
421
421
422 def __repr__(self):
422 def __repr__(self):
423 return '<BackgroundJob #%d: %s>' % (self.num, self.strform)
423 return '<BackgroundJob #%d: %s>' % (self.num, self.strform)
424
424
425 def traceback(self):
425 def traceback(self):
426 print(self._tb)
426 print(self._tb)
427
427
428 def run(self):
428 def run(self):
429 try:
429 try:
430 self.status = BackgroundJobBase.stat_running
430 self.status = BackgroundJobBase.stat_running
431 self.stat_code = BackgroundJobBase.stat_running_c
431 self.stat_code = BackgroundJobBase.stat_running_c
432 self.result = self.call()
432 self.result = self.call()
433 except:
433 except:
434 self.status = BackgroundJobBase.stat_dead
434 self.status = BackgroundJobBase.stat_dead
435 self.stat_code = BackgroundJobBase.stat_dead_c
435 self.stat_code = BackgroundJobBase.stat_dead_c
436 self.finished = None
436 self.finished = None
437 self.result = ('<BackgroundJob died, call jobs.traceback() for details>')
437 self.result = ('<BackgroundJob died, call jobs.traceback() for details>')
438 self._tb = self._make_tb()
438 self._tb = self._make_tb()
439 else:
439 else:
440 self.status = BackgroundJobBase.stat_completed
440 self.status = BackgroundJobBase.stat_completed
441 self.stat_code = BackgroundJobBase.stat_completed_c
441 self.stat_code = BackgroundJobBase.stat_completed_c
442 self.finished = True
442 self.finished = True
443
443
444
444
445 class BackgroundJobExpr(BackgroundJobBase):
445 class BackgroundJobExpr(BackgroundJobBase):
446 """Evaluate an expression as a background job (uses a separate thread)."""
446 """Evaluate an expression as a background job (uses a separate thread)."""
447
447
448 def __init__(self, expression, glob=None, loc=None):
448 def __init__(self, expression, glob=None, loc=None):
449 """Create a new job from a string which can be fed to eval().
449 """Create a new job from a string which can be fed to eval().
450
450
451 global/locals dicts can be provided, which will be passed to the eval
451 global/locals dicts can be provided, which will be passed to the eval
452 call."""
452 call."""
453
453
454 # fail immediately if the given expression can't be compiled
454 # fail immediately if the given expression can't be compiled
455 self.code = compile(expression,'<BackgroundJob compilation>','eval')
455 self.code = compile(expression,'<BackgroundJob compilation>','eval')
456
456
457 glob = {} if glob is None else glob
457 glob = {} if glob is None else glob
458 loc = {} if loc is None else loc
458 loc = {} if loc is None else loc
459 self.expression = self.strform = expression
459 self.expression = self.strform = expression
460 self.glob = glob
460 self.glob = glob
461 self.loc = loc
461 self.loc = loc
462 self._init()
462 self._init()
463
463
464 def call(self):
464 def call(self):
465 return eval(self.code,self.glob,self.loc)
465 return eval(self.code,self.glob,self.loc)
466
466
467
467
468 class BackgroundJobFunc(BackgroundJobBase):
468 class BackgroundJobFunc(BackgroundJobBase):
469 """Run a function call as a background job (uses a separate thread)."""
469 """Run a function call as a background job (uses a separate thread)."""
470
470
471 def __init__(self, func, *args, **kwargs):
471 def __init__(self, func, *args, **kwargs):
472 """Create a new job from a callable object.
472 """Create a new job from a callable object.
473
473
474 Any positional arguments and keyword args given to this constructor
474 Any positional arguments and keyword args given to this constructor
475 after the initial callable are passed directly to it."""
475 after the initial callable are passed directly to it."""
476
476
477 if not callable(func):
477 if not callable(func):
478 raise TypeError(
478 raise TypeError(
479 'first argument to BackgroundJobFunc must be callable')
479 'first argument to BackgroundJobFunc must be callable')
480
480
481 self.func = func
481 self.func = func
482 self.args = args
482 self.args = args
483 self.kwargs = kwargs
483 self.kwargs = kwargs
484 # The string form will only include the function passed, because
484 # The string form will only include the function passed, because
485 # generating string representations of the arguments is a potentially
485 # generating string representations of the arguments is a potentially
486 # _very_ expensive operation (e.g. with large arrays).
486 # _very_ expensive operation (e.g. with large arrays).
487 self.strform = str(func)
487 self.strform = str(func)
488 self._init()
488 self._init()
489
489
490 def call(self):
490 def call(self):
491 return self.func(*self.args, **self.kwargs)
491 return self.func(*self.args, **self.kwargs)
@@ -1,574 +1,574 b''
1 # coding: utf-8
1 # coding: utf-8
2 """
2 """
3 Inputhook management for GUI event loop integration.
3 Inputhook management for GUI event loop integration.
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 try:
9 try:
10 import ctypes
10 import ctypes
11 except ImportError:
11 except ImportError:
12 ctypes = None
12 ctypes = None
13 except SystemError: # IronPython issue, 2/8/2014
13 except SystemError: # IronPython issue, 2/8/2014
14 ctypes = None
14 ctypes = None
15 import os
15 import os
16 import platform
16 import platform
17 import sys
17 import sys
18 from distutils.version import LooseVersion as V
18 from distutils.version import LooseVersion as V
19
19
20 from IPython.utils.warn import warn
20 from warnings import warn
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Constants
23 # Constants
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 # Constants for identifying the GUI toolkits.
26 # Constants for identifying the GUI toolkits.
27 GUI_WX = 'wx'
27 GUI_WX = 'wx'
28 GUI_QT = 'qt'
28 GUI_QT = 'qt'
29 GUI_QT4 = 'qt4'
29 GUI_QT4 = 'qt4'
30 GUI_GTK = 'gtk'
30 GUI_GTK = 'gtk'
31 GUI_TK = 'tk'
31 GUI_TK = 'tk'
32 GUI_OSX = 'osx'
32 GUI_OSX = 'osx'
33 GUI_GLUT = 'glut'
33 GUI_GLUT = 'glut'
34 GUI_PYGLET = 'pyglet'
34 GUI_PYGLET = 'pyglet'
35 GUI_GTK3 = 'gtk3'
35 GUI_GTK3 = 'gtk3'
36 GUI_NONE = 'none' # i.e. disable
36 GUI_NONE = 'none' # i.e. disable
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Utilities
39 # Utilities
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 def _stdin_ready_posix():
42 def _stdin_ready_posix():
43 """Return True if there's something to read on stdin (posix version)."""
43 """Return True if there's something to read on stdin (posix version)."""
44 infds, outfds, erfds = select.select([sys.stdin],[],[],0)
44 infds, outfds, erfds = select.select([sys.stdin],[],[],0)
45 return bool(infds)
45 return bool(infds)
46
46
47 def _stdin_ready_nt():
47 def _stdin_ready_nt():
48 """Return True if there's something to read on stdin (nt version)."""
48 """Return True if there's something to read on stdin (nt version)."""
49 return msvcrt.kbhit()
49 return msvcrt.kbhit()
50
50
51 def _stdin_ready_other():
51 def _stdin_ready_other():
52 """Return True, assuming there's something to read on stdin."""
52 """Return True, assuming there's something to read on stdin."""
53 return True
53 return True
54
54
55 def _use_appnope():
55 def _use_appnope():
56 """Should we use appnope for dealing with OS X app nap?
56 """Should we use appnope for dealing with OS X app nap?
57
57
58 Checks if we are on OS X 10.9 or greater.
58 Checks if we are on OS X 10.9 or greater.
59 """
59 """
60 return sys.platform == 'darwin' and V(platform.mac_ver()[0]) >= V('10.9')
60 return sys.platform == 'darwin' and V(platform.mac_ver()[0]) >= V('10.9')
61
61
62 def _ignore_CTRL_C_posix():
62 def _ignore_CTRL_C_posix():
63 """Ignore CTRL+C (SIGINT)."""
63 """Ignore CTRL+C (SIGINT)."""
64 signal.signal(signal.SIGINT, signal.SIG_IGN)
64 signal.signal(signal.SIGINT, signal.SIG_IGN)
65
65
66 def _allow_CTRL_C_posix():
66 def _allow_CTRL_C_posix():
67 """Take CTRL+C into account (SIGINT)."""
67 """Take CTRL+C into account (SIGINT)."""
68 signal.signal(signal.SIGINT, signal.default_int_handler)
68 signal.signal(signal.SIGINT, signal.default_int_handler)
69
69
70 def _ignore_CTRL_C_other():
70 def _ignore_CTRL_C_other():
71 """Ignore CTRL+C (not implemented)."""
71 """Ignore CTRL+C (not implemented)."""
72 pass
72 pass
73
73
74 def _allow_CTRL_C_other():
74 def _allow_CTRL_C_other():
75 """Take CTRL+C into account (not implemented)."""
75 """Take CTRL+C into account (not implemented)."""
76 pass
76 pass
77
77
78 if os.name == 'posix':
78 if os.name == 'posix':
79 import select
79 import select
80 import signal
80 import signal
81 stdin_ready = _stdin_ready_posix
81 stdin_ready = _stdin_ready_posix
82 ignore_CTRL_C = _ignore_CTRL_C_posix
82 ignore_CTRL_C = _ignore_CTRL_C_posix
83 allow_CTRL_C = _allow_CTRL_C_posix
83 allow_CTRL_C = _allow_CTRL_C_posix
84 elif os.name == 'nt':
84 elif os.name == 'nt':
85 import msvcrt
85 import msvcrt
86 stdin_ready = _stdin_ready_nt
86 stdin_ready = _stdin_ready_nt
87 ignore_CTRL_C = _ignore_CTRL_C_other
87 ignore_CTRL_C = _ignore_CTRL_C_other
88 allow_CTRL_C = _allow_CTRL_C_other
88 allow_CTRL_C = _allow_CTRL_C_other
89 else:
89 else:
90 stdin_ready = _stdin_ready_other
90 stdin_ready = _stdin_ready_other
91 ignore_CTRL_C = _ignore_CTRL_C_other
91 ignore_CTRL_C = _ignore_CTRL_C_other
92 allow_CTRL_C = _allow_CTRL_C_other
92 allow_CTRL_C = _allow_CTRL_C_other
93
93
94
94
95 #-----------------------------------------------------------------------------
95 #-----------------------------------------------------------------------------
96 # Main InputHookManager class
96 # Main InputHookManager class
97 #-----------------------------------------------------------------------------
97 #-----------------------------------------------------------------------------
98
98
99
99
100 class InputHookManager(object):
100 class InputHookManager(object):
101 """Manage PyOS_InputHook for different GUI toolkits.
101 """Manage PyOS_InputHook for different GUI toolkits.
102
102
103 This class installs various hooks under ``PyOSInputHook`` to handle
103 This class installs various hooks under ``PyOSInputHook`` to handle
104 GUI event loop integration.
104 GUI event loop integration.
105 """
105 """
106
106
107 def __init__(self):
107 def __init__(self):
108 if ctypes is None:
108 if ctypes is None:
109 warn("IPython GUI event loop requires ctypes, %gui will not be available")
109 warn("IPython GUI event loop requires ctypes, %gui will not be available")
110 else:
110 else:
111 self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int)
111 self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int)
112 self.guihooks = {}
112 self.guihooks = {}
113 self.aliases = {}
113 self.aliases = {}
114 self.apps = {}
114 self.apps = {}
115 self._reset()
115 self._reset()
116
116
117 def _reset(self):
117 def _reset(self):
118 self._callback_pyfunctype = None
118 self._callback_pyfunctype = None
119 self._callback = None
119 self._callback = None
120 self._installed = False
120 self._installed = False
121 self._current_gui = None
121 self._current_gui = None
122
122
123 def get_pyos_inputhook(self):
123 def get_pyos_inputhook(self):
124 """Return the current PyOS_InputHook as a ctypes.c_void_p."""
124 """Return the current PyOS_InputHook as a ctypes.c_void_p."""
125 return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook")
125 return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook")
126
126
127 def get_pyos_inputhook_as_func(self):
127 def get_pyos_inputhook_as_func(self):
128 """Return the current PyOS_InputHook as a ctypes.PYFUNCYPE."""
128 """Return the current PyOS_InputHook as a ctypes.PYFUNCYPE."""
129 return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook")
129 return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook")
130
130
131 def set_inputhook(self, callback):
131 def set_inputhook(self, callback):
132 """Set PyOS_InputHook to callback and return the previous one."""
132 """Set PyOS_InputHook to callback and return the previous one."""
133 # On platforms with 'readline' support, it's all too likely to
133 # On platforms with 'readline' support, it's all too likely to
134 # have a KeyboardInterrupt signal delivered *even before* an
134 # have a KeyboardInterrupt signal delivered *even before* an
135 # initial ``try:`` clause in the callback can be executed, so
135 # initial ``try:`` clause in the callback can be executed, so
136 # we need to disable CTRL+C in this situation.
136 # we need to disable CTRL+C in this situation.
137 ignore_CTRL_C()
137 ignore_CTRL_C()
138 self._callback = callback
138 self._callback = callback
139 self._callback_pyfunctype = self.PYFUNC(callback)
139 self._callback_pyfunctype = self.PYFUNC(callback)
140 pyos_inputhook_ptr = self.get_pyos_inputhook()
140 pyos_inputhook_ptr = self.get_pyos_inputhook()
141 original = self.get_pyos_inputhook_as_func()
141 original = self.get_pyos_inputhook_as_func()
142 pyos_inputhook_ptr.value = \
142 pyos_inputhook_ptr.value = \
143 ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value
143 ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value
144 self._installed = True
144 self._installed = True
145 return original
145 return original
146
146
147 def clear_inputhook(self, app=None):
147 def clear_inputhook(self, app=None):
148 """Set PyOS_InputHook to NULL and return the previous one.
148 """Set PyOS_InputHook to NULL and return the previous one.
149
149
150 Parameters
150 Parameters
151 ----------
151 ----------
152 app : optional, ignored
152 app : optional, ignored
153 This parameter is allowed only so that clear_inputhook() can be
153 This parameter is allowed only so that clear_inputhook() can be
154 called with a similar interface as all the ``enable_*`` methods. But
154 called with a similar interface as all the ``enable_*`` methods. But
155 the actual value of the parameter is ignored. This uniform interface
155 the actual value of the parameter is ignored. This uniform interface
156 makes it easier to have user-level entry points in the main IPython
156 makes it easier to have user-level entry points in the main IPython
157 app like :meth:`enable_gui`."""
157 app like :meth:`enable_gui`."""
158 pyos_inputhook_ptr = self.get_pyos_inputhook()
158 pyos_inputhook_ptr = self.get_pyos_inputhook()
159 original = self.get_pyos_inputhook_as_func()
159 original = self.get_pyos_inputhook_as_func()
160 pyos_inputhook_ptr.value = ctypes.c_void_p(None).value
160 pyos_inputhook_ptr.value = ctypes.c_void_p(None).value
161 allow_CTRL_C()
161 allow_CTRL_C()
162 self._reset()
162 self._reset()
163 return original
163 return original
164
164
165 def clear_app_refs(self, gui=None):
165 def clear_app_refs(self, gui=None):
166 """Clear IPython's internal reference to an application instance.
166 """Clear IPython's internal reference to an application instance.
167
167
168 Whenever we create an app for a user on qt4 or wx, we hold a
168 Whenever we create an app for a user on qt4 or wx, we hold a
169 reference to the app. This is needed because in some cases bad things
169 reference to the app. This is needed because in some cases bad things
170 can happen if a user doesn't hold a reference themselves. This
170 can happen if a user doesn't hold a reference themselves. This
171 method is provided to clear the references we are holding.
171 method is provided to clear the references we are holding.
172
172
173 Parameters
173 Parameters
174 ----------
174 ----------
175 gui : None or str
175 gui : None or str
176 If None, clear all app references. If ('wx', 'qt4') clear
176 If None, clear all app references. If ('wx', 'qt4') clear
177 the app for that toolkit. References are not held for gtk or tk
177 the app for that toolkit. References are not held for gtk or tk
178 as those toolkits don't have the notion of an app.
178 as those toolkits don't have the notion of an app.
179 """
179 """
180 if gui is None:
180 if gui is None:
181 self.apps = {}
181 self.apps = {}
182 elif gui in self.apps:
182 elif gui in self.apps:
183 del self.apps[gui]
183 del self.apps[gui]
184
184
185 def register(self, toolkitname, *aliases):
185 def register(self, toolkitname, *aliases):
186 """Register a class to provide the event loop for a given GUI.
186 """Register a class to provide the event loop for a given GUI.
187
187
188 This is intended to be used as a class decorator. It should be passed
188 This is intended to be used as a class decorator. It should be passed
189 the names with which to register this GUI integration. The classes
189 the names with which to register this GUI integration. The classes
190 themselves should subclass :class:`InputHookBase`.
190 themselves should subclass :class:`InputHookBase`.
191
191
192 ::
192 ::
193
193
194 @inputhook_manager.register('qt')
194 @inputhook_manager.register('qt')
195 class QtInputHook(InputHookBase):
195 class QtInputHook(InputHookBase):
196 def enable(self, app=None):
196 def enable(self, app=None):
197 ...
197 ...
198 """
198 """
199 def decorator(cls):
199 def decorator(cls):
200 if ctypes is not None:
200 if ctypes is not None:
201 inst = cls(self)
201 inst = cls(self)
202 self.guihooks[toolkitname] = inst
202 self.guihooks[toolkitname] = inst
203 for a in aliases:
203 for a in aliases:
204 self.aliases[a] = toolkitname
204 self.aliases[a] = toolkitname
205 return cls
205 return cls
206 return decorator
206 return decorator
207
207
208 def current_gui(self):
208 def current_gui(self):
209 """Return a string indicating the currently active GUI or None."""
209 """Return a string indicating the currently active GUI or None."""
210 return self._current_gui
210 return self._current_gui
211
211
212 def enable_gui(self, gui=None, app=None):
212 def enable_gui(self, gui=None, app=None):
213 """Switch amongst GUI input hooks by name.
213 """Switch amongst GUI input hooks by name.
214
214
215 This is a higher level method than :meth:`set_inputhook` - it uses the
215 This is a higher level method than :meth:`set_inputhook` - it uses the
216 GUI name to look up a registered object which enables the input hook
216 GUI name to look up a registered object which enables the input hook
217 for that GUI.
217 for that GUI.
218
218
219 Parameters
219 Parameters
220 ----------
220 ----------
221 gui : optional, string or None
221 gui : optional, string or None
222 If None (or 'none'), clears input hook, otherwise it must be one
222 If None (or 'none'), clears input hook, otherwise it must be one
223 of the recognized GUI names (see ``GUI_*`` constants in module).
223 of the recognized GUI names (see ``GUI_*`` constants in module).
224
224
225 app : optional, existing application object.
225 app : optional, existing application object.
226 For toolkits that have the concept of a global app, you can supply an
226 For toolkits that have the concept of a global app, you can supply an
227 existing one. If not given, the toolkit will be probed for one, and if
227 existing one. If not given, the toolkit will be probed for one, and if
228 none is found, a new one will be created. Note that GTK does not have
228 none is found, a new one will be created. Note that GTK does not have
229 this concept, and passing an app if ``gui=="GTK"`` will raise an error.
229 this concept, and passing an app if ``gui=="GTK"`` will raise an error.
230
230
231 Returns
231 Returns
232 -------
232 -------
233 The output of the underlying gui switch routine, typically the actual
233 The output of the underlying gui switch routine, typically the actual
234 PyOS_InputHook wrapper object or the GUI toolkit app created, if there was
234 PyOS_InputHook wrapper object or the GUI toolkit app created, if there was
235 one.
235 one.
236 """
236 """
237 if gui in (None, GUI_NONE):
237 if gui in (None, GUI_NONE):
238 return self.disable_gui()
238 return self.disable_gui()
239
239
240 if gui in self.aliases:
240 if gui in self.aliases:
241 return self.enable_gui(self.aliases[gui], app)
241 return self.enable_gui(self.aliases[gui], app)
242
242
243 try:
243 try:
244 gui_hook = self.guihooks[gui]
244 gui_hook = self.guihooks[gui]
245 except KeyError:
245 except KeyError:
246 e = "Invalid GUI request {!r}, valid ones are: {}"
246 e = "Invalid GUI request {!r}, valid ones are: {}"
247 raise ValueError(e.format(gui, ', '.join(self.guihooks)))
247 raise ValueError(e.format(gui, ', '.join(self.guihooks)))
248 self._current_gui = gui
248 self._current_gui = gui
249
249
250 app = gui_hook.enable(app)
250 app = gui_hook.enable(app)
251 if app is not None:
251 if app is not None:
252 app._in_event_loop = True
252 app._in_event_loop = True
253 self.apps[gui] = app
253 self.apps[gui] = app
254 return app
254 return app
255
255
256 def disable_gui(self):
256 def disable_gui(self):
257 """Disable GUI event loop integration.
257 """Disable GUI event loop integration.
258
258
259 If an application was registered, this sets its ``_in_event_loop``
259 If an application was registered, this sets its ``_in_event_loop``
260 attribute to False. It then calls :meth:`clear_inputhook`.
260 attribute to False. It then calls :meth:`clear_inputhook`.
261 """
261 """
262 gui = self._current_gui
262 gui = self._current_gui
263 if gui in self.apps:
263 if gui in self.apps:
264 self.apps[gui]._in_event_loop = False
264 self.apps[gui]._in_event_loop = False
265 return self.clear_inputhook()
265 return self.clear_inputhook()
266
266
267 class InputHookBase(object):
267 class InputHookBase(object):
268 """Base class for input hooks for specific toolkits.
268 """Base class for input hooks for specific toolkits.
269
269
270 Subclasses should define an :meth:`enable` method with one argument, ``app``,
270 Subclasses should define an :meth:`enable` method with one argument, ``app``,
271 which will either be an instance of the toolkit's application class, or None.
271 which will either be an instance of the toolkit's application class, or None.
272 They may also define a :meth:`disable` method with no arguments.
272 They may also define a :meth:`disable` method with no arguments.
273 """
273 """
274 def __init__(self, manager):
274 def __init__(self, manager):
275 self.manager = manager
275 self.manager = manager
276
276
277 def disable(self):
277 def disable(self):
278 pass
278 pass
279
279
280 inputhook_manager = InputHookManager()
280 inputhook_manager = InputHookManager()
281
281
282 @inputhook_manager.register('osx')
282 @inputhook_manager.register('osx')
283 class NullInputHook(InputHookBase):
283 class NullInputHook(InputHookBase):
284 """A null inputhook that doesn't need to do anything"""
284 """A null inputhook that doesn't need to do anything"""
285 def enable(self, app=None):
285 def enable(self, app=None):
286 pass
286 pass
287
287
288 @inputhook_manager.register('wx')
288 @inputhook_manager.register('wx')
289 class WxInputHook(InputHookBase):
289 class WxInputHook(InputHookBase):
290 def enable(self, app=None):
290 def enable(self, app=None):
291 """Enable event loop integration with wxPython.
291 """Enable event loop integration with wxPython.
292
292
293 Parameters
293 Parameters
294 ----------
294 ----------
295 app : WX Application, optional.
295 app : WX Application, optional.
296 Running application to use. If not given, we probe WX for an
296 Running application to use. If not given, we probe WX for an
297 existing application object, and create a new one if none is found.
297 existing application object, and create a new one if none is found.
298
298
299 Notes
299 Notes
300 -----
300 -----
301 This methods sets the ``PyOS_InputHook`` for wxPython, which allows
301 This methods sets the ``PyOS_InputHook`` for wxPython, which allows
302 the wxPython to integrate with terminal based applications like
302 the wxPython to integrate with terminal based applications like
303 IPython.
303 IPython.
304
304
305 If ``app`` is not given we probe for an existing one, and return it if
305 If ``app`` is not given we probe for an existing one, and return it if
306 found. If no existing app is found, we create an :class:`wx.App` as
306 found. If no existing app is found, we create an :class:`wx.App` as
307 follows::
307 follows::
308
308
309 import wx
309 import wx
310 app = wx.App(redirect=False, clearSigInt=False)
310 app = wx.App(redirect=False, clearSigInt=False)
311 """
311 """
312 import wx
312 import wx
313
313
314 wx_version = V(wx.__version__).version
314 wx_version = V(wx.__version__).version
315
315
316 if wx_version < [2, 8]:
316 if wx_version < [2, 8]:
317 raise ValueError("requires wxPython >= 2.8, but you have %s" % wx.__version__)
317 raise ValueError("requires wxPython >= 2.8, but you have %s" % wx.__version__)
318
318
319 from IPython.lib.inputhookwx import inputhook_wx
319 from IPython.lib.inputhookwx import inputhook_wx
320 self.manager.set_inputhook(inputhook_wx)
320 self.manager.set_inputhook(inputhook_wx)
321 if _use_appnope():
321 if _use_appnope():
322 from appnope import nope
322 from appnope import nope
323 nope()
323 nope()
324
324
325 import wx
325 import wx
326 if app is None:
326 if app is None:
327 app = wx.GetApp()
327 app = wx.GetApp()
328 if app is None:
328 if app is None:
329 app = wx.App(redirect=False, clearSigInt=False)
329 app = wx.App(redirect=False, clearSigInt=False)
330
330
331 return app
331 return app
332
332
333 def disable(self):
333 def disable(self):
334 """Disable event loop integration with wxPython.
334 """Disable event loop integration with wxPython.
335
335
336 This restores appnapp on OS X
336 This restores appnapp on OS X
337 """
337 """
338 if _use_appnope():
338 if _use_appnope():
339 from appnope import nap
339 from appnope import nap
340 nap()
340 nap()
341
341
342 @inputhook_manager.register('qt', 'qt4')
342 @inputhook_manager.register('qt', 'qt4')
343 class Qt4InputHook(InputHookBase):
343 class Qt4InputHook(InputHookBase):
344 def enable(self, app=None):
344 def enable(self, app=None):
345 """Enable event loop integration with PyQt4.
345 """Enable event loop integration with PyQt4.
346
346
347 Parameters
347 Parameters
348 ----------
348 ----------
349 app : Qt Application, optional.
349 app : Qt Application, optional.
350 Running application to use. If not given, we probe Qt for an
350 Running application to use. If not given, we probe Qt for an
351 existing application object, and create a new one if none is found.
351 existing application object, and create a new one if none is found.
352
352
353 Notes
353 Notes
354 -----
354 -----
355 This methods sets the PyOS_InputHook for PyQt4, which allows
355 This methods sets the PyOS_InputHook for PyQt4, which allows
356 the PyQt4 to integrate with terminal based applications like
356 the PyQt4 to integrate with terminal based applications like
357 IPython.
357 IPython.
358
358
359 If ``app`` is not given we probe for an existing one, and return it if
359 If ``app`` is not given we probe for an existing one, and return it if
360 found. If no existing app is found, we create an :class:`QApplication`
360 found. If no existing app is found, we create an :class:`QApplication`
361 as follows::
361 as follows::
362
362
363 from PyQt4 import QtCore
363 from PyQt4 import QtCore
364 app = QtGui.QApplication(sys.argv)
364 app = QtGui.QApplication(sys.argv)
365 """
365 """
366 from IPython.lib.inputhookqt4 import create_inputhook_qt4
366 from IPython.lib.inputhookqt4 import create_inputhook_qt4
367 app, inputhook_qt4 = create_inputhook_qt4(self.manager, app)
367 app, inputhook_qt4 = create_inputhook_qt4(self.manager, app)
368 self.manager.set_inputhook(inputhook_qt4)
368 self.manager.set_inputhook(inputhook_qt4)
369 if _use_appnope():
369 if _use_appnope():
370 from appnope import nope
370 from appnope import nope
371 nope()
371 nope()
372
372
373 return app
373 return app
374
374
375 def disable_qt4(self):
375 def disable_qt4(self):
376 """Disable event loop integration with PyQt4.
376 """Disable event loop integration with PyQt4.
377
377
378 This restores appnapp on OS X
378 This restores appnapp on OS X
379 """
379 """
380 if _use_appnope():
380 if _use_appnope():
381 from appnope import nap
381 from appnope import nap
382 nap()
382 nap()
383
383
384
384
385 @inputhook_manager.register('qt5')
385 @inputhook_manager.register('qt5')
386 class Qt5InputHook(Qt4InputHook):
386 class Qt5InputHook(Qt4InputHook):
387 def enable(self, app=None):
387 def enable(self, app=None):
388 os.environ['QT_API'] = 'pyqt5'
388 os.environ['QT_API'] = 'pyqt5'
389 return Qt4InputHook.enable(self, app)
389 return Qt4InputHook.enable(self, app)
390
390
391
391
392 @inputhook_manager.register('gtk')
392 @inputhook_manager.register('gtk')
393 class GtkInputHook(InputHookBase):
393 class GtkInputHook(InputHookBase):
394 def enable(self, app=None):
394 def enable(self, app=None):
395 """Enable event loop integration with PyGTK.
395 """Enable event loop integration with PyGTK.
396
396
397 Parameters
397 Parameters
398 ----------
398 ----------
399 app : ignored
399 app : ignored
400 Ignored, it's only a placeholder to keep the call signature of all
400 Ignored, it's only a placeholder to keep the call signature of all
401 gui activation methods consistent, which simplifies the logic of
401 gui activation methods consistent, which simplifies the logic of
402 supporting magics.
402 supporting magics.
403
403
404 Notes
404 Notes
405 -----
405 -----
406 This methods sets the PyOS_InputHook for PyGTK, which allows
406 This methods sets the PyOS_InputHook for PyGTK, which allows
407 the PyGTK to integrate with terminal based applications like
407 the PyGTK to integrate with terminal based applications like
408 IPython.
408 IPython.
409 """
409 """
410 import gtk
410 import gtk
411 try:
411 try:
412 gtk.set_interactive(True)
412 gtk.set_interactive(True)
413 except AttributeError:
413 except AttributeError:
414 # For older versions of gtk, use our own ctypes version
414 # For older versions of gtk, use our own ctypes version
415 from IPython.lib.inputhookgtk import inputhook_gtk
415 from IPython.lib.inputhookgtk import inputhook_gtk
416 self.manager.set_inputhook(inputhook_gtk)
416 self.manager.set_inputhook(inputhook_gtk)
417
417
418
418
419 @inputhook_manager.register('tk')
419 @inputhook_manager.register('tk')
420 class TkInputHook(InputHookBase):
420 class TkInputHook(InputHookBase):
421 def enable(self, app=None):
421 def enable(self, app=None):
422 """Enable event loop integration with Tk.
422 """Enable event loop integration with Tk.
423
423
424 Parameters
424 Parameters
425 ----------
425 ----------
426 app : toplevel :class:`Tkinter.Tk` widget, optional.
426 app : toplevel :class:`Tkinter.Tk` widget, optional.
427 Running toplevel widget to use. If not given, we probe Tk for an
427 Running toplevel widget to use. If not given, we probe Tk for an
428 existing one, and create a new one if none is found.
428 existing one, and create a new one if none is found.
429
429
430 Notes
430 Notes
431 -----
431 -----
432 If you have already created a :class:`Tkinter.Tk` object, the only
432 If you have already created a :class:`Tkinter.Tk` object, the only
433 thing done by this method is to register with the
433 thing done by this method is to register with the
434 :class:`InputHookManager`, since creating that object automatically
434 :class:`InputHookManager`, since creating that object automatically
435 sets ``PyOS_InputHook``.
435 sets ``PyOS_InputHook``.
436 """
436 """
437 if app is None:
437 if app is None:
438 try:
438 try:
439 from tkinter import Tk # Py 3
439 from tkinter import Tk # Py 3
440 except ImportError:
440 except ImportError:
441 from Tkinter import Tk # Py 2
441 from Tkinter import Tk # Py 2
442 app = Tk()
442 app = Tk()
443 app.withdraw()
443 app.withdraw()
444 self.manager.apps[GUI_TK] = app
444 self.manager.apps[GUI_TK] = app
445 return app
445 return app
446
446
447
447
448 @inputhook_manager.register('glut')
448 @inputhook_manager.register('glut')
449 class GlutInputHook(InputHookBase):
449 class GlutInputHook(InputHookBase):
450 def enable(self, app=None):
450 def enable(self, app=None):
451 """Enable event loop integration with GLUT.
451 """Enable event loop integration with GLUT.
452
452
453 Parameters
453 Parameters
454 ----------
454 ----------
455
455
456 app : ignored
456 app : ignored
457 Ignored, it's only a placeholder to keep the call signature of all
457 Ignored, it's only a placeholder to keep the call signature of all
458 gui activation methods consistent, which simplifies the logic of
458 gui activation methods consistent, which simplifies the logic of
459 supporting magics.
459 supporting magics.
460
460
461 Notes
461 Notes
462 -----
462 -----
463
463
464 This methods sets the PyOS_InputHook for GLUT, which allows the GLUT to
464 This methods sets the PyOS_InputHook for GLUT, which allows the GLUT to
465 integrate with terminal based applications like IPython. Due to GLUT
465 integrate with terminal based applications like IPython. Due to GLUT
466 limitations, it is currently not possible to start the event loop
466 limitations, it is currently not possible to start the event loop
467 without first creating a window. You should thus not create another
467 without first creating a window. You should thus not create another
468 window but use instead the created one. See 'gui-glut.py' in the
468 window but use instead the created one. See 'gui-glut.py' in the
469 docs/examples/lib directory.
469 docs/examples/lib directory.
470
470
471 The default screen mode is set to:
471 The default screen mode is set to:
472 glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH
472 glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH
473 """
473 """
474
474
475 import OpenGL.GLUT as glut
475 import OpenGL.GLUT as glut
476 from IPython.lib.inputhookglut import glut_display_mode, \
476 from IPython.lib.inputhookglut import glut_display_mode, \
477 glut_close, glut_display, \
477 glut_close, glut_display, \
478 glut_idle, inputhook_glut
478 glut_idle, inputhook_glut
479
479
480 if GUI_GLUT not in self.manager.apps:
480 if GUI_GLUT not in self.manager.apps:
481 glut.glutInit( sys.argv )
481 glut.glutInit( sys.argv )
482 glut.glutInitDisplayMode( glut_display_mode )
482 glut.glutInitDisplayMode( glut_display_mode )
483 # This is specific to freeglut
483 # This is specific to freeglut
484 if bool(glut.glutSetOption):
484 if bool(glut.glutSetOption):
485 glut.glutSetOption( glut.GLUT_ACTION_ON_WINDOW_CLOSE,
485 glut.glutSetOption( glut.GLUT_ACTION_ON_WINDOW_CLOSE,
486 glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS )
486 glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS )
487 glut.glutCreateWindow( sys.argv[0] )
487 glut.glutCreateWindow( sys.argv[0] )
488 glut.glutReshapeWindow( 1, 1 )
488 glut.glutReshapeWindow( 1, 1 )
489 glut.glutHideWindow( )
489 glut.glutHideWindow( )
490 glut.glutWMCloseFunc( glut_close )
490 glut.glutWMCloseFunc( glut_close )
491 glut.glutDisplayFunc( glut_display )
491 glut.glutDisplayFunc( glut_display )
492 glut.glutIdleFunc( glut_idle )
492 glut.glutIdleFunc( glut_idle )
493 else:
493 else:
494 glut.glutWMCloseFunc( glut_close )
494 glut.glutWMCloseFunc( glut_close )
495 glut.glutDisplayFunc( glut_display )
495 glut.glutDisplayFunc( glut_display )
496 glut.glutIdleFunc( glut_idle)
496 glut.glutIdleFunc( glut_idle)
497 self.manager.set_inputhook( inputhook_glut )
497 self.manager.set_inputhook( inputhook_glut )
498
498
499
499
500 def disable(self):
500 def disable(self):
501 """Disable event loop integration with glut.
501 """Disable event loop integration with glut.
502
502
503 This sets PyOS_InputHook to NULL and set the display function to a
503 This sets PyOS_InputHook to NULL and set the display function to a
504 dummy one and set the timer to a dummy timer that will be triggered
504 dummy one and set the timer to a dummy timer that will be triggered
505 very far in the future.
505 very far in the future.
506 """
506 """
507 import OpenGL.GLUT as glut
507 import OpenGL.GLUT as glut
508 from glut_support import glutMainLoopEvent
508 from glut_support import glutMainLoopEvent
509
509
510 glut.glutHideWindow() # This is an event to be processed below
510 glut.glutHideWindow() # This is an event to be processed below
511 glutMainLoopEvent()
511 glutMainLoopEvent()
512 super(GlutInputHook, self).disable()
512 super(GlutInputHook, self).disable()
513
513
514 @inputhook_manager.register('pyglet')
514 @inputhook_manager.register('pyglet')
515 class PygletInputHook(InputHookBase):
515 class PygletInputHook(InputHookBase):
516 def enable(self, app=None):
516 def enable(self, app=None):
517 """Enable event loop integration with pyglet.
517 """Enable event loop integration with pyglet.
518
518
519 Parameters
519 Parameters
520 ----------
520 ----------
521 app : ignored
521 app : ignored
522 Ignored, it's only a placeholder to keep the call signature of all
522 Ignored, it's only a placeholder to keep the call signature of all
523 gui activation methods consistent, which simplifies the logic of
523 gui activation methods consistent, which simplifies the logic of
524 supporting magics.
524 supporting magics.
525
525
526 Notes
526 Notes
527 -----
527 -----
528 This methods sets the ``PyOS_InputHook`` for pyglet, which allows
528 This methods sets the ``PyOS_InputHook`` for pyglet, which allows
529 pyglet to integrate with terminal based applications like
529 pyglet to integrate with terminal based applications like
530 IPython.
530 IPython.
531
531
532 """
532 """
533 from IPython.lib.inputhookpyglet import inputhook_pyglet
533 from IPython.lib.inputhookpyglet import inputhook_pyglet
534 self.manager.set_inputhook(inputhook_pyglet)
534 self.manager.set_inputhook(inputhook_pyglet)
535 return app
535 return app
536
536
537
537
538 @inputhook_manager.register('gtk3')
538 @inputhook_manager.register('gtk3')
539 class Gtk3InputHook(InputHookBase):
539 class Gtk3InputHook(InputHookBase):
540 def enable(self, app=None):
540 def enable(self, app=None):
541 """Enable event loop integration with Gtk3 (gir bindings).
541 """Enable event loop integration with Gtk3 (gir bindings).
542
542
543 Parameters
543 Parameters
544 ----------
544 ----------
545 app : ignored
545 app : ignored
546 Ignored, it's only a placeholder to keep the call signature of all
546 Ignored, it's only a placeholder to keep the call signature of all
547 gui activation methods consistent, which simplifies the logic of
547 gui activation methods consistent, which simplifies the logic of
548 supporting magics.
548 supporting magics.
549
549
550 Notes
550 Notes
551 -----
551 -----
552 This methods sets the PyOS_InputHook for Gtk3, which allows
552 This methods sets the PyOS_InputHook for Gtk3, which allows
553 the Gtk3 to integrate with terminal based applications like
553 the Gtk3 to integrate with terminal based applications like
554 IPython.
554 IPython.
555 """
555 """
556 from IPython.lib.inputhookgtk3 import inputhook_gtk3
556 from IPython.lib.inputhookgtk3 import inputhook_gtk3
557 self.manager.set_inputhook(inputhook_gtk3)
557 self.manager.set_inputhook(inputhook_gtk3)
558
558
559
559
560 clear_inputhook = inputhook_manager.clear_inputhook
560 clear_inputhook = inputhook_manager.clear_inputhook
561 set_inputhook = inputhook_manager.set_inputhook
561 set_inputhook = inputhook_manager.set_inputhook
562 current_gui = inputhook_manager.current_gui
562 current_gui = inputhook_manager.current_gui
563 clear_app_refs = inputhook_manager.clear_app_refs
563 clear_app_refs = inputhook_manager.clear_app_refs
564 enable_gui = inputhook_manager.enable_gui
564 enable_gui = inputhook_manager.enable_gui
565 disable_gui = inputhook_manager.disable_gui
565 disable_gui = inputhook_manager.disable_gui
566 register = inputhook_manager.register
566 register = inputhook_manager.register
567 guis = inputhook_manager.guihooks
567 guis = inputhook_manager.guihooks
568
568
569
569
570 def _deprecated_disable():
570 def _deprecated_disable():
571 warn("This function is deprecated: use disable_gui() instead")
571 warn("This function is deprecated: use disable_gui() instead")
572 inputhook_manager.disable_gui()
572 inputhook_manager.disable_gui()
573 disable_wx = disable_qt4 = disable_gtk = disable_gtk3 = disable_glut = \
573 disable_wx = disable_qt4 = disable_gtk = disable_gtk3 = disable_glut = \
574 disable_pyglet = disable_osx = _deprecated_disable
574 disable_pyglet = disable_osx = _deprecated_disable
@@ -1,807 +1,808 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Subclass of InteractiveShell for terminal based frontends."""
2 """Subclass of InteractiveShell for terminal based frontends."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 import bdb
9 import bdb
10 import os
10 import os
11 import sys
11 import sys
12
12
13 from IPython.core.error import TryNext, UsageError
13 from IPython.core.error import TryNext, UsageError
14 from IPython.core.usage import interactive_usage
14 from IPython.core.usage import interactive_usage
15 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC
15 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC
16 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
16 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
17 from IPython.core.magic import Magics, magics_class, line_magic
17 from IPython.core.magic import Magics, magics_class, line_magic
18 from IPython.lib.clipboard import ClipboardEmpty
18 from IPython.lib.clipboard import ClipboardEmpty
19 from IPython.utils.contexts import NoOpContext
19 from IPython.utils.contexts import NoOpContext
20 from IPython.utils.decorators import undoc
20 from IPython.utils.decorators import undoc
21 from IPython.utils.encoding import get_stream_enc
21 from IPython.utils.encoding import get_stream_enc
22 from IPython.utils import py3compat
22 from IPython.utils import py3compat
23 from IPython.utils.terminal import toggle_set_term_title, set_term_title
23 from IPython.utils.terminal import toggle_set_term_title, set_term_title
24 from IPython.utils.process import abbrev_cwd
24 from IPython.utils.process import abbrev_cwd
25 from IPython.utils.warn import warn, error
25 from warnings import warn
26 from logging import error
26 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
27 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
27 from traitlets import Integer, CBool, Unicode
28 from traitlets import Integer, CBool, Unicode
28
29
29
30
30 def get_default_editor():
31 def get_default_editor():
31 try:
32 try:
32 ed = os.environ['EDITOR']
33 ed = os.environ['EDITOR']
33 if not py3compat.PY3:
34 if not py3compat.PY3:
34 ed = ed.decode()
35 ed = ed.decode()
35 return ed
36 return ed
36 except KeyError:
37 except KeyError:
37 pass
38 pass
38 except UnicodeError:
39 except UnicodeError:
39 warn("$EDITOR environment variable is not pure ASCII. Using platform "
40 warn("$EDITOR environment variable is not pure ASCII. Using platform "
40 "default editor.")
41 "default editor.")
41
42
42 if os.name == 'posix':
43 if os.name == 'posix':
43 return 'vi' # the only one guaranteed to be there!
44 return 'vi' # the only one guaranteed to be there!
44 else:
45 else:
45 return 'notepad' # same in Windows!
46 return 'notepad' # same in Windows!
46
47
47 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
48 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
48 """ Yield pasted lines until the user enters the given sentinel value.
49 """ Yield pasted lines until the user enters the given sentinel value.
49 """
50 """
50 if not quiet:
51 if not quiet:
51 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
52 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
52 % sentinel)
53 % sentinel)
53 prompt = ":"
54 prompt = ":"
54 else:
55 else:
55 prompt = ""
56 prompt = ""
56 while True:
57 while True:
57 try:
58 try:
58 l = py3compat.str_to_unicode(l_input(prompt))
59 l = py3compat.str_to_unicode(l_input(prompt))
59 if l == sentinel:
60 if l == sentinel:
60 return
61 return
61 else:
62 else:
62 yield l
63 yield l
63 except EOFError:
64 except EOFError:
64 print('<EOF>')
65 print('<EOF>')
65 return
66 return
66
67
67 @undoc
68 @undoc
68 def no_op(*a, **kw): pass
69 def no_op(*a, **kw): pass
69
70
70
71
71 class ReadlineNoRecord(object):
72 class ReadlineNoRecord(object):
72 """Context manager to execute some code, then reload readline history
73 """Context manager to execute some code, then reload readline history
73 so that interactive input to the code doesn't appear when pressing up."""
74 so that interactive input to the code doesn't appear when pressing up."""
74 def __init__(self, shell):
75 def __init__(self, shell):
75 self.shell = shell
76 self.shell = shell
76 self._nested_level = 0
77 self._nested_level = 0
77
78
78 def __enter__(self):
79 def __enter__(self):
79 if self._nested_level == 0:
80 if self._nested_level == 0:
80 try:
81 try:
81 self.orig_length = self.current_length()
82 self.orig_length = self.current_length()
82 self.readline_tail = self.get_readline_tail()
83 self.readline_tail = self.get_readline_tail()
83 except (AttributeError, IndexError): # Can fail with pyreadline
84 except (AttributeError, IndexError): # Can fail with pyreadline
84 self.orig_length, self.readline_tail = 999999, []
85 self.orig_length, self.readline_tail = 999999, []
85 self._nested_level += 1
86 self._nested_level += 1
86
87
87 def __exit__(self, type, value, traceback):
88 def __exit__(self, type, value, traceback):
88 self._nested_level -= 1
89 self._nested_level -= 1
89 if self._nested_level == 0:
90 if self._nested_level == 0:
90 # Try clipping the end if it's got longer
91 # Try clipping the end if it's got longer
91 try:
92 try:
92 e = self.current_length() - self.orig_length
93 e = self.current_length() - self.orig_length
93 if e > 0:
94 if e > 0:
94 for _ in range(e):
95 for _ in range(e):
95 self.shell.readline.remove_history_item(self.orig_length)
96 self.shell.readline.remove_history_item(self.orig_length)
96
97
97 # If it still doesn't match, just reload readline history.
98 # If it still doesn't match, just reload readline history.
98 if self.current_length() != self.orig_length \
99 if self.current_length() != self.orig_length \
99 or self.get_readline_tail() != self.readline_tail:
100 or self.get_readline_tail() != self.readline_tail:
100 self.shell.refill_readline_hist()
101 self.shell.refill_readline_hist()
101 except (AttributeError, IndexError):
102 except (AttributeError, IndexError):
102 pass
103 pass
103 # Returning False will cause exceptions to propagate
104 # Returning False will cause exceptions to propagate
104 return False
105 return False
105
106
106 def current_length(self):
107 def current_length(self):
107 return self.shell.readline.get_current_history_length()
108 return self.shell.readline.get_current_history_length()
108
109
109 def get_readline_tail(self, n=10):
110 def get_readline_tail(self, n=10):
110 """Get the last n items in readline history."""
111 """Get the last n items in readline history."""
111 end = self.shell.readline.get_current_history_length() + 1
112 end = self.shell.readline.get_current_history_length() + 1
112 start = max(end-n, 1)
113 start = max(end-n, 1)
113 ghi = self.shell.readline.get_history_item
114 ghi = self.shell.readline.get_history_item
114 return [ghi(x) for x in range(start, end)]
115 return [ghi(x) for x in range(start, end)]
115
116
116
117
117 @magics_class
118 @magics_class
118 class TerminalMagics(Magics):
119 class TerminalMagics(Magics):
119 def __init__(self, shell):
120 def __init__(self, shell):
120 super(TerminalMagics, self).__init__(shell)
121 super(TerminalMagics, self).__init__(shell)
121 self.input_splitter = IPythonInputSplitter()
122 self.input_splitter = IPythonInputSplitter()
122
123
123 def store_or_execute(self, block, name):
124 def store_or_execute(self, block, name):
124 """ Execute a block, or store it in a variable, per the user's request.
125 """ Execute a block, or store it in a variable, per the user's request.
125 """
126 """
126 if name:
127 if name:
127 # If storing it for further editing
128 # If storing it for further editing
128 self.shell.user_ns[name] = SList(block.splitlines())
129 self.shell.user_ns[name] = SList(block.splitlines())
129 print("Block assigned to '%s'" % name)
130 print("Block assigned to '%s'" % name)
130 else:
131 else:
131 b = self.preclean_input(block)
132 b = self.preclean_input(block)
132 self.shell.user_ns['pasted_block'] = b
133 self.shell.user_ns['pasted_block'] = b
133 self.shell.using_paste_magics = True
134 self.shell.using_paste_magics = True
134 try:
135 try:
135 self.shell.run_cell(b)
136 self.shell.run_cell(b)
136 finally:
137 finally:
137 self.shell.using_paste_magics = False
138 self.shell.using_paste_magics = False
138
139
139 def preclean_input(self, block):
140 def preclean_input(self, block):
140 lines = block.splitlines()
141 lines = block.splitlines()
141 while lines and not lines[0].strip():
142 while lines and not lines[0].strip():
142 lines = lines[1:]
143 lines = lines[1:]
143 return strip_email_quotes('\n'.join(lines))
144 return strip_email_quotes('\n'.join(lines))
144
145
145 def rerun_pasted(self, name='pasted_block'):
146 def rerun_pasted(self, name='pasted_block'):
146 """ Rerun a previously pasted command.
147 """ Rerun a previously pasted command.
147 """
148 """
148 b = self.shell.user_ns.get(name)
149 b = self.shell.user_ns.get(name)
149
150
150 # Sanity checks
151 # Sanity checks
151 if b is None:
152 if b is None:
152 raise UsageError('No previous pasted block available')
153 raise UsageError('No previous pasted block available')
153 if not isinstance(b, py3compat.string_types):
154 if not isinstance(b, py3compat.string_types):
154 raise UsageError(
155 raise UsageError(
155 "Variable 'pasted_block' is not a string, can't execute")
156 "Variable 'pasted_block' is not a string, can't execute")
156
157
157 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
158 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
158 self.shell.run_cell(b)
159 self.shell.run_cell(b)
159
160
160 @line_magic
161 @line_magic
161 def autoindent(self, parameter_s = ''):
162 def autoindent(self, parameter_s = ''):
162 """Toggle autoindent on/off (if available)."""
163 """Toggle autoindent on/off (if available)."""
163
164
164 self.shell.set_autoindent()
165 self.shell.set_autoindent()
165 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
166 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
166
167
167 @line_magic
168 @line_magic
168 def cpaste(self, parameter_s=''):
169 def cpaste(self, parameter_s=''):
169 """Paste & execute a pre-formatted code block from clipboard.
170 """Paste & execute a pre-formatted code block from clipboard.
170
171
171 You must terminate the block with '--' (two minus-signs) or Ctrl-D
172 You must terminate the block with '--' (two minus-signs) or Ctrl-D
172 alone on the line. You can also provide your own sentinel with '%paste
173 alone on the line. You can also provide your own sentinel with '%paste
173 -s %%' ('%%' is the new sentinel for this operation).
174 -s %%' ('%%' is the new sentinel for this operation).
174
175
175 The block is dedented prior to execution to enable execution of method
176 The block is dedented prior to execution to enable execution of method
176 definitions. '>' and '+' characters at the beginning of a line are
177 definitions. '>' and '+' characters at the beginning of a line are
177 ignored, to allow pasting directly from e-mails, diff files and
178 ignored, to allow pasting directly from e-mails, diff files and
178 doctests (the '...' continuation prompt is also stripped). The
179 doctests (the '...' continuation prompt is also stripped). The
179 executed block is also assigned to variable named 'pasted_block' for
180 executed block is also assigned to variable named 'pasted_block' for
180 later editing with '%edit pasted_block'.
181 later editing with '%edit pasted_block'.
181
182
182 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
183 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
183 This assigns the pasted block to variable 'foo' as string, without
184 This assigns the pasted block to variable 'foo' as string, without
184 dedenting or executing it (preceding >>> and + is still stripped)
185 dedenting or executing it (preceding >>> and + is still stripped)
185
186
186 '%cpaste -r' re-executes the block previously entered by cpaste.
187 '%cpaste -r' re-executes the block previously entered by cpaste.
187 '%cpaste -q' suppresses any additional output messages.
188 '%cpaste -q' suppresses any additional output messages.
188
189
189 Do not be alarmed by garbled output on Windows (it's a readline bug).
190 Do not be alarmed by garbled output on Windows (it's a readline bug).
190 Just press enter and type -- (and press enter again) and the block
191 Just press enter and type -- (and press enter again) and the block
191 will be what was just pasted.
192 will be what was just pasted.
192
193
193 IPython statements (magics, shell escapes) are not supported (yet).
194 IPython statements (magics, shell escapes) are not supported (yet).
194
195
195 See also
196 See also
196 --------
197 --------
197 paste: automatically pull code from clipboard.
198 paste: automatically pull code from clipboard.
198
199
199 Examples
200 Examples
200 --------
201 --------
201 ::
202 ::
202
203
203 In [8]: %cpaste
204 In [8]: %cpaste
204 Pasting code; enter '--' alone on the line to stop.
205 Pasting code; enter '--' alone on the line to stop.
205 :>>> a = ["world!", "Hello"]
206 :>>> a = ["world!", "Hello"]
206 :>>> print " ".join(sorted(a))
207 :>>> print " ".join(sorted(a))
207 :--
208 :--
208 Hello world!
209 Hello world!
209 """
210 """
210 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
211 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
211 if 'r' in opts:
212 if 'r' in opts:
212 self.rerun_pasted()
213 self.rerun_pasted()
213 return
214 return
214
215
215 quiet = ('q' in opts)
216 quiet = ('q' in opts)
216
217
217 sentinel = opts.get('s', u'--')
218 sentinel = opts.get('s', u'--')
218 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
219 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
219 self.store_or_execute(block, name)
220 self.store_or_execute(block, name)
220
221
221 @line_magic
222 @line_magic
222 def paste(self, parameter_s=''):
223 def paste(self, parameter_s=''):
223 """Paste & execute a pre-formatted code block from clipboard.
224 """Paste & execute a pre-formatted code block from clipboard.
224
225
225 The text is pulled directly from the clipboard without user
226 The text is pulled directly from the clipboard without user
226 intervention and printed back on the screen before execution (unless
227 intervention and printed back on the screen before execution (unless
227 the -q flag is given to force quiet mode).
228 the -q flag is given to force quiet mode).
228
229
229 The block is dedented prior to execution to enable execution of method
230 The block is dedented prior to execution to enable execution of method
230 definitions. '>' and '+' characters at the beginning of a line are
231 definitions. '>' and '+' characters at the beginning of a line are
231 ignored, to allow pasting directly from e-mails, diff files and
232 ignored, to allow pasting directly from e-mails, diff files and
232 doctests (the '...' continuation prompt is also stripped). The
233 doctests (the '...' continuation prompt is also stripped). The
233 executed block is also assigned to variable named 'pasted_block' for
234 executed block is also assigned to variable named 'pasted_block' for
234 later editing with '%edit pasted_block'.
235 later editing with '%edit pasted_block'.
235
236
236 You can also pass a variable name as an argument, e.g. '%paste foo'.
237 You can also pass a variable name as an argument, e.g. '%paste foo'.
237 This assigns the pasted block to variable 'foo' as string, without
238 This assigns the pasted block to variable 'foo' as string, without
238 executing it (preceding >>> and + is still stripped).
239 executing it (preceding >>> and + is still stripped).
239
240
240 Options:
241 Options:
241
242
242 -r: re-executes the block previously entered by cpaste.
243 -r: re-executes the block previously entered by cpaste.
243
244
244 -q: quiet mode: do not echo the pasted text back to the terminal.
245 -q: quiet mode: do not echo the pasted text back to the terminal.
245
246
246 IPython statements (magics, shell escapes) are not supported (yet).
247 IPython statements (magics, shell escapes) are not supported (yet).
247
248
248 See also
249 See also
249 --------
250 --------
250 cpaste: manually paste code into terminal until you mark its end.
251 cpaste: manually paste code into terminal until you mark its end.
251 """
252 """
252 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
253 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
253 if 'r' in opts:
254 if 'r' in opts:
254 self.rerun_pasted()
255 self.rerun_pasted()
255 return
256 return
256 try:
257 try:
257 block = self.shell.hooks.clipboard_get()
258 block = self.shell.hooks.clipboard_get()
258 except TryNext as clipboard_exc:
259 except TryNext as clipboard_exc:
259 message = getattr(clipboard_exc, 'args')
260 message = getattr(clipboard_exc, 'args')
260 if message:
261 if message:
261 error(message[0])
262 error(message[0])
262 else:
263 else:
263 error('Could not get text from the clipboard.')
264 error('Could not get text from the clipboard.')
264 return
265 return
265 except ClipboardEmpty:
266 except ClipboardEmpty:
266 raise UsageError("The clipboard appears to be empty")
267 raise UsageError("The clipboard appears to be empty")
267
268
268 # By default, echo back to terminal unless quiet mode is requested
269 # By default, echo back to terminal unless quiet mode is requested
269 if 'q' not in opts:
270 if 'q' not in opts:
270 write = self.shell.write
271 write = self.shell.write
271 write(self.shell.pycolorize(block))
272 write(self.shell.pycolorize(block))
272 if not block.endswith('\n'):
273 if not block.endswith('\n'):
273 write('\n')
274 write('\n')
274 write("## -- End pasted text --\n")
275 write("## -- End pasted text --\n")
275
276
276 self.store_or_execute(block, name)
277 self.store_or_execute(block, name)
277
278
278 # Class-level: add a '%cls' magic only on Windows
279 # Class-level: add a '%cls' magic only on Windows
279 if sys.platform == 'win32':
280 if sys.platform == 'win32':
280 @line_magic
281 @line_magic
281 def cls(self, s):
282 def cls(self, s):
282 """Clear screen.
283 """Clear screen.
283 """
284 """
284 os.system("cls")
285 os.system("cls")
285
286
286
287
287 class TerminalInteractiveShell(InteractiveShell):
288 class TerminalInteractiveShell(InteractiveShell):
288
289
289 autoedit_syntax = CBool(False, config=True,
290 autoedit_syntax = CBool(False, config=True,
290 help="auto editing of files with syntax errors.")
291 help="auto editing of files with syntax errors.")
291 confirm_exit = CBool(True, config=True,
292 confirm_exit = CBool(True, config=True,
292 help="""
293 help="""
293 Set to confirm when you try to exit IPython with an EOF (Control-D
294 Set to confirm when you try to exit IPython with an EOF (Control-D
294 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
295 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
295 you can force a direct exit without any confirmation.""",
296 you can force a direct exit without any confirmation.""",
296 )
297 )
297 # This display_banner only controls whether or not self.show_banner()
298 # This display_banner only controls whether or not self.show_banner()
298 # is called when mainloop/interact are called. The default is False
299 # is called when mainloop/interact are called. The default is False
299 # because for the terminal based application, the banner behavior
300 # because for the terminal based application, the banner behavior
300 # is controlled by the application.
301 # is controlled by the application.
301 display_banner = CBool(False) # This isn't configurable!
302 display_banner = CBool(False) # This isn't configurable!
302 embedded = CBool(False)
303 embedded = CBool(False)
303 embedded_active = CBool(False)
304 embedded_active = CBool(False)
304 editor = Unicode(get_default_editor(), config=True,
305 editor = Unicode(get_default_editor(), config=True,
305 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
306 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
306 )
307 )
307 pager = Unicode('less', config=True,
308 pager = Unicode('less', config=True,
308 help="The shell program to be used for paging.")
309 help="The shell program to be used for paging.")
309
310
310 screen_length = Integer(0, config=True,
311 screen_length = Integer(0, config=True,
311 help=
312 help=
312 """Number of lines of your screen, used to control printing of very
313 """Number of lines of your screen, used to control printing of very
313 long strings. Strings longer than this number of lines will be sent
314 long strings. Strings longer than this number of lines will be sent
314 through a pager instead of directly printed. The default value for
315 through a pager instead of directly printed. The default value for
315 this is 0, which means IPython will auto-detect your screen size every
316 this is 0, which means IPython will auto-detect your screen size every
316 time it needs to print certain potentially long strings (this doesn't
317 time it needs to print certain potentially long strings (this doesn't
317 change the behavior of the 'print' keyword, it's only triggered
318 change the behavior of the 'print' keyword, it's only triggered
318 internally). If for some reason this isn't working well (it needs
319 internally). If for some reason this isn't working well (it needs
319 curses support), specify it yourself. Otherwise don't change the
320 curses support), specify it yourself. Otherwise don't change the
320 default.""",
321 default.""",
321 )
322 )
322 term_title = CBool(False, config=True,
323 term_title = CBool(False, config=True,
323 help="Enable auto setting the terminal title."
324 help="Enable auto setting the terminal title."
324 )
325 )
325 usage = Unicode(interactive_usage)
326 usage = Unicode(interactive_usage)
326
327
327 # This `using_paste_magics` is used to detect whether the code is being
328 # This `using_paste_magics` is used to detect whether the code is being
328 # executed via paste magics functions
329 # executed via paste magics functions
329 using_paste_magics = CBool(False)
330 using_paste_magics = CBool(False)
330
331
331 # In the terminal, GUI control is done via PyOS_InputHook
332 # In the terminal, GUI control is done via PyOS_InputHook
332 @staticmethod
333 @staticmethod
333 def enable_gui(gui=None, app=None):
334 def enable_gui(gui=None, app=None):
334 """Switch amongst GUI input hooks by name.
335 """Switch amongst GUI input hooks by name.
335 """
336 """
336 # Deferred import
337 # Deferred import
337 from IPython.lib.inputhook import enable_gui as real_enable_gui
338 from IPython.lib.inputhook import enable_gui as real_enable_gui
338 try:
339 try:
339 return real_enable_gui(gui, app)
340 return real_enable_gui(gui, app)
340 except ValueError as e:
341 except ValueError as e:
341 raise UsageError("%s" % e)
342 raise UsageError("%s" % e)
342
343
343 system = InteractiveShell.system_raw
344 system = InteractiveShell.system_raw
344
345
345 #-------------------------------------------------------------------------
346 #-------------------------------------------------------------------------
346 # Overrides of init stages
347 # Overrides of init stages
347 #-------------------------------------------------------------------------
348 #-------------------------------------------------------------------------
348
349
349 def init_display_formatter(self):
350 def init_display_formatter(self):
350 super(TerminalInteractiveShell, self).init_display_formatter()
351 super(TerminalInteractiveShell, self).init_display_formatter()
351 # terminal only supports plaintext
352 # terminal only supports plaintext
352 self.display_formatter.active_types = ['text/plain']
353 self.display_formatter.active_types = ['text/plain']
353
354
354 #-------------------------------------------------------------------------
355 #-------------------------------------------------------------------------
355 # Things related to readline
356 # Things related to readline
356 #-------------------------------------------------------------------------
357 #-------------------------------------------------------------------------
357
358
358 def init_readline(self):
359 def init_readline(self):
359 """Command history completion/saving/reloading."""
360 """Command history completion/saving/reloading."""
360
361
361 if self.readline_use:
362 if self.readline_use:
362 import IPython.utils.rlineimpl as readline
363 import IPython.utils.rlineimpl as readline
363
364
364 self.rl_next_input = None
365 self.rl_next_input = None
365 self.rl_do_indent = False
366 self.rl_do_indent = False
366
367
367 if not self.readline_use or not readline.have_readline:
368 if not self.readline_use or not readline.have_readline:
368 self.readline = None
369 self.readline = None
369 # Set a number of methods that depend on readline to be no-op
370 # Set a number of methods that depend on readline to be no-op
370 self.readline_no_record = NoOpContext()
371 self.readline_no_record = NoOpContext()
371 self.set_readline_completer = no_op
372 self.set_readline_completer = no_op
372 self.set_custom_completer = no_op
373 self.set_custom_completer = no_op
373 if self.readline_use:
374 if self.readline_use:
374 warn('Readline services not available or not loaded.')
375 warn('Readline services not available or not loaded.')
375 else:
376 else:
376 self.has_readline = True
377 self.has_readline = True
377 self.readline = readline
378 self.readline = readline
378 sys.modules['readline'] = readline
379 sys.modules['readline'] = readline
379
380
380 # Platform-specific configuration
381 # Platform-specific configuration
381 if os.name == 'nt':
382 if os.name == 'nt':
382 # FIXME - check with Frederick to see if we can harmonize
383 # FIXME - check with Frederick to see if we can harmonize
383 # naming conventions with pyreadline to avoid this
384 # naming conventions with pyreadline to avoid this
384 # platform-dependent check
385 # platform-dependent check
385 self.readline_startup_hook = readline.set_pre_input_hook
386 self.readline_startup_hook = readline.set_pre_input_hook
386 else:
387 else:
387 self.readline_startup_hook = readline.set_startup_hook
388 self.readline_startup_hook = readline.set_startup_hook
388
389
389 # Readline config order:
390 # Readline config order:
390 # - IPython config (default value)
391 # - IPython config (default value)
391 # - custom inputrc
392 # - custom inputrc
392 # - IPython config (user customized)
393 # - IPython config (user customized)
393
394
394 # load IPython config before inputrc if default
395 # load IPython config before inputrc if default
395 # skip if libedit because parse_and_bind syntax is different
396 # skip if libedit because parse_and_bind syntax is different
396 if not self._custom_readline_config and not readline.uses_libedit:
397 if not self._custom_readline_config and not readline.uses_libedit:
397 for rlcommand in self.readline_parse_and_bind:
398 for rlcommand in self.readline_parse_and_bind:
398 readline.parse_and_bind(rlcommand)
399 readline.parse_and_bind(rlcommand)
399
400
400 # Load user's initrc file (readline config)
401 # Load user's initrc file (readline config)
401 # Or if libedit is used, load editrc.
402 # Or if libedit is used, load editrc.
402 inputrc_name = os.environ.get('INPUTRC')
403 inputrc_name = os.environ.get('INPUTRC')
403 if inputrc_name is None:
404 if inputrc_name is None:
404 inputrc_name = '.inputrc'
405 inputrc_name = '.inputrc'
405 if readline.uses_libedit:
406 if readline.uses_libedit:
406 inputrc_name = '.editrc'
407 inputrc_name = '.editrc'
407 inputrc_name = os.path.join(self.home_dir, inputrc_name)
408 inputrc_name = os.path.join(self.home_dir, inputrc_name)
408 if os.path.isfile(inputrc_name):
409 if os.path.isfile(inputrc_name):
409 try:
410 try:
410 readline.read_init_file(inputrc_name)
411 readline.read_init_file(inputrc_name)
411 except:
412 except:
412 warn('Problems reading readline initialization file <%s>'
413 warn('Problems reading readline initialization file <%s>'
413 % inputrc_name)
414 % inputrc_name)
414
415
415 # load IPython config after inputrc if user has customized
416 # load IPython config after inputrc if user has customized
416 if self._custom_readline_config:
417 if self._custom_readline_config:
417 for rlcommand in self.readline_parse_and_bind:
418 for rlcommand in self.readline_parse_and_bind:
418 readline.parse_and_bind(rlcommand)
419 readline.parse_and_bind(rlcommand)
419
420
420 # Remove some chars from the delimiters list. If we encounter
421 # Remove some chars from the delimiters list. If we encounter
421 # unicode chars, discard them.
422 # unicode chars, discard them.
422 delims = readline.get_completer_delims()
423 delims = readline.get_completer_delims()
423 if not py3compat.PY3:
424 if not py3compat.PY3:
424 delims = delims.encode("ascii", "ignore")
425 delims = delims.encode("ascii", "ignore")
425 for d in self.readline_remove_delims:
426 for d in self.readline_remove_delims:
426 delims = delims.replace(d, "")
427 delims = delims.replace(d, "")
427 delims = delims.replace(ESC_MAGIC, '')
428 delims = delims.replace(ESC_MAGIC, '')
428 readline.set_completer_delims(delims)
429 readline.set_completer_delims(delims)
429 # Store these so we can restore them if something like rpy2 modifies
430 # Store these so we can restore them if something like rpy2 modifies
430 # them.
431 # them.
431 self.readline_delims = delims
432 self.readline_delims = delims
432 # otherwise we end up with a monster history after a while:
433 # otherwise we end up with a monster history after a while:
433 readline.set_history_length(self.history_length)
434 readline.set_history_length(self.history_length)
434
435
435 self.refill_readline_hist()
436 self.refill_readline_hist()
436 self.readline_no_record = ReadlineNoRecord(self)
437 self.readline_no_record = ReadlineNoRecord(self)
437
438
438 # Configure auto-indent for all platforms
439 # Configure auto-indent for all platforms
439 self.set_autoindent(self.autoindent)
440 self.set_autoindent(self.autoindent)
440
441
441 def init_completer(self):
442 def init_completer(self):
442 super(TerminalInteractiveShell, self).init_completer()
443 super(TerminalInteractiveShell, self).init_completer()
443
444
444 # Only configure readline if we truly are using readline.
445 # Only configure readline if we truly are using readline.
445 if self.has_readline:
446 if self.has_readline:
446 self.set_readline_completer()
447 self.set_readline_completer()
447
448
448 def set_readline_completer(self):
449 def set_readline_completer(self):
449 """Reset readline's completer to be our own."""
450 """Reset readline's completer to be our own."""
450 self.readline.set_completer(self.Completer.rlcomplete)
451 self.readline.set_completer(self.Completer.rlcomplete)
451
452
452
453
453 def pre_readline(self):
454 def pre_readline(self):
454 """readline hook to be used at the start of each line.
455 """readline hook to be used at the start of each line.
455
456
456 It handles auto-indent and text from set_next_input."""
457 It handles auto-indent and text from set_next_input."""
457
458
458 if self.rl_do_indent:
459 if self.rl_do_indent:
459 self.readline.insert_text(self._indent_current_str())
460 self.readline.insert_text(self._indent_current_str())
460 if self.rl_next_input is not None:
461 if self.rl_next_input is not None:
461 self.readline.insert_text(self.rl_next_input)
462 self.readline.insert_text(self.rl_next_input)
462 self.rl_next_input = None
463 self.rl_next_input = None
463
464
464 def refill_readline_hist(self):
465 def refill_readline_hist(self):
465 # Load the last 1000 lines from history
466 # Load the last 1000 lines from history
466 self.readline.clear_history()
467 self.readline.clear_history()
467 stdin_encoding = sys.stdin.encoding or "utf-8"
468 stdin_encoding = sys.stdin.encoding or "utf-8"
468 last_cell = u""
469 last_cell = u""
469 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
470 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
470 include_latest=True):
471 include_latest=True):
471 # Ignore blank lines and consecutive duplicates
472 # Ignore blank lines and consecutive duplicates
472 cell = cell.rstrip()
473 cell = cell.rstrip()
473 if cell and (cell != last_cell):
474 if cell and (cell != last_cell):
474 try:
475 try:
475 if self.multiline_history:
476 if self.multiline_history:
476 self.readline.add_history(py3compat.unicode_to_str(cell,
477 self.readline.add_history(py3compat.unicode_to_str(cell,
477 stdin_encoding))
478 stdin_encoding))
478 else:
479 else:
479 for line in cell.splitlines():
480 for line in cell.splitlines():
480 self.readline.add_history(py3compat.unicode_to_str(line,
481 self.readline.add_history(py3compat.unicode_to_str(line,
481 stdin_encoding))
482 stdin_encoding))
482 last_cell = cell
483 last_cell = cell
483
484
484 except TypeError:
485 except TypeError:
485 # The history DB can get corrupted so it returns strings
486 # The history DB can get corrupted so it returns strings
486 # containing null bytes, which readline objects to.
487 # containing null bytes, which readline objects to.
487 continue
488 continue
488
489
489 #-------------------------------------------------------------------------
490 #-------------------------------------------------------------------------
490 # Things related to the terminal
491 # Things related to the terminal
491 #-------------------------------------------------------------------------
492 #-------------------------------------------------------------------------
492
493
493 @property
494 @property
494 def usable_screen_length(self):
495 def usable_screen_length(self):
495 if self.screen_length == 0:
496 if self.screen_length == 0:
496 return 0
497 return 0
497 else:
498 else:
498 num_lines_bot = self.separate_in.count('\n')+1
499 num_lines_bot = self.separate_in.count('\n')+1
499 return self.screen_length - num_lines_bot
500 return self.screen_length - num_lines_bot
500
501
501 def _term_title_changed(self, name, new_value):
502 def _term_title_changed(self, name, new_value):
502 self.init_term_title()
503 self.init_term_title()
503
504
504 def init_term_title(self):
505 def init_term_title(self):
505 # Enable or disable the terminal title.
506 # Enable or disable the terminal title.
506 if self.term_title:
507 if self.term_title:
507 toggle_set_term_title(True)
508 toggle_set_term_title(True)
508 set_term_title('IPython: ' + abbrev_cwd())
509 set_term_title('IPython: ' + abbrev_cwd())
509 else:
510 else:
510 toggle_set_term_title(False)
511 toggle_set_term_title(False)
511
512
512 #-------------------------------------------------------------------------
513 #-------------------------------------------------------------------------
513 # Things related to aliases
514 # Things related to aliases
514 #-------------------------------------------------------------------------
515 #-------------------------------------------------------------------------
515
516
516 def init_alias(self):
517 def init_alias(self):
517 # The parent class defines aliases that can be safely used with any
518 # The parent class defines aliases that can be safely used with any
518 # frontend.
519 # frontend.
519 super(TerminalInteractiveShell, self).init_alias()
520 super(TerminalInteractiveShell, self).init_alias()
520
521
521 # Now define aliases that only make sense on the terminal, because they
522 # Now define aliases that only make sense on the terminal, because they
522 # need direct access to the console in a way that we can't emulate in
523 # need direct access to the console in a way that we can't emulate in
523 # GUI or web frontend
524 # GUI or web frontend
524 if os.name == 'posix':
525 if os.name == 'posix':
525 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
526 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
526 ('man', 'man')]
527 ('man', 'man')]
527 else :
528 else :
528 aliases = []
529 aliases = []
529
530
530 for name, cmd in aliases:
531 for name, cmd in aliases:
531 self.alias_manager.soft_define_alias(name, cmd)
532 self.alias_manager.soft_define_alias(name, cmd)
532
533
533 #-------------------------------------------------------------------------
534 #-------------------------------------------------------------------------
534 # Mainloop and code execution logic
535 # Mainloop and code execution logic
535 #-------------------------------------------------------------------------
536 #-------------------------------------------------------------------------
536
537
537 def mainloop(self, display_banner=None):
538 def mainloop(self, display_banner=None):
538 """Start the mainloop.
539 """Start the mainloop.
539
540
540 If an optional banner argument is given, it will override the
541 If an optional banner argument is given, it will override the
541 internally created default banner.
542 internally created default banner.
542 """
543 """
543
544
544 with self.builtin_trap, self.display_trap:
545 with self.builtin_trap, self.display_trap:
545
546
546 while 1:
547 while 1:
547 try:
548 try:
548 self.interact(display_banner=display_banner)
549 self.interact(display_banner=display_banner)
549 #self.interact_with_readline()
550 #self.interact_with_readline()
550 # XXX for testing of a readline-decoupled repl loop, call
551 # XXX for testing of a readline-decoupled repl loop, call
551 # interact_with_readline above
552 # interact_with_readline above
552 break
553 break
553 except KeyboardInterrupt:
554 except KeyboardInterrupt:
554 # this should not be necessary, but KeyboardInterrupt
555 # this should not be necessary, but KeyboardInterrupt
555 # handling seems rather unpredictable...
556 # handling seems rather unpredictable...
556 self.write("\nKeyboardInterrupt in interact()\n")
557 self.write("\nKeyboardInterrupt in interact()\n")
557
558
558 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
559 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
559 """Store multiple lines as a single entry in history"""
560 """Store multiple lines as a single entry in history"""
560
561
561 # do nothing without readline or disabled multiline
562 # do nothing without readline or disabled multiline
562 if not self.has_readline or not self.multiline_history:
563 if not self.has_readline or not self.multiline_history:
563 return hlen_before_cell
564 return hlen_before_cell
564
565
565 # windows rl has no remove_history_item
566 # windows rl has no remove_history_item
566 if not hasattr(self.readline, "remove_history_item"):
567 if not hasattr(self.readline, "remove_history_item"):
567 return hlen_before_cell
568 return hlen_before_cell
568
569
569 # skip empty cells
570 # skip empty cells
570 if not source_raw.rstrip():
571 if not source_raw.rstrip():
571 return hlen_before_cell
572 return hlen_before_cell
572
573
573 # nothing changed do nothing, e.g. when rl removes consecutive dups
574 # nothing changed do nothing, e.g. when rl removes consecutive dups
574 hlen = self.readline.get_current_history_length()
575 hlen = self.readline.get_current_history_length()
575 if hlen == hlen_before_cell:
576 if hlen == hlen_before_cell:
576 return hlen_before_cell
577 return hlen_before_cell
577
578
578 for i in range(hlen - hlen_before_cell):
579 for i in range(hlen - hlen_before_cell):
579 self.readline.remove_history_item(hlen - i - 1)
580 self.readline.remove_history_item(hlen - i - 1)
580 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
581 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
581 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
582 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
582 stdin_encoding))
583 stdin_encoding))
583 return self.readline.get_current_history_length()
584 return self.readline.get_current_history_length()
584
585
585 def interact(self, display_banner=None):
586 def interact(self, display_banner=None):
586 """Closely emulate the interactive Python console."""
587 """Closely emulate the interactive Python console."""
587
588
588 # batch run -> do not interact
589 # batch run -> do not interact
589 if self.exit_now:
590 if self.exit_now:
590 return
591 return
591
592
592 if display_banner is None:
593 if display_banner is None:
593 display_banner = self.display_banner
594 display_banner = self.display_banner
594
595
595 if isinstance(display_banner, py3compat.string_types):
596 if isinstance(display_banner, py3compat.string_types):
596 self.show_banner(display_banner)
597 self.show_banner(display_banner)
597 elif display_banner:
598 elif display_banner:
598 self.show_banner()
599 self.show_banner()
599
600
600 more = False
601 more = False
601
602
602 if self.has_readline:
603 if self.has_readline:
603 self.readline_startup_hook(self.pre_readline)
604 self.readline_startup_hook(self.pre_readline)
604 hlen_b4_cell = self.readline.get_current_history_length()
605 hlen_b4_cell = self.readline.get_current_history_length()
605 else:
606 else:
606 hlen_b4_cell = 0
607 hlen_b4_cell = 0
607 # exit_now is set by a call to %Exit or %Quit, through the
608 # exit_now is set by a call to %Exit or %Quit, through the
608 # ask_exit callback.
609 # ask_exit callback.
609
610
610 while not self.exit_now:
611 while not self.exit_now:
611 self.hooks.pre_prompt_hook()
612 self.hooks.pre_prompt_hook()
612 if more:
613 if more:
613 try:
614 try:
614 prompt = self.prompt_manager.render('in2')
615 prompt = self.prompt_manager.render('in2')
615 except:
616 except:
616 self.showtraceback()
617 self.showtraceback()
617 if self.autoindent:
618 if self.autoindent:
618 self.rl_do_indent = True
619 self.rl_do_indent = True
619
620
620 else:
621 else:
621 try:
622 try:
622 prompt = self.separate_in + self.prompt_manager.render('in')
623 prompt = self.separate_in + self.prompt_manager.render('in')
623 except:
624 except:
624 self.showtraceback()
625 self.showtraceback()
625 try:
626 try:
626 line = self.raw_input(prompt)
627 line = self.raw_input(prompt)
627 if self.exit_now:
628 if self.exit_now:
628 # quick exit on sys.std[in|out] close
629 # quick exit on sys.std[in|out] close
629 break
630 break
630 if self.autoindent:
631 if self.autoindent:
631 self.rl_do_indent = False
632 self.rl_do_indent = False
632
633
633 except KeyboardInterrupt:
634 except KeyboardInterrupt:
634 #double-guard against keyboardinterrupts during kbdint handling
635 #double-guard against keyboardinterrupts during kbdint handling
635 try:
636 try:
636 self.write('\n' + self.get_exception_only())
637 self.write('\n' + self.get_exception_only())
637 source_raw = self.input_splitter.raw_reset()
638 source_raw = self.input_splitter.raw_reset()
638 hlen_b4_cell = \
639 hlen_b4_cell = \
639 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
640 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
640 more = False
641 more = False
641 except KeyboardInterrupt:
642 except KeyboardInterrupt:
642 pass
643 pass
643 except EOFError:
644 except EOFError:
644 if self.autoindent:
645 if self.autoindent:
645 self.rl_do_indent = False
646 self.rl_do_indent = False
646 if self.has_readline:
647 if self.has_readline:
647 self.readline_startup_hook(None)
648 self.readline_startup_hook(None)
648 self.write('\n')
649 self.write('\n')
649 self.exit()
650 self.exit()
650 except bdb.BdbQuit:
651 except bdb.BdbQuit:
651 warn('The Python debugger has exited with a BdbQuit exception.\n'
652 warn('The Python debugger has exited with a BdbQuit exception.\n'
652 'Because of how pdb handles the stack, it is impossible\n'
653 'Because of how pdb handles the stack, it is impossible\n'
653 'for IPython to properly format this particular exception.\n'
654 'for IPython to properly format this particular exception.\n'
654 'IPython will resume normal operation.')
655 'IPython will resume normal operation.')
655 except:
656 except:
656 # exceptions here are VERY RARE, but they can be triggered
657 # exceptions here are VERY RARE, but they can be triggered
657 # asynchronously by signal handlers, for example.
658 # asynchronously by signal handlers, for example.
658 self.showtraceback()
659 self.showtraceback()
659 else:
660 else:
660 try:
661 try:
661 self.input_splitter.push(line)
662 self.input_splitter.push(line)
662 more = self.input_splitter.push_accepts_more()
663 more = self.input_splitter.push_accepts_more()
663 except SyntaxError:
664 except SyntaxError:
664 # Run the code directly - run_cell takes care of displaying
665 # Run the code directly - run_cell takes care of displaying
665 # the exception.
666 # the exception.
666 more = False
667 more = False
667 if (self.SyntaxTB.last_syntax_error and
668 if (self.SyntaxTB.last_syntax_error and
668 self.autoedit_syntax):
669 self.autoedit_syntax):
669 self.edit_syntax_error()
670 self.edit_syntax_error()
670 if not more:
671 if not more:
671 source_raw = self.input_splitter.raw_reset()
672 source_raw = self.input_splitter.raw_reset()
672 self.run_cell(source_raw, store_history=True)
673 self.run_cell(source_raw, store_history=True)
673 hlen_b4_cell = \
674 hlen_b4_cell = \
674 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
675 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
675
676
676 # Turn off the exit flag, so the mainloop can be restarted if desired
677 # Turn off the exit flag, so the mainloop can be restarted if desired
677 self.exit_now = False
678 self.exit_now = False
678
679
679 def raw_input(self, prompt=''):
680 def raw_input(self, prompt=''):
680 """Write a prompt and read a line.
681 """Write a prompt and read a line.
681
682
682 The returned line does not include the trailing newline.
683 The returned line does not include the trailing newline.
683 When the user enters the EOF key sequence, EOFError is raised.
684 When the user enters the EOF key sequence, EOFError is raised.
684
685
685 Parameters
686 Parameters
686 ----------
687 ----------
687
688
688 prompt : str, optional
689 prompt : str, optional
689 A string to be printed to prompt the user.
690 A string to be printed to prompt the user.
690 """
691 """
691 # raw_input expects str, but we pass it unicode sometimes
692 # raw_input expects str, but we pass it unicode sometimes
692 prompt = py3compat.cast_bytes_py2(prompt)
693 prompt = py3compat.cast_bytes_py2(prompt)
693
694
694 try:
695 try:
695 line = py3compat.cast_unicode_py2(self.raw_input_original(prompt))
696 line = py3compat.cast_unicode_py2(self.raw_input_original(prompt))
696 except ValueError:
697 except ValueError:
697 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
698 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
698 " or sys.stdout.close()!\nExiting IPython!\n")
699 " or sys.stdout.close()!\nExiting IPython!\n")
699 self.ask_exit()
700 self.ask_exit()
700 return ""
701 return ""
701
702
702 # Try to be reasonably smart about not re-indenting pasted input more
703 # Try to be reasonably smart about not re-indenting pasted input more
703 # than necessary. We do this by trimming out the auto-indent initial
704 # than necessary. We do this by trimming out the auto-indent initial
704 # spaces, if the user's actual input started itself with whitespace.
705 # spaces, if the user's actual input started itself with whitespace.
705 if self.autoindent:
706 if self.autoindent:
706 if num_ini_spaces(line) > self.indent_current_nsp:
707 if num_ini_spaces(line) > self.indent_current_nsp:
707 line = line[self.indent_current_nsp:]
708 line = line[self.indent_current_nsp:]
708 self.indent_current_nsp = 0
709 self.indent_current_nsp = 0
709
710
710 return line
711 return line
711
712
712 #-------------------------------------------------------------------------
713 #-------------------------------------------------------------------------
713 # Methods to support auto-editing of SyntaxErrors.
714 # Methods to support auto-editing of SyntaxErrors.
714 #-------------------------------------------------------------------------
715 #-------------------------------------------------------------------------
715
716
716 def edit_syntax_error(self):
717 def edit_syntax_error(self):
717 """The bottom half of the syntax error handler called in the main loop.
718 """The bottom half of the syntax error handler called in the main loop.
718
719
719 Loop until syntax error is fixed or user cancels.
720 Loop until syntax error is fixed or user cancels.
720 """
721 """
721
722
722 while self.SyntaxTB.last_syntax_error:
723 while self.SyntaxTB.last_syntax_error:
723 # copy and clear last_syntax_error
724 # copy and clear last_syntax_error
724 err = self.SyntaxTB.clear_err_state()
725 err = self.SyntaxTB.clear_err_state()
725 if not self._should_recompile(err):
726 if not self._should_recompile(err):
726 return
727 return
727 try:
728 try:
728 # may set last_syntax_error again if a SyntaxError is raised
729 # may set last_syntax_error again if a SyntaxError is raised
729 self.safe_execfile(err.filename,self.user_ns)
730 self.safe_execfile(err.filename,self.user_ns)
730 except:
731 except:
731 self.showtraceback()
732 self.showtraceback()
732 else:
733 else:
733 try:
734 try:
734 f = open(err.filename)
735 f = open(err.filename)
735 try:
736 try:
736 # This should be inside a display_trap block and I
737 # This should be inside a display_trap block and I
737 # think it is.
738 # think it is.
738 sys.displayhook(f.read())
739 sys.displayhook(f.read())
739 finally:
740 finally:
740 f.close()
741 f.close()
741 except:
742 except:
742 self.showtraceback()
743 self.showtraceback()
743
744
744 def _should_recompile(self,e):
745 def _should_recompile(self,e):
745 """Utility routine for edit_syntax_error"""
746 """Utility routine for edit_syntax_error"""
746
747
747 if e.filename in ('<ipython console>','<input>','<string>',
748 if e.filename in ('<ipython console>','<input>','<string>',
748 '<console>','<BackgroundJob compilation>',
749 '<console>','<BackgroundJob compilation>',
749 None):
750 None):
750
751
751 return False
752 return False
752 try:
753 try:
753 if (self.autoedit_syntax and
754 if (self.autoedit_syntax and
754 not self.ask_yes_no('Return to editor to correct syntax error? '
755 not self.ask_yes_no('Return to editor to correct syntax error? '
755 '[Y/n] ','y')):
756 '[Y/n] ','y')):
756 return False
757 return False
757 except EOFError:
758 except EOFError:
758 return False
759 return False
759
760
760 def int0(x):
761 def int0(x):
761 try:
762 try:
762 return int(x)
763 return int(x)
763 except TypeError:
764 except TypeError:
764 return 0
765 return 0
765 # always pass integer line and offset values to editor hook
766 # always pass integer line and offset values to editor hook
766 try:
767 try:
767 self.hooks.fix_error_editor(e.filename,
768 self.hooks.fix_error_editor(e.filename,
768 int0(e.lineno),int0(e.offset),e.msg)
769 int0(e.lineno),int0(e.offset),e.msg)
769 except TryNext:
770 except TryNext:
770 warn('Could not open editor')
771 warn('Could not open editor')
771 return False
772 return False
772 return True
773 return True
773
774
774 #-------------------------------------------------------------------------
775 #-------------------------------------------------------------------------
775 # Things related to exiting
776 # Things related to exiting
776 #-------------------------------------------------------------------------
777 #-------------------------------------------------------------------------
777
778
778 def ask_exit(self):
779 def ask_exit(self):
779 """ Ask the shell to exit. Can be overiden and used as a callback. """
780 """ Ask the shell to exit. Can be overiden and used as a callback. """
780 self.exit_now = True
781 self.exit_now = True
781
782
782 def exit(self):
783 def exit(self):
783 """Handle interactive exit.
784 """Handle interactive exit.
784
785
785 This method calls the ask_exit callback."""
786 This method calls the ask_exit callback."""
786 if self.confirm_exit:
787 if self.confirm_exit:
787 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
788 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
788 self.ask_exit()
789 self.ask_exit()
789 else:
790 else:
790 self.ask_exit()
791 self.ask_exit()
791
792
792 #-------------------------------------------------------------------------
793 #-------------------------------------------------------------------------
793 # Things related to magics
794 # Things related to magics
794 #-------------------------------------------------------------------------
795 #-------------------------------------------------------------------------
795
796
796 def init_magics(self):
797 def init_magics(self):
797 super(TerminalInteractiveShell, self).init_magics()
798 super(TerminalInteractiveShell, self).init_magics()
798 self.register_magics(TerminalMagics)
799 self.register_magics(TerminalMagics)
799
800
800 def showindentationerror(self):
801 def showindentationerror(self):
801 super(TerminalInteractiveShell, self).showindentationerror()
802 super(TerminalInteractiveShell, self).showindentationerror()
802 if not self.using_paste_magics:
803 if not self.using_paste_magics:
803 print("If you want to paste code into IPython, try the "
804 print("If you want to paste code into IPython, try the "
804 "%paste and %cpaste magic functions.")
805 "%paste and %cpaste magic functions.")
805
806
806
807
807 InteractiveShellABC.register(TerminalInteractiveShell)
808 InteractiveShellABC.register(TerminalInteractiveShell)
@@ -1,442 +1,441 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Test Suite Runner.
2 """IPython Test Suite Runner.
3
3
4 This module provides a main entry point to a user script to test IPython
4 This module provides a main entry point to a user script to test IPython
5 itself from the command line. There are two ways of running this script:
5 itself from the command line. There are two ways of running this script:
6
6
7 1. With the syntax `iptest all`. This runs our entire test suite by
7 1. With the syntax `iptest all`. This runs our entire test suite by
8 calling this script (with different arguments) recursively. This
8 calling this script (with different arguments) recursively. This
9 causes modules and package to be tested in different processes, using nose
9 causes modules and package to be tested in different processes, using nose
10 or trial where appropriate.
10 or trial where appropriate.
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 the script simply calls nose, but with special command line flags and
12 the script simply calls nose, but with special command line flags and
13 plugins loaded.
13 plugins loaded.
14
14
15 """
15 """
16
16
17 # Copyright (c) IPython Development Team.
17 # Copyright (c) IPython Development Team.
18 # Distributed under the terms of the Modified BSD License.
18 # Distributed under the terms of the Modified BSD License.
19
19
20 from __future__ import print_function
20 from __future__ import print_function
21
21
22 import glob
22 import glob
23 from io import BytesIO
23 from io import BytesIO
24 import os
24 import os
25 import os.path as path
25 import os.path as path
26 import sys
26 import sys
27 from threading import Thread, Lock, Event
27 from threading import Thread, Lock, Event
28 import warnings
28 import warnings
29
29
30 import nose.plugins.builtin
30 import nose.plugins.builtin
31 from nose.plugins.xunit import Xunit
31 from nose.plugins.xunit import Xunit
32 from nose import SkipTest
32 from nose import SkipTest
33 from nose.core import TestProgram
33 from nose.core import TestProgram
34 from nose.plugins import Plugin
34 from nose.plugins import Plugin
35 from nose.util import safe_str
35 from nose.util import safe_str
36
36
37 from IPython import version_info
37 from IPython import version_info
38 from IPython.utils.py3compat import bytes_to_str
38 from IPython.utils.py3compat import bytes_to_str
39 from IPython.utils.importstring import import_item
39 from IPython.utils.importstring import import_item
40 from IPython.testing.plugin.ipdoctest import IPythonDoctest
40 from IPython.testing.plugin.ipdoctest import IPythonDoctest
41 from IPython.external.decorators import KnownFailure, knownfailureif
41 from IPython.external.decorators import KnownFailure, knownfailureif
42
42
43 pjoin = path.join
43 pjoin = path.join
44
44
45
45
46 # Enable printing all warnings raise by IPython's modules
46 # Enable printing all warnings raise by IPython's modules
47 warnings.filterwarnings('default', message='.*', category=Warning, module='IPy.*')
47 warnings.filterwarnings('default', message='.*', category=Warning, module='IPy.*')
48
48
49
49
50 if version_info < (4,2):
50 if version_info < (4,2):
51 # ignore some warnings from traitlets until 6.0
51 # ignore some warnings from traitlets until 6.0
52 warnings.filterwarnings('ignore', message='.*on_trait_change is deprecated: use observe instead.*')
52 warnings.filterwarnings('ignore', message='.*on_trait_change is deprecated: use observe instead.*')
53 warnings.filterwarnings('ignore', message='.*was set from the constructor.*', category=Warning, module='IPython.*')
53 warnings.filterwarnings('ignore', message='.*was set from the constructor.*', category=Warning, module='IPython.*')
54 warnings.filterwarnings('ignore', message='.*use the instance .help string directly, like x.help.*', category=DeprecationWarning, module='IPython.*')
54 warnings.filterwarnings('ignore', message='.*use the instance .help string directly, like x.help.*', category=DeprecationWarning, module='IPython.*')
55 else :
55 else :
56 warnings.warn('iptest has been filtering out for Traitlets warnings messages, for 2 minor versions (since 4.x), please consider updating to use new API')
56 warnings.warn('iptest has been filtering out for Traitlets warnings messages, for 2 minor versions (since 4.x), please consider updating to use new API')
57
57
58 if version_info < (6,):
58 if version_info < (6,):
59 # nose.tools renames all things from `camelCase` to `snake_case` which raise an
59 # nose.tools renames all things from `camelCase` to `snake_case` which raise an
60 # warning with the runner they also import from standard import library. (as of Dec 2015)
60 # warning with the runner they also import from standard import library. (as of Dec 2015)
61 # Ignore, let's revisit that in a couple of years for IPython 6.
61 # Ignore, let's revisit that in a couple of years for IPython 6.
62 warnings.filterwarnings('ignore', message='.*Please use assertEqual instead', category=Warning, module='IPython.*')
62 warnings.filterwarnings('ignore', message='.*Please use assertEqual instead', category=Warning, module='IPython.*')
63
63
64
64
65 # ------------------------------------------------------------------------------
65 # ------------------------------------------------------------------------------
66 # Monkeypatch Xunit to count known failures as skipped.
66 # Monkeypatch Xunit to count known failures as skipped.
67 # ------------------------------------------------------------------------------
67 # ------------------------------------------------------------------------------
68 def monkeypatch_xunit():
68 def monkeypatch_xunit():
69 try:
69 try:
70 knownfailureif(True)(lambda: None)()
70 knownfailureif(True)(lambda: None)()
71 except Exception as e:
71 except Exception as e:
72 KnownFailureTest = type(e)
72 KnownFailureTest = type(e)
73
73
74 def addError(self, test, err, capt=None):
74 def addError(self, test, err, capt=None):
75 if issubclass(err[0], KnownFailureTest):
75 if issubclass(err[0], KnownFailureTest):
76 err = (SkipTest,) + err[1:]
76 err = (SkipTest,) + err[1:]
77 return self.orig_addError(test, err, capt)
77 return self.orig_addError(test, err, capt)
78
78
79 Xunit.orig_addError = Xunit.addError
79 Xunit.orig_addError = Xunit.addError
80 Xunit.addError = addError
80 Xunit.addError = addError
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Check which dependencies are installed and greater than minimum version.
83 # Check which dependencies are installed and greater than minimum version.
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85 def extract_version(mod):
85 def extract_version(mod):
86 return mod.__version__
86 return mod.__version__
87
87
88 def test_for(item, min_version=None, callback=extract_version):
88 def test_for(item, min_version=None, callback=extract_version):
89 """Test to see if item is importable, and optionally check against a minimum
89 """Test to see if item is importable, and optionally check against a minimum
90 version.
90 version.
91
91
92 If min_version is given, the default behavior is to check against the
92 If min_version is given, the default behavior is to check against the
93 `__version__` attribute of the item, but specifying `callback` allows you to
93 `__version__` attribute of the item, but specifying `callback` allows you to
94 extract the value you are interested in. e.g::
94 extract the value you are interested in. e.g::
95
95
96 In [1]: import sys
96 In [1]: import sys
97
97
98 In [2]: from IPython.testing.iptest import test_for
98 In [2]: from IPython.testing.iptest import test_for
99
99
100 In [3]: test_for('sys', (2,6), callback=lambda sys: sys.version_info)
100 In [3]: test_for('sys', (2,6), callback=lambda sys: sys.version_info)
101 Out[3]: True
101 Out[3]: True
102
102
103 """
103 """
104 try:
104 try:
105 check = import_item(item)
105 check = import_item(item)
106 except (ImportError, RuntimeError):
106 except (ImportError, RuntimeError):
107 # GTK reports Runtime error if it can't be initialized even if it's
107 # GTK reports Runtime error if it can't be initialized even if it's
108 # importable.
108 # importable.
109 return False
109 return False
110 else:
110 else:
111 if min_version:
111 if min_version:
112 if callback:
112 if callback:
113 # extra processing step to get version to compare
113 # extra processing step to get version to compare
114 check = callback(check)
114 check = callback(check)
115
115
116 return check >= min_version
116 return check >= min_version
117 else:
117 else:
118 return True
118 return True
119
119
120 # Global dict where we can store information on what we have and what we don't
120 # Global dict where we can store information on what we have and what we don't
121 # have available at test run time
121 # have available at test run time
122 have = {'matplotlib': test_for('matplotlib'),
122 have = {'matplotlib': test_for('matplotlib'),
123 'pygments': test_for('pygments'),
123 'pygments': test_for('pygments'),
124 'sqlite3': test_for('sqlite3')}
124 'sqlite3': test_for('sqlite3')}
125
125
126 #-----------------------------------------------------------------------------
126 #-----------------------------------------------------------------------------
127 # Test suite definitions
127 # Test suite definitions
128 #-----------------------------------------------------------------------------
128 #-----------------------------------------------------------------------------
129
129
130 test_group_names = ['core',
130 test_group_names = ['core',
131 'extensions', 'lib', 'terminal', 'testing', 'utils',
131 'extensions', 'lib', 'terminal', 'testing', 'utils',
132 ]
132 ]
133
133
134 class TestSection(object):
134 class TestSection(object):
135 def __init__(self, name, includes):
135 def __init__(self, name, includes):
136 self.name = name
136 self.name = name
137 self.includes = includes
137 self.includes = includes
138 self.excludes = []
138 self.excludes = []
139 self.dependencies = []
139 self.dependencies = []
140 self.enabled = True
140 self.enabled = True
141
141
142 def exclude(self, module):
142 def exclude(self, module):
143 if not module.startswith('IPython'):
143 if not module.startswith('IPython'):
144 module = self.includes[0] + "." + module
144 module = self.includes[0] + "." + module
145 self.excludes.append(module.replace('.', os.sep))
145 self.excludes.append(module.replace('.', os.sep))
146
146
147 def requires(self, *packages):
147 def requires(self, *packages):
148 self.dependencies.extend(packages)
148 self.dependencies.extend(packages)
149
149
150 @property
150 @property
151 def will_run(self):
151 def will_run(self):
152 return self.enabled and all(have[p] for p in self.dependencies)
152 return self.enabled and all(have[p] for p in self.dependencies)
153
153
154 # Name -> (include, exclude, dependencies_met)
154 # Name -> (include, exclude, dependencies_met)
155 test_sections = {n:TestSection(n, ['IPython.%s' % n]) for n in test_group_names}
155 test_sections = {n:TestSection(n, ['IPython.%s' % n]) for n in test_group_names}
156
156
157
157
158 # Exclusions and dependencies
158 # Exclusions and dependencies
159 # ---------------------------
159 # ---------------------------
160
160
161 # core:
161 # core:
162 sec = test_sections['core']
162 sec = test_sections['core']
163 if not have['sqlite3']:
163 if not have['sqlite3']:
164 sec.exclude('tests.test_history')
164 sec.exclude('tests.test_history')
165 sec.exclude('history')
165 sec.exclude('history')
166 if not have['matplotlib']:
166 if not have['matplotlib']:
167 sec.exclude('pylabtools'),
167 sec.exclude('pylabtools'),
168 sec.exclude('tests.test_pylabtools')
168 sec.exclude('tests.test_pylabtools')
169
169
170 # lib:
170 # lib:
171 sec = test_sections['lib']
171 sec = test_sections['lib']
172 sec.exclude('kernel')
172 sec.exclude('kernel')
173 if not have['pygments']:
173 if not have['pygments']:
174 sec.exclude('tests.test_lexers')
174 sec.exclude('tests.test_lexers')
175 # We do this unconditionally, so that the test suite doesn't import
175 # We do this unconditionally, so that the test suite doesn't import
176 # gtk, changing the default encoding and masking some unicode bugs.
176 # gtk, changing the default encoding and masking some unicode bugs.
177 sec.exclude('inputhookgtk')
177 sec.exclude('inputhookgtk')
178 # We also do this unconditionally, because wx can interfere with Unix signals.
178 # We also do this unconditionally, because wx can interfere with Unix signals.
179 # There are currently no tests for it anyway.
179 # There are currently no tests for it anyway.
180 sec.exclude('inputhookwx')
180 sec.exclude('inputhookwx')
181 # Testing inputhook will need a lot of thought, to figure out
181 # Testing inputhook will need a lot of thought, to figure out
182 # how to have tests that don't lock up with the gui event
182 # how to have tests that don't lock up with the gui event
183 # loops in the picture
183 # loops in the picture
184 sec.exclude('inputhook')
184 sec.exclude('inputhook')
185
185
186 # testing:
186 # testing:
187 sec = test_sections['testing']
187 sec = test_sections['testing']
188 # These have to be skipped on win32 because they use echo, rm, cd, etc.
188 # These have to be skipped on win32 because they use echo, rm, cd, etc.
189 # See ticket https://github.com/ipython/ipython/issues/87
189 # See ticket https://github.com/ipython/ipython/issues/87
190 if sys.platform == 'win32':
190 if sys.platform == 'win32':
191 sec.exclude('plugin.test_exampleip')
191 sec.exclude('plugin.test_exampleip')
192 sec.exclude('plugin.dtexample')
192 sec.exclude('plugin.dtexample')
193
193
194 # don't run jupyter_console tests found via shim
194 # don't run jupyter_console tests found via shim
195 test_sections['terminal'].exclude('console')
195 test_sections['terminal'].exclude('console')
196
196
197 # extensions:
197 # extensions:
198 sec = test_sections['extensions']
198 sec = test_sections['extensions']
199 # This is deprecated in favour of rpy2
199 # This is deprecated in favour of rpy2
200 sec.exclude('rmagic')
200 sec.exclude('rmagic')
201 # autoreload does some strange stuff, so move it to its own test section
201 # autoreload does some strange stuff, so move it to its own test section
202 sec.exclude('autoreload')
202 sec.exclude('autoreload')
203 sec.exclude('tests.test_autoreload')
203 sec.exclude('tests.test_autoreload')
204 test_sections['autoreload'] = TestSection('autoreload',
204 test_sections['autoreload'] = TestSection('autoreload',
205 ['IPython.extensions.autoreload', 'IPython.extensions.tests.test_autoreload'])
205 ['IPython.extensions.autoreload', 'IPython.extensions.tests.test_autoreload'])
206 test_group_names.append('autoreload')
206 test_group_names.append('autoreload')
207
207
208
208
209 #-----------------------------------------------------------------------------
209 #-----------------------------------------------------------------------------
210 # Functions and classes
210 # Functions and classes
211 #-----------------------------------------------------------------------------
211 #-----------------------------------------------------------------------------
212
212
213 def check_exclusions_exist():
213 def check_exclusions_exist():
214 from IPython.paths import get_ipython_package_dir
214 from IPython.paths import get_ipython_package_dir
215 from IPython.utils.warn import warn
215 from warnings import warn
216 parent = os.path.dirname(get_ipython_package_dir())
216 parent = os.path.dirname(get_ipython_package_dir())
217 for sec in test_sections:
217 for sec in test_sections:
218 for pattern in sec.exclusions:
218 for pattern in sec.exclusions:
219 fullpath = pjoin(parent, pattern)
219 fullpath = pjoin(parent, pattern)
220 if not os.path.exists(fullpath) and not glob.glob(fullpath + '.*'):
220 if not os.path.exists(fullpath) and not glob.glob(fullpath + '.*'):
221 warn("Excluding nonexistent file: %r" % pattern)
221 warn("Excluding nonexistent file: %r" % pattern)
222
222
223
223
224 class ExclusionPlugin(Plugin):
224 class ExclusionPlugin(Plugin):
225 """A nose plugin to effect our exclusions of files and directories.
225 """A nose plugin to effect our exclusions of files and directories.
226 """
226 """
227 name = 'exclusions'
227 name = 'exclusions'
228 score = 3000 # Should come before any other plugins
228 score = 3000 # Should come before any other plugins
229
229
230 def __init__(self, exclude_patterns=None):
230 def __init__(self, exclude_patterns=None):
231 """
231 """
232 Parameters
232 Parameters
233 ----------
233 ----------
234
234
235 exclude_patterns : sequence of strings, optional
235 exclude_patterns : sequence of strings, optional
236 Filenames containing these patterns (as raw strings, not as regular
236 Filenames containing these patterns (as raw strings, not as regular
237 expressions) are excluded from the tests.
237 expressions) are excluded from the tests.
238 """
238 """
239 self.exclude_patterns = exclude_patterns or []
239 self.exclude_patterns = exclude_patterns or []
240 super(ExclusionPlugin, self).__init__()
240 super(ExclusionPlugin, self).__init__()
241
241
242 def options(self, parser, env=os.environ):
242 def options(self, parser, env=os.environ):
243 Plugin.options(self, parser, env)
243 Plugin.options(self, parser, env)
244
244
245 def configure(self, options, config):
245 def configure(self, options, config):
246 Plugin.configure(self, options, config)
246 Plugin.configure(self, options, config)
247 # Override nose trying to disable plugin.
247 # Override nose trying to disable plugin.
248 self.enabled = True
248 self.enabled = True
249
249
250 def wantFile(self, filename):
250 def wantFile(self, filename):
251 """Return whether the given filename should be scanned for tests.
251 """Return whether the given filename should be scanned for tests.
252 """
252 """
253 if any(pat in filename for pat in self.exclude_patterns):
253 if any(pat in filename for pat in self.exclude_patterns):
254 return False
254 return False
255 return None
255 return None
256
256
257 def wantDirectory(self, directory):
257 def wantDirectory(self, directory):
258 """Return whether the given directory should be scanned for tests.
258 """Return whether the given directory should be scanned for tests.
259 """
259 """
260 if any(pat in directory for pat in self.exclude_patterns):
260 if any(pat in directory for pat in self.exclude_patterns):
261 return False
261 return False
262 return None
262 return None
263
263
264
264
265 class StreamCapturer(Thread):
265 class StreamCapturer(Thread):
266 daemon = True # Don't hang if main thread crashes
266 daemon = True # Don't hang if main thread crashes
267 started = False
267 started = False
268 def __init__(self, echo=False):
268 def __init__(self, echo=False):
269 super(StreamCapturer, self).__init__()
269 super(StreamCapturer, self).__init__()
270 self.echo = echo
270 self.echo = echo
271 self.streams = []
271 self.streams = []
272 self.buffer = BytesIO()
272 self.buffer = BytesIO()
273 self.readfd, self.writefd = os.pipe()
273 self.readfd, self.writefd = os.pipe()
274 self.buffer_lock = Lock()
274 self.buffer_lock = Lock()
275 self.stop = Event()
275 self.stop = Event()
276
276
277 def run(self):
277 def run(self):
278 self.started = True
278 self.started = True
279
279
280 while not self.stop.is_set():
280 while not self.stop.is_set():
281 chunk = os.read(self.readfd, 1024)
281 chunk = os.read(self.readfd, 1024)
282
282
283 with self.buffer_lock:
283 with self.buffer_lock:
284 self.buffer.write(chunk)
284 self.buffer.write(chunk)
285 if self.echo:
285 if self.echo:
286 sys.stdout.write(bytes_to_str(chunk))
286 sys.stdout.write(bytes_to_str(chunk))
287
287
288 os.close(self.readfd)
288 os.close(self.readfd)
289 os.close(self.writefd)
289 os.close(self.writefd)
290
290
291 def reset_buffer(self):
291 def reset_buffer(self):
292 with self.buffer_lock:
292 with self.buffer_lock:
293 self.buffer.truncate(0)
293 self.buffer.truncate(0)
294 self.buffer.seek(0)
294 self.buffer.seek(0)
295
295
296 def get_buffer(self):
296 def get_buffer(self):
297 with self.buffer_lock:
297 with self.buffer_lock:
298 return self.buffer.getvalue()
298 return self.buffer.getvalue()
299
299
300 def ensure_started(self):
300 def ensure_started(self):
301 if not self.started:
301 if not self.started:
302 self.start()
302 self.start()
303
303
304 def halt(self):
304 def halt(self):
305 """Safely stop the thread."""
305 """Safely stop the thread."""
306 if not self.started:
306 if not self.started:
307 return
307 return
308
308
309 self.stop.set()
309 self.stop.set()
310 os.write(self.writefd, b'\0') # Ensure we're not locked in a read()
310 os.write(self.writefd, b'\0') # Ensure we're not locked in a read()
311 self.join()
311 self.join()
312
312
313 class SubprocessStreamCapturePlugin(Plugin):
313 class SubprocessStreamCapturePlugin(Plugin):
314 name='subprocstreams'
314 name='subprocstreams'
315 def __init__(self):
315 def __init__(self):
316 Plugin.__init__(self)
316 Plugin.__init__(self)
317 self.stream_capturer = StreamCapturer()
317 self.stream_capturer = StreamCapturer()
318 self.destination = os.environ.get('IPTEST_SUBPROC_STREAMS', 'capture')
318 self.destination = os.environ.get('IPTEST_SUBPROC_STREAMS', 'capture')
319 # This is ugly, but distant parts of the test machinery need to be able
319 # This is ugly, but distant parts of the test machinery need to be able
320 # to redirect streams, so we make the object globally accessible.
320 # to redirect streams, so we make the object globally accessible.
321 nose.iptest_stdstreams_fileno = self.get_write_fileno
321 nose.iptest_stdstreams_fileno = self.get_write_fileno
322
322
323 def get_write_fileno(self):
323 def get_write_fileno(self):
324 if self.destination == 'capture':
324 if self.destination == 'capture':
325 self.stream_capturer.ensure_started()
325 self.stream_capturer.ensure_started()
326 return self.stream_capturer.writefd
326 return self.stream_capturer.writefd
327 elif self.destination == 'discard':
327 elif self.destination == 'discard':
328 return os.open(os.devnull, os.O_WRONLY)
328 return os.open(os.devnull, os.O_WRONLY)
329 else:
329 else:
330 return sys.__stdout__.fileno()
330 return sys.__stdout__.fileno()
331
331
332 def configure(self, options, config):
332 def configure(self, options, config):
333 Plugin.configure(self, options, config)
333 Plugin.configure(self, options, config)
334 # Override nose trying to disable plugin.
334 # Override nose trying to disable plugin.
335 if self.destination == 'capture':
335 if self.destination == 'capture':
336 self.enabled = True
336 self.enabled = True
337
337
338 def startTest(self, test):
338 def startTest(self, test):
339 # Reset log capture
339 # Reset log capture
340 self.stream_capturer.reset_buffer()
340 self.stream_capturer.reset_buffer()
341
341
342 def formatFailure(self, test, err):
342 def formatFailure(self, test, err):
343 # Show output
343 # Show output
344 ec, ev, tb = err
344 ec, ev, tb = err
345 captured = self.stream_capturer.get_buffer().decode('utf-8', 'replace')
345 captured = self.stream_capturer.get_buffer().decode('utf-8', 'replace')
346 if captured.strip():
346 if captured.strip():
347 ev = safe_str(ev)
347 ev = safe_str(ev)
348 out = [ev, '>> begin captured subprocess output <<',
348 out = [ev, '>> begin captured subprocess output <<',
349 captured,
349 captured,
350 '>> end captured subprocess output <<']
350 '>> end captured subprocess output <<']
351 return ec, '\n'.join(out), tb
351 return ec, '\n'.join(out), tb
352
352
353 return err
353 return err
354
354
355 formatError = formatFailure
355 formatError = formatFailure
356
356
357 def finalize(self, result):
357 def finalize(self, result):
358 self.stream_capturer.halt()
358 self.stream_capturer.halt()
359
359
360
360
361 def run_iptest():
361 def run_iptest():
362 """Run the IPython test suite using nose.
362 """Run the IPython test suite using nose.
363
363
364 This function is called when this script is **not** called with the form
364 This function is called when this script is **not** called with the form
365 `iptest all`. It simply calls nose with appropriate command line flags
365 `iptest all`. It simply calls nose with appropriate command line flags
366 and accepts all of the standard nose arguments.
366 and accepts all of the standard nose arguments.
367 """
367 """
368 # Apply our monkeypatch to Xunit
368 # Apply our monkeypatch to Xunit
369 if '--with-xunit' in sys.argv and not hasattr(Xunit, 'orig_addError'):
369 if '--with-xunit' in sys.argv and not hasattr(Xunit, 'orig_addError'):
370 monkeypatch_xunit()
370 monkeypatch_xunit()
371
371
372 warnings.filterwarnings('ignore',
372 warnings.filterwarnings('ignore',
373 'This will be removed soon. Use IPython.testing.util instead')
373 'This will be removed soon. Use IPython.testing.util instead')
374
374
375 arg1 = sys.argv[1]
375 arg1 = sys.argv[1]
376 if arg1 in test_sections:
376 if arg1 in test_sections:
377 section = test_sections[arg1]
377 section = test_sections[arg1]
378 sys.argv[1:2] = section.includes
378 sys.argv[1:2] = section.includes
379 elif arg1.startswith('IPython.') and arg1[8:] in test_sections:
379 elif arg1.startswith('IPython.') and arg1[8:] in test_sections:
380 section = test_sections[arg1[8:]]
380 section = test_sections[arg1[8:]]
381 sys.argv[1:2] = section.includes
381 sys.argv[1:2] = section.includes
382 else:
382 else:
383 section = TestSection(arg1, includes=[arg1])
383 section = TestSection(arg1, includes=[arg1])
384
384
385
385
386 argv = sys.argv + [ '--detailed-errors', # extra info in tracebacks
386 argv = sys.argv + [ '--detailed-errors', # extra info in tracebacks
387 # We add --exe because of setuptools' imbecility (it
387 # We add --exe because of setuptools' imbecility (it
388 # blindly does chmod +x on ALL files). Nose does the
388 # blindly does chmod +x on ALL files). Nose does the
389 # right thing and it tries to avoid executables,
389 # right thing and it tries to avoid executables,
390 # setuptools unfortunately forces our hand here. This
390 # setuptools unfortunately forces our hand here. This
391 # has been discussed on the distutils list and the
391 # has been discussed on the distutils list and the
392 # setuptools devs refuse to fix this problem!
392 # setuptools devs refuse to fix this problem!
393 '--exe',
393 '--exe',
394 ]
394 ]
395 if '-a' not in argv and '-A' not in argv:
395 if '-a' not in argv and '-A' not in argv:
396 argv = argv + ['-a', '!crash']
396 argv = argv + ['-a', '!crash']
397
397
398 if nose.__version__ >= '0.11':
398 if nose.__version__ >= '0.11':
399 # I don't fully understand why we need this one, but depending on what
399 # I don't fully understand why we need this one, but depending on what
400 # directory the test suite is run from, if we don't give it, 0 tests
400 # directory the test suite is run from, if we don't give it, 0 tests
401 # get run. Specifically, if the test suite is run from the source dir
401 # get run. Specifically, if the test suite is run from the source dir
402 # with an argument (like 'iptest.py IPython.core', 0 tests are run,
402 # with an argument (like 'iptest.py IPython.core', 0 tests are run,
403 # even if the same call done in this directory works fine). It appears
403 # even if the same call done in this directory works fine). It appears
404 # that if the requested package is in the current dir, nose bails early
404 # that if the requested package is in the current dir, nose bails early
405 # by default. Since it's otherwise harmless, leave it in by default
405 # by default. Since it's otherwise harmless, leave it in by default
406 # for nose >= 0.11, though unfortunately nose 0.10 doesn't support it.
406 # for nose >= 0.11, though unfortunately nose 0.10 doesn't support it.
407 argv.append('--traverse-namespace')
407 argv.append('--traverse-namespace')
408
408
409 plugins = [ ExclusionPlugin(section.excludes), KnownFailure(),
409 plugins = [ ExclusionPlugin(section.excludes), KnownFailure(),
410 SubprocessStreamCapturePlugin() ]
410 SubprocessStreamCapturePlugin() ]
411
411
412 # we still have some vestigial doctests in core
412 # we still have some vestigial doctests in core
413 if (section.name.startswith(('core', 'IPython.core'))):
413 if (section.name.startswith(('core', 'IPython.core'))):
414 plugins.append(IPythonDoctest())
414 plugins.append(IPythonDoctest())
415 argv.extend([
415 argv.extend([
416 '--with-ipdoctest',
416 '--with-ipdoctest',
417 '--ipdoctest-tests',
417 '--ipdoctest-tests',
418 '--ipdoctest-extension=txt',
418 '--ipdoctest-extension=txt',
419 ])
419 ])
420
420
421
421
422 # Use working directory set by parent process (see iptestcontroller)
422 # Use working directory set by parent process (see iptestcontroller)
423 if 'IPTEST_WORKING_DIR' in os.environ:
423 if 'IPTEST_WORKING_DIR' in os.environ:
424 os.chdir(os.environ['IPTEST_WORKING_DIR'])
424 os.chdir(os.environ['IPTEST_WORKING_DIR'])
425
425
426 # We need a global ipython running in this process, but the special
426 # We need a global ipython running in this process, but the special
427 # in-process group spawns its own IPython kernels, so for *that* group we
427 # in-process group spawns its own IPython kernels, so for *that* group we
428 # must avoid also opening the global one (otherwise there's a conflict of
428 # must avoid also opening the global one (otherwise there's a conflict of
429 # singletons). Ultimately the solution to this problem is to refactor our
429 # singletons). Ultimately the solution to this problem is to refactor our
430 # assumptions about what needs to be a singleton and what doesn't (app
430 # assumptions about what needs to be a singleton and what doesn't (app
431 # objects should, individual shells shouldn't). But for now, this
431 # objects should, individual shells shouldn't). But for now, this
432 # workaround allows the test suite for the inprocess module to complete.
432 # workaround allows the test suite for the inprocess module to complete.
433 if 'kernel.inprocess' not in section.name:
433 if 'kernel.inprocess' not in section.name:
434 from IPython.testing import globalipapp
434 from IPython.testing import globalipapp
435 globalipapp.start_ipython()
435 globalipapp.start_ipython()
436
436
437 # Now nose can run
437 # Now nose can run
438 TestProgram(argv=argv, addplugins=plugins)
438 TestProgram(argv=argv, addplugins=plugins)
439
439
440 if __name__ == '__main__':
440 if __name__ == '__main__':
441 run_iptest()
441 run_iptest()
442
@@ -1,60 +1,60 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Utilities for warnings. Shoudn't we just use the built in warnings module.
3 Utilities for warnings. Shoudn't we just use the built in warnings module.
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 from __future__ import print_function
9 from __future__ import print_function
10
10
11 import sys
11 import sys
12
12
13 from IPython.utils import io
13 from IPython.utils import io
14
14
15 from warning import warn
15 from warnings import warn
16
16
17 warn("The module IPython.utils.warn is deprecated, use the standard warnings module instead", DeprecationWarning)
17 warn("The module IPython.utils.warn is deprecated, use the standard warnings module instead", DeprecationWarning)
18
18
19 def warn(msg,level=2,exit_val=1):
19 def warn(msg,level=2,exit_val=1):
20 """Standard warning printer. Gives formatting consistency.
20 """Standard warning printer. Gives formatting consistency.
21
21
22 Output is sent to io.stderr (sys.stderr by default).
22 Output is sent to io.stderr (sys.stderr by default).
23
23
24 Options:
24 Options:
25
25
26 -level(2): allows finer control:
26 -level(2): allows finer control:
27 0 -> Do nothing, dummy function.
27 0 -> Do nothing, dummy function.
28 1 -> Print message.
28 1 -> Print message.
29 2 -> Print 'WARNING:' + message. (Default level).
29 2 -> Print 'WARNING:' + message. (Default level).
30 3 -> Print 'ERROR:' + message.
30 3 -> Print 'ERROR:' + message.
31 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
31 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
32
32
33 -exit_val (1): exit value returned by sys.exit() for a level 4
33 -exit_val (1): exit value returned by sys.exit() for a level 4
34 warning. Ignored for all other levels."""
34 warning. Ignored for all other levels."""
35
35
36 warn("The module IPython.utils.warn is deprecated, use the standard warnings module instead", DeprecationWarning)
36 warn("The module IPython.utils.warn is deprecated, use the standard warnings module instead", DeprecationWarning)
37 if level>0:
37 if level>0:
38 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
38 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
39 print(header[level], msg, sep='', file=io.stderr)
39 print(header[level], msg, sep='', file=io.stderr)
40 if level == 4:
40 if level == 4:
41 print('Exiting.\n', file=io.stderr)
41 print('Exiting.\n', file=io.stderr)
42 sys.exit(exit_val)
42 sys.exit(exit_val)
43
43
44
44
45 def info(msg):
45 def info(msg):
46 """Equivalent to warn(msg,level=1)."""
46 """Equivalent to warn(msg,level=1)."""
47
47
48 warn(msg,level=1)
48 warn(msg,level=1)
49
49
50
50
51 def error(msg):
51 def error(msg):
52 """Equivalent to warn(msg,level=3)."""
52 """Equivalent to warn(msg,level=3)."""
53
53
54 warn(msg,level=3)
54 warn(msg,level=3)
55
55
56
56
57 def fatal(msg,exit_val=1):
57 def fatal(msg,exit_val=1):
58 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
58 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
59
59
60 warn(msg,exit_val=exit_val,level=4)
60 warn(msg,exit_val=exit_val,level=4)
General Comments 0
You need to be logged in to leave comments. Login now