##// END OF EJS Templates
update dependency imports...
Min RK -
Show More

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

@@ -1,147 +1,146 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 IPython: tools for interactive and parallel computing in Python.
3 IPython: tools for interactive and parallel computing in Python.
4
4
5 http://ipython.org
5 http://ipython.org
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2008-2011, IPython Development Team.
8 # Copyright (c) 2008-2011, IPython Development Team.
9 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
9 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
10 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
10 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
11 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
11 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
12 #
12 #
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14 #
14 #
15 # The full license is in the file COPYING.txt, distributed with this software.
15 # The full license is in the file COPYING.txt, distributed with this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 from __future__ import absolute_import
21 from __future__ import absolute_import
22
22
23 import os
23 import os
24 import sys
24 import sys
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Setup everything
27 # Setup everything
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 # Don't forget to also update setup.py when this changes!
30 # Don't forget to also update setup.py when this changes!
31 v = sys.version_info
31 v = sys.version_info
32 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
32 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
33 raise ImportError('IPython requires Python version 2.7 or 3.3 or above.')
33 raise ImportError('IPython requires Python version 2.7 or 3.3 or above.')
34 del v
34 del v
35
35
36 # Make it easy to import extensions - they are always directly on pythonpath.
36 # Make it easy to import extensions - they are always directly on pythonpath.
37 # Therefore, non-IPython modules can be added to extensions directory.
37 # Therefore, non-IPython modules can be added to extensions directory.
38 # This should probably be in ipapp.py.
38 # This should probably be in ipapp.py.
39 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
39 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
40
40
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42 # Setup the top level names
42 # Setup the top level names
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44
44
45 from .config.loader import Config
46 from .core.getipython import get_ipython
45 from .core.getipython import get_ipython
47 from .core import release
46 from .core import release
48 from .core.application import Application
47 from .core.application import Application
49 from .terminal.embed import embed
48 from .terminal.embed import embed
50
49
51 from .core.error import TryNext
50 from .core.error import TryNext
52 from .core.interactiveshell import InteractiveShell
51 from .core.interactiveshell import InteractiveShell
53 from .testing import test
52 from .testing import test
54 from .utils.sysinfo import sys_info
53 from .utils.sysinfo import sys_info
55 from .utils.frame import extract_module_locals
54 from .utils.frame import extract_module_locals
56
55
57 # Release data
56 # Release data
58 __author__ = '%s <%s>' % (release.author, release.author_email)
57 __author__ = '%s <%s>' % (release.author, release.author_email)
59 __license__ = release.license
58 __license__ = release.license
60 __version__ = release.version
59 __version__ = release.version
61 version_info = release.version_info
60 version_info = release.version_info
62
61
63 def embed_kernel(module=None, local_ns=None, **kwargs):
62 def embed_kernel(module=None, local_ns=None, **kwargs):
64 """Embed and start an IPython kernel in a given scope.
63 """Embed and start an IPython kernel in a given scope.
65
64
66 If you don't want the kernel to initialize the namespace
65 If you don't want the kernel to initialize the namespace
67 from the scope of the surrounding function,
66 from the scope of the surrounding function,
68 and/or you want to load full IPython configuration,
67 and/or you want to load full IPython configuration,
69 you probably want `IPython.start_kernel()` instead.
68 you probably want `IPython.start_kernel()` instead.
70
69
71 Parameters
70 Parameters
72 ----------
71 ----------
73 module : ModuleType, optional
72 module : ModuleType, optional
74 The module to load into IPython globals (default: caller)
73 The module to load into IPython globals (default: caller)
75 local_ns : dict, optional
74 local_ns : dict, optional
76 The namespace to load into IPython user namespace (default: caller)
75 The namespace to load into IPython user namespace (default: caller)
77
76
78 kwargs : various, optional
77 kwargs : various, optional
79 Further keyword args are relayed to the IPKernelApp constructor,
78 Further keyword args are relayed to the IPKernelApp constructor,
80 allowing configuration of the Kernel. Will only have an effect
79 allowing configuration of the Kernel. Will only have an effect
81 on the first embed_kernel call for a given process.
80 on the first embed_kernel call for a given process.
82 """
81 """
83
82
84 (caller_module, caller_locals) = extract_module_locals(1)
83 (caller_module, caller_locals) = extract_module_locals(1)
85 if module is None:
84 if module is None:
86 module = caller_module
85 module = caller_module
87 if local_ns is None:
86 if local_ns is None:
88 local_ns = caller_locals
87 local_ns = caller_locals
89
88
90 # Only import .zmq when we really need it
89 # Only import .zmq when we really need it
91 from IPython.kernel.zmq.embed import embed_kernel as real_embed_kernel
90 from ipython_kernel.embed import embed_kernel as real_embed_kernel
92 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
91 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
93
92
94 def start_ipython(argv=None, **kwargs):
93 def start_ipython(argv=None, **kwargs):
95 """Launch a normal IPython instance (as opposed to embedded)
94 """Launch a normal IPython instance (as opposed to embedded)
96
95
97 `IPython.embed()` puts a shell in a particular calling scope,
96 `IPython.embed()` puts a shell in a particular calling scope,
98 such as a function or method for debugging purposes,
97 such as a function or method for debugging purposes,
99 which is often not desirable.
98 which is often not desirable.
100
99
101 `start_ipython()` does full, regular IPython initialization,
100 `start_ipython()` does full, regular IPython initialization,
102 including loading startup files, configuration, etc.
101 including loading startup files, configuration, etc.
103 much of which is skipped by `embed()`.
102 much of which is skipped by `embed()`.
104
103
105 This is a public API method, and will survive implementation changes.
104 This is a public API method, and will survive implementation changes.
106
105
107 Parameters
106 Parameters
108 ----------
107 ----------
109
108
110 argv : list or None, optional
109 argv : list or None, optional
111 If unspecified or None, IPython will parse command-line options from sys.argv.
110 If unspecified or None, IPython will parse command-line options from sys.argv.
112 To prevent any command-line parsing, pass an empty list: `argv=[]`.
111 To prevent any command-line parsing, pass an empty list: `argv=[]`.
113 user_ns : dict, optional
112 user_ns : dict, optional
114 specify this dictionary to initialize the IPython user namespace with particular values.
113 specify this dictionary to initialize the IPython user namespace with particular values.
115 kwargs : various, optional
114 kwargs : various, optional
116 Any other kwargs will be passed to the Application constructor,
115 Any other kwargs will be passed to the Application constructor,
117 such as `config`.
116 such as `config`.
118 """
117 """
119 from IPython.terminal.ipapp import launch_new_instance
118 from IPython.terminal.ipapp import launch_new_instance
120 return launch_new_instance(argv=argv, **kwargs)
119 return launch_new_instance(argv=argv, **kwargs)
121
120
122 def start_kernel(argv=None, **kwargs):
121 def start_kernel(argv=None, **kwargs):
123 """Launch a normal IPython kernel instance (as opposed to embedded)
122 """Launch a normal IPython kernel instance (as opposed to embedded)
124
123
125 `IPython.embed_kernel()` puts a shell in a particular calling scope,
124 `IPython.embed_kernel()` puts a shell in a particular calling scope,
126 such as a function or method for debugging purposes,
125 such as a function or method for debugging purposes,
127 which is often not desirable.
126 which is often not desirable.
128
127
129 `start_kernel()` does full, regular IPython initialization,
128 `start_kernel()` does full, regular IPython initialization,
130 including loading startup files, configuration, etc.
129 including loading startup files, configuration, etc.
131 much of which is skipped by `embed()`.
130 much of which is skipped by `embed()`.
132
131
133 Parameters
132 Parameters
134 ----------
133 ----------
135
134
136 argv : list or None, optional
135 argv : list or None, optional
137 If unspecified or None, IPython will parse command-line options from sys.argv.
136 If unspecified or None, IPython will parse command-line options from sys.argv.
138 To prevent any command-line parsing, pass an empty list: `argv=[]`.
137 To prevent any command-line parsing, pass an empty list: `argv=[]`.
139 user_ns : dict, optional
138 user_ns : dict, optional
140 specify this dictionary to initialize the IPython user namespace with particular values.
139 specify this dictionary to initialize the IPython user namespace with particular values.
141 kwargs : various, optional
140 kwargs : various, optional
142 Any other kwargs will be passed to the Application constructor,
141 Any other kwargs will be passed to the Application constructor,
143 such as `config`.
142 such as `config`.
144 """
143 """
145 from IPython.kernel.zmq.kernelapp import launch_new_instance
144 from IPython.kernel.zmq.kernelapp import launch_new_instance
146 return launch_new_instance(argv=argv, **kwargs)
145 return launch_new_instance(argv=argv, **kwargs)
147 No newline at end of file
146
@@ -1,256 +1,256 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 IPython.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 IPython.utils.traitlets import List, Instance
31 from traitlets import List, Instance
32 from IPython.utils.warn import error
32 from IPython.utils.warn 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.nargs = self.validate()
134 self.nargs = self.validate()
135
135
136 def validate(self):
136 def validate(self):
137 """Validate the alias, and return the number of arguments."""
137 """Validate the alias, and return the number of arguments."""
138 if self.name in self.blacklist:
138 if self.name in self.blacklist:
139 raise InvalidAliasError("The name %s can't be aliased "
139 raise InvalidAliasError("The name %s can't be aliased "
140 "because it is a keyword or builtin." % self.name)
140 "because it is a keyword or builtin." % self.name)
141 try:
141 try:
142 caller = self.shell.magics_manager.magics['line'][self.name]
142 caller = self.shell.magics_manager.magics['line'][self.name]
143 except KeyError:
143 except KeyError:
144 pass
144 pass
145 else:
145 else:
146 if not isinstance(caller, Alias):
146 if not isinstance(caller, Alias):
147 raise InvalidAliasError("The name %s can't be aliased "
147 raise InvalidAliasError("The name %s can't be aliased "
148 "because it is another magic command." % self.name)
148 "because it is another magic command." % self.name)
149
149
150 if not (isinstance(self.cmd, string_types)):
150 if not (isinstance(self.cmd, string_types)):
151 raise InvalidAliasError("An alias command must be a string, "
151 raise InvalidAliasError("An alias command must be a string, "
152 "got: %r" % self.cmd)
152 "got: %r" % self.cmd)
153
153
154 nargs = self.cmd.count('%s') - self.cmd.count('%%s')
154 nargs = self.cmd.count('%s') - self.cmd.count('%%s')
155
155
156 if (nargs > 0) and (self.cmd.find('%l') >= 0):
156 if (nargs > 0) and (self.cmd.find('%l') >= 0):
157 raise InvalidAliasError('The %s and %l specifiers are mutually '
157 raise InvalidAliasError('The %s and %l specifiers are mutually '
158 'exclusive in alias definitions.')
158 'exclusive in alias definitions.')
159
159
160 return nargs
160 return nargs
161
161
162 def __repr__(self):
162 def __repr__(self):
163 return "<alias {} for {!r}>".format(self.name, self.cmd)
163 return "<alias {} for {!r}>".format(self.name, self.cmd)
164
164
165 def __call__(self, rest=''):
165 def __call__(self, rest=''):
166 cmd = self.cmd
166 cmd = self.cmd
167 nargs = self.nargs
167 nargs = self.nargs
168 # Expand the %l special to be the user's input line
168 # Expand the %l special to be the user's input line
169 if cmd.find('%l') >= 0:
169 if cmd.find('%l') >= 0:
170 cmd = cmd.replace('%l', rest)
170 cmd = cmd.replace('%l', rest)
171 rest = ''
171 rest = ''
172
172
173 if nargs==0:
173 if nargs==0:
174 if cmd.find('%%s') >= 1:
174 if cmd.find('%%s') >= 1:
175 cmd = cmd.replace('%%s', '%s')
175 cmd = cmd.replace('%%s', '%s')
176 # Simple, argument-less aliases
176 # Simple, argument-less aliases
177 cmd = '%s %s' % (cmd, rest)
177 cmd = '%s %s' % (cmd, rest)
178 else:
178 else:
179 # Handle aliases with positional arguments
179 # Handle aliases with positional arguments
180 args = rest.split(None, nargs)
180 args = rest.split(None, nargs)
181 if len(args) < nargs:
181 if len(args) < nargs:
182 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
182 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
183 (self.name, nargs, len(args)))
183 (self.name, nargs, len(args)))
184 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
184 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
185
185
186 self.shell.system(cmd)
186 self.shell.system(cmd)
187
187
188 #-----------------------------------------------------------------------------
188 #-----------------------------------------------------------------------------
189 # Main AliasManager class
189 # Main AliasManager class
190 #-----------------------------------------------------------------------------
190 #-----------------------------------------------------------------------------
191
191
192 class AliasManager(Configurable):
192 class AliasManager(Configurable):
193
193
194 default_aliases = List(default_aliases(), config=True)
194 default_aliases = List(default_aliases(), config=True)
195 user_aliases = List(default_value=[], config=True)
195 user_aliases = List(default_value=[], config=True)
196 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
196 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
197
197
198 def __init__(self, shell=None, **kwargs):
198 def __init__(self, shell=None, **kwargs):
199 super(AliasManager, self).__init__(shell=shell, **kwargs)
199 super(AliasManager, self).__init__(shell=shell, **kwargs)
200 # For convenient access
200 # For convenient access
201 self.linemagics = self.shell.magics_manager.magics['line']
201 self.linemagics = self.shell.magics_manager.magics['line']
202 self.init_aliases()
202 self.init_aliases()
203
203
204 def init_aliases(self):
204 def init_aliases(self):
205 # Load default & user aliases
205 # Load default & user aliases
206 for name, cmd in self.default_aliases + self.user_aliases:
206 for name, cmd in self.default_aliases + self.user_aliases:
207 self.soft_define_alias(name, cmd)
207 self.soft_define_alias(name, cmd)
208
208
209 @property
209 @property
210 def aliases(self):
210 def aliases(self):
211 return [(n, func.cmd) for (n, func) in self.linemagics.items()
211 return [(n, func.cmd) for (n, func) in self.linemagics.items()
212 if isinstance(func, Alias)]
212 if isinstance(func, Alias)]
213
213
214 def soft_define_alias(self, name, cmd):
214 def soft_define_alias(self, name, cmd):
215 """Define an alias, but don't raise on an AliasError."""
215 """Define an alias, but don't raise on an AliasError."""
216 try:
216 try:
217 self.define_alias(name, cmd)
217 self.define_alias(name, cmd)
218 except AliasError as e:
218 except AliasError as e:
219 error("Invalid alias: %s" % e)
219 error("Invalid alias: %s" % e)
220
220
221 def define_alias(self, name, cmd):
221 def define_alias(self, name, cmd):
222 """Define a new alias after validating it.
222 """Define a new alias after validating it.
223
223
224 This will raise an :exc:`AliasError` if there are validation
224 This will raise an :exc:`AliasError` if there are validation
225 problems.
225 problems.
226 """
226 """
227 caller = Alias(shell=self.shell, name=name, cmd=cmd)
227 caller = Alias(shell=self.shell, name=name, cmd=cmd)
228 self.shell.magics_manager.register_function(caller, magic_kind='line',
228 self.shell.magics_manager.register_function(caller, magic_kind='line',
229 magic_name=name)
229 magic_name=name)
230
230
231 def get_alias(self, name):
231 def get_alias(self, name):
232 """Return an alias, or None if no alias by that name exists."""
232 """Return an alias, or None if no alias by that name exists."""
233 aname = self.linemagics.get(name, None)
233 aname = self.linemagics.get(name, None)
234 return aname if isinstance(aname, Alias) else None
234 return aname if isinstance(aname, Alias) else None
235
235
236 def is_alias(self, name):
236 def is_alias(self, name):
237 """Return whether or not a given name has been defined as an alias"""
237 """Return whether or not a given name has been defined as an alias"""
238 return self.get_alias(name) is not None
238 return self.get_alias(name) is not None
239
239
240 def undefine_alias(self, name):
240 def undefine_alias(self, name):
241 if self.is_alias(name):
241 if self.is_alias(name):
242 del self.linemagics[name]
242 del self.linemagics[name]
243 else:
243 else:
244 raise ValueError('%s is not an alias' % name)
244 raise ValueError('%s is not an alias' % name)
245
245
246 def clear_aliases(self):
246 def clear_aliases(self):
247 for name, cmd in self.aliases:
247 for name, cmd in self.aliases:
248 self.undefine_alias(name)
248 self.undefine_alias(name)
249
249
250 def retrieve_alias(self, name):
250 def retrieve_alias(self, name):
251 """Retrieve the command to which an alias expands."""
251 """Retrieve the command to which an alias expands."""
252 caller = self.get_alias(name)
252 caller = self.get_alias(name)
253 if caller:
253 if caller:
254 return caller.cmd
254 return caller.cmd
255 else:
255 else:
256 raise ValueError('%s is not an alias' % name)
256 raise ValueError('%s is not an alias' % name)
@@ -1,396 +1,397 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for IPython.
3 An application for IPython.
4
4
5 All top-level applications should use the classes in this module for
5 All top-level applications should use the classes in this module for
6 handling configuration and creating configurables.
6 handling configuration and creating configurables.
7
7
8 The job of an :class:`Application` is to create the master configuration
8 The job of an :class:`Application` is to create the master configuration
9 object and then create the configurable objects, passing the config to them.
9 object and then create the configurable objects, passing the config to them.
10 """
10 """
11
11
12 # Copyright (c) IPython Development Team.
12 # Copyright (c) IPython Development Team.
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14
14
15 import atexit
15 import atexit
16 import glob
16 import glob
17 import logging
17 import logging
18 import os
18 import os
19 import shutil
19 import shutil
20 import sys
20 import sys
21
21
22 from IPython.config.application import Application, catch_config_error
22 from traitlets.config.application import Application, catch_config_error
23 from IPython.config.loader import ConfigFileNotFound, PyFileConfigLoader
23 from traitlets.config.loader import ConfigFileNotFound, PyFileConfigLoader
24 from IPython.core import release, crashhandler
24 from IPython.core import release, crashhandler
25 from IPython.core.profiledir import ProfileDir, ProfileDirError
25 from IPython.core.profiledir import ProfileDir, ProfileDirError
26 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir, ensure_dir_exists
26 from IPython.paths import get_ipython_dir, get_ipython_package_dir
27 from IPython.utils.path import ensure_dir_exists
27 from IPython.utils import py3compat
28 from IPython.utils import py3compat
28 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, Set, Instance, Undefined
29 from traitlets import List, Unicode, Type, Bool, Dict, Set, Instance, Undefined
29
30
30 if os.name == 'nt':
31 if os.name == 'nt':
31 programdata = os.environ.get('PROGRAMDATA', None)
32 programdata = os.environ.get('PROGRAMDATA', None)
32 if programdata:
33 if programdata:
33 SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')]
34 SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')]
34 else: # PROGRAMDATA is not defined by default on XP.
35 else: # PROGRAMDATA is not defined by default on XP.
35 SYSTEM_CONFIG_DIRS = []
36 SYSTEM_CONFIG_DIRS = []
36 else:
37 else:
37 SYSTEM_CONFIG_DIRS = [
38 SYSTEM_CONFIG_DIRS = [
38 "/usr/local/etc/ipython",
39 "/usr/local/etc/ipython",
39 "/etc/ipython",
40 "/etc/ipython",
40 ]
41 ]
41
42
42
43
43 # aliases and flags
44 # aliases and flags
44
45
45 base_aliases = {
46 base_aliases = {
46 'profile-dir' : 'ProfileDir.location',
47 'profile-dir' : 'ProfileDir.location',
47 'profile' : 'BaseIPythonApplication.profile',
48 'profile' : 'BaseIPythonApplication.profile',
48 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
49 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
49 'log-level' : 'Application.log_level',
50 'log-level' : 'Application.log_level',
50 'config' : 'BaseIPythonApplication.extra_config_file',
51 'config' : 'BaseIPythonApplication.extra_config_file',
51 }
52 }
52
53
53 base_flags = dict(
54 base_flags = dict(
54 debug = ({'Application' : {'log_level' : logging.DEBUG}},
55 debug = ({'Application' : {'log_level' : logging.DEBUG}},
55 "set log level to logging.DEBUG (maximize logging output)"),
56 "set log level to logging.DEBUG (maximize logging output)"),
56 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
57 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
57 "set log level to logging.CRITICAL (minimize logging output)"),
58 "set log level to logging.CRITICAL (minimize logging output)"),
58 init = ({'BaseIPythonApplication' : {
59 init = ({'BaseIPythonApplication' : {
59 'copy_config_files' : True,
60 'copy_config_files' : True,
60 'auto_create' : True}
61 'auto_create' : True}
61 }, """Initialize profile with default config files. This is equivalent
62 }, """Initialize profile with default config files. This is equivalent
62 to running `ipython profile create <profile>` prior to startup.
63 to running `ipython profile create <profile>` prior to startup.
63 """)
64 """)
64 )
65 )
65
66
66 class ProfileAwareConfigLoader(PyFileConfigLoader):
67 class ProfileAwareConfigLoader(PyFileConfigLoader):
67 """A Python file config loader that is aware of IPython profiles."""
68 """A Python file config loader that is aware of IPython profiles."""
68 def load_subconfig(self, fname, path=None, profile=None):
69 def load_subconfig(self, fname, path=None, profile=None):
69 if profile is not None:
70 if profile is not None:
70 try:
71 try:
71 profile_dir = ProfileDir.find_profile_dir_by_name(
72 profile_dir = ProfileDir.find_profile_dir_by_name(
72 get_ipython_dir(),
73 get_ipython_dir(),
73 profile,
74 profile,
74 )
75 )
75 except ProfileDirError:
76 except ProfileDirError:
76 return
77 return
77 path = profile_dir.location
78 path = profile_dir.location
78 return super(ProfileAwareConfigLoader, self).load_subconfig(fname, path=path)
79 return super(ProfileAwareConfigLoader, self).load_subconfig(fname, path=path)
79
80
80 class BaseIPythonApplication(Application):
81 class BaseIPythonApplication(Application):
81
82
82 name = Unicode(u'ipython')
83 name = Unicode(u'ipython')
83 description = Unicode(u'IPython: an enhanced interactive Python shell.')
84 description = Unicode(u'IPython: an enhanced interactive Python shell.')
84 version = Unicode(release.version)
85 version = Unicode(release.version)
85
86
86 aliases = Dict(base_aliases)
87 aliases = Dict(base_aliases)
87 flags = Dict(base_flags)
88 flags = Dict(base_flags)
88 classes = List([ProfileDir])
89 classes = List([ProfileDir])
89
90
90 # enable `load_subconfig('cfg.py', profile='name')`
91 # enable `load_subconfig('cfg.py', profile='name')`
91 python_config_loader_class = ProfileAwareConfigLoader
92 python_config_loader_class = ProfileAwareConfigLoader
92
93
93 # Track whether the config_file has changed,
94 # Track whether the config_file has changed,
94 # because some logic happens only if we aren't using the default.
95 # because some logic happens only if we aren't using the default.
95 config_file_specified = Set()
96 config_file_specified = Set()
96
97
97 config_file_name = Unicode()
98 config_file_name = Unicode()
98 def _config_file_name_default(self):
99 def _config_file_name_default(self):
99 return self.name.replace('-','_') + u'_config.py'
100 return self.name.replace('-','_') + u'_config.py'
100 def _config_file_name_changed(self, name, old, new):
101 def _config_file_name_changed(self, name, old, new):
101 if new != old:
102 if new != old:
102 self.config_file_specified.add(new)
103 self.config_file_specified.add(new)
103
104
104 # The directory that contains IPython's builtin profiles.
105 # The directory that contains IPython's builtin profiles.
105 builtin_profile_dir = Unicode(
106 builtin_profile_dir = Unicode(
106 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
107 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
107 )
108 )
108
109
109 config_file_paths = List(Unicode)
110 config_file_paths = List(Unicode)
110 def _config_file_paths_default(self):
111 def _config_file_paths_default(self):
111 return [py3compat.getcwd()]
112 return [py3compat.getcwd()]
112
113
113 extra_config_file = Unicode(config=True,
114 extra_config_file = Unicode(config=True,
114 help="""Path to an extra config file to load.
115 help="""Path to an extra config file to load.
115
116
116 If specified, load this config file in addition to any other IPython config.
117 If specified, load this config file in addition to any other IPython config.
117 """)
118 """)
118 def _extra_config_file_changed(self, name, old, new):
119 def _extra_config_file_changed(self, name, old, new):
119 try:
120 try:
120 self.config_files.remove(old)
121 self.config_files.remove(old)
121 except ValueError:
122 except ValueError:
122 pass
123 pass
123 self.config_file_specified.add(new)
124 self.config_file_specified.add(new)
124 self.config_files.append(new)
125 self.config_files.append(new)
125
126
126 profile = Unicode(u'default', config=True,
127 profile = Unicode(u'default', config=True,
127 help="""The IPython profile to use."""
128 help="""The IPython profile to use."""
128 )
129 )
129
130
130 def _profile_changed(self, name, old, new):
131 def _profile_changed(self, name, old, new):
131 self.builtin_profile_dir = os.path.join(
132 self.builtin_profile_dir = os.path.join(
132 get_ipython_package_dir(), u'config', u'profile', new
133 get_ipython_package_dir(), u'config', u'profile', new
133 )
134 )
134
135
135 ipython_dir = Unicode(config=True,
136 ipython_dir = Unicode(config=True,
136 help="""
137 help="""
137 The name of the IPython directory. This directory is used for logging
138 The name of the IPython directory. This directory is used for logging
138 configuration (through profiles), history storage, etc. The default
139 configuration (through profiles), history storage, etc. The default
139 is usually $HOME/.ipython. This option can also be specified through
140 is usually $HOME/.ipython. This option can also be specified through
140 the environment variable IPYTHONDIR.
141 the environment variable IPYTHONDIR.
141 """
142 """
142 )
143 )
143 def _ipython_dir_default(self):
144 def _ipython_dir_default(self):
144 d = get_ipython_dir()
145 d = get_ipython_dir()
145 self._ipython_dir_changed('ipython_dir', d, d)
146 self._ipython_dir_changed('ipython_dir', d, d)
146 return d
147 return d
147
148
148 _in_init_profile_dir = False
149 _in_init_profile_dir = False
149 profile_dir = Instance(ProfileDir, allow_none=True)
150 profile_dir = Instance(ProfileDir, allow_none=True)
150 def _profile_dir_default(self):
151 def _profile_dir_default(self):
151 # avoid recursion
152 # avoid recursion
152 if self._in_init_profile_dir:
153 if self._in_init_profile_dir:
153 return
154 return
154 # profile_dir requested early, force initialization
155 # profile_dir requested early, force initialization
155 self.init_profile_dir()
156 self.init_profile_dir()
156 return self.profile_dir
157 return self.profile_dir
157
158
158 overwrite = Bool(False, config=True,
159 overwrite = Bool(False, config=True,
159 help="""Whether to overwrite existing config files when copying""")
160 help="""Whether to overwrite existing config files when copying""")
160 auto_create = Bool(False, config=True,
161 auto_create = Bool(False, config=True,
161 help="""Whether to create profile dir if it doesn't exist""")
162 help="""Whether to create profile dir if it doesn't exist""")
162
163
163 config_files = List(Unicode)
164 config_files = List(Unicode)
164 def _config_files_default(self):
165 def _config_files_default(self):
165 return [self.config_file_name]
166 return [self.config_file_name]
166
167
167 copy_config_files = Bool(False, config=True,
168 copy_config_files = Bool(False, config=True,
168 help="""Whether to install the default config files into the profile dir.
169 help="""Whether to install the default config files into the profile dir.
169 If a new profile is being created, and IPython contains config files for that
170 If a new profile is being created, and IPython contains config files for that
170 profile, then they will be staged into the new directory. Otherwise,
171 profile, then they will be staged into the new directory. Otherwise,
171 default config files will be automatically generated.
172 default config files will be automatically generated.
172 """)
173 """)
173
174
174 verbose_crash = Bool(False, config=True,
175 verbose_crash = Bool(False, config=True,
175 help="""Create a massive crash report when IPython encounters what may be an
176 help="""Create a massive crash report when IPython encounters what may be an
176 internal error. The default is to append a short message to the
177 internal error. The default is to append a short message to the
177 usual traceback""")
178 usual traceback""")
178
179
179 # The class to use as the crash handler.
180 # The class to use as the crash handler.
180 crash_handler_class = Type(crashhandler.CrashHandler)
181 crash_handler_class = Type(crashhandler.CrashHandler)
181
182
182 @catch_config_error
183 @catch_config_error
183 def __init__(self, **kwargs):
184 def __init__(self, **kwargs):
184 super(BaseIPythonApplication, self).__init__(**kwargs)
185 super(BaseIPythonApplication, self).__init__(**kwargs)
185 # ensure current working directory exists
186 # ensure current working directory exists
186 try:
187 try:
187 directory = py3compat.getcwd()
188 directory = py3compat.getcwd()
188 except:
189 except:
189 # exit if cwd doesn't exist
190 # exit if cwd doesn't exist
190 self.log.error("Current working directory doesn't exist.")
191 self.log.error("Current working directory doesn't exist.")
191 self.exit(1)
192 self.exit(1)
192
193
193 #-------------------------------------------------------------------------
194 #-------------------------------------------------------------------------
194 # Various stages of Application creation
195 # Various stages of Application creation
195 #-------------------------------------------------------------------------
196 #-------------------------------------------------------------------------
196
197
197 def init_crash_handler(self):
198 def init_crash_handler(self):
198 """Create a crash handler, typically setting sys.excepthook to it."""
199 """Create a crash handler, typically setting sys.excepthook to it."""
199 self.crash_handler = self.crash_handler_class(self)
200 self.crash_handler = self.crash_handler_class(self)
200 sys.excepthook = self.excepthook
201 sys.excepthook = self.excepthook
201 def unset_crashhandler():
202 def unset_crashhandler():
202 sys.excepthook = sys.__excepthook__
203 sys.excepthook = sys.__excepthook__
203 atexit.register(unset_crashhandler)
204 atexit.register(unset_crashhandler)
204
205
205 def excepthook(self, etype, evalue, tb):
206 def excepthook(self, etype, evalue, tb):
206 """this is sys.excepthook after init_crashhandler
207 """this is sys.excepthook after init_crashhandler
207
208
208 set self.verbose_crash=True to use our full crashhandler, instead of
209 set self.verbose_crash=True to use our full crashhandler, instead of
209 a regular traceback with a short message (crash_handler_lite)
210 a regular traceback with a short message (crash_handler_lite)
210 """
211 """
211
212
212 if self.verbose_crash:
213 if self.verbose_crash:
213 return self.crash_handler(etype, evalue, tb)
214 return self.crash_handler(etype, evalue, tb)
214 else:
215 else:
215 return crashhandler.crash_handler_lite(etype, evalue, tb)
216 return crashhandler.crash_handler_lite(etype, evalue, tb)
216
217
217 def _ipython_dir_changed(self, name, old, new):
218 def _ipython_dir_changed(self, name, old, new):
218 if old is not Undefined:
219 if old is not Undefined:
219 str_old = py3compat.cast_bytes_py2(os.path.abspath(old),
220 str_old = py3compat.cast_bytes_py2(os.path.abspath(old),
220 sys.getfilesystemencoding()
221 sys.getfilesystemencoding()
221 )
222 )
222 if str_old in sys.path:
223 if str_old in sys.path:
223 sys.path.remove(str_old)
224 sys.path.remove(str_old)
224 str_path = py3compat.cast_bytes_py2(os.path.abspath(new),
225 str_path = py3compat.cast_bytes_py2(os.path.abspath(new),
225 sys.getfilesystemencoding()
226 sys.getfilesystemencoding()
226 )
227 )
227 sys.path.append(str_path)
228 sys.path.append(str_path)
228 ensure_dir_exists(new)
229 ensure_dir_exists(new)
229 readme = os.path.join(new, 'README')
230 readme = os.path.join(new, 'README')
230 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
231 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
231 if not os.path.exists(readme) and os.path.exists(readme_src):
232 if not os.path.exists(readme) and os.path.exists(readme_src):
232 shutil.copy(readme_src, readme)
233 shutil.copy(readme_src, readme)
233 for d in ('extensions', 'nbextensions'):
234 for d in ('extensions', 'nbextensions'):
234 path = os.path.join(new, d)
235 path = os.path.join(new, d)
235 try:
236 try:
236 ensure_dir_exists(path)
237 ensure_dir_exists(path)
237 except OSError:
238 except OSError:
238 # this will not be EEXIST
239 # this will not be EEXIST
239 self.log.error("couldn't create path %s: %s", path, e)
240 self.log.error("couldn't create path %s: %s", path, e)
240 self.log.debug("IPYTHONDIR set to: %s" % new)
241 self.log.debug("IPYTHONDIR set to: %s" % new)
241
242
242 def load_config_file(self, suppress_errors=True):
243 def load_config_file(self, suppress_errors=True):
243 """Load the config file.
244 """Load the config file.
244
245
245 By default, errors in loading config are handled, and a warning
246 By default, errors in loading config are handled, and a warning
246 printed on screen. For testing, the suppress_errors option is set
247 printed on screen. For testing, the suppress_errors option is set
247 to False, so errors will make tests fail.
248 to False, so errors will make tests fail.
248 """
249 """
249 self.log.debug("Searching path %s for config files", self.config_file_paths)
250 self.log.debug("Searching path %s for config files", self.config_file_paths)
250 base_config = 'ipython_config.py'
251 base_config = 'ipython_config.py'
251 self.log.debug("Attempting to load config file: %s" %
252 self.log.debug("Attempting to load config file: %s" %
252 base_config)
253 base_config)
253 try:
254 try:
254 Application.load_config_file(
255 Application.load_config_file(
255 self,
256 self,
256 base_config,
257 base_config,
257 path=self.config_file_paths
258 path=self.config_file_paths
258 )
259 )
259 except ConfigFileNotFound:
260 except ConfigFileNotFound:
260 # ignore errors loading parent
261 # ignore errors loading parent
261 self.log.debug("Config file %s not found", base_config)
262 self.log.debug("Config file %s not found", base_config)
262 pass
263 pass
263
264
264 for config_file_name in self.config_files:
265 for config_file_name in self.config_files:
265 if not config_file_name or config_file_name == base_config:
266 if not config_file_name or config_file_name == base_config:
266 continue
267 continue
267 self.log.debug("Attempting to load config file: %s" %
268 self.log.debug("Attempting to load config file: %s" %
268 self.config_file_name)
269 self.config_file_name)
269 try:
270 try:
270 Application.load_config_file(
271 Application.load_config_file(
271 self,
272 self,
272 config_file_name,
273 config_file_name,
273 path=self.config_file_paths
274 path=self.config_file_paths
274 )
275 )
275 except ConfigFileNotFound:
276 except ConfigFileNotFound:
276 # Only warn if the default config file was NOT being used.
277 # Only warn if the default config file was NOT being used.
277 if config_file_name in self.config_file_specified:
278 if config_file_name in self.config_file_specified:
278 msg = self.log.warn
279 msg = self.log.warn
279 else:
280 else:
280 msg = self.log.debug
281 msg = self.log.debug
281 msg("Config file not found, skipping: %s", config_file_name)
282 msg("Config file not found, skipping: %s", config_file_name)
282 except:
283 except:
283 # For testing purposes.
284 # For testing purposes.
284 if not suppress_errors:
285 if not suppress_errors:
285 raise
286 raise
286 self.log.warn("Error loading config file: %s" %
287 self.log.warn("Error loading config file: %s" %
287 self.config_file_name, exc_info=True)
288 self.config_file_name, exc_info=True)
288
289
289 def init_profile_dir(self):
290 def init_profile_dir(self):
290 """initialize the profile dir"""
291 """initialize the profile dir"""
291 self._in_init_profile_dir = True
292 self._in_init_profile_dir = True
292 if self.profile_dir is not None:
293 if self.profile_dir is not None:
293 # already ran
294 # already ran
294 return
295 return
295 if 'ProfileDir.location' not in self.config:
296 if 'ProfileDir.location' not in self.config:
296 # location not specified, find by profile name
297 # location not specified, find by profile name
297 try:
298 try:
298 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
299 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
299 except ProfileDirError:
300 except ProfileDirError:
300 # not found, maybe create it (always create default profile)
301 # not found, maybe create it (always create default profile)
301 if self.auto_create or self.profile == 'default':
302 if self.auto_create or self.profile == 'default':
302 try:
303 try:
303 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
304 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
304 except ProfileDirError:
305 except ProfileDirError:
305 self.log.fatal("Could not create profile: %r"%self.profile)
306 self.log.fatal("Could not create profile: %r"%self.profile)
306 self.exit(1)
307 self.exit(1)
307 else:
308 else:
308 self.log.info("Created profile dir: %r"%p.location)
309 self.log.info("Created profile dir: %r"%p.location)
309 else:
310 else:
310 self.log.fatal("Profile %r not found."%self.profile)
311 self.log.fatal("Profile %r not found."%self.profile)
311 self.exit(1)
312 self.exit(1)
312 else:
313 else:
313 self.log.debug("Using existing profile dir: %r"%p.location)
314 self.log.debug("Using existing profile dir: %r"%p.location)
314 else:
315 else:
315 location = self.config.ProfileDir.location
316 location = self.config.ProfileDir.location
316 # location is fully specified
317 # location is fully specified
317 try:
318 try:
318 p = ProfileDir.find_profile_dir(location, self.config)
319 p = ProfileDir.find_profile_dir(location, self.config)
319 except ProfileDirError:
320 except ProfileDirError:
320 # not found, maybe create it
321 # not found, maybe create it
321 if self.auto_create:
322 if self.auto_create:
322 try:
323 try:
323 p = ProfileDir.create_profile_dir(location, self.config)
324 p = ProfileDir.create_profile_dir(location, self.config)
324 except ProfileDirError:
325 except ProfileDirError:
325 self.log.fatal("Could not create profile directory: %r"%location)
326 self.log.fatal("Could not create profile directory: %r"%location)
326 self.exit(1)
327 self.exit(1)
327 else:
328 else:
328 self.log.debug("Creating new profile dir: %r"%location)
329 self.log.debug("Creating new profile dir: %r"%location)
329 else:
330 else:
330 self.log.fatal("Profile directory %r not found."%location)
331 self.log.fatal("Profile directory %r not found."%location)
331 self.exit(1)
332 self.exit(1)
332 else:
333 else:
333 self.log.info("Using existing profile dir: %r"%location)
334 self.log.info("Using existing profile dir: %r"%location)
334 # if profile_dir is specified explicitly, set profile name
335 # if profile_dir is specified explicitly, set profile name
335 dir_name = os.path.basename(p.location)
336 dir_name = os.path.basename(p.location)
336 if dir_name.startswith('profile_'):
337 if dir_name.startswith('profile_'):
337 self.profile = dir_name[8:]
338 self.profile = dir_name[8:]
338
339
339 self.profile_dir = p
340 self.profile_dir = p
340 self.config_file_paths.append(p.location)
341 self.config_file_paths.append(p.location)
341 self._in_init_profile_dir = False
342 self._in_init_profile_dir = False
342
343
343 def init_config_files(self):
344 def init_config_files(self):
344 """[optionally] copy default config files into profile dir."""
345 """[optionally] copy default config files into profile dir."""
345 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
346 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
346 # copy config files
347 # copy config files
347 path = self.builtin_profile_dir
348 path = self.builtin_profile_dir
348 if self.copy_config_files:
349 if self.copy_config_files:
349 src = self.profile
350 src = self.profile
350
351
351 cfg = self.config_file_name
352 cfg = self.config_file_name
352 if path and os.path.exists(os.path.join(path, cfg)):
353 if path and os.path.exists(os.path.join(path, cfg)):
353 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
354 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
354 cfg, src, self.profile_dir.location, self.overwrite)
355 cfg, src, self.profile_dir.location, self.overwrite)
355 )
356 )
356 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
357 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
357 else:
358 else:
358 self.stage_default_config_file()
359 self.stage_default_config_file()
359 else:
360 else:
360 # Still stage *bundled* config files, but not generated ones
361 # Still stage *bundled* config files, but not generated ones
361 # This is necessary for `ipython profile=sympy` to load the profile
362 # This is necessary for `ipython profile=sympy` to load the profile
362 # on the first go
363 # on the first go
363 files = glob.glob(os.path.join(path, '*.py'))
364 files = glob.glob(os.path.join(path, '*.py'))
364 for fullpath in files:
365 for fullpath in files:
365 cfg = os.path.basename(fullpath)
366 cfg = os.path.basename(fullpath)
366 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
367 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
367 # file was copied
368 # file was copied
368 self.log.warn("Staging bundled %s from %s into %r"%(
369 self.log.warn("Staging bundled %s from %s into %r"%(
369 cfg, self.profile, self.profile_dir.location)
370 cfg, self.profile, self.profile_dir.location)
370 )
371 )
371
372
372
373
373 def stage_default_config_file(self):
374 def stage_default_config_file(self):
374 """auto generate default config file, and stage it into the profile."""
375 """auto generate default config file, and stage it into the profile."""
375 s = self.generate_config_file()
376 s = self.generate_config_file()
376 fname = os.path.join(self.profile_dir.location, self.config_file_name)
377 fname = os.path.join(self.profile_dir.location, self.config_file_name)
377 if self.overwrite or not os.path.exists(fname):
378 if self.overwrite or not os.path.exists(fname):
378 self.log.warn("Generating default config file: %r"%(fname))
379 self.log.warn("Generating default config file: %r"%(fname))
379 with open(fname, 'w') as f:
380 with open(fname, 'w') as f:
380 f.write(s)
381 f.write(s)
381
382
382 @catch_config_error
383 @catch_config_error
383 def initialize(self, argv=None):
384 def initialize(self, argv=None):
384 # don't hook up crash handler before parsing command-line
385 # don't hook up crash handler before parsing command-line
385 self.parse_command_line(argv)
386 self.parse_command_line(argv)
386 self.init_crash_handler()
387 self.init_crash_handler()
387 if self.subapp is not None:
388 if self.subapp is not None:
388 # stop here if subapp is taking over
389 # stop here if subapp is taking over
389 return
390 return
390 cl_config = self.config
391 cl_config = self.config
391 self.init_profile_dir()
392 self.init_profile_dir()
392 self.init_config_files()
393 self.init_config_files()
393 self.load_config_file()
394 self.load_config_file()
394 # enforce cl-opts override configfile opts:
395 # enforce cl-opts override configfile opts:
395 self.update_config(cl_config)
396 self.update_config(cl_config)
396
397
@@ -1,112 +1,112 b''
1 """
1 """
2 A context manager for managing things injected into :mod:`__builtin__`.
2 A context manager for managing things injected into :mod:`__builtin__`.
3
3
4 Authors:
4 Authors:
5
5
6 * Brian Granger
6 * Brian Granger
7 * Fernando Perez
7 * Fernando Perez
8 """
8 """
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010-2011 The IPython Development Team.
10 # Copyright (C) 2010-2011 The IPython Development Team.
11 #
11 #
12 # Distributed under the terms of the BSD License.
12 # Distributed under the terms of the BSD License.
13 #
13 #
14 # Complete license in the file COPYING.txt, distributed with this software.
14 # Complete license in the file COPYING.txt, distributed with this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 from IPython.config.configurable import Configurable
21 from traitlets.config.configurable import Configurable
22
22
23 from IPython.utils.py3compat import builtin_mod, iteritems
23 from IPython.utils.py3compat import builtin_mod, iteritems
24 from IPython.utils.traitlets import Instance
24 from traitlets import Instance
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Classes and functions
27 # Classes and functions
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 class __BuiltinUndefined(object): pass
30 class __BuiltinUndefined(object): pass
31 BuiltinUndefined = __BuiltinUndefined()
31 BuiltinUndefined = __BuiltinUndefined()
32
32
33 class __HideBuiltin(object): pass
33 class __HideBuiltin(object): pass
34 HideBuiltin = __HideBuiltin()
34 HideBuiltin = __HideBuiltin()
35
35
36
36
37 class BuiltinTrap(Configurable):
37 class BuiltinTrap(Configurable):
38
38
39 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
39 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
40 allow_none=True)
40 allow_none=True)
41
41
42 def __init__(self, shell=None):
42 def __init__(self, shell=None):
43 super(BuiltinTrap, self).__init__(shell=shell, config=None)
43 super(BuiltinTrap, self).__init__(shell=shell, config=None)
44 self._orig_builtins = {}
44 self._orig_builtins = {}
45 # We define this to track if a single BuiltinTrap is nested.
45 # We define this to track if a single BuiltinTrap is nested.
46 # Only turn off the trap when the outermost call to __exit__ is made.
46 # Only turn off the trap when the outermost call to __exit__ is made.
47 self._nested_level = 0
47 self._nested_level = 0
48 self.shell = shell
48 self.shell = shell
49 # builtins we always add - if set to HideBuiltin, they will just
49 # builtins we always add - if set to HideBuiltin, they will just
50 # be removed instead of being replaced by something else
50 # be removed instead of being replaced by something else
51 self.auto_builtins = {'exit': HideBuiltin,
51 self.auto_builtins = {'exit': HideBuiltin,
52 'quit': HideBuiltin,
52 'quit': HideBuiltin,
53 'get_ipython': self.shell.get_ipython,
53 'get_ipython': self.shell.get_ipython,
54 }
54 }
55 # Recursive reload function
55 # Recursive reload function
56 try:
56 try:
57 from IPython.lib import deepreload
57 from IPython.lib import deepreload
58 if self.shell.deep_reload:
58 if self.shell.deep_reload:
59 self.auto_builtins['reload'] = deepreload.reload
59 self.auto_builtins['reload'] = deepreload.reload
60 else:
60 else:
61 self.auto_builtins['dreload']= deepreload.reload
61 self.auto_builtins['dreload']= deepreload.reload
62 except ImportError:
62 except ImportError:
63 pass
63 pass
64
64
65 def __enter__(self):
65 def __enter__(self):
66 if self._nested_level == 0:
66 if self._nested_level == 0:
67 self.activate()
67 self.activate()
68 self._nested_level += 1
68 self._nested_level += 1
69 # I return self, so callers can use add_builtin in a with clause.
69 # I return self, so callers can use add_builtin in a with clause.
70 return self
70 return self
71
71
72 def __exit__(self, type, value, traceback):
72 def __exit__(self, type, value, traceback):
73 if self._nested_level == 1:
73 if self._nested_level == 1:
74 self.deactivate()
74 self.deactivate()
75 self._nested_level -= 1
75 self._nested_level -= 1
76 # Returning False will cause exceptions to propagate
76 # Returning False will cause exceptions to propagate
77 return False
77 return False
78
78
79 def add_builtin(self, key, value):
79 def add_builtin(self, key, value):
80 """Add a builtin and save the original."""
80 """Add a builtin and save the original."""
81 bdict = builtin_mod.__dict__
81 bdict = builtin_mod.__dict__
82 orig = bdict.get(key, BuiltinUndefined)
82 orig = bdict.get(key, BuiltinUndefined)
83 if value is HideBuiltin:
83 if value is HideBuiltin:
84 if orig is not BuiltinUndefined: #same as 'key in bdict'
84 if orig is not BuiltinUndefined: #same as 'key in bdict'
85 self._orig_builtins[key] = orig
85 self._orig_builtins[key] = orig
86 del bdict[key]
86 del bdict[key]
87 else:
87 else:
88 self._orig_builtins[key] = orig
88 self._orig_builtins[key] = orig
89 bdict[key] = value
89 bdict[key] = value
90
90
91 def remove_builtin(self, key, orig):
91 def remove_builtin(self, key, orig):
92 """Remove an added builtin and re-set the original."""
92 """Remove an added builtin and re-set the original."""
93 if orig is BuiltinUndefined:
93 if orig is BuiltinUndefined:
94 del builtin_mod.__dict__[key]
94 del builtin_mod.__dict__[key]
95 else:
95 else:
96 builtin_mod.__dict__[key] = orig
96 builtin_mod.__dict__[key] = orig
97
97
98 def activate(self):
98 def activate(self):
99 """Store ipython references in the __builtin__ namespace."""
99 """Store ipython references in the __builtin__ namespace."""
100
100
101 add_builtin = self.add_builtin
101 add_builtin = self.add_builtin
102 for name, func in iteritems(self.auto_builtins):
102 for name, func in iteritems(self.auto_builtins):
103 add_builtin(name, func)
103 add_builtin(name, func)
104
104
105 def deactivate(self):
105 def deactivate(self):
106 """Remove any builtins which might have been added by add_builtins, or
106 """Remove any builtins which might have been added by add_builtins, or
107 restore overwritten ones to their previous values."""
107 restore overwritten ones to their previous values."""
108 remove_builtin = self.remove_builtin
108 remove_builtin = self.remove_builtin
109 for key, val in iteritems(self._orig_builtins):
109 for key, val in iteritems(self._orig_builtins):
110 remove_builtin(key, val)
110 remove_builtin(key, val)
111 self._orig_builtins.clear()
111 self._orig_builtins.clear()
112 self._builtins_added = False
112 self._builtins_added = False
@@ -1,1266 +1,1266 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Word completion for IPython.
2 """Word completion for IPython.
3
3
4 This module is a fork of the rlcompleter module in the Python standard
4 This module is a fork of the rlcompleter module in the Python standard
5 library. The original enhancements made to rlcompleter have been sent
5 library. The original enhancements made to rlcompleter have been sent
6 upstream and were accepted as of Python 2.3, but we need a lot more
6 upstream and were accepted as of Python 2.3, but we need a lot more
7 functionality specific to IPython, so this module will continue to live as an
7 functionality specific to IPython, so this module will continue to live as an
8 IPython-specific utility.
8 IPython-specific utility.
9
9
10 Original rlcompleter documentation:
10 Original rlcompleter documentation:
11
11
12 This requires the latest extension to the readline module (the
12 This requires the latest extension to the readline module (the
13 completes keywords, built-ins and globals in __main__; when completing
13 completes keywords, built-ins and globals in __main__; when completing
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 completes its attributes.
15 completes its attributes.
16
16
17 It's very cool to do "import string" type "string.", hit the
17 It's very cool to do "import string" type "string.", hit the
18 completion key (twice), and see the list of names defined by the
18 completion key (twice), and see the list of names defined by the
19 string module!
19 string module!
20
20
21 Tip: to use the tab key as the completion key, call
21 Tip: to use the tab key as the completion key, call
22
22
23 readline.parse_and_bind("tab: complete")
23 readline.parse_and_bind("tab: complete")
24
24
25 Notes:
25 Notes:
26
26
27 - Exceptions raised by the completer function are *ignored* (and
27 - Exceptions raised by the completer function are *ignored* (and
28 generally cause the completion to fail). This is a feature -- since
28 generally cause the completion to fail). This is a feature -- since
29 readline sets the tty device in raw (or cbreak) mode, printing a
29 readline sets the tty device in raw (or cbreak) mode, printing a
30 traceback wouldn't work well without some complicated hoopla to save,
30 traceback wouldn't work well without some complicated hoopla to save,
31 reset and restore the tty state.
31 reset and restore the tty state.
32
32
33 - The evaluation of the NAME.NAME... form may cause arbitrary
33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 application defined code to be executed if an object with a
34 application defined code to be executed if an object with a
35 ``__getattr__`` hook is found. Since it is the responsibility of the
35 ``__getattr__`` hook is found. Since it is the responsibility of the
36 application (or the user) to enable this feature, I consider this an
36 application (or the user) to enable this feature, I consider this an
37 acceptable risk. More complicated expressions (e.g. function calls or
37 acceptable risk. More complicated expressions (e.g. function calls or
38 indexing operations) are *not* evaluated.
38 indexing operations) are *not* evaluated.
39
39
40 - GNU readline is also used by the built-in functions input() and
40 - GNU readline is also used by the built-in functions input() and
41 raw_input(), and thus these also benefit/suffer from the completer
41 raw_input(), and thus these also benefit/suffer from the completer
42 features. Clearly an interactive application can benefit by
42 features. Clearly an interactive application can benefit by
43 specifying its own completer function and using raw_input() for all
43 specifying its own completer function and using raw_input() for all
44 its input.
44 its input.
45
45
46 - When the original stdin is not a tty device, GNU readline is never
46 - When the original stdin is not a tty device, GNU readline is never
47 used, and this module (and the readline module) are silently inactive.
47 used, and this module (and the readline module) are silently inactive.
48 """
48 """
49
49
50 # Copyright (c) IPython Development Team.
50 # Copyright (c) IPython Development Team.
51 # Distributed under the terms of the Modified BSD License.
51 # Distributed under the terms of the Modified BSD License.
52 #
52 #
53 # Some of this code originated from rlcompleter in the Python standard library
53 # Some of this code originated from rlcompleter in the Python standard library
54 # Copyright (C) 2001 Python Software Foundation, www.python.org
54 # Copyright (C) 2001 Python Software Foundation, www.python.org
55
55
56 import __main__
56 import __main__
57 import glob
57 import glob
58 import inspect
58 import inspect
59 import itertools
59 import itertools
60 import keyword
60 import keyword
61 import os
61 import os
62 import re
62 import re
63 import sys
63 import sys
64 import unicodedata
64 import unicodedata
65 import string
65 import string
66
66
67 from IPython.config.configurable import Configurable
67 from traitlets.config.configurable import Configurable
68 from IPython.core.error import TryNext
68 from IPython.core.error import TryNext
69 from IPython.core.inputsplitter import ESC_MAGIC
69 from IPython.core.inputsplitter import ESC_MAGIC
70 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
70 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
71 from IPython.utils import generics
71 from IPython.utils import generics
72 from IPython.utils import io
72 from IPython.utils import io
73 from IPython.utils.decorators import undoc
73 from IPython.utils.decorators import undoc
74 from IPython.utils.dir2 import dir2
74 from IPython.utils.dir2 import dir2
75 from IPython.utils.process import arg_split
75 from IPython.utils.process import arg_split
76 from IPython.utils.py3compat import builtin_mod, string_types, PY3
76 from IPython.utils.py3compat import builtin_mod, string_types, PY3
77 from IPython.utils.traitlets import CBool, Enum
77 from traitlets import CBool, Enum
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 # Globals
80 # Globals
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82
82
83 # Public API
83 # Public API
84 __all__ = ['Completer','IPCompleter']
84 __all__ = ['Completer','IPCompleter']
85
85
86 if sys.platform == 'win32':
86 if sys.platform == 'win32':
87 PROTECTABLES = ' '
87 PROTECTABLES = ' '
88 else:
88 else:
89 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
89 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
90
90
91
91
92 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
93 # Main functions and classes
93 # Main functions and classes
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95
95
96 def has_open_quotes(s):
96 def has_open_quotes(s):
97 """Return whether a string has open quotes.
97 """Return whether a string has open quotes.
98
98
99 This simply counts whether the number of quote characters of either type in
99 This simply counts whether the number of quote characters of either type in
100 the string is odd.
100 the string is odd.
101
101
102 Returns
102 Returns
103 -------
103 -------
104 If there is an open quote, the quote character is returned. Else, return
104 If there is an open quote, the quote character is returned. Else, return
105 False.
105 False.
106 """
106 """
107 # We check " first, then ', so complex cases with nested quotes will get
107 # We check " first, then ', so complex cases with nested quotes will get
108 # the " to take precedence.
108 # the " to take precedence.
109 if s.count('"') % 2:
109 if s.count('"') % 2:
110 return '"'
110 return '"'
111 elif s.count("'") % 2:
111 elif s.count("'") % 2:
112 return "'"
112 return "'"
113 else:
113 else:
114 return False
114 return False
115
115
116
116
117 def protect_filename(s):
117 def protect_filename(s):
118 """Escape a string to protect certain characters."""
118 """Escape a string to protect certain characters."""
119
119
120 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
120 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
121 for ch in s])
121 for ch in s])
122
122
123 def expand_user(path):
123 def expand_user(path):
124 """Expand '~'-style usernames in strings.
124 """Expand '~'-style usernames in strings.
125
125
126 This is similar to :func:`os.path.expanduser`, but it computes and returns
126 This is similar to :func:`os.path.expanduser`, but it computes and returns
127 extra information that will be useful if the input was being used in
127 extra information that will be useful if the input was being used in
128 computing completions, and you wish to return the completions with the
128 computing completions, and you wish to return the completions with the
129 original '~' instead of its expanded value.
129 original '~' instead of its expanded value.
130
130
131 Parameters
131 Parameters
132 ----------
132 ----------
133 path : str
133 path : str
134 String to be expanded. If no ~ is present, the output is the same as the
134 String to be expanded. If no ~ is present, the output is the same as the
135 input.
135 input.
136
136
137 Returns
137 Returns
138 -------
138 -------
139 newpath : str
139 newpath : str
140 Result of ~ expansion in the input path.
140 Result of ~ expansion in the input path.
141 tilde_expand : bool
141 tilde_expand : bool
142 Whether any expansion was performed or not.
142 Whether any expansion was performed or not.
143 tilde_val : str
143 tilde_val : str
144 The value that ~ was replaced with.
144 The value that ~ was replaced with.
145 """
145 """
146 # Default values
146 # Default values
147 tilde_expand = False
147 tilde_expand = False
148 tilde_val = ''
148 tilde_val = ''
149 newpath = path
149 newpath = path
150
150
151 if path.startswith('~'):
151 if path.startswith('~'):
152 tilde_expand = True
152 tilde_expand = True
153 rest = len(path)-1
153 rest = len(path)-1
154 newpath = os.path.expanduser(path)
154 newpath = os.path.expanduser(path)
155 if rest:
155 if rest:
156 tilde_val = newpath[:-rest]
156 tilde_val = newpath[:-rest]
157 else:
157 else:
158 tilde_val = newpath
158 tilde_val = newpath
159
159
160 return newpath, tilde_expand, tilde_val
160 return newpath, tilde_expand, tilde_val
161
161
162
162
163 def compress_user(path, tilde_expand, tilde_val):
163 def compress_user(path, tilde_expand, tilde_val):
164 """Does the opposite of expand_user, with its outputs.
164 """Does the opposite of expand_user, with its outputs.
165 """
165 """
166 if tilde_expand:
166 if tilde_expand:
167 return path.replace(tilde_val, '~')
167 return path.replace(tilde_val, '~')
168 else:
168 else:
169 return path
169 return path
170
170
171
171
172
172
173 def penalize_magics_key(word):
173 def penalize_magics_key(word):
174 """key for sorting that penalizes magic commands in the ordering
174 """key for sorting that penalizes magic commands in the ordering
175
175
176 Normal words are left alone.
176 Normal words are left alone.
177
177
178 Magic commands have the initial % moved to the end, e.g.
178 Magic commands have the initial % moved to the end, e.g.
179 %matplotlib is transformed as follows:
179 %matplotlib is transformed as follows:
180
180
181 %matplotlib -> matplotlib%
181 %matplotlib -> matplotlib%
182
182
183 [The choice of the final % is arbitrary.]
183 [The choice of the final % is arbitrary.]
184
184
185 Since "matplotlib" < "matplotlib%" as strings,
185 Since "matplotlib" < "matplotlib%" as strings,
186 "timeit" will appear before the magic "%timeit" in the ordering
186 "timeit" will appear before the magic "%timeit" in the ordering
187
187
188 For consistency, move "%%" to the end, so cell magics appear *after*
188 For consistency, move "%%" to the end, so cell magics appear *after*
189 line magics with the same name.
189 line magics with the same name.
190
190
191 A check is performed that there are no other "%" in the string;
191 A check is performed that there are no other "%" in the string;
192 if there are, then the string is not a magic command and is left unchanged.
192 if there are, then the string is not a magic command and is left unchanged.
193
193
194 """
194 """
195
195
196 # Move any % signs from start to end of the key
196 # Move any % signs from start to end of the key
197 # provided there are no others elsewhere in the string
197 # provided there are no others elsewhere in the string
198
198
199 if word[:2] == "%%":
199 if word[:2] == "%%":
200 if not "%" in word[2:]:
200 if not "%" in word[2:]:
201 return word[2:] + "%%"
201 return word[2:] + "%%"
202
202
203 if word[:1] == "%":
203 if word[:1] == "%":
204 if not "%" in word[1:]:
204 if not "%" in word[1:]:
205 return word[1:] + "%"
205 return word[1:] + "%"
206
206
207 return word
207 return word
208
208
209
209
210 @undoc
210 @undoc
211 class Bunch(object): pass
211 class Bunch(object): pass
212
212
213
213
214 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
214 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
215 GREEDY_DELIMS = ' =\r\n'
215 GREEDY_DELIMS = ' =\r\n'
216
216
217
217
218 class CompletionSplitter(object):
218 class CompletionSplitter(object):
219 """An object to split an input line in a manner similar to readline.
219 """An object to split an input line in a manner similar to readline.
220
220
221 By having our own implementation, we can expose readline-like completion in
221 By having our own implementation, we can expose readline-like completion in
222 a uniform manner to all frontends. This object only needs to be given the
222 a uniform manner to all frontends. This object only needs to be given the
223 line of text to be split and the cursor position on said line, and it
223 line of text to be split and the cursor position on said line, and it
224 returns the 'word' to be completed on at the cursor after splitting the
224 returns the 'word' to be completed on at the cursor after splitting the
225 entire line.
225 entire line.
226
226
227 What characters are used as splitting delimiters can be controlled by
227 What characters are used as splitting delimiters can be controlled by
228 setting the `delims` attribute (this is a property that internally
228 setting the `delims` attribute (this is a property that internally
229 automatically builds the necessary regular expression)"""
229 automatically builds the necessary regular expression)"""
230
230
231 # Private interface
231 # Private interface
232
232
233 # A string of delimiter characters. The default value makes sense for
233 # A string of delimiter characters. The default value makes sense for
234 # IPython's most typical usage patterns.
234 # IPython's most typical usage patterns.
235 _delims = DELIMS
235 _delims = DELIMS
236
236
237 # The expression (a normal string) to be compiled into a regular expression
237 # The expression (a normal string) to be compiled into a regular expression
238 # for actual splitting. We store it as an attribute mostly for ease of
238 # for actual splitting. We store it as an attribute mostly for ease of
239 # debugging, since this type of code can be so tricky to debug.
239 # debugging, since this type of code can be so tricky to debug.
240 _delim_expr = None
240 _delim_expr = None
241
241
242 # The regular expression that does the actual splitting
242 # The regular expression that does the actual splitting
243 _delim_re = None
243 _delim_re = None
244
244
245 def __init__(self, delims=None):
245 def __init__(self, delims=None):
246 delims = CompletionSplitter._delims if delims is None else delims
246 delims = CompletionSplitter._delims if delims is None else delims
247 self.delims = delims
247 self.delims = delims
248
248
249 @property
249 @property
250 def delims(self):
250 def delims(self):
251 """Return the string of delimiter characters."""
251 """Return the string of delimiter characters."""
252 return self._delims
252 return self._delims
253
253
254 @delims.setter
254 @delims.setter
255 def delims(self, delims):
255 def delims(self, delims):
256 """Set the delimiters for line splitting."""
256 """Set the delimiters for line splitting."""
257 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
257 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
258 self._delim_re = re.compile(expr)
258 self._delim_re = re.compile(expr)
259 self._delims = delims
259 self._delims = delims
260 self._delim_expr = expr
260 self._delim_expr = expr
261
261
262 def split_line(self, line, cursor_pos=None):
262 def split_line(self, line, cursor_pos=None):
263 """Split a line of text with a cursor at the given position.
263 """Split a line of text with a cursor at the given position.
264 """
264 """
265 l = line if cursor_pos is None else line[:cursor_pos]
265 l = line if cursor_pos is None else line[:cursor_pos]
266 return self._delim_re.split(l)[-1]
266 return self._delim_re.split(l)[-1]
267
267
268
268
269 class Completer(Configurable):
269 class Completer(Configurable):
270
270
271 greedy = CBool(False, config=True,
271 greedy = CBool(False, config=True,
272 help="""Activate greedy completion
272 help="""Activate greedy completion
273
273
274 This will enable completion on elements of lists, results of function calls, etc.,
274 This will enable completion on elements of lists, results of function calls, etc.,
275 but can be unsafe because the code is actually evaluated on TAB.
275 but can be unsafe because the code is actually evaluated on TAB.
276 """
276 """
277 )
277 )
278
278
279
279
280 def __init__(self, namespace=None, global_namespace=None, **kwargs):
280 def __init__(self, namespace=None, global_namespace=None, **kwargs):
281 """Create a new completer for the command line.
281 """Create a new completer for the command line.
282
282
283 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
283 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
284
284
285 If unspecified, the default namespace where completions are performed
285 If unspecified, the default namespace where completions are performed
286 is __main__ (technically, __main__.__dict__). Namespaces should be
286 is __main__ (technically, __main__.__dict__). Namespaces should be
287 given as dictionaries.
287 given as dictionaries.
288
288
289 An optional second namespace can be given. This allows the completer
289 An optional second namespace can be given. This allows the completer
290 to handle cases where both the local and global scopes need to be
290 to handle cases where both the local and global scopes need to be
291 distinguished.
291 distinguished.
292
292
293 Completer instances should be used as the completion mechanism of
293 Completer instances should be used as the completion mechanism of
294 readline via the set_completer() call:
294 readline via the set_completer() call:
295
295
296 readline.set_completer(Completer(my_namespace).complete)
296 readline.set_completer(Completer(my_namespace).complete)
297 """
297 """
298
298
299 # Don't bind to namespace quite yet, but flag whether the user wants a
299 # Don't bind to namespace quite yet, but flag whether the user wants a
300 # specific namespace or to use __main__.__dict__. This will allow us
300 # specific namespace or to use __main__.__dict__. This will allow us
301 # to bind to __main__.__dict__ at completion time, not now.
301 # to bind to __main__.__dict__ at completion time, not now.
302 if namespace is None:
302 if namespace is None:
303 self.use_main_ns = 1
303 self.use_main_ns = 1
304 else:
304 else:
305 self.use_main_ns = 0
305 self.use_main_ns = 0
306 self.namespace = namespace
306 self.namespace = namespace
307
307
308 # The global namespace, if given, can be bound directly
308 # The global namespace, if given, can be bound directly
309 if global_namespace is None:
309 if global_namespace is None:
310 self.global_namespace = {}
310 self.global_namespace = {}
311 else:
311 else:
312 self.global_namespace = global_namespace
312 self.global_namespace = global_namespace
313
313
314 super(Completer, self).__init__(**kwargs)
314 super(Completer, self).__init__(**kwargs)
315
315
316 def complete(self, text, state):
316 def complete(self, text, state):
317 """Return the next possible completion for 'text'.
317 """Return the next possible completion for 'text'.
318
318
319 This is called successively with state == 0, 1, 2, ... until it
319 This is called successively with state == 0, 1, 2, ... until it
320 returns None. The completion should begin with 'text'.
320 returns None. The completion should begin with 'text'.
321
321
322 """
322 """
323 if self.use_main_ns:
323 if self.use_main_ns:
324 self.namespace = __main__.__dict__
324 self.namespace = __main__.__dict__
325
325
326 if state == 0:
326 if state == 0:
327 if "." in text:
327 if "." in text:
328 self.matches = self.attr_matches(text)
328 self.matches = self.attr_matches(text)
329 else:
329 else:
330 self.matches = self.global_matches(text)
330 self.matches = self.global_matches(text)
331 try:
331 try:
332 return self.matches[state]
332 return self.matches[state]
333 except IndexError:
333 except IndexError:
334 return None
334 return None
335
335
336 def global_matches(self, text):
336 def global_matches(self, text):
337 """Compute matches when text is a simple name.
337 """Compute matches when text is a simple name.
338
338
339 Return a list of all keywords, built-in functions and names currently
339 Return a list of all keywords, built-in functions and names currently
340 defined in self.namespace or self.global_namespace that match.
340 defined in self.namespace or self.global_namespace that match.
341
341
342 """
342 """
343 #print 'Completer->global_matches, txt=%r' % text # dbg
343 #print 'Completer->global_matches, txt=%r' % text # dbg
344 matches = []
344 matches = []
345 match_append = matches.append
345 match_append = matches.append
346 n = len(text)
346 n = len(text)
347 for lst in [keyword.kwlist,
347 for lst in [keyword.kwlist,
348 builtin_mod.__dict__.keys(),
348 builtin_mod.__dict__.keys(),
349 self.namespace.keys(),
349 self.namespace.keys(),
350 self.global_namespace.keys()]:
350 self.global_namespace.keys()]:
351 for word in lst:
351 for word in lst:
352 if word[:n] == text and word != "__builtins__":
352 if word[:n] == text and word != "__builtins__":
353 match_append(word)
353 match_append(word)
354 return matches
354 return matches
355
355
356 def attr_matches(self, text):
356 def attr_matches(self, text):
357 """Compute matches when text contains a dot.
357 """Compute matches when text contains a dot.
358
358
359 Assuming the text is of the form NAME.NAME....[NAME], and is
359 Assuming the text is of the form NAME.NAME....[NAME], and is
360 evaluatable in self.namespace or self.global_namespace, it will be
360 evaluatable in self.namespace or self.global_namespace, it will be
361 evaluated and its attributes (as revealed by dir()) are used as
361 evaluated and its attributes (as revealed by dir()) are used as
362 possible completions. (For class instances, class members are are
362 possible completions. (For class instances, class members are are
363 also considered.)
363 also considered.)
364
364
365 WARNING: this can still invoke arbitrary C code, if an object
365 WARNING: this can still invoke arbitrary C code, if an object
366 with a __getattr__ hook is evaluated.
366 with a __getattr__ hook is evaluated.
367
367
368 """
368 """
369
369
370 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
370 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
371 # Another option, seems to work great. Catches things like ''.<tab>
371 # Another option, seems to work great. Catches things like ''.<tab>
372 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
372 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
373
373
374 if m:
374 if m:
375 expr, attr = m.group(1, 3)
375 expr, attr = m.group(1, 3)
376 elif self.greedy:
376 elif self.greedy:
377 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
377 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
378 if not m2:
378 if not m2:
379 return []
379 return []
380 expr, attr = m2.group(1,2)
380 expr, attr = m2.group(1,2)
381 else:
381 else:
382 return []
382 return []
383
383
384 try:
384 try:
385 obj = eval(expr, self.namespace)
385 obj = eval(expr, self.namespace)
386 except:
386 except:
387 try:
387 try:
388 obj = eval(expr, self.global_namespace)
388 obj = eval(expr, self.global_namespace)
389 except:
389 except:
390 return []
390 return []
391
391
392 if self.limit_to__all__ and hasattr(obj, '__all__'):
392 if self.limit_to__all__ and hasattr(obj, '__all__'):
393 words = get__all__entries(obj)
393 words = get__all__entries(obj)
394 else:
394 else:
395 words = dir2(obj)
395 words = dir2(obj)
396
396
397 try:
397 try:
398 words = generics.complete_object(obj, words)
398 words = generics.complete_object(obj, words)
399 except TryNext:
399 except TryNext:
400 pass
400 pass
401 except Exception:
401 except Exception:
402 # Silence errors from completion function
402 # Silence errors from completion function
403 #raise # dbg
403 #raise # dbg
404 pass
404 pass
405 # Build match list to return
405 # Build match list to return
406 n = len(attr)
406 n = len(attr)
407 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
407 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
408 return res
408 return res
409
409
410
410
411 def get__all__entries(obj):
411 def get__all__entries(obj):
412 """returns the strings in the __all__ attribute"""
412 """returns the strings in the __all__ attribute"""
413 try:
413 try:
414 words = getattr(obj, '__all__')
414 words = getattr(obj, '__all__')
415 except:
415 except:
416 return []
416 return []
417
417
418 return [w for w in words if isinstance(w, string_types)]
418 return [w for w in words if isinstance(w, string_types)]
419
419
420
420
421 def match_dict_keys(keys, prefix):
421 def match_dict_keys(keys, prefix):
422 """Used by dict_key_matches, matching the prefix to a list of keys"""
422 """Used by dict_key_matches, matching the prefix to a list of keys"""
423 if not prefix:
423 if not prefix:
424 return None, 0, [repr(k) for k in keys
424 return None, 0, [repr(k) for k in keys
425 if isinstance(k, (string_types, bytes))]
425 if isinstance(k, (string_types, bytes))]
426 quote_match = re.search('["\']', prefix)
426 quote_match = re.search('["\']', prefix)
427 quote = quote_match.group()
427 quote = quote_match.group()
428 try:
428 try:
429 prefix_str = eval(prefix + quote, {})
429 prefix_str = eval(prefix + quote, {})
430 except Exception:
430 except Exception:
431 return None, 0, []
431 return None, 0, []
432
432
433 token_match = re.search(r'\w*$', prefix, re.UNICODE)
433 token_match = re.search(r'\w*$', prefix, re.UNICODE)
434 token_start = token_match.start()
434 token_start = token_match.start()
435 token_prefix = token_match.group()
435 token_prefix = token_match.group()
436
436
437 # TODO: support bytes in Py3k
437 # TODO: support bytes in Py3k
438 matched = []
438 matched = []
439 for key in keys:
439 for key in keys:
440 try:
440 try:
441 if not key.startswith(prefix_str):
441 if not key.startswith(prefix_str):
442 continue
442 continue
443 except (AttributeError, TypeError, UnicodeError):
443 except (AttributeError, TypeError, UnicodeError):
444 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
444 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
445 continue
445 continue
446
446
447 # reformat remainder of key to begin with prefix
447 # reformat remainder of key to begin with prefix
448 rem = key[len(prefix_str):]
448 rem = key[len(prefix_str):]
449 # force repr wrapped in '
449 # force repr wrapped in '
450 rem_repr = repr(rem + '"')
450 rem_repr = repr(rem + '"')
451 if rem_repr.startswith('u') and prefix[0] not in 'uU':
451 if rem_repr.startswith('u') and prefix[0] not in 'uU':
452 # Found key is unicode, but prefix is Py2 string.
452 # Found key is unicode, but prefix is Py2 string.
453 # Therefore attempt to interpret key as string.
453 # Therefore attempt to interpret key as string.
454 try:
454 try:
455 rem_repr = repr(rem.encode('ascii') + '"')
455 rem_repr = repr(rem.encode('ascii') + '"')
456 except UnicodeEncodeError:
456 except UnicodeEncodeError:
457 continue
457 continue
458
458
459 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
459 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
460 if quote == '"':
460 if quote == '"':
461 # The entered prefix is quoted with ",
461 # The entered prefix is quoted with ",
462 # but the match is quoted with '.
462 # but the match is quoted with '.
463 # A contained " hence needs escaping for comparison:
463 # A contained " hence needs escaping for comparison:
464 rem_repr = rem_repr.replace('"', '\\"')
464 rem_repr = rem_repr.replace('"', '\\"')
465
465
466 # then reinsert prefix from start of token
466 # then reinsert prefix from start of token
467 matched.append('%s%s' % (token_prefix, rem_repr))
467 matched.append('%s%s' % (token_prefix, rem_repr))
468 return quote, token_start, matched
468 return quote, token_start, matched
469
469
470
470
471 def _safe_isinstance(obj, module, class_name):
471 def _safe_isinstance(obj, module, class_name):
472 """Checks if obj is an instance of module.class_name if loaded
472 """Checks if obj is an instance of module.class_name if loaded
473 """
473 """
474 return (module in sys.modules and
474 return (module in sys.modules and
475 isinstance(obj, getattr(__import__(module), class_name)))
475 isinstance(obj, getattr(__import__(module), class_name)))
476
476
477
477
478
478
479 def back_unicode_name_matches(text):
479 def back_unicode_name_matches(text):
480 u"""Match unicode characters back to unicode name
480 u"""Match unicode characters back to unicode name
481
481
482 This does ☃ -> \\snowman
482 This does ☃ -> \\snowman
483
483
484 Note that snowman is not a valid python3 combining character but will be expanded.
484 Note that snowman is not a valid python3 combining character but will be expanded.
485 Though it will not recombine back to the snowman character by the completion machinery.
485 Though it will not recombine back to the snowman character by the completion machinery.
486
486
487 This will not either back-complete standard sequences like \n, \b ...
487 This will not either back-complete standard sequences like \n, \b ...
488
488
489 Used on Python 3 only.
489 Used on Python 3 only.
490 """
490 """
491 if len(text)<2:
491 if len(text)<2:
492 return u'', ()
492 return u'', ()
493 maybe_slash = text[-2]
493 maybe_slash = text[-2]
494 if maybe_slash != '\\':
494 if maybe_slash != '\\':
495 return u'', ()
495 return u'', ()
496
496
497 char = text[-1]
497 char = text[-1]
498 # no expand on quote for completion in strings.
498 # no expand on quote for completion in strings.
499 # nor backcomplete standard ascii keys
499 # nor backcomplete standard ascii keys
500 if char in string.ascii_letters or char in ['"',"'"]:
500 if char in string.ascii_letters or char in ['"',"'"]:
501 return u'', ()
501 return u'', ()
502 try :
502 try :
503 unic = unicodedata.name(char)
503 unic = unicodedata.name(char)
504 return '\\'+char,['\\'+unic]
504 return '\\'+char,['\\'+unic]
505 except KeyError as e:
505 except KeyError as e:
506 pass
506 pass
507 return u'', ()
507 return u'', ()
508
508
509 def back_latex_name_matches(text):
509 def back_latex_name_matches(text):
510 u"""Match latex characters back to unicode name
510 u"""Match latex characters back to unicode name
511
511
512 This does ->\\sqrt
512 This does ->\\sqrt
513
513
514 Used on Python 3 only.
514 Used on Python 3 only.
515 """
515 """
516 if len(text)<2:
516 if len(text)<2:
517 return u'', ()
517 return u'', ()
518 maybe_slash = text[-2]
518 maybe_slash = text[-2]
519 if maybe_slash != '\\':
519 if maybe_slash != '\\':
520 return u'', ()
520 return u'', ()
521
521
522
522
523 char = text[-1]
523 char = text[-1]
524 # no expand on quote for completion in strings.
524 # no expand on quote for completion in strings.
525 # nor backcomplete standard ascii keys
525 # nor backcomplete standard ascii keys
526 if char in string.ascii_letters or char in ['"',"'"]:
526 if char in string.ascii_letters or char in ['"',"'"]:
527 return u'', ()
527 return u'', ()
528 try :
528 try :
529 latex = reverse_latex_symbol[char]
529 latex = reverse_latex_symbol[char]
530 # '\\' replace the \ as well
530 # '\\' replace the \ as well
531 return '\\'+char,[latex]
531 return '\\'+char,[latex]
532 except KeyError as e:
532 except KeyError as e:
533 pass
533 pass
534 return u'', ()
534 return u'', ()
535
535
536
536
537 class IPCompleter(Completer):
537 class IPCompleter(Completer):
538 """Extension of the completer class with IPython-specific features"""
538 """Extension of the completer class with IPython-specific features"""
539
539
540 def _greedy_changed(self, name, old, new):
540 def _greedy_changed(self, name, old, new):
541 """update the splitter and readline delims when greedy is changed"""
541 """update the splitter and readline delims when greedy is changed"""
542 if new:
542 if new:
543 self.splitter.delims = GREEDY_DELIMS
543 self.splitter.delims = GREEDY_DELIMS
544 else:
544 else:
545 self.splitter.delims = DELIMS
545 self.splitter.delims = DELIMS
546
546
547 if self.readline:
547 if self.readline:
548 self.readline.set_completer_delims(self.splitter.delims)
548 self.readline.set_completer_delims(self.splitter.delims)
549
549
550 merge_completions = CBool(True, config=True,
550 merge_completions = CBool(True, config=True,
551 help="""Whether to merge completion results into a single list
551 help="""Whether to merge completion results into a single list
552
552
553 If False, only the completion results from the first non-empty
553 If False, only the completion results from the first non-empty
554 completer will be returned.
554 completer will be returned.
555 """
555 """
556 )
556 )
557 omit__names = Enum((0,1,2), default_value=2, config=True,
557 omit__names = Enum((0,1,2), default_value=2, config=True,
558 help="""Instruct the completer to omit private method names
558 help="""Instruct the completer to omit private method names
559
559
560 Specifically, when completing on ``object.<tab>``.
560 Specifically, when completing on ``object.<tab>``.
561
561
562 When 2 [default]: all names that start with '_' will be excluded.
562 When 2 [default]: all names that start with '_' will be excluded.
563
563
564 When 1: all 'magic' names (``__foo__``) will be excluded.
564 When 1: all 'magic' names (``__foo__``) will be excluded.
565
565
566 When 0: nothing will be excluded.
566 When 0: nothing will be excluded.
567 """
567 """
568 )
568 )
569 limit_to__all__ = CBool(default_value=False, config=True,
569 limit_to__all__ = CBool(default_value=False, config=True,
570 help="""Instruct the completer to use __all__ for the completion
570 help="""Instruct the completer to use __all__ for the completion
571
571
572 Specifically, when completing on ``object.<tab>``.
572 Specifically, when completing on ``object.<tab>``.
573
573
574 When True: only those names in obj.__all__ will be included.
574 When True: only those names in obj.__all__ will be included.
575
575
576 When False [default]: the __all__ attribute is ignored
576 When False [default]: the __all__ attribute is ignored
577 """
577 """
578 )
578 )
579
579
580 def __init__(self, shell=None, namespace=None, global_namespace=None,
580 def __init__(self, shell=None, namespace=None, global_namespace=None,
581 use_readline=True, config=None, **kwargs):
581 use_readline=True, config=None, **kwargs):
582 """IPCompleter() -> completer
582 """IPCompleter() -> completer
583
583
584 Return a completer object suitable for use by the readline library
584 Return a completer object suitable for use by the readline library
585 via readline.set_completer().
585 via readline.set_completer().
586
586
587 Inputs:
587 Inputs:
588
588
589 - shell: a pointer to the ipython shell itself. This is needed
589 - shell: a pointer to the ipython shell itself. This is needed
590 because this completer knows about magic functions, and those can
590 because this completer knows about magic functions, and those can
591 only be accessed via the ipython instance.
591 only be accessed via the ipython instance.
592
592
593 - namespace: an optional dict where completions are performed.
593 - namespace: an optional dict where completions are performed.
594
594
595 - global_namespace: secondary optional dict for completions, to
595 - global_namespace: secondary optional dict for completions, to
596 handle cases (such as IPython embedded inside functions) where
596 handle cases (such as IPython embedded inside functions) where
597 both Python scopes are visible.
597 both Python scopes are visible.
598
598
599 use_readline : bool, optional
599 use_readline : bool, optional
600 If true, use the readline library. This completer can still function
600 If true, use the readline library. This completer can still function
601 without readline, though in that case callers must provide some extra
601 without readline, though in that case callers must provide some extra
602 information on each call about the current line."""
602 information on each call about the current line."""
603
603
604 self.magic_escape = ESC_MAGIC
604 self.magic_escape = ESC_MAGIC
605 self.splitter = CompletionSplitter()
605 self.splitter = CompletionSplitter()
606
606
607 # Readline configuration, only used by the rlcompleter method.
607 # Readline configuration, only used by the rlcompleter method.
608 if use_readline:
608 if use_readline:
609 # We store the right version of readline so that later code
609 # We store the right version of readline so that later code
610 import IPython.utils.rlineimpl as readline
610 import IPython.utils.rlineimpl as readline
611 self.readline = readline
611 self.readline = readline
612 else:
612 else:
613 self.readline = None
613 self.readline = None
614
614
615 # _greedy_changed() depends on splitter and readline being defined:
615 # _greedy_changed() depends on splitter and readline being defined:
616 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
616 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
617 config=config, **kwargs)
617 config=config, **kwargs)
618
618
619 # List where completion matches will be stored
619 # List where completion matches will be stored
620 self.matches = []
620 self.matches = []
621 self.shell = shell
621 self.shell = shell
622 # Regexp to split filenames with spaces in them
622 # Regexp to split filenames with spaces in them
623 self.space_name_re = re.compile(r'([^\\] )')
623 self.space_name_re = re.compile(r'([^\\] )')
624 # Hold a local ref. to glob.glob for speed
624 # Hold a local ref. to glob.glob for speed
625 self.glob = glob.glob
625 self.glob = glob.glob
626
626
627 # Determine if we are running on 'dumb' terminals, like (X)Emacs
627 # Determine if we are running on 'dumb' terminals, like (X)Emacs
628 # buffers, to avoid completion problems.
628 # buffers, to avoid completion problems.
629 term = os.environ.get('TERM','xterm')
629 term = os.environ.get('TERM','xterm')
630 self.dumb_terminal = term in ['dumb','emacs']
630 self.dumb_terminal = term in ['dumb','emacs']
631
631
632 # Special handling of backslashes needed in win32 platforms
632 # Special handling of backslashes needed in win32 platforms
633 if sys.platform == "win32":
633 if sys.platform == "win32":
634 self.clean_glob = self._clean_glob_win32
634 self.clean_glob = self._clean_glob_win32
635 else:
635 else:
636 self.clean_glob = self._clean_glob
636 self.clean_glob = self._clean_glob
637
637
638 #regexp to parse docstring for function signature
638 #regexp to parse docstring for function signature
639 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
639 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
640 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
640 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
641 #use this if positional argument name is also needed
641 #use this if positional argument name is also needed
642 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
642 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
643
643
644 # All active matcher routines for completion
644 # All active matcher routines for completion
645 self.matchers = [self.python_matches,
645 self.matchers = [self.python_matches,
646 self.file_matches,
646 self.file_matches,
647 self.magic_matches,
647 self.magic_matches,
648 self.python_func_kw_matches,
648 self.python_func_kw_matches,
649 self.dict_key_matches,
649 self.dict_key_matches,
650 ]
650 ]
651
651
652 def all_completions(self, text):
652 def all_completions(self, text):
653 """
653 """
654 Wrapper around the complete method for the benefit of emacs
654 Wrapper around the complete method for the benefit of emacs
655 and pydb.
655 and pydb.
656 """
656 """
657 return self.complete(text)[1]
657 return self.complete(text)[1]
658
658
659 def _clean_glob(self,text):
659 def _clean_glob(self,text):
660 return self.glob("%s*" % text)
660 return self.glob("%s*" % text)
661
661
662 def _clean_glob_win32(self,text):
662 def _clean_glob_win32(self,text):
663 return [f.replace("\\","/")
663 return [f.replace("\\","/")
664 for f in self.glob("%s*" % text)]
664 for f in self.glob("%s*" % text)]
665
665
666 def file_matches(self, text):
666 def file_matches(self, text):
667 """Match filenames, expanding ~USER type strings.
667 """Match filenames, expanding ~USER type strings.
668
668
669 Most of the seemingly convoluted logic in this completer is an
669 Most of the seemingly convoluted logic in this completer is an
670 attempt to handle filenames with spaces in them. And yet it's not
670 attempt to handle filenames with spaces in them. And yet it's not
671 quite perfect, because Python's readline doesn't expose all of the
671 quite perfect, because Python's readline doesn't expose all of the
672 GNU readline details needed for this to be done correctly.
672 GNU readline details needed for this to be done correctly.
673
673
674 For a filename with a space in it, the printed completions will be
674 For a filename with a space in it, the printed completions will be
675 only the parts after what's already been typed (instead of the
675 only the parts after what's already been typed (instead of the
676 full completions, as is normally done). I don't think with the
676 full completions, as is normally done). I don't think with the
677 current (as of Python 2.3) Python readline it's possible to do
677 current (as of Python 2.3) Python readline it's possible to do
678 better."""
678 better."""
679
679
680 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
680 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
681
681
682 # chars that require escaping with backslash - i.e. chars
682 # chars that require escaping with backslash - i.e. chars
683 # that readline treats incorrectly as delimiters, but we
683 # that readline treats incorrectly as delimiters, but we
684 # don't want to treat as delimiters in filename matching
684 # don't want to treat as delimiters in filename matching
685 # when escaped with backslash
685 # when escaped with backslash
686 if text.startswith('!'):
686 if text.startswith('!'):
687 text = text[1:]
687 text = text[1:]
688 text_prefix = '!'
688 text_prefix = '!'
689 else:
689 else:
690 text_prefix = ''
690 text_prefix = ''
691
691
692 text_until_cursor = self.text_until_cursor
692 text_until_cursor = self.text_until_cursor
693 # track strings with open quotes
693 # track strings with open quotes
694 open_quotes = has_open_quotes(text_until_cursor)
694 open_quotes = has_open_quotes(text_until_cursor)
695
695
696 if '(' in text_until_cursor or '[' in text_until_cursor:
696 if '(' in text_until_cursor or '[' in text_until_cursor:
697 lsplit = text
697 lsplit = text
698 else:
698 else:
699 try:
699 try:
700 # arg_split ~ shlex.split, but with unicode bugs fixed by us
700 # arg_split ~ shlex.split, but with unicode bugs fixed by us
701 lsplit = arg_split(text_until_cursor)[-1]
701 lsplit = arg_split(text_until_cursor)[-1]
702 except ValueError:
702 except ValueError:
703 # typically an unmatched ", or backslash without escaped char.
703 # typically an unmatched ", or backslash without escaped char.
704 if open_quotes:
704 if open_quotes:
705 lsplit = text_until_cursor.split(open_quotes)[-1]
705 lsplit = text_until_cursor.split(open_quotes)[-1]
706 else:
706 else:
707 return []
707 return []
708 except IndexError:
708 except IndexError:
709 # tab pressed on empty line
709 # tab pressed on empty line
710 lsplit = ""
710 lsplit = ""
711
711
712 if not open_quotes and lsplit != protect_filename(lsplit):
712 if not open_quotes and lsplit != protect_filename(lsplit):
713 # if protectables are found, do matching on the whole escaped name
713 # if protectables are found, do matching on the whole escaped name
714 has_protectables = True
714 has_protectables = True
715 text0,text = text,lsplit
715 text0,text = text,lsplit
716 else:
716 else:
717 has_protectables = False
717 has_protectables = False
718 text = os.path.expanduser(text)
718 text = os.path.expanduser(text)
719
719
720 if text == "":
720 if text == "":
721 return [text_prefix + protect_filename(f) for f in self.glob("*")]
721 return [text_prefix + protect_filename(f) for f in self.glob("*")]
722
722
723 # Compute the matches from the filesystem
723 # Compute the matches from the filesystem
724 m0 = self.clean_glob(text.replace('\\',''))
724 m0 = self.clean_glob(text.replace('\\',''))
725
725
726 if has_protectables:
726 if has_protectables:
727 # If we had protectables, we need to revert our changes to the
727 # If we had protectables, we need to revert our changes to the
728 # beginning of filename so that we don't double-write the part
728 # beginning of filename so that we don't double-write the part
729 # of the filename we have so far
729 # of the filename we have so far
730 len_lsplit = len(lsplit)
730 len_lsplit = len(lsplit)
731 matches = [text_prefix + text0 +
731 matches = [text_prefix + text0 +
732 protect_filename(f[len_lsplit:]) for f in m0]
732 protect_filename(f[len_lsplit:]) for f in m0]
733 else:
733 else:
734 if open_quotes:
734 if open_quotes:
735 # if we have a string with an open quote, we don't need to
735 # if we have a string with an open quote, we don't need to
736 # protect the names at all (and we _shouldn't_, as it
736 # protect the names at all (and we _shouldn't_, as it
737 # would cause bugs when the filesystem call is made).
737 # would cause bugs when the filesystem call is made).
738 matches = m0
738 matches = m0
739 else:
739 else:
740 matches = [text_prefix +
740 matches = [text_prefix +
741 protect_filename(f) for f in m0]
741 protect_filename(f) for f in m0]
742
742
743 #io.rprint('mm', matches) # dbg
743 #io.rprint('mm', matches) # dbg
744
744
745 # Mark directories in input list by appending '/' to their names.
745 # Mark directories in input list by appending '/' to their names.
746 matches = [x+'/' if os.path.isdir(x) else x for x in matches]
746 matches = [x+'/' if os.path.isdir(x) else x for x in matches]
747 return matches
747 return matches
748
748
749 def magic_matches(self, text):
749 def magic_matches(self, text):
750 """Match magics"""
750 """Match magics"""
751 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
751 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
752 # Get all shell magics now rather than statically, so magics loaded at
752 # Get all shell magics now rather than statically, so magics loaded at
753 # runtime show up too.
753 # runtime show up too.
754 lsm = self.shell.magics_manager.lsmagic()
754 lsm = self.shell.magics_manager.lsmagic()
755 line_magics = lsm['line']
755 line_magics = lsm['line']
756 cell_magics = lsm['cell']
756 cell_magics = lsm['cell']
757 pre = self.magic_escape
757 pre = self.magic_escape
758 pre2 = pre+pre
758 pre2 = pre+pre
759
759
760 # Completion logic:
760 # Completion logic:
761 # - user gives %%: only do cell magics
761 # - user gives %%: only do cell magics
762 # - user gives %: do both line and cell magics
762 # - user gives %: do both line and cell magics
763 # - no prefix: do both
763 # - no prefix: do both
764 # In other words, line magics are skipped if the user gives %% explicitly
764 # In other words, line magics are skipped if the user gives %% explicitly
765 bare_text = text.lstrip(pre)
765 bare_text = text.lstrip(pre)
766 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
766 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
767 if not text.startswith(pre2):
767 if not text.startswith(pre2):
768 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
768 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
769 return comp
769 return comp
770
770
771 def python_matches(self,text):
771 def python_matches(self,text):
772 """Match attributes or global python names"""
772 """Match attributes or global python names"""
773
773
774 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
774 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
775 if "." in text:
775 if "." in text:
776 try:
776 try:
777 matches = self.attr_matches(text)
777 matches = self.attr_matches(text)
778 if text.endswith('.') and self.omit__names:
778 if text.endswith('.') and self.omit__names:
779 if self.omit__names == 1:
779 if self.omit__names == 1:
780 # true if txt is _not_ a __ name, false otherwise:
780 # true if txt is _not_ a __ name, false otherwise:
781 no__name = (lambda txt:
781 no__name = (lambda txt:
782 re.match(r'.*\.__.*?__',txt) is None)
782 re.match(r'.*\.__.*?__',txt) is None)
783 else:
783 else:
784 # true if txt is _not_ a _ name, false otherwise:
784 # true if txt is _not_ a _ name, false otherwise:
785 no__name = (lambda txt:
785 no__name = (lambda txt:
786 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
786 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
787 matches = filter(no__name, matches)
787 matches = filter(no__name, matches)
788 except NameError:
788 except NameError:
789 # catches <undefined attributes>.<tab>
789 # catches <undefined attributes>.<tab>
790 matches = []
790 matches = []
791 else:
791 else:
792 matches = self.global_matches(text)
792 matches = self.global_matches(text)
793
793
794 return matches
794 return matches
795
795
796 def _default_arguments_from_docstring(self, doc):
796 def _default_arguments_from_docstring(self, doc):
797 """Parse the first line of docstring for call signature.
797 """Parse the first line of docstring for call signature.
798
798
799 Docstring should be of the form 'min(iterable[, key=func])\n'.
799 Docstring should be of the form 'min(iterable[, key=func])\n'.
800 It can also parse cython docstring of the form
800 It can also parse cython docstring of the form
801 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
801 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
802 """
802 """
803 if doc is None:
803 if doc is None:
804 return []
804 return []
805
805
806 #care only the firstline
806 #care only the firstline
807 line = doc.lstrip().splitlines()[0]
807 line = doc.lstrip().splitlines()[0]
808
808
809 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
809 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
810 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
810 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
811 sig = self.docstring_sig_re.search(line)
811 sig = self.docstring_sig_re.search(line)
812 if sig is None:
812 if sig is None:
813 return []
813 return []
814 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
814 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
815 sig = sig.groups()[0].split(',')
815 sig = sig.groups()[0].split(',')
816 ret = []
816 ret = []
817 for s in sig:
817 for s in sig:
818 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
818 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
819 ret += self.docstring_kwd_re.findall(s)
819 ret += self.docstring_kwd_re.findall(s)
820 return ret
820 return ret
821
821
822 def _default_arguments(self, obj):
822 def _default_arguments(self, obj):
823 """Return the list of default arguments of obj if it is callable,
823 """Return the list of default arguments of obj if it is callable,
824 or empty list otherwise."""
824 or empty list otherwise."""
825 call_obj = obj
825 call_obj = obj
826 ret = []
826 ret = []
827 if inspect.isbuiltin(obj):
827 if inspect.isbuiltin(obj):
828 pass
828 pass
829 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
829 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
830 if inspect.isclass(obj):
830 if inspect.isclass(obj):
831 #for cython embededsignature=True the constructor docstring
831 #for cython embededsignature=True the constructor docstring
832 #belongs to the object itself not __init__
832 #belongs to the object itself not __init__
833 ret += self._default_arguments_from_docstring(
833 ret += self._default_arguments_from_docstring(
834 getattr(obj, '__doc__', ''))
834 getattr(obj, '__doc__', ''))
835 # for classes, check for __init__,__new__
835 # for classes, check for __init__,__new__
836 call_obj = (getattr(obj, '__init__', None) or
836 call_obj = (getattr(obj, '__init__', None) or
837 getattr(obj, '__new__', None))
837 getattr(obj, '__new__', None))
838 # for all others, check if they are __call__able
838 # for all others, check if they are __call__able
839 elif hasattr(obj, '__call__'):
839 elif hasattr(obj, '__call__'):
840 call_obj = obj.__call__
840 call_obj = obj.__call__
841
841
842 ret += self._default_arguments_from_docstring(
842 ret += self._default_arguments_from_docstring(
843 getattr(call_obj, '__doc__', ''))
843 getattr(call_obj, '__doc__', ''))
844
844
845 try:
845 try:
846 args,_,_1,defaults = inspect.getargspec(call_obj)
846 args,_,_1,defaults = inspect.getargspec(call_obj)
847 if defaults:
847 if defaults:
848 ret+=args[-len(defaults):]
848 ret+=args[-len(defaults):]
849 except TypeError:
849 except TypeError:
850 pass
850 pass
851
851
852 return list(set(ret))
852 return list(set(ret))
853
853
854 def python_func_kw_matches(self,text):
854 def python_func_kw_matches(self,text):
855 """Match named parameters (kwargs) of the last open function"""
855 """Match named parameters (kwargs) of the last open function"""
856
856
857 if "." in text: # a parameter cannot be dotted
857 if "." in text: # a parameter cannot be dotted
858 return []
858 return []
859 try: regexp = self.__funcParamsRegex
859 try: regexp = self.__funcParamsRegex
860 except AttributeError:
860 except AttributeError:
861 regexp = self.__funcParamsRegex = re.compile(r'''
861 regexp = self.__funcParamsRegex = re.compile(r'''
862 '.*?(?<!\\)' | # single quoted strings or
862 '.*?(?<!\\)' | # single quoted strings or
863 ".*?(?<!\\)" | # double quoted strings or
863 ".*?(?<!\\)" | # double quoted strings or
864 \w+ | # identifier
864 \w+ | # identifier
865 \S # other characters
865 \S # other characters
866 ''', re.VERBOSE | re.DOTALL)
866 ''', re.VERBOSE | re.DOTALL)
867 # 1. find the nearest identifier that comes before an unclosed
867 # 1. find the nearest identifier that comes before an unclosed
868 # parenthesis before the cursor
868 # parenthesis before the cursor
869 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
869 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
870 tokens = regexp.findall(self.text_until_cursor)
870 tokens = regexp.findall(self.text_until_cursor)
871 tokens.reverse()
871 tokens.reverse()
872 iterTokens = iter(tokens); openPar = 0
872 iterTokens = iter(tokens); openPar = 0
873
873
874 for token in iterTokens:
874 for token in iterTokens:
875 if token == ')':
875 if token == ')':
876 openPar -= 1
876 openPar -= 1
877 elif token == '(':
877 elif token == '(':
878 openPar += 1
878 openPar += 1
879 if openPar > 0:
879 if openPar > 0:
880 # found the last unclosed parenthesis
880 # found the last unclosed parenthesis
881 break
881 break
882 else:
882 else:
883 return []
883 return []
884 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
884 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
885 ids = []
885 ids = []
886 isId = re.compile(r'\w+$').match
886 isId = re.compile(r'\w+$').match
887
887
888 while True:
888 while True:
889 try:
889 try:
890 ids.append(next(iterTokens))
890 ids.append(next(iterTokens))
891 if not isId(ids[-1]):
891 if not isId(ids[-1]):
892 ids.pop(); break
892 ids.pop(); break
893 if not next(iterTokens) == '.':
893 if not next(iterTokens) == '.':
894 break
894 break
895 except StopIteration:
895 except StopIteration:
896 break
896 break
897 # lookup the candidate callable matches either using global_matches
897 # lookup the candidate callable matches either using global_matches
898 # or attr_matches for dotted names
898 # or attr_matches for dotted names
899 if len(ids) == 1:
899 if len(ids) == 1:
900 callableMatches = self.global_matches(ids[0])
900 callableMatches = self.global_matches(ids[0])
901 else:
901 else:
902 callableMatches = self.attr_matches('.'.join(ids[::-1]))
902 callableMatches = self.attr_matches('.'.join(ids[::-1]))
903 argMatches = []
903 argMatches = []
904 for callableMatch in callableMatches:
904 for callableMatch in callableMatches:
905 try:
905 try:
906 namedArgs = self._default_arguments(eval(callableMatch,
906 namedArgs = self._default_arguments(eval(callableMatch,
907 self.namespace))
907 self.namespace))
908 except:
908 except:
909 continue
909 continue
910
910
911 for namedArg in namedArgs:
911 for namedArg in namedArgs:
912 if namedArg.startswith(text):
912 if namedArg.startswith(text):
913 argMatches.append("%s=" %namedArg)
913 argMatches.append("%s=" %namedArg)
914 return argMatches
914 return argMatches
915
915
916 def dict_key_matches(self, text):
916 def dict_key_matches(self, text):
917 "Match string keys in a dictionary, after e.g. 'foo[' "
917 "Match string keys in a dictionary, after e.g. 'foo[' "
918 def get_keys(obj):
918 def get_keys(obj):
919 # Only allow completion for known in-memory dict-like types
919 # Only allow completion for known in-memory dict-like types
920 if isinstance(obj, dict) or\
920 if isinstance(obj, dict) or\
921 _safe_isinstance(obj, 'pandas', 'DataFrame'):
921 _safe_isinstance(obj, 'pandas', 'DataFrame'):
922 try:
922 try:
923 return list(obj.keys())
923 return list(obj.keys())
924 except Exception:
924 except Exception:
925 return []
925 return []
926 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
926 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
927 _safe_isinstance(obj, 'numpy', 'void'):
927 _safe_isinstance(obj, 'numpy', 'void'):
928 return obj.dtype.names or []
928 return obj.dtype.names or []
929 return []
929 return []
930
930
931 try:
931 try:
932 regexps = self.__dict_key_regexps
932 regexps = self.__dict_key_regexps
933 except AttributeError:
933 except AttributeError:
934 dict_key_re_fmt = r'''(?x)
934 dict_key_re_fmt = r'''(?x)
935 ( # match dict-referring expression wrt greedy setting
935 ( # match dict-referring expression wrt greedy setting
936 %s
936 %s
937 )
937 )
938 \[ # open bracket
938 \[ # open bracket
939 \s* # and optional whitespace
939 \s* # and optional whitespace
940 ([uUbB]? # string prefix (r not handled)
940 ([uUbB]? # string prefix (r not handled)
941 (?: # unclosed string
941 (?: # unclosed string
942 '(?:[^']|(?<!\\)\\')*
942 '(?:[^']|(?<!\\)\\')*
943 |
943 |
944 "(?:[^"]|(?<!\\)\\")*
944 "(?:[^"]|(?<!\\)\\")*
945 )
945 )
946 )?
946 )?
947 $
947 $
948 '''
948 '''
949 regexps = self.__dict_key_regexps = {
949 regexps = self.__dict_key_regexps = {
950 False: re.compile(dict_key_re_fmt % '''
950 False: re.compile(dict_key_re_fmt % '''
951 # identifiers separated by .
951 # identifiers separated by .
952 (?!\d)\w+
952 (?!\d)\w+
953 (?:\.(?!\d)\w+)*
953 (?:\.(?!\d)\w+)*
954 '''),
954 '''),
955 True: re.compile(dict_key_re_fmt % '''
955 True: re.compile(dict_key_re_fmt % '''
956 .+
956 .+
957 ''')
957 ''')
958 }
958 }
959
959
960 match = regexps[self.greedy].search(self.text_until_cursor)
960 match = regexps[self.greedy].search(self.text_until_cursor)
961 if match is None:
961 if match is None:
962 return []
962 return []
963
963
964 expr, prefix = match.groups()
964 expr, prefix = match.groups()
965 try:
965 try:
966 obj = eval(expr, self.namespace)
966 obj = eval(expr, self.namespace)
967 except Exception:
967 except Exception:
968 try:
968 try:
969 obj = eval(expr, self.global_namespace)
969 obj = eval(expr, self.global_namespace)
970 except Exception:
970 except Exception:
971 return []
971 return []
972
972
973 keys = get_keys(obj)
973 keys = get_keys(obj)
974 if not keys:
974 if not keys:
975 return keys
975 return keys
976 closing_quote, token_offset, matches = match_dict_keys(keys, prefix)
976 closing_quote, token_offset, matches = match_dict_keys(keys, prefix)
977 if not matches:
977 if not matches:
978 return matches
978 return matches
979
979
980 # get the cursor position of
980 # get the cursor position of
981 # - the text being completed
981 # - the text being completed
982 # - the start of the key text
982 # - the start of the key text
983 # - the start of the completion
983 # - the start of the completion
984 text_start = len(self.text_until_cursor) - len(text)
984 text_start = len(self.text_until_cursor) - len(text)
985 if prefix:
985 if prefix:
986 key_start = match.start(2)
986 key_start = match.start(2)
987 completion_start = key_start + token_offset
987 completion_start = key_start + token_offset
988 else:
988 else:
989 key_start = completion_start = match.end()
989 key_start = completion_start = match.end()
990
990
991 # grab the leading prefix, to make sure all completions start with `text`
991 # grab the leading prefix, to make sure all completions start with `text`
992 if text_start > key_start:
992 if text_start > key_start:
993 leading = ''
993 leading = ''
994 else:
994 else:
995 leading = text[text_start:completion_start]
995 leading = text[text_start:completion_start]
996
996
997 # the index of the `[` character
997 # the index of the `[` character
998 bracket_idx = match.end(1)
998 bracket_idx = match.end(1)
999
999
1000 # append closing quote and bracket as appropriate
1000 # append closing quote and bracket as appropriate
1001 # this is *not* appropriate if the opening quote or bracket is outside
1001 # this is *not* appropriate if the opening quote or bracket is outside
1002 # the text given to this method
1002 # the text given to this method
1003 suf = ''
1003 suf = ''
1004 continuation = self.line_buffer[len(self.text_until_cursor):]
1004 continuation = self.line_buffer[len(self.text_until_cursor):]
1005 if key_start > text_start and closing_quote:
1005 if key_start > text_start and closing_quote:
1006 # quotes were opened inside text, maybe close them
1006 # quotes were opened inside text, maybe close them
1007 if continuation.startswith(closing_quote):
1007 if continuation.startswith(closing_quote):
1008 continuation = continuation[len(closing_quote):]
1008 continuation = continuation[len(closing_quote):]
1009 else:
1009 else:
1010 suf += closing_quote
1010 suf += closing_quote
1011 if bracket_idx > text_start:
1011 if bracket_idx > text_start:
1012 # brackets were opened inside text, maybe close them
1012 # brackets were opened inside text, maybe close them
1013 if not continuation.startswith(']'):
1013 if not continuation.startswith(']'):
1014 suf += ']'
1014 suf += ']'
1015
1015
1016 return [leading + k + suf for k in matches]
1016 return [leading + k + suf for k in matches]
1017
1017
1018 def unicode_name_matches(self, text):
1018 def unicode_name_matches(self, text):
1019 u"""Match Latex-like syntax for unicode characters base
1019 u"""Match Latex-like syntax for unicode characters base
1020 on the name of the character.
1020 on the name of the character.
1021
1021
1022 This does \\GREEK SMALL LETTER ETA -> η
1022 This does \\GREEK SMALL LETTER ETA -> η
1023
1023
1024 Works only on valid python 3 identifier, or on combining characters that
1024 Works only on valid python 3 identifier, or on combining characters that
1025 will combine to form a valid identifier.
1025 will combine to form a valid identifier.
1026
1026
1027 Used on Python 3 only.
1027 Used on Python 3 only.
1028 """
1028 """
1029 slashpos = text.rfind('\\')
1029 slashpos = text.rfind('\\')
1030 if slashpos > -1:
1030 if slashpos > -1:
1031 s = text[slashpos+1:]
1031 s = text[slashpos+1:]
1032 try :
1032 try :
1033 unic = unicodedata.lookup(s)
1033 unic = unicodedata.lookup(s)
1034 # allow combining chars
1034 # allow combining chars
1035 if ('a'+unic).isidentifier():
1035 if ('a'+unic).isidentifier():
1036 return '\\'+s,[unic]
1036 return '\\'+s,[unic]
1037 except KeyError as e:
1037 except KeyError as e:
1038 pass
1038 pass
1039 return u'', []
1039 return u'', []
1040
1040
1041
1041
1042
1042
1043
1043
1044 def latex_matches(self, text):
1044 def latex_matches(self, text):
1045 u"""Match Latex syntax for unicode characters.
1045 u"""Match Latex syntax for unicode characters.
1046
1046
1047 This does both \\alp -> \\alpha and \\alpha -> α
1047 This does both \\alp -> \\alpha and \\alpha -> α
1048
1048
1049 Used on Python 3 only.
1049 Used on Python 3 only.
1050 """
1050 """
1051 slashpos = text.rfind('\\')
1051 slashpos = text.rfind('\\')
1052 if slashpos > -1:
1052 if slashpos > -1:
1053 s = text[slashpos:]
1053 s = text[slashpos:]
1054 if s in latex_symbols:
1054 if s in latex_symbols:
1055 # Try to complete a full latex symbol to unicode
1055 # Try to complete a full latex symbol to unicode
1056 # \\alpha -> α
1056 # \\alpha -> α
1057 return s, [latex_symbols[s]]
1057 return s, [latex_symbols[s]]
1058 else:
1058 else:
1059 # If a user has partially typed a latex symbol, give them
1059 # If a user has partially typed a latex symbol, give them
1060 # a full list of options \al -> [\aleph, \alpha]
1060 # a full list of options \al -> [\aleph, \alpha]
1061 matches = [k for k in latex_symbols if k.startswith(s)]
1061 matches = [k for k in latex_symbols if k.startswith(s)]
1062 return s, matches
1062 return s, matches
1063 return u'', []
1063 return u'', []
1064
1064
1065 def dispatch_custom_completer(self, text):
1065 def dispatch_custom_completer(self, text):
1066 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
1066 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
1067 line = self.line_buffer
1067 line = self.line_buffer
1068 if not line.strip():
1068 if not line.strip():
1069 return None
1069 return None
1070
1070
1071 # Create a little structure to pass all the relevant information about
1071 # Create a little structure to pass all the relevant information about
1072 # the current completion to any custom completer.
1072 # the current completion to any custom completer.
1073 event = Bunch()
1073 event = Bunch()
1074 event.line = line
1074 event.line = line
1075 event.symbol = text
1075 event.symbol = text
1076 cmd = line.split(None,1)[0]
1076 cmd = line.split(None,1)[0]
1077 event.command = cmd
1077 event.command = cmd
1078 event.text_until_cursor = self.text_until_cursor
1078 event.text_until_cursor = self.text_until_cursor
1079
1079
1080 #print "\ncustom:{%s]\n" % event # dbg
1080 #print "\ncustom:{%s]\n" % event # dbg
1081
1081
1082 # for foo etc, try also to find completer for %foo
1082 # for foo etc, try also to find completer for %foo
1083 if not cmd.startswith(self.magic_escape):
1083 if not cmd.startswith(self.magic_escape):
1084 try_magic = self.custom_completers.s_matches(
1084 try_magic = self.custom_completers.s_matches(
1085 self.magic_escape + cmd)
1085 self.magic_escape + cmd)
1086 else:
1086 else:
1087 try_magic = []
1087 try_magic = []
1088
1088
1089 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1089 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1090 try_magic,
1090 try_magic,
1091 self.custom_completers.flat_matches(self.text_until_cursor)):
1091 self.custom_completers.flat_matches(self.text_until_cursor)):
1092 #print "try",c # dbg
1092 #print "try",c # dbg
1093 try:
1093 try:
1094 res = c(event)
1094 res = c(event)
1095 if res:
1095 if res:
1096 # first, try case sensitive match
1096 # first, try case sensitive match
1097 withcase = [r for r in res if r.startswith(text)]
1097 withcase = [r for r in res if r.startswith(text)]
1098 if withcase:
1098 if withcase:
1099 return withcase
1099 return withcase
1100 # if none, then case insensitive ones are ok too
1100 # if none, then case insensitive ones are ok too
1101 text_low = text.lower()
1101 text_low = text.lower()
1102 return [r for r in res if r.lower().startswith(text_low)]
1102 return [r for r in res if r.lower().startswith(text_low)]
1103 except TryNext:
1103 except TryNext:
1104 pass
1104 pass
1105
1105
1106 return None
1106 return None
1107
1107
1108 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1108 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1109 """Find completions for the given text and line context.
1109 """Find completions for the given text and line context.
1110
1110
1111 Note that both the text and the line_buffer are optional, but at least
1111 Note that both the text and the line_buffer are optional, but at least
1112 one of them must be given.
1112 one of them must be given.
1113
1113
1114 Parameters
1114 Parameters
1115 ----------
1115 ----------
1116 text : string, optional
1116 text : string, optional
1117 Text to perform the completion on. If not given, the line buffer
1117 Text to perform the completion on. If not given, the line buffer
1118 is split using the instance's CompletionSplitter object.
1118 is split using the instance's CompletionSplitter object.
1119
1119
1120 line_buffer : string, optional
1120 line_buffer : string, optional
1121 If not given, the completer attempts to obtain the current line
1121 If not given, the completer attempts to obtain the current line
1122 buffer via readline. This keyword allows clients which are
1122 buffer via readline. This keyword allows clients which are
1123 requesting for text completions in non-readline contexts to inform
1123 requesting for text completions in non-readline contexts to inform
1124 the completer of the entire text.
1124 the completer of the entire text.
1125
1125
1126 cursor_pos : int, optional
1126 cursor_pos : int, optional
1127 Index of the cursor in the full line buffer. Should be provided by
1127 Index of the cursor in the full line buffer. Should be provided by
1128 remote frontends where kernel has no access to frontend state.
1128 remote frontends where kernel has no access to frontend state.
1129
1129
1130 Returns
1130 Returns
1131 -------
1131 -------
1132 text : str
1132 text : str
1133 Text that was actually used in the completion.
1133 Text that was actually used in the completion.
1134
1134
1135 matches : list
1135 matches : list
1136 A list of completion matches.
1136 A list of completion matches.
1137 """
1137 """
1138 # io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1138 # io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1139
1139
1140 # if the cursor position isn't given, the only sane assumption we can
1140 # if the cursor position isn't given, the only sane assumption we can
1141 # make is that it's at the end of the line (the common case)
1141 # make is that it's at the end of the line (the common case)
1142 if cursor_pos is None:
1142 if cursor_pos is None:
1143 cursor_pos = len(line_buffer) if text is None else len(text)
1143 cursor_pos = len(line_buffer) if text is None else len(text)
1144
1144
1145 if PY3:
1145 if PY3:
1146
1146
1147 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1147 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1148 latex_text, latex_matches = self.latex_matches(base_text)
1148 latex_text, latex_matches = self.latex_matches(base_text)
1149 if latex_matches:
1149 if latex_matches:
1150 return latex_text, latex_matches
1150 return latex_text, latex_matches
1151 name_text = ''
1151 name_text = ''
1152 name_matches = []
1152 name_matches = []
1153 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1153 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1154 name_text, name_matches = meth(base_text)
1154 name_text, name_matches = meth(base_text)
1155 if name_text:
1155 if name_text:
1156 return name_text, name_matches
1156 return name_text, name_matches
1157
1157
1158 # if text is either None or an empty string, rely on the line buffer
1158 # if text is either None or an empty string, rely on the line buffer
1159 if not text:
1159 if not text:
1160 text = self.splitter.split_line(line_buffer, cursor_pos)
1160 text = self.splitter.split_line(line_buffer, cursor_pos)
1161
1161
1162 # If no line buffer is given, assume the input text is all there was
1162 # If no line buffer is given, assume the input text is all there was
1163 if line_buffer is None:
1163 if line_buffer is None:
1164 line_buffer = text
1164 line_buffer = text
1165
1165
1166 self.line_buffer = line_buffer
1166 self.line_buffer = line_buffer
1167 self.text_until_cursor = self.line_buffer[:cursor_pos]
1167 self.text_until_cursor = self.line_buffer[:cursor_pos]
1168 # io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1168 # io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1169
1169
1170 # Start with a clean slate of completions
1170 # Start with a clean slate of completions
1171 self.matches[:] = []
1171 self.matches[:] = []
1172 custom_res = self.dispatch_custom_completer(text)
1172 custom_res = self.dispatch_custom_completer(text)
1173 if custom_res is not None:
1173 if custom_res is not None:
1174 # did custom completers produce something?
1174 # did custom completers produce something?
1175 self.matches = custom_res
1175 self.matches = custom_res
1176 else:
1176 else:
1177 # Extend the list of completions with the results of each
1177 # Extend the list of completions with the results of each
1178 # matcher, so we return results to the user from all
1178 # matcher, so we return results to the user from all
1179 # namespaces.
1179 # namespaces.
1180 if self.merge_completions:
1180 if self.merge_completions:
1181 self.matches = []
1181 self.matches = []
1182 for matcher in self.matchers:
1182 for matcher in self.matchers:
1183 try:
1183 try:
1184 self.matches.extend(matcher(text))
1184 self.matches.extend(matcher(text))
1185 except:
1185 except:
1186 # Show the ugly traceback if the matcher causes an
1186 # Show the ugly traceback if the matcher causes an
1187 # exception, but do NOT crash the kernel!
1187 # exception, but do NOT crash the kernel!
1188 sys.excepthook(*sys.exc_info())
1188 sys.excepthook(*sys.exc_info())
1189 else:
1189 else:
1190 for matcher in self.matchers:
1190 for matcher in self.matchers:
1191 self.matches = matcher(text)
1191 self.matches = matcher(text)
1192 if self.matches:
1192 if self.matches:
1193 break
1193 break
1194 # FIXME: we should extend our api to return a dict with completions for
1194 # FIXME: we should extend our api to return a dict with completions for
1195 # different types of objects. The rlcomplete() method could then
1195 # different types of objects. The rlcomplete() method could then
1196 # simply collapse the dict into a list for readline, but we'd have
1196 # simply collapse the dict into a list for readline, but we'd have
1197 # richer completion semantics in other evironments.
1197 # richer completion semantics in other evironments.
1198
1198
1199 # use penalize_magics_key to put magics after variables with same name
1199 # use penalize_magics_key to put magics after variables with same name
1200 self.matches = sorted(set(self.matches), key=penalize_magics_key)
1200 self.matches = sorted(set(self.matches), key=penalize_magics_key)
1201
1201
1202 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
1202 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
1203 return text, self.matches
1203 return text, self.matches
1204
1204
1205 def rlcomplete(self, text, state):
1205 def rlcomplete(self, text, state):
1206 """Return the state-th possible completion for 'text'.
1206 """Return the state-th possible completion for 'text'.
1207
1207
1208 This is called successively with state == 0, 1, 2, ... until it
1208 This is called successively with state == 0, 1, 2, ... until it
1209 returns None. The completion should begin with 'text'.
1209 returns None. The completion should begin with 'text'.
1210
1210
1211 Parameters
1211 Parameters
1212 ----------
1212 ----------
1213 text : string
1213 text : string
1214 Text to perform the completion on.
1214 Text to perform the completion on.
1215
1215
1216 state : int
1216 state : int
1217 Counter used by readline.
1217 Counter used by readline.
1218 """
1218 """
1219 if state==0:
1219 if state==0:
1220
1220
1221 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1221 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1222 cursor_pos = self.readline.get_endidx()
1222 cursor_pos = self.readline.get_endidx()
1223
1223
1224 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1224 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1225 # (text, line_buffer, cursor_pos) ) # dbg
1225 # (text, line_buffer, cursor_pos) ) # dbg
1226
1226
1227 # if there is only a tab on a line with only whitespace, instead of
1227 # if there is only a tab on a line with only whitespace, instead of
1228 # the mostly useless 'do you want to see all million completions'
1228 # the mostly useless 'do you want to see all million completions'
1229 # message, just do the right thing and give the user his tab!
1229 # message, just do the right thing and give the user his tab!
1230 # Incidentally, this enables pasting of tabbed text from an editor
1230 # Incidentally, this enables pasting of tabbed text from an editor
1231 # (as long as autoindent is off).
1231 # (as long as autoindent is off).
1232
1232
1233 # It should be noted that at least pyreadline still shows file
1233 # It should be noted that at least pyreadline still shows file
1234 # completions - is there a way around it?
1234 # completions - is there a way around it?
1235
1235
1236 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1236 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1237 # we don't interfere with their own tab-completion mechanism.
1237 # we don't interfere with their own tab-completion mechanism.
1238 if not (self.dumb_terminal or line_buffer.strip()):
1238 if not (self.dumb_terminal or line_buffer.strip()):
1239 self.readline.insert_text('\t')
1239 self.readline.insert_text('\t')
1240 sys.stdout.flush()
1240 sys.stdout.flush()
1241 return None
1241 return None
1242
1242
1243 # Note: debugging exceptions that may occur in completion is very
1243 # Note: debugging exceptions that may occur in completion is very
1244 # tricky, because readline unconditionally silences them. So if
1244 # tricky, because readline unconditionally silences them. So if
1245 # during development you suspect a bug in the completion code, turn
1245 # during development you suspect a bug in the completion code, turn
1246 # this flag on temporarily by uncommenting the second form (don't
1246 # this flag on temporarily by uncommenting the second form (don't
1247 # flip the value in the first line, as the '# dbg' marker can be
1247 # flip the value in the first line, as the '# dbg' marker can be
1248 # automatically detected and is used elsewhere).
1248 # automatically detected and is used elsewhere).
1249 DEBUG = False
1249 DEBUG = False
1250 #DEBUG = True # dbg
1250 #DEBUG = True # dbg
1251 if DEBUG:
1251 if DEBUG:
1252 try:
1252 try:
1253 self.complete(text, line_buffer, cursor_pos)
1253 self.complete(text, line_buffer, cursor_pos)
1254 except:
1254 except:
1255 import traceback; traceback.print_exc()
1255 import traceback; traceback.print_exc()
1256 else:
1256 else:
1257 # The normal production version is here
1257 # The normal production version is here
1258
1258
1259 # This method computes the self.matches array
1259 # This method computes the self.matches array
1260 self.complete(text, line_buffer, cursor_pos)
1260 self.complete(text, line_buffer, cursor_pos)
1261
1261
1262 try:
1262 try:
1263 return self.matches[state]
1263 return self.matches[state]
1264 except IndexError:
1264 except IndexError:
1265 return None
1265 return None
1266
1266
@@ -1,967 +1,967 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Top-level display functions for displaying object in different formats."""
2 """Top-level display functions for displaying object in different formats."""
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 json
9 import json
10 import mimetypes
10 import mimetypes
11 import os
11 import os
12 import struct
12 import struct
13 import warnings
13 import warnings
14
14
15 from IPython.core.formatters import _safe_get_formatter_method
15 from IPython.core.formatters import _safe_get_formatter_method
16 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
16 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
17 unicode_type)
17 unicode_type)
18 from IPython.testing.skipdoctest import skip_doctest
18 from IPython.testing.skipdoctest import skip_doctest
19
19
20 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
20 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
21 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
21 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
22 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
22 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
23 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
23 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
24 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
24 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
25 'publish_display_data']
25 'publish_display_data']
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # utility functions
28 # utility functions
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def _safe_exists(path):
31 def _safe_exists(path):
32 """Check path, but don't let exceptions raise"""
32 """Check path, but don't let exceptions raise"""
33 try:
33 try:
34 return os.path.exists(path)
34 return os.path.exists(path)
35 except Exception:
35 except Exception:
36 return False
36 return False
37
37
38 def _merge(d1, d2):
38 def _merge(d1, d2):
39 """Like update, but merges sub-dicts instead of clobbering at the top level.
39 """Like update, but merges sub-dicts instead of clobbering at the top level.
40
40
41 Updates d1 in-place
41 Updates d1 in-place
42 """
42 """
43
43
44 if not isinstance(d2, dict) or not isinstance(d1, dict):
44 if not isinstance(d2, dict) or not isinstance(d1, dict):
45 return d2
45 return d2
46 for key, value in d2.items():
46 for key, value in d2.items():
47 d1[key] = _merge(d1.get(key), value)
47 d1[key] = _merge(d1.get(key), value)
48 return d1
48 return d1
49
49
50 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
50 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
51 """internal implementation of all display_foo methods
51 """internal implementation of all display_foo methods
52
52
53 Parameters
53 Parameters
54 ----------
54 ----------
55 mimetype : str
55 mimetype : str
56 The mimetype to be published (e.g. 'image/png')
56 The mimetype to be published (e.g. 'image/png')
57 objs : tuple of objects
57 objs : tuple of objects
58 The Python objects to display, or if raw=True raw text data to
58 The Python objects to display, or if raw=True raw text data to
59 display.
59 display.
60 raw : bool
60 raw : bool
61 Are the data objects raw data or Python objects that need to be
61 Are the data objects raw data or Python objects that need to be
62 formatted before display? [default: False]
62 formatted before display? [default: False]
63 metadata : dict (optional)
63 metadata : dict (optional)
64 Metadata to be associated with the specific mimetype output.
64 Metadata to be associated with the specific mimetype output.
65 """
65 """
66 if metadata:
66 if metadata:
67 metadata = {mimetype: metadata}
67 metadata = {mimetype: metadata}
68 if raw:
68 if raw:
69 # turn list of pngdata into list of { 'image/png': pngdata }
69 # turn list of pngdata into list of { 'image/png': pngdata }
70 objs = [ {mimetype: obj} for obj in objs ]
70 objs = [ {mimetype: obj} for obj in objs ]
71 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
71 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
72
72
73 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
74 # Main functions
74 # Main functions
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76
76
77 def publish_display_data(data, metadata=None, source=None):
77 def publish_display_data(data, metadata=None, source=None):
78 """Publish data and metadata to all frontends.
78 """Publish data and metadata to all frontends.
79
79
80 See the ``display_data`` message in the messaging documentation for
80 See the ``display_data`` message in the messaging documentation for
81 more details about this message type.
81 more details about this message type.
82
82
83 The following MIME types are currently implemented:
83 The following MIME types are currently implemented:
84
84
85 * text/plain
85 * text/plain
86 * text/html
86 * text/html
87 * text/markdown
87 * text/markdown
88 * text/latex
88 * text/latex
89 * application/json
89 * application/json
90 * application/javascript
90 * application/javascript
91 * image/png
91 * image/png
92 * image/jpeg
92 * image/jpeg
93 * image/svg+xml
93 * image/svg+xml
94
94
95 Parameters
95 Parameters
96 ----------
96 ----------
97 data : dict
97 data : dict
98 A dictionary having keys that are valid MIME types (like
98 A dictionary having keys that are valid MIME types (like
99 'text/plain' or 'image/svg+xml') and values that are the data for
99 'text/plain' or 'image/svg+xml') and values that are the data for
100 that MIME type. The data itself must be a JSON'able data
100 that MIME type. The data itself must be a JSON'able data
101 structure. Minimally all data should have the 'text/plain' data,
101 structure. Minimally all data should have the 'text/plain' data,
102 which can be displayed by all frontends. If more than the plain
102 which can be displayed by all frontends. If more than the plain
103 text is given, it is up to the frontend to decide which
103 text is given, it is up to the frontend to decide which
104 representation to use.
104 representation to use.
105 metadata : dict
105 metadata : dict
106 A dictionary for metadata related to the data. This can contain
106 A dictionary for metadata related to the data. This can contain
107 arbitrary key, value pairs that frontends can use to interpret
107 arbitrary key, value pairs that frontends can use to interpret
108 the data. mime-type keys matching those in data can be used
108 the data. mime-type keys matching those in data can be used
109 to specify metadata about particular representations.
109 to specify metadata about particular representations.
110 source : str, deprecated
110 source : str, deprecated
111 Unused.
111 Unused.
112 """
112 """
113 from IPython.core.interactiveshell import InteractiveShell
113 from IPython.core.interactiveshell import InteractiveShell
114 InteractiveShell.instance().display_pub.publish(
114 InteractiveShell.instance().display_pub.publish(
115 data=data,
115 data=data,
116 metadata=metadata,
116 metadata=metadata,
117 )
117 )
118
118
119 def display(*objs, **kwargs):
119 def display(*objs, **kwargs):
120 """Display a Python object in all frontends.
120 """Display a Python object in all frontends.
121
121
122 By default all representations will be computed and sent to the frontends.
122 By default all representations will be computed and sent to the frontends.
123 Frontends can decide which representation is used and how.
123 Frontends can decide which representation is used and how.
124
124
125 Parameters
125 Parameters
126 ----------
126 ----------
127 objs : tuple of objects
127 objs : tuple of objects
128 The Python objects to display.
128 The Python objects to display.
129 raw : bool, optional
129 raw : bool, optional
130 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
130 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
131 or Python objects that need to be formatted before display? [default: False]
131 or Python objects that need to be formatted before display? [default: False]
132 include : list or tuple, optional
132 include : list or tuple, optional
133 A list of format type strings (MIME types) to include in the
133 A list of format type strings (MIME types) to include in the
134 format data dict. If this is set *only* the format types included
134 format data dict. If this is set *only* the format types included
135 in this list will be computed.
135 in this list will be computed.
136 exclude : list or tuple, optional
136 exclude : list or tuple, optional
137 A list of format type strings (MIME types) to exclude in the format
137 A list of format type strings (MIME types) to exclude in the format
138 data dict. If this is set all format types will be computed,
138 data dict. If this is set all format types will be computed,
139 except for those included in this argument.
139 except for those included in this argument.
140 metadata : dict, optional
140 metadata : dict, optional
141 A dictionary of metadata to associate with the output.
141 A dictionary of metadata to associate with the output.
142 mime-type keys in this dictionary will be associated with the individual
142 mime-type keys in this dictionary will be associated with the individual
143 representation formats, if they exist.
143 representation formats, if they exist.
144 """
144 """
145 raw = kwargs.get('raw', False)
145 raw = kwargs.get('raw', False)
146 include = kwargs.get('include')
146 include = kwargs.get('include')
147 exclude = kwargs.get('exclude')
147 exclude = kwargs.get('exclude')
148 metadata = kwargs.get('metadata')
148 metadata = kwargs.get('metadata')
149
149
150 from IPython.core.interactiveshell import InteractiveShell
150 from IPython.core.interactiveshell import InteractiveShell
151
151
152 if not raw:
152 if not raw:
153 format = InteractiveShell.instance().display_formatter.format
153 format = InteractiveShell.instance().display_formatter.format
154
154
155 for obj in objs:
155 for obj in objs:
156 if raw:
156 if raw:
157 publish_display_data(data=obj, metadata=metadata)
157 publish_display_data(data=obj, metadata=metadata)
158 else:
158 else:
159 format_dict, md_dict = format(obj, include=include, exclude=exclude)
159 format_dict, md_dict = format(obj, include=include, exclude=exclude)
160 if not format_dict:
160 if not format_dict:
161 # nothing to display (e.g. _ipython_display_ took over)
161 # nothing to display (e.g. _ipython_display_ took over)
162 continue
162 continue
163 if metadata:
163 if metadata:
164 # kwarg-specified metadata gets precedence
164 # kwarg-specified metadata gets precedence
165 _merge(md_dict, metadata)
165 _merge(md_dict, metadata)
166 publish_display_data(data=format_dict, metadata=md_dict)
166 publish_display_data(data=format_dict, metadata=md_dict)
167
167
168
168
169 def display_pretty(*objs, **kwargs):
169 def display_pretty(*objs, **kwargs):
170 """Display the pretty (default) representation of an object.
170 """Display the pretty (default) representation of an object.
171
171
172 Parameters
172 Parameters
173 ----------
173 ----------
174 objs : tuple of objects
174 objs : tuple of objects
175 The Python objects to display, or if raw=True raw text data to
175 The Python objects to display, or if raw=True raw text data to
176 display.
176 display.
177 raw : bool
177 raw : bool
178 Are the data objects raw data or Python objects that need to be
178 Are the data objects raw data or Python objects that need to be
179 formatted before display? [default: False]
179 formatted before display? [default: False]
180 metadata : dict (optional)
180 metadata : dict (optional)
181 Metadata to be associated with the specific mimetype output.
181 Metadata to be associated with the specific mimetype output.
182 """
182 """
183 _display_mimetype('text/plain', objs, **kwargs)
183 _display_mimetype('text/plain', objs, **kwargs)
184
184
185
185
186 def display_html(*objs, **kwargs):
186 def display_html(*objs, **kwargs):
187 """Display the HTML representation of an object.
187 """Display the HTML representation of an object.
188
188
189 Parameters
189 Parameters
190 ----------
190 ----------
191 objs : tuple of objects
191 objs : tuple of objects
192 The Python objects to display, or if raw=True raw HTML data to
192 The Python objects to display, or if raw=True raw HTML data to
193 display.
193 display.
194 raw : bool
194 raw : bool
195 Are the data objects raw data or Python objects that need to be
195 Are the data objects raw data or Python objects that need to be
196 formatted before display? [default: False]
196 formatted before display? [default: False]
197 metadata : dict (optional)
197 metadata : dict (optional)
198 Metadata to be associated with the specific mimetype output.
198 Metadata to be associated with the specific mimetype output.
199 """
199 """
200 _display_mimetype('text/html', objs, **kwargs)
200 _display_mimetype('text/html', objs, **kwargs)
201
201
202
202
203 def display_markdown(*objs, **kwargs):
203 def display_markdown(*objs, **kwargs):
204 """Displays the Markdown representation of an object.
204 """Displays the Markdown representation of an object.
205
205
206 Parameters
206 Parameters
207 ----------
207 ----------
208 objs : tuple of objects
208 objs : tuple of objects
209 The Python objects to display, or if raw=True raw markdown data to
209 The Python objects to display, or if raw=True raw markdown data to
210 display.
210 display.
211 raw : bool
211 raw : bool
212 Are the data objects raw data or Python objects that need to be
212 Are the data objects raw data or Python objects that need to be
213 formatted before display? [default: False]
213 formatted before display? [default: False]
214 metadata : dict (optional)
214 metadata : dict (optional)
215 Metadata to be associated with the specific mimetype output.
215 Metadata to be associated with the specific mimetype output.
216 """
216 """
217
217
218 _display_mimetype('text/markdown', objs, **kwargs)
218 _display_mimetype('text/markdown', objs, **kwargs)
219
219
220
220
221 def display_svg(*objs, **kwargs):
221 def display_svg(*objs, **kwargs):
222 """Display the SVG representation of an object.
222 """Display the SVG representation of an object.
223
223
224 Parameters
224 Parameters
225 ----------
225 ----------
226 objs : tuple of objects
226 objs : tuple of objects
227 The Python objects to display, or if raw=True raw svg data to
227 The Python objects to display, or if raw=True raw svg data to
228 display.
228 display.
229 raw : bool
229 raw : bool
230 Are the data objects raw data or Python objects that need to be
230 Are the data objects raw data or Python objects that need to be
231 formatted before display? [default: False]
231 formatted before display? [default: False]
232 metadata : dict (optional)
232 metadata : dict (optional)
233 Metadata to be associated with the specific mimetype output.
233 Metadata to be associated with the specific mimetype output.
234 """
234 """
235 _display_mimetype('image/svg+xml', objs, **kwargs)
235 _display_mimetype('image/svg+xml', objs, **kwargs)
236
236
237
237
238 def display_png(*objs, **kwargs):
238 def display_png(*objs, **kwargs):
239 """Display the PNG representation of an object.
239 """Display the PNG representation of an object.
240
240
241 Parameters
241 Parameters
242 ----------
242 ----------
243 objs : tuple of objects
243 objs : tuple of objects
244 The Python objects to display, or if raw=True raw png data to
244 The Python objects to display, or if raw=True raw png data to
245 display.
245 display.
246 raw : bool
246 raw : bool
247 Are the data objects raw data or Python objects that need to be
247 Are the data objects raw data or Python objects that need to be
248 formatted before display? [default: False]
248 formatted before display? [default: False]
249 metadata : dict (optional)
249 metadata : dict (optional)
250 Metadata to be associated with the specific mimetype output.
250 Metadata to be associated with the specific mimetype output.
251 """
251 """
252 _display_mimetype('image/png', objs, **kwargs)
252 _display_mimetype('image/png', objs, **kwargs)
253
253
254
254
255 def display_jpeg(*objs, **kwargs):
255 def display_jpeg(*objs, **kwargs):
256 """Display the JPEG representation of an object.
256 """Display the JPEG representation of an object.
257
257
258 Parameters
258 Parameters
259 ----------
259 ----------
260 objs : tuple of objects
260 objs : tuple of objects
261 The Python objects to display, or if raw=True raw JPEG data to
261 The Python objects to display, or if raw=True raw JPEG data to
262 display.
262 display.
263 raw : bool
263 raw : bool
264 Are the data objects raw data or Python objects that need to be
264 Are the data objects raw data or Python objects that need to be
265 formatted before display? [default: False]
265 formatted before display? [default: False]
266 metadata : dict (optional)
266 metadata : dict (optional)
267 Metadata to be associated with the specific mimetype output.
267 Metadata to be associated with the specific mimetype output.
268 """
268 """
269 _display_mimetype('image/jpeg', objs, **kwargs)
269 _display_mimetype('image/jpeg', objs, **kwargs)
270
270
271
271
272 def display_latex(*objs, **kwargs):
272 def display_latex(*objs, **kwargs):
273 """Display the LaTeX representation of an object.
273 """Display the LaTeX representation of an object.
274
274
275 Parameters
275 Parameters
276 ----------
276 ----------
277 objs : tuple of objects
277 objs : tuple of objects
278 The Python objects to display, or if raw=True raw latex data to
278 The Python objects to display, or if raw=True raw latex data to
279 display.
279 display.
280 raw : bool
280 raw : bool
281 Are the data objects raw data or Python objects that need to be
281 Are the data objects raw data or Python objects that need to be
282 formatted before display? [default: False]
282 formatted before display? [default: False]
283 metadata : dict (optional)
283 metadata : dict (optional)
284 Metadata to be associated with the specific mimetype output.
284 Metadata to be associated with the specific mimetype output.
285 """
285 """
286 _display_mimetype('text/latex', objs, **kwargs)
286 _display_mimetype('text/latex', objs, **kwargs)
287
287
288
288
289 def display_json(*objs, **kwargs):
289 def display_json(*objs, **kwargs):
290 """Display the JSON representation of an object.
290 """Display the JSON representation of an object.
291
291
292 Note that not many frontends support displaying JSON.
292 Note that not many frontends support displaying JSON.
293
293
294 Parameters
294 Parameters
295 ----------
295 ----------
296 objs : tuple of objects
296 objs : tuple of objects
297 The Python objects to display, or if raw=True raw json data to
297 The Python objects to display, or if raw=True raw json data to
298 display.
298 display.
299 raw : bool
299 raw : bool
300 Are the data objects raw data or Python objects that need to be
300 Are the data objects raw data or Python objects that need to be
301 formatted before display? [default: False]
301 formatted before display? [default: False]
302 metadata : dict (optional)
302 metadata : dict (optional)
303 Metadata to be associated with the specific mimetype output.
303 Metadata to be associated with the specific mimetype output.
304 """
304 """
305 _display_mimetype('application/json', objs, **kwargs)
305 _display_mimetype('application/json', objs, **kwargs)
306
306
307
307
308 def display_javascript(*objs, **kwargs):
308 def display_javascript(*objs, **kwargs):
309 """Display the Javascript representation of an object.
309 """Display the Javascript representation of an object.
310
310
311 Parameters
311 Parameters
312 ----------
312 ----------
313 objs : tuple of objects
313 objs : tuple of objects
314 The Python objects to display, or if raw=True raw javascript data to
314 The Python objects to display, or if raw=True raw javascript data to
315 display.
315 display.
316 raw : bool
316 raw : bool
317 Are the data objects raw data or Python objects that need to be
317 Are the data objects raw data or Python objects that need to be
318 formatted before display? [default: False]
318 formatted before display? [default: False]
319 metadata : dict (optional)
319 metadata : dict (optional)
320 Metadata to be associated with the specific mimetype output.
320 Metadata to be associated with the specific mimetype output.
321 """
321 """
322 _display_mimetype('application/javascript', objs, **kwargs)
322 _display_mimetype('application/javascript', objs, **kwargs)
323
323
324
324
325 def display_pdf(*objs, **kwargs):
325 def display_pdf(*objs, **kwargs):
326 """Display the PDF representation of an object.
326 """Display the PDF representation of an object.
327
327
328 Parameters
328 Parameters
329 ----------
329 ----------
330 objs : tuple of objects
330 objs : tuple of objects
331 The Python objects to display, or if raw=True raw javascript data to
331 The Python objects to display, or if raw=True raw javascript data to
332 display.
332 display.
333 raw : bool
333 raw : bool
334 Are the data objects raw data or Python objects that need to be
334 Are the data objects raw data or Python objects that need to be
335 formatted before display? [default: False]
335 formatted before display? [default: False]
336 metadata : dict (optional)
336 metadata : dict (optional)
337 Metadata to be associated with the specific mimetype output.
337 Metadata to be associated with the specific mimetype output.
338 """
338 """
339 _display_mimetype('application/pdf', objs, **kwargs)
339 _display_mimetype('application/pdf', objs, **kwargs)
340
340
341
341
342 #-----------------------------------------------------------------------------
342 #-----------------------------------------------------------------------------
343 # Smart classes
343 # Smart classes
344 #-----------------------------------------------------------------------------
344 #-----------------------------------------------------------------------------
345
345
346
346
347 class DisplayObject(object):
347 class DisplayObject(object):
348 """An object that wraps data to be displayed."""
348 """An object that wraps data to be displayed."""
349
349
350 _read_flags = 'r'
350 _read_flags = 'r'
351 _show_mem_addr = False
351 _show_mem_addr = False
352
352
353 def __init__(self, data=None, url=None, filename=None):
353 def __init__(self, data=None, url=None, filename=None):
354 """Create a display object given raw data.
354 """Create a display object given raw data.
355
355
356 When this object is returned by an expression or passed to the
356 When this object is returned by an expression or passed to the
357 display function, it will result in the data being displayed
357 display function, it will result in the data being displayed
358 in the frontend. The MIME type of the data should match the
358 in the frontend. The MIME type of the data should match the
359 subclasses used, so the Png subclass should be used for 'image/png'
359 subclasses used, so the Png subclass should be used for 'image/png'
360 data. If the data is a URL, the data will first be downloaded
360 data. If the data is a URL, the data will first be downloaded
361 and then displayed. If
361 and then displayed. If
362
362
363 Parameters
363 Parameters
364 ----------
364 ----------
365 data : unicode, str or bytes
365 data : unicode, str or bytes
366 The raw data or a URL or file to load the data from
366 The raw data or a URL or file to load the data from
367 url : unicode
367 url : unicode
368 A URL to download the data from.
368 A URL to download the data from.
369 filename : unicode
369 filename : unicode
370 Path to a local file to load the data from.
370 Path to a local file to load the data from.
371 """
371 """
372 if data is not None and isinstance(data, string_types):
372 if data is not None and isinstance(data, string_types):
373 if data.startswith('http') and url is None:
373 if data.startswith('http') and url is None:
374 url = data
374 url = data
375 filename = None
375 filename = None
376 data = None
376 data = None
377 elif _safe_exists(data) and filename is None:
377 elif _safe_exists(data) and filename is None:
378 url = None
378 url = None
379 filename = data
379 filename = data
380 data = None
380 data = None
381
381
382 self.data = data
382 self.data = data
383 self.url = url
383 self.url = url
384 self.filename = None if filename is None else unicode_type(filename)
384 self.filename = None if filename is None else unicode_type(filename)
385
385
386 self.reload()
386 self.reload()
387 self._check_data()
387 self._check_data()
388
388
389 def __repr__(self):
389 def __repr__(self):
390 if not self._show_mem_addr:
390 if not self._show_mem_addr:
391 cls = self.__class__
391 cls = self.__class__
392 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
392 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
393 else:
393 else:
394 r = super(DisplayObject, self).__repr__()
394 r = super(DisplayObject, self).__repr__()
395 return r
395 return r
396
396
397 def _check_data(self):
397 def _check_data(self):
398 """Override in subclasses if there's something to check."""
398 """Override in subclasses if there's something to check."""
399 pass
399 pass
400
400
401 def reload(self):
401 def reload(self):
402 """Reload the raw data from file or URL."""
402 """Reload the raw data from file or URL."""
403 if self.filename is not None:
403 if self.filename is not None:
404 with open(self.filename, self._read_flags) as f:
404 with open(self.filename, self._read_flags) as f:
405 self.data = f.read()
405 self.data = f.read()
406 elif self.url is not None:
406 elif self.url is not None:
407 try:
407 try:
408 try:
408 try:
409 from urllib.request import urlopen # Py3
409 from urllib.request import urlopen # Py3
410 except ImportError:
410 except ImportError:
411 from urllib2 import urlopen
411 from urllib2 import urlopen
412 response = urlopen(self.url)
412 response = urlopen(self.url)
413 self.data = response.read()
413 self.data = response.read()
414 # extract encoding from header, if there is one:
414 # extract encoding from header, if there is one:
415 encoding = None
415 encoding = None
416 for sub in response.headers['content-type'].split(';'):
416 for sub in response.headers['content-type'].split(';'):
417 sub = sub.strip()
417 sub = sub.strip()
418 if sub.startswith('charset'):
418 if sub.startswith('charset'):
419 encoding = sub.split('=')[-1].strip()
419 encoding = sub.split('=')[-1].strip()
420 break
420 break
421 # decode data, if an encoding was specified
421 # decode data, if an encoding was specified
422 if encoding:
422 if encoding:
423 self.data = self.data.decode(encoding, 'replace')
423 self.data = self.data.decode(encoding, 'replace')
424 except:
424 except:
425 self.data = None
425 self.data = None
426
426
427 class TextDisplayObject(DisplayObject):
427 class TextDisplayObject(DisplayObject):
428 """Validate that display data is text"""
428 """Validate that display data is text"""
429 def _check_data(self):
429 def _check_data(self):
430 if self.data is not None and not isinstance(self.data, string_types):
430 if self.data is not None and not isinstance(self.data, string_types):
431 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
431 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
432
432
433 class Pretty(TextDisplayObject):
433 class Pretty(TextDisplayObject):
434
434
435 def _repr_pretty_(self):
435 def _repr_pretty_(self):
436 return self.data
436 return self.data
437
437
438
438
439 class HTML(TextDisplayObject):
439 class HTML(TextDisplayObject):
440
440
441 def _repr_html_(self):
441 def _repr_html_(self):
442 return self.data
442 return self.data
443
443
444 def __html__(self):
444 def __html__(self):
445 """
445 """
446 This method exists to inform other HTML-using modules (e.g. Markupsafe,
446 This method exists to inform other HTML-using modules (e.g. Markupsafe,
447 htmltag, etc) that this object is HTML and does not need things like
447 htmltag, etc) that this object is HTML and does not need things like
448 special characters (<>&) escaped.
448 special characters (<>&) escaped.
449 """
449 """
450 return self._repr_html_()
450 return self._repr_html_()
451
451
452
452
453 class Markdown(TextDisplayObject):
453 class Markdown(TextDisplayObject):
454
454
455 def _repr_markdown_(self):
455 def _repr_markdown_(self):
456 return self.data
456 return self.data
457
457
458
458
459 class Math(TextDisplayObject):
459 class Math(TextDisplayObject):
460
460
461 def _repr_latex_(self):
461 def _repr_latex_(self):
462 s = self.data.strip('$')
462 s = self.data.strip('$')
463 return "$$%s$$" % s
463 return "$$%s$$" % s
464
464
465
465
466 class Latex(TextDisplayObject):
466 class Latex(TextDisplayObject):
467
467
468 def _repr_latex_(self):
468 def _repr_latex_(self):
469 return self.data
469 return self.data
470
470
471
471
472 class SVG(DisplayObject):
472 class SVG(DisplayObject):
473
473
474 # wrap data in a property, which extracts the <svg> tag, discarding
474 # wrap data in a property, which extracts the <svg> tag, discarding
475 # document headers
475 # document headers
476 _data = None
476 _data = None
477
477
478 @property
478 @property
479 def data(self):
479 def data(self):
480 return self._data
480 return self._data
481
481
482 @data.setter
482 @data.setter
483 def data(self, svg):
483 def data(self, svg):
484 if svg is None:
484 if svg is None:
485 self._data = None
485 self._data = None
486 return
486 return
487 # parse into dom object
487 # parse into dom object
488 from xml.dom import minidom
488 from xml.dom import minidom
489 svg = cast_bytes_py2(svg)
489 svg = cast_bytes_py2(svg)
490 x = minidom.parseString(svg)
490 x = minidom.parseString(svg)
491 # get svg tag (should be 1)
491 # get svg tag (should be 1)
492 found_svg = x.getElementsByTagName('svg')
492 found_svg = x.getElementsByTagName('svg')
493 if found_svg:
493 if found_svg:
494 svg = found_svg[0].toxml()
494 svg = found_svg[0].toxml()
495 else:
495 else:
496 # fallback on the input, trust the user
496 # fallback on the input, trust the user
497 # but this is probably an error.
497 # but this is probably an error.
498 pass
498 pass
499 svg = cast_unicode(svg)
499 svg = cast_unicode(svg)
500 self._data = svg
500 self._data = svg
501
501
502 def _repr_svg_(self):
502 def _repr_svg_(self):
503 return self.data
503 return self.data
504
504
505
505
506 class JSON(DisplayObject):
506 class JSON(DisplayObject):
507 """JSON expects a JSON-able dict or list
507 """JSON expects a JSON-able dict or list
508
508
509 not an already-serialized JSON string.
509 not an already-serialized JSON string.
510
510
511 Scalar types (None, number, string) are not allowed, only dict or list containers.
511 Scalar types (None, number, string) are not allowed, only dict or list containers.
512 """
512 """
513 # wrap data in a property, which warns about passing already-serialized JSON
513 # wrap data in a property, which warns about passing already-serialized JSON
514 _data = None
514 _data = None
515 def _check_data(self):
515 def _check_data(self):
516 if self.data is not None and not isinstance(self.data, (dict, list)):
516 if self.data is not None and not isinstance(self.data, (dict, list)):
517 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
517 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
518
518
519 @property
519 @property
520 def data(self):
520 def data(self):
521 return self._data
521 return self._data
522
522
523 @data.setter
523 @data.setter
524 def data(self, data):
524 def data(self, data):
525 if isinstance(data, string_types):
525 if isinstance(data, string_types):
526 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
526 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
527 data = json.loads(data)
527 data = json.loads(data)
528 self._data = data
528 self._data = data
529
529
530 def _repr_json_(self):
530 def _repr_json_(self):
531 return self.data
531 return self.data
532
532
533 css_t = """$("head").append($("<link/>").attr({
533 css_t = """$("head").append($("<link/>").attr({
534 rel: "stylesheet",
534 rel: "stylesheet",
535 type: "text/css",
535 type: "text/css",
536 href: "%s"
536 href: "%s"
537 }));
537 }));
538 """
538 """
539
539
540 lib_t1 = """$.getScript("%s", function () {
540 lib_t1 = """$.getScript("%s", function () {
541 """
541 """
542 lib_t2 = """});
542 lib_t2 = """});
543 """
543 """
544
544
545 class Javascript(TextDisplayObject):
545 class Javascript(TextDisplayObject):
546
546
547 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
547 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
548 """Create a Javascript display object given raw data.
548 """Create a Javascript display object given raw data.
549
549
550 When this object is returned by an expression or passed to the
550 When this object is returned by an expression or passed to the
551 display function, it will result in the data being displayed
551 display function, it will result in the data being displayed
552 in the frontend. If the data is a URL, the data will first be
552 in the frontend. If the data is a URL, the data will first be
553 downloaded and then displayed.
553 downloaded and then displayed.
554
554
555 In the Notebook, the containing element will be available as `element`,
555 In the Notebook, the containing element will be available as `element`,
556 and jQuery will be available. Content appended to `element` will be
556 and jQuery will be available. Content appended to `element` will be
557 visible in the output area.
557 visible in the output area.
558
558
559 Parameters
559 Parameters
560 ----------
560 ----------
561 data : unicode, str or bytes
561 data : unicode, str or bytes
562 The Javascript source code or a URL to download it from.
562 The Javascript source code or a URL to download it from.
563 url : unicode
563 url : unicode
564 A URL to download the data from.
564 A URL to download the data from.
565 filename : unicode
565 filename : unicode
566 Path to a local file to load the data from.
566 Path to a local file to load the data from.
567 lib : list or str
567 lib : list or str
568 A sequence of Javascript library URLs to load asynchronously before
568 A sequence of Javascript library URLs to load asynchronously before
569 running the source code. The full URLs of the libraries should
569 running the source code. The full URLs of the libraries should
570 be given. A single Javascript library URL can also be given as a
570 be given. A single Javascript library URL can also be given as a
571 string.
571 string.
572 css: : list or str
572 css: : list or str
573 A sequence of css files to load before running the source code.
573 A sequence of css files to load before running the source code.
574 The full URLs of the css files should be given. A single css URL
574 The full URLs of the css files should be given. A single css URL
575 can also be given as a string.
575 can also be given as a string.
576 """
576 """
577 if isinstance(lib, string_types):
577 if isinstance(lib, string_types):
578 lib = [lib]
578 lib = [lib]
579 elif lib is None:
579 elif lib is None:
580 lib = []
580 lib = []
581 if isinstance(css, string_types):
581 if isinstance(css, string_types):
582 css = [css]
582 css = [css]
583 elif css is None:
583 elif css is None:
584 css = []
584 css = []
585 if not isinstance(lib, (list,tuple)):
585 if not isinstance(lib, (list,tuple)):
586 raise TypeError('expected sequence, got: %r' % lib)
586 raise TypeError('expected sequence, got: %r' % lib)
587 if not isinstance(css, (list,tuple)):
587 if not isinstance(css, (list,tuple)):
588 raise TypeError('expected sequence, got: %r' % css)
588 raise TypeError('expected sequence, got: %r' % css)
589 self.lib = lib
589 self.lib = lib
590 self.css = css
590 self.css = css
591 super(Javascript, self).__init__(data=data, url=url, filename=filename)
591 super(Javascript, self).__init__(data=data, url=url, filename=filename)
592
592
593 def _repr_javascript_(self):
593 def _repr_javascript_(self):
594 r = ''
594 r = ''
595 for c in self.css:
595 for c in self.css:
596 r += css_t % c
596 r += css_t % c
597 for l in self.lib:
597 for l in self.lib:
598 r += lib_t1 % l
598 r += lib_t1 % l
599 r += self.data
599 r += self.data
600 r += lib_t2*len(self.lib)
600 r += lib_t2*len(self.lib)
601 return r
601 return r
602
602
603 # constants for identifying png/jpeg data
603 # constants for identifying png/jpeg data
604 _PNG = b'\x89PNG\r\n\x1a\n'
604 _PNG = b'\x89PNG\r\n\x1a\n'
605 _JPEG = b'\xff\xd8'
605 _JPEG = b'\xff\xd8'
606
606
607 def _pngxy(data):
607 def _pngxy(data):
608 """read the (width, height) from a PNG header"""
608 """read the (width, height) from a PNG header"""
609 ihdr = data.index(b'IHDR')
609 ihdr = data.index(b'IHDR')
610 # next 8 bytes are width/height
610 # next 8 bytes are width/height
611 w4h4 = data[ihdr+4:ihdr+12]
611 w4h4 = data[ihdr+4:ihdr+12]
612 return struct.unpack('>ii', w4h4)
612 return struct.unpack('>ii', w4h4)
613
613
614 def _jpegxy(data):
614 def _jpegxy(data):
615 """read the (width, height) from a JPEG header"""
615 """read the (width, height) from a JPEG header"""
616 # adapted from http://www.64lines.com/jpeg-width-height
616 # adapted from http://www.64lines.com/jpeg-width-height
617
617
618 idx = 4
618 idx = 4
619 while True:
619 while True:
620 block_size = struct.unpack('>H', data[idx:idx+2])[0]
620 block_size = struct.unpack('>H', data[idx:idx+2])[0]
621 idx = idx + block_size
621 idx = idx + block_size
622 if data[idx:idx+2] == b'\xFF\xC0':
622 if data[idx:idx+2] == b'\xFF\xC0':
623 # found Start of Frame
623 # found Start of Frame
624 iSOF = idx
624 iSOF = idx
625 break
625 break
626 else:
626 else:
627 # read another block
627 # read another block
628 idx += 2
628 idx += 2
629
629
630 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
630 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
631 return w, h
631 return w, h
632
632
633 class Image(DisplayObject):
633 class Image(DisplayObject):
634
634
635 _read_flags = 'rb'
635 _read_flags = 'rb'
636 _FMT_JPEG = u'jpeg'
636 _FMT_JPEG = u'jpeg'
637 _FMT_PNG = u'png'
637 _FMT_PNG = u'png'
638 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
638 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
639
639
640 def __init__(self, data=None, url=None, filename=None, format=u'png',
640 def __init__(self, data=None, url=None, filename=None, format=u'png',
641 embed=None, width=None, height=None, retina=False,
641 embed=None, width=None, height=None, retina=False,
642 unconfined=False, metadata=None):
642 unconfined=False, metadata=None):
643 """Create a PNG/JPEG image object given raw data.
643 """Create a PNG/JPEG image object given raw data.
644
644
645 When this object is returned by an input cell or passed to the
645 When this object is returned by an input cell or passed to the
646 display function, it will result in the image being displayed
646 display function, it will result in the image being displayed
647 in the frontend.
647 in the frontend.
648
648
649 Parameters
649 Parameters
650 ----------
650 ----------
651 data : unicode, str or bytes
651 data : unicode, str or bytes
652 The raw image data or a URL or filename to load the data from.
652 The raw image data or a URL or filename to load the data from.
653 This always results in embedded image data.
653 This always results in embedded image data.
654 url : unicode
654 url : unicode
655 A URL to download the data from. If you specify `url=`,
655 A URL to download the data from. If you specify `url=`,
656 the image data will not be embedded unless you also specify `embed=True`.
656 the image data will not be embedded unless you also specify `embed=True`.
657 filename : unicode
657 filename : unicode
658 Path to a local file to load the data from.
658 Path to a local file to load the data from.
659 Images from a file are always embedded.
659 Images from a file are always embedded.
660 format : unicode
660 format : unicode
661 The format of the image data (png/jpeg/jpg). If a filename or URL is given
661 The format of the image data (png/jpeg/jpg). If a filename or URL is given
662 for format will be inferred from the filename extension.
662 for format will be inferred from the filename extension.
663 embed : bool
663 embed : bool
664 Should the image data be embedded using a data URI (True) or be
664 Should the image data be embedded using a data URI (True) or be
665 loaded using an <img> tag. Set this to True if you want the image
665 loaded using an <img> tag. Set this to True if you want the image
666 to be viewable later with no internet connection in the notebook.
666 to be viewable later with no internet connection in the notebook.
667
667
668 Default is `True`, unless the keyword argument `url` is set, then
668 Default is `True`, unless the keyword argument `url` is set, then
669 default value is `False`.
669 default value is `False`.
670
670
671 Note that QtConsole is not able to display images if `embed` is set to `False`
671 Note that QtConsole is not able to display images if `embed` is set to `False`
672 width : int
672 width : int
673 Width to which to constrain the image in html
673 Width to which to constrain the image in html
674 height : int
674 height : int
675 Height to which to constrain the image in html
675 Height to which to constrain the image in html
676 retina : bool
676 retina : bool
677 Automatically set the width and height to half of the measured
677 Automatically set the width and height to half of the measured
678 width and height.
678 width and height.
679 This only works for embedded images because it reads the width/height
679 This only works for embedded images because it reads the width/height
680 from image data.
680 from image data.
681 For non-embedded images, you can just set the desired display width
681 For non-embedded images, you can just set the desired display width
682 and height directly.
682 and height directly.
683 unconfined: bool
683 unconfined: bool
684 Set unconfined=True to disable max-width confinement of the image.
684 Set unconfined=True to disable max-width confinement of the image.
685 metadata: dict
685 metadata: dict
686 Specify extra metadata to attach to the image.
686 Specify extra metadata to attach to the image.
687
687
688 Examples
688 Examples
689 --------
689 --------
690 # embedded image data, works in qtconsole and notebook
690 # embedded image data, works in qtconsole and notebook
691 # when passed positionally, the first arg can be any of raw image data,
691 # when passed positionally, the first arg can be any of raw image data,
692 # a URL, or a filename from which to load image data.
692 # a URL, or a filename from which to load image data.
693 # The result is always embedding image data for inline images.
693 # The result is always embedding image data for inline images.
694 Image('http://www.google.fr/images/srpr/logo3w.png')
694 Image('http://www.google.fr/images/srpr/logo3w.png')
695 Image('/path/to/image.jpg')
695 Image('/path/to/image.jpg')
696 Image(b'RAW_PNG_DATA...')
696 Image(b'RAW_PNG_DATA...')
697
697
698 # Specifying Image(url=...) does not embed the image data,
698 # Specifying Image(url=...) does not embed the image data,
699 # it only generates `<img>` tag with a link to the source.
699 # it only generates `<img>` tag with a link to the source.
700 # This will not work in the qtconsole or offline.
700 # This will not work in the qtconsole or offline.
701 Image(url='http://www.google.fr/images/srpr/logo3w.png')
701 Image(url='http://www.google.fr/images/srpr/logo3w.png')
702
702
703 """
703 """
704 if filename is not None:
704 if filename is not None:
705 ext = self._find_ext(filename)
705 ext = self._find_ext(filename)
706 elif url is not None:
706 elif url is not None:
707 ext = self._find_ext(url)
707 ext = self._find_ext(url)
708 elif data is None:
708 elif data is None:
709 raise ValueError("No image data found. Expecting filename, url, or data.")
709 raise ValueError("No image data found. Expecting filename, url, or data.")
710 elif isinstance(data, string_types) and (
710 elif isinstance(data, string_types) and (
711 data.startswith('http') or _safe_exists(data)
711 data.startswith('http') or _safe_exists(data)
712 ):
712 ):
713 ext = self._find_ext(data)
713 ext = self._find_ext(data)
714 else:
714 else:
715 ext = None
715 ext = None
716
716
717 if ext is not None:
717 if ext is not None:
718 format = ext.lower()
718 format = ext.lower()
719 if ext == u'jpg' or ext == u'jpeg':
719 if ext == u'jpg' or ext == u'jpeg':
720 format = self._FMT_JPEG
720 format = self._FMT_JPEG
721 if ext == u'png':
721 if ext == u'png':
722 format = self._FMT_PNG
722 format = self._FMT_PNG
723 elif isinstance(data, bytes) and format == 'png':
723 elif isinstance(data, bytes) and format == 'png':
724 # infer image type from image data header,
724 # infer image type from image data header,
725 # only if format might not have been specified.
725 # only if format might not have been specified.
726 if data[:2] == _JPEG:
726 if data[:2] == _JPEG:
727 format = 'jpeg'
727 format = 'jpeg'
728
728
729 self.format = unicode_type(format).lower()
729 self.format = unicode_type(format).lower()
730 self.embed = embed if embed is not None else (url is None)
730 self.embed = embed if embed is not None else (url is None)
731
731
732 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
732 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
733 raise ValueError("Cannot embed the '%s' image format" % (self.format))
733 raise ValueError("Cannot embed the '%s' image format" % (self.format))
734 self.width = width
734 self.width = width
735 self.height = height
735 self.height = height
736 self.retina = retina
736 self.retina = retina
737 self.unconfined = unconfined
737 self.unconfined = unconfined
738 self.metadata = metadata
738 self.metadata = metadata
739 super(Image, self).__init__(data=data, url=url, filename=filename)
739 super(Image, self).__init__(data=data, url=url, filename=filename)
740
740
741 if retina:
741 if retina:
742 self._retina_shape()
742 self._retina_shape()
743
743
744 def _retina_shape(self):
744 def _retina_shape(self):
745 """load pixel-doubled width and height from image data"""
745 """load pixel-doubled width and height from image data"""
746 if not self.embed:
746 if not self.embed:
747 return
747 return
748 if self.format == 'png':
748 if self.format == 'png':
749 w, h = _pngxy(self.data)
749 w, h = _pngxy(self.data)
750 elif self.format == 'jpeg':
750 elif self.format == 'jpeg':
751 w, h = _jpegxy(self.data)
751 w, h = _jpegxy(self.data)
752 else:
752 else:
753 # retina only supports png
753 # retina only supports png
754 return
754 return
755 self.width = w // 2
755 self.width = w // 2
756 self.height = h // 2
756 self.height = h // 2
757
757
758 def reload(self):
758 def reload(self):
759 """Reload the raw data from file or URL."""
759 """Reload the raw data from file or URL."""
760 if self.embed:
760 if self.embed:
761 super(Image,self).reload()
761 super(Image,self).reload()
762 if self.retina:
762 if self.retina:
763 self._retina_shape()
763 self._retina_shape()
764
764
765 def _repr_html_(self):
765 def _repr_html_(self):
766 if not self.embed:
766 if not self.embed:
767 width = height = klass = ''
767 width = height = klass = ''
768 if self.width:
768 if self.width:
769 width = ' width="%d"' % self.width
769 width = ' width="%d"' % self.width
770 if self.height:
770 if self.height:
771 height = ' height="%d"' % self.height
771 height = ' height="%d"' % self.height
772 if self.unconfined:
772 if self.unconfined:
773 klass = ' class="unconfined"'
773 klass = ' class="unconfined"'
774 return u'<img src="{url}"{width}{height}{klass}/>'.format(
774 return u'<img src="{url}"{width}{height}{klass}/>'.format(
775 url=self.url,
775 url=self.url,
776 width=width,
776 width=width,
777 height=height,
777 height=height,
778 klass=klass,
778 klass=klass,
779 )
779 )
780
780
781 def _data_and_metadata(self):
781 def _data_and_metadata(self):
782 """shortcut for returning metadata with shape information, if defined"""
782 """shortcut for returning metadata with shape information, if defined"""
783 md = {}
783 md = {}
784 if self.width:
784 if self.width:
785 md['width'] = self.width
785 md['width'] = self.width
786 if self.height:
786 if self.height:
787 md['height'] = self.height
787 md['height'] = self.height
788 if self.unconfined:
788 if self.unconfined:
789 md['unconfined'] = self.unconfined
789 md['unconfined'] = self.unconfined
790 if self.metadata:
790 if self.metadata:
791 md.update(self.metadata)
791 md.update(self.metadata)
792 if md:
792 if md:
793 return self.data, md
793 return self.data, md
794 else:
794 else:
795 return self.data
795 return self.data
796
796
797 def _repr_png_(self):
797 def _repr_png_(self):
798 if self.embed and self.format == u'png':
798 if self.embed and self.format == u'png':
799 return self._data_and_metadata()
799 return self._data_and_metadata()
800
800
801 def _repr_jpeg_(self):
801 def _repr_jpeg_(self):
802 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
802 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
803 return self._data_and_metadata()
803 return self._data_and_metadata()
804
804
805 def _find_ext(self, s):
805 def _find_ext(self, s):
806 return unicode_type(s.split('.')[-1].lower())
806 return unicode_type(s.split('.')[-1].lower())
807
807
808 class Video(DisplayObject):
808 class Video(DisplayObject):
809
809
810 def __init__(self, data=None, url=None, filename=None, embed=None, mimetype=None):
810 def __init__(self, data=None, url=None, filename=None, embed=None, mimetype=None):
811 """Create a video object given raw data or an URL.
811 """Create a video object given raw data or an URL.
812
812
813 When this object is returned by an input cell or passed to the
813 When this object is returned by an input cell or passed to the
814 display function, it will result in the video being displayed
814 display function, it will result in the video being displayed
815 in the frontend.
815 in the frontend.
816
816
817 Parameters
817 Parameters
818 ----------
818 ----------
819 data : unicode, str or bytes
819 data : unicode, str or bytes
820 The raw image data or a URL or filename to load the data from.
820 The raw image data or a URL or filename to load the data from.
821 This always results in embedded image data.
821 This always results in embedded image data.
822 url : unicode
822 url : unicode
823 A URL to download the data from. If you specify `url=`,
823 A URL to download the data from. If you specify `url=`,
824 the image data will not be embedded unless you also specify `embed=True`.
824 the image data will not be embedded unless you also specify `embed=True`.
825 filename : unicode
825 filename : unicode
826 Path to a local file to load the data from.
826 Path to a local file to load the data from.
827 Videos from a file are always embedded.
827 Videos from a file are always embedded.
828 embed : bool
828 embed : bool
829 Should the image data be embedded using a data URI (True) or be
829 Should the image data be embedded using a data URI (True) or be
830 loaded using an <img> tag. Set this to True if you want the image
830 loaded using an <img> tag. Set this to True if you want the image
831 to be viewable later with no internet connection in the notebook.
831 to be viewable later with no internet connection in the notebook.
832
832
833 Default is `True`, unless the keyword argument `url` is set, then
833 Default is `True`, unless the keyword argument `url` is set, then
834 default value is `False`.
834 default value is `False`.
835
835
836 Note that QtConsole is not able to display images if `embed` is set to `False`
836 Note that QtConsole is not able to display images if `embed` is set to `False`
837 mimetype: unicode
837 mimetype: unicode
838 Specify the mimetype in case you load in a encoded video.
838 Specify the mimetype in case you load in a encoded video.
839 Examples
839 Examples
840 --------
840 --------
841 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
841 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
842 Video('path/to/video.mp4')
842 Video('path/to/video.mp4')
843 Video('path/to/video.mp4', embed=False)
843 Video('path/to/video.mp4', embed=False)
844 """
844 """
845 if url is None and (data.startswith('http') or data.startswith('https')):
845 if url is None and (data.startswith('http') or data.startswith('https')):
846 url = data
846 url = data
847 data = None
847 data = None
848 embed = False
848 embed = False
849 elif os.path.exists(data):
849 elif os.path.exists(data):
850 filename = data
850 filename = data
851 data = None
851 data = None
852
852
853 self.mimetype = mimetype
853 self.mimetype = mimetype
854 self.embed = embed if embed is not None else (filename is not None)
854 self.embed = embed if embed is not None else (filename is not None)
855 super(Video, self).__init__(data=data, url=url, filename=filename)
855 super(Video, self).__init__(data=data, url=url, filename=filename)
856
856
857 def _repr_html_(self):
857 def _repr_html_(self):
858 # External URLs and potentially local files are not embedded into the
858 # External URLs and potentially local files are not embedded into the
859 # notebook output.
859 # notebook output.
860 if not self.embed:
860 if not self.embed:
861 url = self.url if self.url is not None else self.filename
861 url = self.url if self.url is not None else self.filename
862 output = """<video src="{0}" controls>
862 output = """<video src="{0}" controls>
863 Your browser does not support the <code>video</code> element.
863 Your browser does not support the <code>video</code> element.
864 </video>""".format(url)
864 </video>""".format(url)
865 return output
865 return output
866 # Embedded videos uses base64 encoded videos.
866 # Embedded videos uses base64 encoded videos.
867 if self.filename is not None:
867 if self.filename is not None:
868 mimetypes.init()
868 mimetypes.init()
869 mimetype, encoding = mimetypes.guess_type(self.filename)
869 mimetype, encoding = mimetypes.guess_type(self.filename)
870
870
871 video = open(self.filename, 'rb').read()
871 video = open(self.filename, 'rb').read()
872 video_encoded = video.encode('base64')
872 video_encoded = video.encode('base64')
873 else:
873 else:
874 video_encoded = self.data
874 video_encoded = self.data
875 mimetype = self.mimetype
875 mimetype = self.mimetype
876 output = """<video controls>
876 output = """<video controls>
877 <source src="data:{0};base64,{1}" type="{0}">
877 <source src="data:{0};base64,{1}" type="{0}">
878 Your browser does not support the video tag.
878 Your browser does not support the video tag.
879 </video>""".format(mimetype, video_encoded)
879 </video>""".format(mimetype, video_encoded)
880 return output
880 return output
881
881
882 def reload(self):
882 def reload(self):
883 # TODO
883 # TODO
884 pass
884 pass
885
885
886 def _repr_png_(self):
886 def _repr_png_(self):
887 # TODO
887 # TODO
888 pass
888 pass
889 def _repr_jpeg_(self):
889 def _repr_jpeg_(self):
890 # TODO
890 # TODO
891 pass
891 pass
892
892
893 def clear_output(wait=False):
893 def clear_output(wait=False):
894 """Clear the output of the current cell receiving output.
894 """Clear the output of the current cell receiving output.
895
895
896 Parameters
896 Parameters
897 ----------
897 ----------
898 wait : bool [default: false]
898 wait : bool [default: false]
899 Wait to clear the output until new output is available to replace it."""
899 Wait to clear the output until new output is available to replace it."""
900 from IPython.core.interactiveshell import InteractiveShell
900 from IPython.core.interactiveshell import InteractiveShell
901 if InteractiveShell.initialized():
901 if InteractiveShell.initialized():
902 InteractiveShell.instance().display_pub.clear_output(wait)
902 InteractiveShell.instance().display_pub.clear_output(wait)
903 else:
903 else:
904 from IPython.utils import io
904 from IPython.utils import io
905 print('\033[2K\r', file=io.stdout, end='')
905 print('\033[2K\r', file=io.stdout, end='')
906 io.stdout.flush()
906 io.stdout.flush()
907 print('\033[2K\r', file=io.stderr, end='')
907 print('\033[2K\r', file=io.stderr, end='')
908 io.stderr.flush()
908 io.stderr.flush()
909
909
910
910
911 @skip_doctest
911 @skip_doctest
912 def set_matplotlib_formats(*formats, **kwargs):
912 def set_matplotlib_formats(*formats, **kwargs):
913 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
913 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
914
914
915 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
915 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
916
916
917 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
917 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
918
918
919 To set this in your config files use the following::
919 To set this in your config files use the following::
920
920
921 c.InlineBackend.figure_formats = {'png', 'jpeg'}
921 c.InlineBackend.figure_formats = {'png', 'jpeg'}
922 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
922 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
923
923
924 Parameters
924 Parameters
925 ----------
925 ----------
926 *formats : strs
926 *formats : strs
927 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
927 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
928 **kwargs :
928 **kwargs :
929 Keyword args will be relayed to ``figure.canvas.print_figure``.
929 Keyword args will be relayed to ``figure.canvas.print_figure``.
930 """
930 """
931 from IPython.core.interactiveshell import InteractiveShell
931 from IPython.core.interactiveshell import InteractiveShell
932 from IPython.core.pylabtools import select_figure_formats
932 from IPython.core.pylabtools import select_figure_formats
933 from IPython.kernel.zmq.pylab.config import InlineBackend
934 # build kwargs, starting with InlineBackend config
933 # build kwargs, starting with InlineBackend config
935 kw = {}
934 kw = {}
935 from ipython_kernel.pylab.config import InlineBackend
936 cfg = InlineBackend.instance()
936 cfg = InlineBackend.instance()
937 kw.update(cfg.print_figure_kwargs)
937 kw.update(cfg.print_figure_kwargs)
938 kw.update(**kwargs)
938 kw.update(**kwargs)
939 shell = InteractiveShell.instance()
939 shell = InteractiveShell.instance()
940 select_figure_formats(shell, formats, **kw)
940 select_figure_formats(shell, formats, **kw)
941
941
942 @skip_doctest
942 @skip_doctest
943 def set_matplotlib_close(close=True):
943 def set_matplotlib_close(close=True):
944 """Set whether the inline backend closes all figures automatically or not.
944 """Set whether the inline backend closes all figures automatically or not.
945
945
946 By default, the inline backend used in the IPython Notebook will close all
946 By default, the inline backend used in the IPython Notebook will close all
947 matplotlib figures automatically after each cell is run. This means that
947 matplotlib figures automatically after each cell is run. This means that
948 plots in different cells won't interfere. Sometimes, you may want to make
948 plots in different cells won't interfere. Sometimes, you may want to make
949 a plot in one cell and then refine it in later cells. This can be accomplished
949 a plot in one cell and then refine it in later cells. This can be accomplished
950 by::
950 by::
951
951
952 In [1]: set_matplotlib_close(False)
952 In [1]: set_matplotlib_close(False)
953
953
954 To set this in your config files use the following::
954 To set this in your config files use the following::
955
955
956 c.InlineBackend.close_figures = False
956 c.InlineBackend.close_figures = False
957
957
958 Parameters
958 Parameters
959 ----------
959 ----------
960 close : bool
960 close : bool
961 Should all matplotlib figures be automatically closed after each cell is
961 Should all matplotlib figures be automatically closed after each cell is
962 run?
962 run?
963 """
963 """
964 from IPython.kernel.zmq.pylab.config import InlineBackend
964 from ipython_kernel.pylab.config import InlineBackend
965 cfg = InlineBackend.instance()
965 cfg = InlineBackend.instance()
966 cfg.close_figures = close
966 cfg.close_figures = close
967
967
@@ -1,70 +1,70 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A context manager for handling sys.displayhook.
3 A context manager for handling sys.displayhook.
4
4
5 Authors:
5 Authors:
6
6
7 * Robert Kern
7 * Robert Kern
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. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import sys
22 import sys
23
23
24 from IPython.config.configurable import Configurable
24 from traitlets.config.configurable import Configurable
25 from IPython.utils.traitlets import Any
25 from traitlets import Any
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Classes and functions
28 # Classes and functions
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31
31
32 class DisplayTrap(Configurable):
32 class DisplayTrap(Configurable):
33 """Object to manage sys.displayhook.
33 """Object to manage sys.displayhook.
34
34
35 This came from IPython.core.kernel.display_hook, but is simplified
35 This came from IPython.core.kernel.display_hook, but is simplified
36 (no callbacks or formatters) until more of the core is refactored.
36 (no callbacks or formatters) until more of the core is refactored.
37 """
37 """
38
38
39 hook = Any
39 hook = Any
40
40
41 def __init__(self, hook=None):
41 def __init__(self, hook=None):
42 super(DisplayTrap, self).__init__(hook=hook, config=None)
42 super(DisplayTrap, self).__init__(hook=hook, config=None)
43 self.old_hook = None
43 self.old_hook = None
44 # We define this to track if a single BuiltinTrap is nested.
44 # We define this to track if a single BuiltinTrap is nested.
45 # Only turn off the trap when the outermost call to __exit__ is made.
45 # Only turn off the trap when the outermost call to __exit__ is made.
46 self._nested_level = 0
46 self._nested_level = 0
47
47
48 def __enter__(self):
48 def __enter__(self):
49 if self._nested_level == 0:
49 if self._nested_level == 0:
50 self.set()
50 self.set()
51 self._nested_level += 1
51 self._nested_level += 1
52 return self
52 return self
53
53
54 def __exit__(self, type, value, traceback):
54 def __exit__(self, type, value, traceback):
55 if self._nested_level == 1:
55 if self._nested_level == 1:
56 self.unset()
56 self.unset()
57 self._nested_level -= 1
57 self._nested_level -= 1
58 # Returning False will cause exceptions to propagate
58 # Returning False will cause exceptions to propagate
59 return False
59 return False
60
60
61 def set(self):
61 def set(self):
62 """Set the hook."""
62 """Set the hook."""
63 if sys.displayhook is not self.hook:
63 if sys.displayhook is not self.hook:
64 self.old_hook = sys.displayhook
64 self.old_hook = sys.displayhook
65 sys.displayhook = self.hook
65 sys.displayhook = self.hook
66
66
67 def unset(self):
67 def unset(self):
68 """Unset the hook."""
68 """Unset the hook."""
69 sys.displayhook = self.old_hook
69 sys.displayhook = self.old_hook
70
70
@@ -1,283 +1,283 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
13
14 from IPython.core.formatters import _safe_get_formatter_method
14 from IPython.core.formatters import _safe_get_formatter_method
15 from IPython.config.configurable import Configurable
15 from traitlets.config.configurable import Configurable
16 from IPython.utils import io
16 from IPython.utils import io
17 from IPython.utils.py3compat import builtin_mod
17 from IPython.utils.py3compat import builtin_mod
18 from IPython.utils.traitlets import Instance, Float
18 from traitlets import Instance, Float
19 from IPython.utils.warn import warn
19 from IPython.utils.warn import warn
20
20
21 # TODO: Move the various attributes (cache_size, [others now moved]). Some
21 # TODO: Move the various attributes (cache_size, [others now moved]). Some
22 # of these are also attributes of InteractiveShell. They should be on ONE object
22 # of these are also attributes of InteractiveShell. They should be on ONE object
23 # only and the other objects should ask that one object for their values.
23 # only and the other objects should ask that one object for their values.
24
24
25 class DisplayHook(Configurable):
25 class DisplayHook(Configurable):
26 """The custom IPython displayhook to replace sys.displayhook.
26 """The custom IPython displayhook to replace sys.displayhook.
27
27
28 This class does many things, but the basic idea is that it is a callable
28 This class does many things, but the basic idea is that it is a callable
29 that gets called anytime user code returns a value.
29 that gets called anytime user code returns a value.
30 """
30 """
31
31
32 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
32 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
33 allow_none=True)
33 allow_none=True)
34 exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
34 exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
35 allow_none=True)
35 allow_none=True)
36 cull_fraction = Float(0.2)
36 cull_fraction = Float(0.2)
37
37
38 def __init__(self, shell=None, cache_size=1000, **kwargs):
38 def __init__(self, shell=None, cache_size=1000, **kwargs):
39 super(DisplayHook, self).__init__(shell=shell, **kwargs)
39 super(DisplayHook, self).__init__(shell=shell, **kwargs)
40 cache_size_min = 3
40 cache_size_min = 3
41 if cache_size <= 0:
41 if cache_size <= 0:
42 self.do_full_cache = 0
42 self.do_full_cache = 0
43 cache_size = 0
43 cache_size = 0
44 elif cache_size < cache_size_min:
44 elif cache_size < cache_size_min:
45 self.do_full_cache = 0
45 self.do_full_cache = 0
46 cache_size = 0
46 cache_size = 0
47 warn('caching was disabled (min value for cache size is %s).' %
47 warn('caching was disabled (min value for cache size is %s).' %
48 cache_size_min,level=3)
48 cache_size_min,level=3)
49 else:
49 else:
50 self.do_full_cache = 1
50 self.do_full_cache = 1
51
51
52 self.cache_size = cache_size
52 self.cache_size = cache_size
53
53
54 # we need a reference to the user-level namespace
54 # we need a reference to the user-level namespace
55 self.shell = shell
55 self.shell = shell
56
56
57 self._,self.__,self.___ = '','',''
57 self._,self.__,self.___ = '','',''
58
58
59 # these are deliberately global:
59 # these are deliberately global:
60 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
60 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
61 self.shell.user_ns.update(to_user_ns)
61 self.shell.user_ns.update(to_user_ns)
62
62
63 @property
63 @property
64 def prompt_count(self):
64 def prompt_count(self):
65 return self.shell.execution_count
65 return self.shell.execution_count
66
66
67 #-------------------------------------------------------------------------
67 #-------------------------------------------------------------------------
68 # Methods used in __call__. Override these methods to modify the behavior
68 # Methods used in __call__. Override these methods to modify the behavior
69 # of the displayhook.
69 # of the displayhook.
70 #-------------------------------------------------------------------------
70 #-------------------------------------------------------------------------
71
71
72 def check_for_underscore(self):
72 def check_for_underscore(self):
73 """Check if the user has set the '_' variable by hand."""
73 """Check if the user has set the '_' variable by hand."""
74 # If something injected a '_' variable in __builtin__, delete
74 # If something injected a '_' variable in __builtin__, delete
75 # ipython's automatic one so we don't clobber that. gettext() in
75 # ipython's automatic one so we don't clobber that. gettext() in
76 # particular uses _, so we need to stay away from it.
76 # particular uses _, so we need to stay away from it.
77 if '_' in builtin_mod.__dict__:
77 if '_' in builtin_mod.__dict__:
78 try:
78 try:
79 del self.shell.user_ns['_']
79 del self.shell.user_ns['_']
80 except KeyError:
80 except KeyError:
81 pass
81 pass
82
82
83 def quiet(self):
83 def quiet(self):
84 """Should we silence the display hook because of ';'?"""
84 """Should we silence the display hook because of ';'?"""
85 # do not print output if input ends in ';'
85 # do not print output if input ends in ';'
86 try:
86 try:
87 cell = self.shell.history_manager.input_hist_parsed[self.prompt_count]
87 cell = self.shell.history_manager.input_hist_parsed[self.prompt_count]
88 return cell.rstrip().endswith(';')
88 return cell.rstrip().endswith(';')
89 except IndexError:
89 except IndexError:
90 # some uses of ipshellembed may fail here
90 # some uses of ipshellembed may fail here
91 return False
91 return False
92
92
93 def start_displayhook(self):
93 def start_displayhook(self):
94 """Start the displayhook, initializing resources."""
94 """Start the displayhook, initializing resources."""
95 pass
95 pass
96
96
97 def write_output_prompt(self):
97 def write_output_prompt(self):
98 """Write the output prompt.
98 """Write the output prompt.
99
99
100 The default implementation simply writes the prompt to
100 The default implementation simply writes the prompt to
101 ``io.stdout``.
101 ``io.stdout``.
102 """
102 """
103 # Use write, not print which adds an extra space.
103 # Use write, not print which adds an extra space.
104 io.stdout.write(self.shell.separate_out)
104 io.stdout.write(self.shell.separate_out)
105 outprompt = self.shell.prompt_manager.render('out')
105 outprompt = self.shell.prompt_manager.render('out')
106 if self.do_full_cache:
106 if self.do_full_cache:
107 io.stdout.write(outprompt)
107 io.stdout.write(outprompt)
108
108
109 def compute_format_data(self, result):
109 def compute_format_data(self, result):
110 """Compute format data of the object to be displayed.
110 """Compute format data of the object to be displayed.
111
111
112 The format data is a generalization of the :func:`repr` of an object.
112 The format data is a generalization of the :func:`repr` of an object.
113 In the default implementation the format data is a :class:`dict` of
113 In the default implementation the format data is a :class:`dict` of
114 key value pair where the keys are valid MIME types and the values
114 key value pair where the keys are valid MIME types and the values
115 are JSON'able data structure containing the raw data for that MIME
115 are JSON'able data structure containing the raw data for that MIME
116 type. It is up to frontends to determine pick a MIME to to use and
116 type. It is up to frontends to determine pick a MIME to to use and
117 display that data in an appropriate manner.
117 display that data in an appropriate manner.
118
118
119 This method only computes the format data for the object and should
119 This method only computes the format data for the object and should
120 NOT actually print or write that to a stream.
120 NOT actually print or write that to a stream.
121
121
122 Parameters
122 Parameters
123 ----------
123 ----------
124 result : object
124 result : object
125 The Python object passed to the display hook, whose format will be
125 The Python object passed to the display hook, whose format will be
126 computed.
126 computed.
127
127
128 Returns
128 Returns
129 -------
129 -------
130 (format_dict, md_dict) : dict
130 (format_dict, md_dict) : dict
131 format_dict is a :class:`dict` whose keys are valid MIME types and values are
131 format_dict is a :class:`dict` whose keys are valid MIME types and values are
132 JSON'able raw data for that MIME type. It is recommended that
132 JSON'able raw data for that MIME type. It is recommended that
133 all return values of this should always include the "text/plain"
133 all return values of this should always include the "text/plain"
134 MIME type representation of the object.
134 MIME type representation of the object.
135 md_dict is a :class:`dict` with the same MIME type keys
135 md_dict is a :class:`dict` with the same MIME type keys
136 of metadata associated with each output.
136 of metadata associated with each output.
137
137
138 """
138 """
139 return self.shell.display_formatter.format(result)
139 return self.shell.display_formatter.format(result)
140
140
141 def write_format_data(self, format_dict, md_dict=None):
141 def write_format_data(self, format_dict, md_dict=None):
142 """Write the format data dict to the frontend.
142 """Write the format data dict to the frontend.
143
143
144 This default version of this method simply writes the plain text
144 This default version of this method simply writes the plain text
145 representation of the object to ``io.stdout``. Subclasses should
145 representation of the object to ``io.stdout``. Subclasses should
146 override this method to send the entire `format_dict` to the
146 override this method to send the entire `format_dict` to the
147 frontends.
147 frontends.
148
148
149 Parameters
149 Parameters
150 ----------
150 ----------
151 format_dict : dict
151 format_dict : dict
152 The format dict for the object passed to `sys.displayhook`.
152 The format dict for the object passed to `sys.displayhook`.
153 md_dict : dict (optional)
153 md_dict : dict (optional)
154 The metadata dict to be associated with the display data.
154 The metadata dict to be associated with the display data.
155 """
155 """
156 if 'text/plain' not in format_dict:
156 if 'text/plain' not in format_dict:
157 # nothing to do
157 # nothing to do
158 return
158 return
159 # We want to print because we want to always make sure we have a
159 # We want to print because we want to always make sure we have a
160 # newline, even if all the prompt separators are ''. This is the
160 # newline, even if all the prompt separators are ''. This is the
161 # standard IPython behavior.
161 # standard IPython behavior.
162 result_repr = format_dict['text/plain']
162 result_repr = format_dict['text/plain']
163 if '\n' in result_repr:
163 if '\n' in result_repr:
164 # So that multi-line strings line up with the left column of
164 # So that multi-line strings line up with the left column of
165 # the screen, instead of having the output prompt mess up
165 # the screen, instead of having the output prompt mess up
166 # their first line.
166 # their first line.
167 # We use the prompt template instead of the expanded prompt
167 # We use the prompt template instead of the expanded prompt
168 # because the expansion may add ANSI escapes that will interfere
168 # because the expansion may add ANSI escapes that will interfere
169 # with our ability to determine whether or not we should add
169 # with our ability to determine whether or not we should add
170 # a newline.
170 # a newline.
171 prompt_template = self.shell.prompt_manager.out_template
171 prompt_template = self.shell.prompt_manager.out_template
172 if prompt_template and not prompt_template.endswith('\n'):
172 if prompt_template and not prompt_template.endswith('\n'):
173 # But avoid extraneous empty lines.
173 # But avoid extraneous empty lines.
174 result_repr = '\n' + result_repr
174 result_repr = '\n' + result_repr
175
175
176 print(result_repr, file=io.stdout)
176 print(result_repr, file=io.stdout)
177
177
178 def update_user_ns(self, result):
178 def update_user_ns(self, result):
179 """Update user_ns with various things like _, __, _1, etc."""
179 """Update user_ns with various things like _, __, _1, etc."""
180
180
181 # Avoid recursive reference when displaying _oh/Out
181 # Avoid recursive reference when displaying _oh/Out
182 if result is not self.shell.user_ns['_oh']:
182 if result is not self.shell.user_ns['_oh']:
183 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
183 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
184 self.cull_cache()
184 self.cull_cache()
185 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
185 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
186 # we cause buggy behavior for things like gettext).
186 # we cause buggy behavior for things like gettext).
187
187
188 if '_' not in builtin_mod.__dict__:
188 if '_' not in builtin_mod.__dict__:
189 self.___ = self.__
189 self.___ = self.__
190 self.__ = self._
190 self.__ = self._
191 self._ = result
191 self._ = result
192 self.shell.push({'_':self._,
192 self.shell.push({'_':self._,
193 '__':self.__,
193 '__':self.__,
194 '___':self.___}, interactive=False)
194 '___':self.___}, interactive=False)
195
195
196 # hackish access to top-level namespace to create _1,_2... dynamically
196 # hackish access to top-level namespace to create _1,_2... dynamically
197 to_main = {}
197 to_main = {}
198 if self.do_full_cache:
198 if self.do_full_cache:
199 new_result = '_'+repr(self.prompt_count)
199 new_result = '_'+repr(self.prompt_count)
200 to_main[new_result] = result
200 to_main[new_result] = result
201 self.shell.push(to_main, interactive=False)
201 self.shell.push(to_main, interactive=False)
202 self.shell.user_ns['_oh'][self.prompt_count] = result
202 self.shell.user_ns['_oh'][self.prompt_count] = result
203
203
204 def fill_exec_result(self, result):
204 def fill_exec_result(self, result):
205 if self.exec_result is not None:
205 if self.exec_result is not None:
206 self.exec_result.result = result
206 self.exec_result.result = result
207
207
208 def log_output(self, format_dict):
208 def log_output(self, format_dict):
209 """Log the output."""
209 """Log the output."""
210 if 'text/plain' not in format_dict:
210 if 'text/plain' not in format_dict:
211 # nothing to do
211 # nothing to do
212 return
212 return
213 if self.shell.logger.log_output:
213 if self.shell.logger.log_output:
214 self.shell.logger.log_write(format_dict['text/plain'], 'output')
214 self.shell.logger.log_write(format_dict['text/plain'], 'output')
215 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
215 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
216 format_dict['text/plain']
216 format_dict['text/plain']
217
217
218 def finish_displayhook(self):
218 def finish_displayhook(self):
219 """Finish up all displayhook activities."""
219 """Finish up all displayhook activities."""
220 io.stdout.write(self.shell.separate_out2)
220 io.stdout.write(self.shell.separate_out2)
221 io.stdout.flush()
221 io.stdout.flush()
222
222
223 def __call__(self, result=None):
223 def __call__(self, result=None):
224 """Printing with history cache management.
224 """Printing with history cache management.
225
225
226 This is invoked everytime the interpreter needs to print, and is
226 This is invoked everytime the interpreter needs to print, and is
227 activated by setting the variable sys.displayhook to it.
227 activated by setting the variable sys.displayhook to it.
228 """
228 """
229 self.check_for_underscore()
229 self.check_for_underscore()
230 if result is not None and not self.quiet():
230 if result is not None and not self.quiet():
231 self.start_displayhook()
231 self.start_displayhook()
232 self.write_output_prompt()
232 self.write_output_prompt()
233 format_dict, md_dict = self.compute_format_data(result)
233 format_dict, md_dict = self.compute_format_data(result)
234 self.update_user_ns(result)
234 self.update_user_ns(result)
235 self.fill_exec_result(result)
235 self.fill_exec_result(result)
236 if format_dict:
236 if format_dict:
237 self.write_format_data(format_dict, md_dict)
237 self.write_format_data(format_dict, md_dict)
238 self.log_output(format_dict)
238 self.log_output(format_dict)
239 self.finish_displayhook()
239 self.finish_displayhook()
240
240
241 def cull_cache(self):
241 def cull_cache(self):
242 """Output cache is full, cull the oldest entries"""
242 """Output cache is full, cull the oldest entries"""
243 oh = self.shell.user_ns.get('_oh', {})
243 oh = self.shell.user_ns.get('_oh', {})
244 sz = len(oh)
244 sz = len(oh)
245 cull_count = max(int(sz * self.cull_fraction), 2)
245 cull_count = max(int(sz * self.cull_fraction), 2)
246 warn('Output cache limit (currently {sz} entries) hit.\n'
246 warn('Output cache limit (currently {sz} entries) hit.\n'
247 'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
247 'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
248
248
249 for i, n in enumerate(sorted(oh)):
249 for i, n in enumerate(sorted(oh)):
250 if i >= cull_count:
250 if i >= cull_count:
251 break
251 break
252 self.shell.user_ns.pop('_%i' % n, None)
252 self.shell.user_ns.pop('_%i' % n, None)
253 oh.pop(n, None)
253 oh.pop(n, None)
254
254
255
255
256 def flush(self):
256 def flush(self):
257 if not self.do_full_cache:
257 if not self.do_full_cache:
258 raise ValueError("You shouldn't have reached the cache flush "
258 raise ValueError("You shouldn't have reached the cache flush "
259 "if full caching is not enabled!")
259 "if full caching is not enabled!")
260 # delete auto-generated vars from global namespace
260 # delete auto-generated vars from global namespace
261
261
262 for n in range(1,self.prompt_count + 1):
262 for n in range(1,self.prompt_count + 1):
263 key = '_'+repr(n)
263 key = '_'+repr(n)
264 try:
264 try:
265 del self.shell.user_ns[key]
265 del self.shell.user_ns[key]
266 except: pass
266 except: pass
267 # In some embedded circumstances, the user_ns doesn't have the
267 # In some embedded circumstances, the user_ns doesn't have the
268 # '_oh' key set up.
268 # '_oh' key set up.
269 oh = self.shell.user_ns.get('_oh', None)
269 oh = self.shell.user_ns.get('_oh', None)
270 if oh is not None:
270 if oh is not None:
271 oh.clear()
271 oh.clear()
272
272
273 # Release our own references to objects:
273 # Release our own references to objects:
274 self._, self.__, self.___ = '', '', ''
274 self._, self.__, self.___ = '', '', ''
275
275
276 if '_' not in builtin_mod.__dict__:
276 if '_' not in builtin_mod.__dict__:
277 self.shell.user_ns.update({'_':None,'__':None, '___':None})
277 self.shell.user_ns.update({'_':None,'__':None, '___':None})
278 import gc
278 import gc
279 # TODO: Is this really needed?
279 # TODO: Is this really needed?
280 # IronPython blocks here forever
280 # IronPython blocks here forever
281 if sys.platform != "cli":
281 if sys.platform != "cli":
282 gc.collect()
282 gc.collect()
283
283
@@ -1,116 +1,116 b''
1 """An interface for publishing rich data to frontends.
1 """An interface for publishing rich data to frontends.
2
2
3 There are two components of the display system:
3 There are two components of the display system:
4
4
5 * Display formatters, which take a Python object and compute the
5 * Display formatters, which take a Python object and compute the
6 representation of the object in various formats (text, HTML, SVG, etc.).
6 representation of the object in various formats (text, HTML, SVG, etc.).
7 * The display publisher that is used to send the representation data to the
7 * The display publisher that is used to send the representation data to the
8 various frontends.
8 various frontends.
9
9
10 This module defines the logic display publishing. The display publisher uses
10 This module defines the logic display publishing. The display publisher uses
11 the ``display_data`` message type that is defined in the IPython messaging
11 the ``display_data`` message type that is defined in the IPython messaging
12 spec.
12 spec.
13 """
13 """
14
14
15 # Copyright (c) IPython Development Team.
15 # Copyright (c) IPython Development Team.
16 # Distributed under the terms of the Modified BSD License.
16 # Distributed under the terms of the Modified BSD License.
17
17
18 from __future__ import print_function
18 from __future__ import print_function
19
19
20 from IPython.config.configurable import Configurable
20 from traitlets.config.configurable import Configurable
21 from IPython.utils import io
21 from IPython.utils import io
22 from IPython.utils.traitlets import List
22 from traitlets import List
23
23
24 # This used to be defined here - it is imported for backwards compatibility
24 # This used to be defined here - it is imported for backwards compatibility
25 from .display import publish_display_data
25 from .display import publish_display_data
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Main payload class
28 # Main payload class
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 class DisplayPublisher(Configurable):
31 class DisplayPublisher(Configurable):
32 """A traited class that publishes display data to frontends.
32 """A traited class that publishes display data to frontends.
33
33
34 Instances of this class are created by the main IPython object and should
34 Instances of this class are created by the main IPython object and should
35 be accessed there.
35 be accessed there.
36 """
36 """
37
37
38 def _validate_data(self, data, metadata=None):
38 def _validate_data(self, data, metadata=None):
39 """Validate the display data.
39 """Validate the display data.
40
40
41 Parameters
41 Parameters
42 ----------
42 ----------
43 data : dict
43 data : dict
44 The formata data dictionary.
44 The formata data dictionary.
45 metadata : dict
45 metadata : dict
46 Any metadata for the data.
46 Any metadata for the data.
47 """
47 """
48
48
49 if not isinstance(data, dict):
49 if not isinstance(data, dict):
50 raise TypeError('data must be a dict, got: %r' % data)
50 raise TypeError('data must be a dict, got: %r' % data)
51 if metadata is not None:
51 if metadata is not None:
52 if not isinstance(metadata, dict):
52 if not isinstance(metadata, dict):
53 raise TypeError('metadata must be a dict, got: %r' % data)
53 raise TypeError('metadata must be a dict, got: %r' % data)
54
54
55 def publish(self, data, metadata=None, source=None):
55 def publish(self, data, metadata=None, source=None):
56 """Publish data and metadata to all frontends.
56 """Publish data and metadata to all frontends.
57
57
58 See the ``display_data`` message in the messaging documentation for
58 See the ``display_data`` message in the messaging documentation for
59 more details about this message type.
59 more details about this message type.
60
60
61 The following MIME types are currently implemented:
61 The following MIME types are currently implemented:
62
62
63 * text/plain
63 * text/plain
64 * text/html
64 * text/html
65 * text/markdown
65 * text/markdown
66 * text/latex
66 * text/latex
67 * application/json
67 * application/json
68 * application/javascript
68 * application/javascript
69 * image/png
69 * image/png
70 * image/jpeg
70 * image/jpeg
71 * image/svg+xml
71 * image/svg+xml
72
72
73 Parameters
73 Parameters
74 ----------
74 ----------
75 data : dict
75 data : dict
76 A dictionary having keys that are valid MIME types (like
76 A dictionary having keys that are valid MIME types (like
77 'text/plain' or 'image/svg+xml') and values that are the data for
77 'text/plain' or 'image/svg+xml') and values that are the data for
78 that MIME type. The data itself must be a JSON'able data
78 that MIME type. The data itself must be a JSON'able data
79 structure. Minimally all data should have the 'text/plain' data,
79 structure. Minimally all data should have the 'text/plain' data,
80 which can be displayed by all frontends. If more than the plain
80 which can be displayed by all frontends. If more than the plain
81 text is given, it is up to the frontend to decide which
81 text is given, it is up to the frontend to decide which
82 representation to use.
82 representation to use.
83 metadata : dict
83 metadata : dict
84 A dictionary for metadata related to the data. This can contain
84 A dictionary for metadata related to the data. This can contain
85 arbitrary key, value pairs that frontends can use to interpret
85 arbitrary key, value pairs that frontends can use to interpret
86 the data. Metadata specific to each mime-type can be specified
86 the data. Metadata specific to each mime-type can be specified
87 in the metadata dict with the same mime-type keys as
87 in the metadata dict with the same mime-type keys as
88 the data itself.
88 the data itself.
89 source : str, deprecated
89 source : str, deprecated
90 Unused.
90 Unused.
91 """
91 """
92
92
93 # The default is to simply write the plain text data using io.stdout.
93 # The default is to simply write the plain text data using io.stdout.
94 if 'text/plain' in data:
94 if 'text/plain' in data:
95 print(data['text/plain'], file=io.stdout)
95 print(data['text/plain'], file=io.stdout)
96
96
97 def clear_output(self, wait=False):
97 def clear_output(self, wait=False):
98 """Clear the output of the cell receiving output."""
98 """Clear the output of the cell receiving output."""
99 print('\033[2K\r', file=io.stdout, end='')
99 print('\033[2K\r', file=io.stdout, end='')
100 io.stdout.flush()
100 io.stdout.flush()
101 print('\033[2K\r', file=io.stderr, end='')
101 print('\033[2K\r', file=io.stderr, end='')
102 io.stderr.flush()
102 io.stderr.flush()
103
103
104
104
105 class CapturingDisplayPublisher(DisplayPublisher):
105 class CapturingDisplayPublisher(DisplayPublisher):
106 """A DisplayPublisher that stores"""
106 """A DisplayPublisher that stores"""
107 outputs = List()
107 outputs = List()
108
108
109 def publish(self, data, metadata=None, source=None):
109 def publish(self, data, metadata=None, source=None):
110 self.outputs.append((data, metadata))
110 self.outputs.append((data, metadata))
111
111
112 def clear_output(self, wait=False):
112 def clear_output(self, wait=False):
113 super(CapturingDisplayPublisher, self).clear_output(wait)
113 super(CapturingDisplayPublisher, self).clear_output(wait)
114
114
115 # empty the list, *do not* reassign a new list
115 # empty the list, *do not* reassign a new list
116 del self.outputs[:]
116 del self.outputs[:]
@@ -1,176 +1,176 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """A class for managing IPython extensions."""
2 """A class for managing IPython extensions."""
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 import os
7 import os
8 from shutil import copyfile
8 from shutil import copyfile
9 import sys
9 import sys
10
10
11 from IPython.config.configurable import Configurable
11 from traitlets.config.configurable import Configurable
12 from IPython.utils.path import ensure_dir_exists
12 from IPython.utils.path import ensure_dir_exists
13 from IPython.utils.traitlets import Instance
13 from traitlets import Instance
14 from IPython.utils.py3compat import PY3
14 from IPython.utils.py3compat import PY3
15 if PY3:
15 if PY3:
16 from imp import reload
16 from imp import reload
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Main class
19 # Main class
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 class ExtensionManager(Configurable):
22 class ExtensionManager(Configurable):
23 """A class to manage IPython extensions.
23 """A class to manage IPython extensions.
24
24
25 An IPython extension is an importable Python module that has
25 An IPython extension is an importable Python module that has
26 a function with the signature::
26 a function with the signature::
27
27
28 def load_ipython_extension(ipython):
28 def load_ipython_extension(ipython):
29 # Do things with ipython
29 # Do things with ipython
30
30
31 This function is called after your extension is imported and the
31 This function is called after your extension is imported and the
32 currently active :class:`InteractiveShell` instance is passed as
32 currently active :class:`InteractiveShell` instance is passed as
33 the only argument. You can do anything you want with IPython at
33 the only argument. You can do anything you want with IPython at
34 that point, including defining new magic and aliases, adding new
34 that point, including defining new magic and aliases, adding new
35 components, etc.
35 components, etc.
36
36
37 You can also optionally define an :func:`unload_ipython_extension(ipython)`
37 You can also optionally define an :func:`unload_ipython_extension(ipython)`
38 function, which will be called if the user unloads or reloads the extension.
38 function, which will be called if the user unloads or reloads the extension.
39 The extension manager will only call :func:`load_ipython_extension` again
39 The extension manager will only call :func:`load_ipython_extension` again
40 if the extension is reloaded.
40 if the extension is reloaded.
41
41
42 You can put your extension modules anywhere you want, as long as
42 You can put your extension modules anywhere you want, as long as
43 they can be imported by Python's standard import mechanism. However,
43 they can be imported by Python's standard import mechanism. However,
44 to make it easy to write extensions, you can also put your extensions
44 to make it easy to write extensions, you can also put your extensions
45 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
45 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
46 is added to ``sys.path`` automatically.
46 is added to ``sys.path`` automatically.
47 """
47 """
48
48
49 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
49 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
50 allow_none=True)
50 allow_none=True)
51
51
52 def __init__(self, shell=None, **kwargs):
52 def __init__(self, shell=None, **kwargs):
53 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
53 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
54 self.shell.on_trait_change(
54 self.shell.on_trait_change(
55 self._on_ipython_dir_changed, 'ipython_dir'
55 self._on_ipython_dir_changed, 'ipython_dir'
56 )
56 )
57 self.loaded = set()
57 self.loaded = set()
58
58
59 def __del__(self):
59 def __del__(self):
60 self.shell.on_trait_change(
60 self.shell.on_trait_change(
61 self._on_ipython_dir_changed, 'ipython_dir', remove=True
61 self._on_ipython_dir_changed, 'ipython_dir', remove=True
62 )
62 )
63
63
64 @property
64 @property
65 def ipython_extension_dir(self):
65 def ipython_extension_dir(self):
66 return os.path.join(self.shell.ipython_dir, u'extensions')
66 return os.path.join(self.shell.ipython_dir, u'extensions')
67
67
68 def _on_ipython_dir_changed(self):
68 def _on_ipython_dir_changed(self):
69 ensure_dir_exists(self.ipython_extension_dir)
69 ensure_dir_exists(self.ipython_extension_dir)
70
70
71 def load_extension(self, module_str):
71 def load_extension(self, module_str):
72 """Load an IPython extension by its module name.
72 """Load an IPython extension by its module name.
73
73
74 Returns the string "already loaded" if the extension is already loaded,
74 Returns the string "already loaded" if the extension is already loaded,
75 "no load function" if the module doesn't have a load_ipython_extension
75 "no load function" if the module doesn't have a load_ipython_extension
76 function, or None if it succeeded.
76 function, or None if it succeeded.
77 """
77 """
78 if module_str in self.loaded:
78 if module_str in self.loaded:
79 return "already loaded"
79 return "already loaded"
80
80
81 from IPython.utils.syspathcontext import prepended_to_syspath
81 from IPython.utils.syspathcontext import prepended_to_syspath
82
82
83 with self.shell.builtin_trap:
83 with self.shell.builtin_trap:
84 if module_str not in sys.modules:
84 if module_str not in sys.modules:
85 with prepended_to_syspath(self.ipython_extension_dir):
85 with prepended_to_syspath(self.ipython_extension_dir):
86 __import__(module_str)
86 __import__(module_str)
87 mod = sys.modules[module_str]
87 mod = sys.modules[module_str]
88 if self._call_load_ipython_extension(mod):
88 if self._call_load_ipython_extension(mod):
89 self.loaded.add(module_str)
89 self.loaded.add(module_str)
90 else:
90 else:
91 return "no load function"
91 return "no load function"
92
92
93 def unload_extension(self, module_str):
93 def unload_extension(self, module_str):
94 """Unload an IPython extension by its module name.
94 """Unload an IPython extension by its module name.
95
95
96 This function looks up the extension's name in ``sys.modules`` and
96 This function looks up the extension's name in ``sys.modules`` and
97 simply calls ``mod.unload_ipython_extension(self)``.
97 simply calls ``mod.unload_ipython_extension(self)``.
98
98
99 Returns the string "no unload function" if the extension doesn't define
99 Returns the string "no unload function" if the extension doesn't define
100 a function to unload itself, "not loaded" if the extension isn't loaded,
100 a function to unload itself, "not loaded" if the extension isn't loaded,
101 otherwise None.
101 otherwise None.
102 """
102 """
103 if module_str not in self.loaded:
103 if module_str not in self.loaded:
104 return "not loaded"
104 return "not loaded"
105
105
106 if module_str in sys.modules:
106 if module_str in sys.modules:
107 mod = sys.modules[module_str]
107 mod = sys.modules[module_str]
108 if self._call_unload_ipython_extension(mod):
108 if self._call_unload_ipython_extension(mod):
109 self.loaded.discard(module_str)
109 self.loaded.discard(module_str)
110 else:
110 else:
111 return "no unload function"
111 return "no unload function"
112
112
113 def reload_extension(self, module_str):
113 def reload_extension(self, module_str):
114 """Reload an IPython extension by calling reload.
114 """Reload an IPython extension by calling reload.
115
115
116 If the module has not been loaded before,
116 If the module has not been loaded before,
117 :meth:`InteractiveShell.load_extension` is called. Otherwise
117 :meth:`InteractiveShell.load_extension` is called. Otherwise
118 :func:`reload` is called and then the :func:`load_ipython_extension`
118 :func:`reload` is called and then the :func:`load_ipython_extension`
119 function of the module, if it exists is called.
119 function of the module, if it exists is called.
120 """
120 """
121 from IPython.utils.syspathcontext import prepended_to_syspath
121 from IPython.utils.syspathcontext import prepended_to_syspath
122
122
123 if (module_str in self.loaded) and (module_str in sys.modules):
123 if (module_str in self.loaded) and (module_str in sys.modules):
124 self.unload_extension(module_str)
124 self.unload_extension(module_str)
125 mod = sys.modules[module_str]
125 mod = sys.modules[module_str]
126 with prepended_to_syspath(self.ipython_extension_dir):
126 with prepended_to_syspath(self.ipython_extension_dir):
127 reload(mod)
127 reload(mod)
128 if self._call_load_ipython_extension(mod):
128 if self._call_load_ipython_extension(mod):
129 self.loaded.add(module_str)
129 self.loaded.add(module_str)
130 else:
130 else:
131 self.load_extension(module_str)
131 self.load_extension(module_str)
132
132
133 def _call_load_ipython_extension(self, mod):
133 def _call_load_ipython_extension(self, mod):
134 if hasattr(mod, 'load_ipython_extension'):
134 if hasattr(mod, 'load_ipython_extension'):
135 mod.load_ipython_extension(self.shell)
135 mod.load_ipython_extension(self.shell)
136 return True
136 return True
137
137
138 def _call_unload_ipython_extension(self, mod):
138 def _call_unload_ipython_extension(self, mod):
139 if hasattr(mod, 'unload_ipython_extension'):
139 if hasattr(mod, 'unload_ipython_extension'):
140 mod.unload_ipython_extension(self.shell)
140 mod.unload_ipython_extension(self.shell)
141 return True
141 return True
142
142
143 def install_extension(self, url, filename=None):
143 def install_extension(self, url, filename=None):
144 """Download and install an IPython extension.
144 """Download and install an IPython extension.
145
145
146 If filename is given, the file will be so named (inside the extension
146 If filename is given, the file will be so named (inside the extension
147 directory). Otherwise, the name from the URL will be used. The file must
147 directory). Otherwise, the name from the URL will be used. The file must
148 have a .py or .zip extension; otherwise, a ValueError will be raised.
148 have a .py or .zip extension; otherwise, a ValueError will be raised.
149
149
150 Returns the full path to the installed file.
150 Returns the full path to the installed file.
151 """
151 """
152 # Ensure the extension directory exists
152 # Ensure the extension directory exists
153 ensure_dir_exists(self.ipython_extension_dir)
153 ensure_dir_exists(self.ipython_extension_dir)
154
154
155 if os.path.isfile(url):
155 if os.path.isfile(url):
156 src_filename = os.path.basename(url)
156 src_filename = os.path.basename(url)
157 copy = copyfile
157 copy = copyfile
158 else:
158 else:
159 # Deferred imports
159 # Deferred imports
160 try:
160 try:
161 from urllib.parse import urlparse # Py3
161 from urllib.parse import urlparse # Py3
162 from urllib.request import urlretrieve
162 from urllib.request import urlretrieve
163 except ImportError:
163 except ImportError:
164 from urlparse import urlparse
164 from urlparse import urlparse
165 from urllib import urlretrieve
165 from urllib import urlretrieve
166 src_filename = urlparse(url).path.split('/')[-1]
166 src_filename = urlparse(url).path.split('/')[-1]
167 copy = urlretrieve
167 copy = urlretrieve
168
168
169 if filename is None:
169 if filename is None:
170 filename = src_filename
170 filename = src_filename
171 if os.path.splitext(filename)[1] not in ('.py', '.zip'):
171 if os.path.splitext(filename)[1] not in ('.py', '.zip'):
172 raise ValueError("The file must have a .py or .zip extension", filename)
172 raise ValueError("The file must have a .py or .zip extension", filename)
173
173
174 filename = os.path.join(self.ipython_extension_dir, filename)
174 filename = os.path.join(self.ipython_extension_dir, filename)
175 copy(url, filename)
175 copy(url, filename)
176 return filename
176 return filename
@@ -1,972 +1,972 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Display formatters.
2 """Display formatters.
3
3
4 Inheritance diagram:
4 Inheritance diagram:
5
5
6 .. inheritance-diagram:: IPython.core.formatters
6 .. inheritance-diagram:: IPython.core.formatters
7 :parts: 3
7 :parts: 3
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 import abc
13 import abc
14 import inspect
14 import inspect
15 import json
15 import json
16 import sys
16 import sys
17 import traceback
17 import traceback
18 import warnings
18 import warnings
19
19
20 from decorator import decorator
20 from decorator import decorator
21
21
22 from IPython.config.configurable import Configurable
22 from traitlets.config.configurable import Configurable
23 from IPython.core.getipython import get_ipython
23 from IPython.core.getipython import get_ipython
24 from IPython.utils.sentinel import Sentinel
24 from IPython.utils.sentinel import Sentinel
25 from IPython.lib import pretty
25 from IPython.lib import pretty
26 from IPython.utils.traitlets import (
26 from traitlets import (
27 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
27 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
28 ForwardDeclaredInstance,
28 ForwardDeclaredInstance,
29 )
29 )
30 from IPython.utils.py3compat import (
30 from IPython.utils.py3compat import (
31 with_metaclass, string_types, unicode_type,
31 with_metaclass, string_types, unicode_type,
32 )
32 )
33
33
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # The main DisplayFormatter class
36 # The main DisplayFormatter class
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39
39
40 def _safe_get_formatter_method(obj, name):
40 def _safe_get_formatter_method(obj, name):
41 """Safely get a formatter method
41 """Safely get a formatter method
42
42
43 - Classes cannot have formatter methods, only instance
43 - Classes cannot have formatter methods, only instance
44 - protect against proxy objects that claim to have everything
44 - protect against proxy objects that claim to have everything
45 """
45 """
46 if inspect.isclass(obj):
46 if inspect.isclass(obj):
47 # repr methods only make sense on instances, not classes
47 # repr methods only make sense on instances, not classes
48 return None
48 return None
49 method = pretty._safe_getattr(obj, name, None)
49 method = pretty._safe_getattr(obj, name, None)
50 if callable(method):
50 if callable(method):
51 # obj claims to have repr method...
51 # obj claims to have repr method...
52 if callable(pretty._safe_getattr(obj, '_ipython_canary_method_should_not_exist_', None)):
52 if callable(pretty._safe_getattr(obj, '_ipython_canary_method_should_not_exist_', None)):
53 # ...but don't trust proxy objects that claim to have everything
53 # ...but don't trust proxy objects that claim to have everything
54 return None
54 return None
55 return method
55 return method
56
56
57
57
58 class DisplayFormatter(Configurable):
58 class DisplayFormatter(Configurable):
59
59
60 # When set to true only the default plain text formatter will be used.
60 # When set to true only the default plain text formatter will be used.
61 plain_text_only = Bool(False, config=True)
61 plain_text_only = Bool(False, config=True)
62 def _plain_text_only_changed(self, name, old, new):
62 def _plain_text_only_changed(self, name, old, new):
63 warnings.warn("""DisplayFormatter.plain_text_only is deprecated.
63 warnings.warn("""DisplayFormatter.plain_text_only is deprecated.
64
64
65 Use DisplayFormatter.active_types = ['text/plain']
65 Use DisplayFormatter.active_types = ['text/plain']
66 for the same effect.
66 for the same effect.
67 """, DeprecationWarning)
67 """, DeprecationWarning)
68 if new:
68 if new:
69 self.active_types = ['text/plain']
69 self.active_types = ['text/plain']
70 else:
70 else:
71 self.active_types = self.format_types
71 self.active_types = self.format_types
72
72
73 active_types = List(Unicode, config=True,
73 active_types = List(Unicode, config=True,
74 help="""List of currently active mime-types to display.
74 help="""List of currently active mime-types to display.
75 You can use this to set a white-list for formats to display.
75 You can use this to set a white-list for formats to display.
76
76
77 Most users will not need to change this value.
77 Most users will not need to change this value.
78 """)
78 """)
79 def _active_types_default(self):
79 def _active_types_default(self):
80 return self.format_types
80 return self.format_types
81
81
82 def _active_types_changed(self, name, old, new):
82 def _active_types_changed(self, name, old, new):
83 for key, formatter in self.formatters.items():
83 for key, formatter in self.formatters.items():
84 if key in new:
84 if key in new:
85 formatter.enabled = True
85 formatter.enabled = True
86 else:
86 else:
87 formatter.enabled = False
87 formatter.enabled = False
88
88
89 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
89 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
90 def _ipython_display_formatter_default(self):
90 def _ipython_display_formatter_default(self):
91 return IPythonDisplayFormatter(parent=self)
91 return IPythonDisplayFormatter(parent=self)
92
92
93 # A dict of formatter whose keys are format types (MIME types) and whose
93 # A dict of formatter whose keys are format types (MIME types) and whose
94 # values are subclasses of BaseFormatter.
94 # values are subclasses of BaseFormatter.
95 formatters = Dict()
95 formatters = Dict()
96 def _formatters_default(self):
96 def _formatters_default(self):
97 """Activate the default formatters."""
97 """Activate the default formatters."""
98 formatter_classes = [
98 formatter_classes = [
99 PlainTextFormatter,
99 PlainTextFormatter,
100 HTMLFormatter,
100 HTMLFormatter,
101 MarkdownFormatter,
101 MarkdownFormatter,
102 SVGFormatter,
102 SVGFormatter,
103 PNGFormatter,
103 PNGFormatter,
104 PDFFormatter,
104 PDFFormatter,
105 JPEGFormatter,
105 JPEGFormatter,
106 LatexFormatter,
106 LatexFormatter,
107 JSONFormatter,
107 JSONFormatter,
108 JavascriptFormatter
108 JavascriptFormatter
109 ]
109 ]
110 d = {}
110 d = {}
111 for cls in formatter_classes:
111 for cls in formatter_classes:
112 f = cls(parent=self)
112 f = cls(parent=self)
113 d[f.format_type] = f
113 d[f.format_type] = f
114 return d
114 return d
115
115
116 def format(self, obj, include=None, exclude=None):
116 def format(self, obj, include=None, exclude=None):
117 """Return a format data dict for an object.
117 """Return a format data dict for an object.
118
118
119 By default all format types will be computed.
119 By default all format types will be computed.
120
120
121 The following MIME types are currently implemented:
121 The following MIME types are currently implemented:
122
122
123 * text/plain
123 * text/plain
124 * text/html
124 * text/html
125 * text/markdown
125 * text/markdown
126 * text/latex
126 * text/latex
127 * application/json
127 * application/json
128 * application/javascript
128 * application/javascript
129 * application/pdf
129 * application/pdf
130 * image/png
130 * image/png
131 * image/jpeg
131 * image/jpeg
132 * image/svg+xml
132 * image/svg+xml
133
133
134 Parameters
134 Parameters
135 ----------
135 ----------
136 obj : object
136 obj : object
137 The Python object whose format data will be computed.
137 The Python object whose format data will be computed.
138 include : list or tuple, optional
138 include : list or tuple, optional
139 A list of format type strings (MIME types) to include in the
139 A list of format type strings (MIME types) to include in the
140 format data dict. If this is set *only* the format types included
140 format data dict. If this is set *only* the format types included
141 in this list will be computed.
141 in this list will be computed.
142 exclude : list or tuple, optional
142 exclude : list or tuple, optional
143 A list of format type string (MIME types) to exclude in the format
143 A list of format type string (MIME types) to exclude in the format
144 data dict. If this is set all format types will be computed,
144 data dict. If this is set all format types will be computed,
145 except for those included in this argument.
145 except for those included in this argument.
146
146
147 Returns
147 Returns
148 -------
148 -------
149 (format_dict, metadata_dict) : tuple of two dicts
149 (format_dict, metadata_dict) : tuple of two dicts
150
150
151 format_dict is a dictionary of key/value pairs, one of each format that was
151 format_dict is a dictionary of key/value pairs, one of each format that was
152 generated for the object. The keys are the format types, which
152 generated for the object. The keys are the format types, which
153 will usually be MIME type strings and the values and JSON'able
153 will usually be MIME type strings and the values and JSON'able
154 data structure containing the raw data for the representation in
154 data structure containing the raw data for the representation in
155 that format.
155 that format.
156
156
157 metadata_dict is a dictionary of metadata about each mime-type output.
157 metadata_dict is a dictionary of metadata about each mime-type output.
158 Its keys will be a strict subset of the keys in format_dict.
158 Its keys will be a strict subset of the keys in format_dict.
159 """
159 """
160 format_dict = {}
160 format_dict = {}
161 md_dict = {}
161 md_dict = {}
162
162
163 if self.ipython_display_formatter(obj):
163 if self.ipython_display_formatter(obj):
164 # object handled itself, don't proceed
164 # object handled itself, don't proceed
165 return {}, {}
165 return {}, {}
166
166
167 for format_type, formatter in self.formatters.items():
167 for format_type, formatter in self.formatters.items():
168 if include and format_type not in include:
168 if include and format_type not in include:
169 continue
169 continue
170 if exclude and format_type in exclude:
170 if exclude and format_type in exclude:
171 continue
171 continue
172
172
173 md = None
173 md = None
174 try:
174 try:
175 data = formatter(obj)
175 data = formatter(obj)
176 except:
176 except:
177 # FIXME: log the exception
177 # FIXME: log the exception
178 raise
178 raise
179
179
180 # formatters can return raw data or (data, metadata)
180 # formatters can return raw data or (data, metadata)
181 if isinstance(data, tuple) and len(data) == 2:
181 if isinstance(data, tuple) and len(data) == 2:
182 data, md = data
182 data, md = data
183
183
184 if data is not None:
184 if data is not None:
185 format_dict[format_type] = data
185 format_dict[format_type] = data
186 if md is not None:
186 if md is not None:
187 md_dict[format_type] = md
187 md_dict[format_type] = md
188
188
189 return format_dict, md_dict
189 return format_dict, md_dict
190
190
191 @property
191 @property
192 def format_types(self):
192 def format_types(self):
193 """Return the format types (MIME types) of the active formatters."""
193 """Return the format types (MIME types) of the active formatters."""
194 return list(self.formatters.keys())
194 return list(self.formatters.keys())
195
195
196
196
197 #-----------------------------------------------------------------------------
197 #-----------------------------------------------------------------------------
198 # Formatters for specific format types (text, html, svg, etc.)
198 # Formatters for specific format types (text, html, svg, etc.)
199 #-----------------------------------------------------------------------------
199 #-----------------------------------------------------------------------------
200
200
201
201
202 def _safe_repr(obj):
202 def _safe_repr(obj):
203 """Try to return a repr of an object
203 """Try to return a repr of an object
204
204
205 always returns a string, at least.
205 always returns a string, at least.
206 """
206 """
207 try:
207 try:
208 return repr(obj)
208 return repr(obj)
209 except Exception as e:
209 except Exception as e:
210 return "un-repr-able object (%r)" % e
210 return "un-repr-able object (%r)" % e
211
211
212
212
213 class FormatterWarning(UserWarning):
213 class FormatterWarning(UserWarning):
214 """Warning class for errors in formatters"""
214 """Warning class for errors in formatters"""
215
215
216 @decorator
216 @decorator
217 def catch_format_error(method, self, *args, **kwargs):
217 def catch_format_error(method, self, *args, **kwargs):
218 """show traceback on failed format call"""
218 """show traceback on failed format call"""
219 try:
219 try:
220 r = method(self, *args, **kwargs)
220 r = method(self, *args, **kwargs)
221 except NotImplementedError:
221 except NotImplementedError:
222 # don't warn on NotImplementedErrors
222 # don't warn on NotImplementedErrors
223 return None
223 return None
224 except Exception:
224 except Exception:
225 exc_info = sys.exc_info()
225 exc_info = sys.exc_info()
226 ip = get_ipython()
226 ip = get_ipython()
227 if ip is not None:
227 if ip is not None:
228 ip.showtraceback(exc_info)
228 ip.showtraceback(exc_info)
229 else:
229 else:
230 traceback.print_exception(*exc_info)
230 traceback.print_exception(*exc_info)
231 return None
231 return None
232 return self._check_return(r, args[0])
232 return self._check_return(r, args[0])
233
233
234
234
235 class FormatterABC(with_metaclass(abc.ABCMeta, object)):
235 class FormatterABC(with_metaclass(abc.ABCMeta, object)):
236 """ Abstract base class for Formatters.
236 """ Abstract base class for Formatters.
237
237
238 A formatter is a callable class that is responsible for computing the
238 A formatter is a callable class that is responsible for computing the
239 raw format data for a particular format type (MIME type). For example,
239 raw format data for a particular format type (MIME type). For example,
240 an HTML formatter would have a format type of `text/html` and would return
240 an HTML formatter would have a format type of `text/html` and would return
241 the HTML representation of the object when called.
241 the HTML representation of the object when called.
242 """
242 """
243
243
244 # The format type of the data returned, usually a MIME type.
244 # The format type of the data returned, usually a MIME type.
245 format_type = 'text/plain'
245 format_type = 'text/plain'
246
246
247 # Is the formatter enabled...
247 # Is the formatter enabled...
248 enabled = True
248 enabled = True
249
249
250 @abc.abstractmethod
250 @abc.abstractmethod
251 def __call__(self, obj):
251 def __call__(self, obj):
252 """Return a JSON'able representation of the object.
252 """Return a JSON'able representation of the object.
253
253
254 If the object cannot be formatted by this formatter,
254 If the object cannot be formatted by this formatter,
255 warn and return None.
255 warn and return None.
256 """
256 """
257 return repr(obj)
257 return repr(obj)
258
258
259
259
260 def _mod_name_key(typ):
260 def _mod_name_key(typ):
261 """Return a (__module__, __name__) tuple for a type.
261 """Return a (__module__, __name__) tuple for a type.
262
262
263 Used as key in Formatter.deferred_printers.
263 Used as key in Formatter.deferred_printers.
264 """
264 """
265 module = getattr(typ, '__module__', None)
265 module = getattr(typ, '__module__', None)
266 name = getattr(typ, '__name__', None)
266 name = getattr(typ, '__name__', None)
267 return (module, name)
267 return (module, name)
268
268
269
269
270 def _get_type(obj):
270 def _get_type(obj):
271 """Return the type of an instance (old and new-style)"""
271 """Return the type of an instance (old and new-style)"""
272 return getattr(obj, '__class__', None) or type(obj)
272 return getattr(obj, '__class__', None) or type(obj)
273
273
274
274
275 _raise_key_error = Sentinel('_raise_key_error', __name__,
275 _raise_key_error = Sentinel('_raise_key_error', __name__,
276 """
276 """
277 Special value to raise a KeyError
277 Special value to raise a KeyError
278
278
279 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
279 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
280 """)
280 """)
281
281
282
282
283 class BaseFormatter(Configurable):
283 class BaseFormatter(Configurable):
284 """A base formatter class that is configurable.
284 """A base formatter class that is configurable.
285
285
286 This formatter should usually be used as the base class of all formatters.
286 This formatter should usually be used as the base class of all formatters.
287 It is a traited :class:`Configurable` class and includes an extensible
287 It is a traited :class:`Configurable` class and includes an extensible
288 API for users to determine how their objects are formatted. The following
288 API for users to determine how their objects are formatted. The following
289 logic is used to find a function to format an given object.
289 logic is used to find a function to format an given object.
290
290
291 1. The object is introspected to see if it has a method with the name
291 1. The object is introspected to see if it has a method with the name
292 :attr:`print_method`. If is does, that object is passed to that method
292 :attr:`print_method`. If is does, that object is passed to that method
293 for formatting.
293 for formatting.
294 2. If no print method is found, three internal dictionaries are consulted
294 2. If no print method is found, three internal dictionaries are consulted
295 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
295 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
296 and :attr:`deferred_printers`.
296 and :attr:`deferred_printers`.
297
297
298 Users should use these dictionaries to register functions that will be
298 Users should use these dictionaries to register functions that will be
299 used to compute the format data for their objects (if those objects don't
299 used to compute the format data for their objects (if those objects don't
300 have the special print methods). The easiest way of using these
300 have the special print methods). The easiest way of using these
301 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
301 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
302 methods.
302 methods.
303
303
304 If no function/callable is found to compute the format data, ``None`` is
304 If no function/callable is found to compute the format data, ``None`` is
305 returned and this format type is not used.
305 returned and this format type is not used.
306 """
306 """
307
307
308 format_type = Unicode('text/plain')
308 format_type = Unicode('text/plain')
309 _return_type = string_types
309 _return_type = string_types
310
310
311 enabled = Bool(True, config=True)
311 enabled = Bool(True, config=True)
312
312
313 print_method = ObjectName('__repr__')
313 print_method = ObjectName('__repr__')
314
314
315 # The singleton printers.
315 # The singleton printers.
316 # Maps the IDs of the builtin singleton objects to the format functions.
316 # Maps the IDs of the builtin singleton objects to the format functions.
317 singleton_printers = Dict(config=True)
317 singleton_printers = Dict(config=True)
318
318
319 # The type-specific printers.
319 # The type-specific printers.
320 # Map type objects to the format functions.
320 # Map type objects to the format functions.
321 type_printers = Dict(config=True)
321 type_printers = Dict(config=True)
322
322
323 # The deferred-import type-specific printers.
323 # The deferred-import type-specific printers.
324 # Map (modulename, classname) pairs to the format functions.
324 # Map (modulename, classname) pairs to the format functions.
325 deferred_printers = Dict(config=True)
325 deferred_printers = Dict(config=True)
326
326
327 @catch_format_error
327 @catch_format_error
328 def __call__(self, obj):
328 def __call__(self, obj):
329 """Compute the format for an object."""
329 """Compute the format for an object."""
330 if self.enabled:
330 if self.enabled:
331 # lookup registered printer
331 # lookup registered printer
332 try:
332 try:
333 printer = self.lookup(obj)
333 printer = self.lookup(obj)
334 except KeyError:
334 except KeyError:
335 pass
335 pass
336 else:
336 else:
337 return printer(obj)
337 return printer(obj)
338 # Finally look for special method names
338 # Finally look for special method names
339 method = _safe_get_formatter_method(obj, self.print_method)
339 method = _safe_get_formatter_method(obj, self.print_method)
340 if method is not None:
340 if method is not None:
341 return method()
341 return method()
342 return None
342 return None
343 else:
343 else:
344 return None
344 return None
345
345
346 def __contains__(self, typ):
346 def __contains__(self, typ):
347 """map in to lookup_by_type"""
347 """map in to lookup_by_type"""
348 try:
348 try:
349 self.lookup_by_type(typ)
349 self.lookup_by_type(typ)
350 except KeyError:
350 except KeyError:
351 return False
351 return False
352 else:
352 else:
353 return True
353 return True
354
354
355 def _check_return(self, r, obj):
355 def _check_return(self, r, obj):
356 """Check that a return value is appropriate
356 """Check that a return value is appropriate
357
357
358 Return the value if so, None otherwise, warning if invalid.
358 Return the value if so, None otherwise, warning if invalid.
359 """
359 """
360 if r is None or isinstance(r, self._return_type) or \
360 if r is None or isinstance(r, self._return_type) or \
361 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
361 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
362 return r
362 return r
363 else:
363 else:
364 warnings.warn(
364 warnings.warn(
365 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
365 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
366 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
366 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
367 FormatterWarning
367 FormatterWarning
368 )
368 )
369
369
370 def lookup(self, obj):
370 def lookup(self, obj):
371 """Look up the formatter for a given instance.
371 """Look up the formatter for a given instance.
372
372
373 Parameters
373 Parameters
374 ----------
374 ----------
375 obj : object instance
375 obj : object instance
376
376
377 Returns
377 Returns
378 -------
378 -------
379 f : callable
379 f : callable
380 The registered formatting callable for the type.
380 The registered formatting callable for the type.
381
381
382 Raises
382 Raises
383 ------
383 ------
384 KeyError if the type has not been registered.
384 KeyError if the type has not been registered.
385 """
385 """
386 # look for singleton first
386 # look for singleton first
387 obj_id = id(obj)
387 obj_id = id(obj)
388 if obj_id in self.singleton_printers:
388 if obj_id in self.singleton_printers:
389 return self.singleton_printers[obj_id]
389 return self.singleton_printers[obj_id]
390 # then lookup by type
390 # then lookup by type
391 return self.lookup_by_type(_get_type(obj))
391 return self.lookup_by_type(_get_type(obj))
392
392
393 def lookup_by_type(self, typ):
393 def lookup_by_type(self, typ):
394 """Look up the registered formatter for a type.
394 """Look up the registered formatter for a type.
395
395
396 Parameters
396 Parameters
397 ----------
397 ----------
398 typ : type or '__module__.__name__' string for a type
398 typ : type or '__module__.__name__' string for a type
399
399
400 Returns
400 Returns
401 -------
401 -------
402 f : callable
402 f : callable
403 The registered formatting callable for the type.
403 The registered formatting callable for the type.
404
404
405 Raises
405 Raises
406 ------
406 ------
407 KeyError if the type has not been registered.
407 KeyError if the type has not been registered.
408 """
408 """
409 if isinstance(typ, string_types):
409 if isinstance(typ, string_types):
410 typ_key = tuple(typ.rsplit('.',1))
410 typ_key = tuple(typ.rsplit('.',1))
411 if typ_key not in self.deferred_printers:
411 if typ_key not in self.deferred_printers:
412 # We may have it cached in the type map. We will have to
412 # We may have it cached in the type map. We will have to
413 # iterate over all of the types to check.
413 # iterate over all of the types to check.
414 for cls in self.type_printers:
414 for cls in self.type_printers:
415 if _mod_name_key(cls) == typ_key:
415 if _mod_name_key(cls) == typ_key:
416 return self.type_printers[cls]
416 return self.type_printers[cls]
417 else:
417 else:
418 return self.deferred_printers[typ_key]
418 return self.deferred_printers[typ_key]
419 else:
419 else:
420 for cls in pretty._get_mro(typ):
420 for cls in pretty._get_mro(typ):
421 if cls in self.type_printers or self._in_deferred_types(cls):
421 if cls in self.type_printers or self._in_deferred_types(cls):
422 return self.type_printers[cls]
422 return self.type_printers[cls]
423
423
424 # If we have reached here, the lookup failed.
424 # If we have reached here, the lookup failed.
425 raise KeyError("No registered printer for {0!r}".format(typ))
425 raise KeyError("No registered printer for {0!r}".format(typ))
426
426
427 def for_type(self, typ, func=None):
427 def for_type(self, typ, func=None):
428 """Add a format function for a given type.
428 """Add a format function for a given type.
429
429
430 Parameters
430 Parameters
431 -----------
431 -----------
432 typ : type or '__module__.__name__' string for a type
432 typ : type or '__module__.__name__' string for a type
433 The class of the object that will be formatted using `func`.
433 The class of the object that will be formatted using `func`.
434 func : callable
434 func : callable
435 A callable for computing the format data.
435 A callable for computing the format data.
436 `func` will be called with the object to be formatted,
436 `func` will be called with the object to be formatted,
437 and will return the raw data in this formatter's format.
437 and will return the raw data in this formatter's format.
438 Subclasses may use a different call signature for the
438 Subclasses may use a different call signature for the
439 `func` argument.
439 `func` argument.
440
440
441 If `func` is None or not specified, there will be no change,
441 If `func` is None or not specified, there will be no change,
442 only returning the current value.
442 only returning the current value.
443
443
444 Returns
444 Returns
445 -------
445 -------
446 oldfunc : callable
446 oldfunc : callable
447 The currently registered callable.
447 The currently registered callable.
448 If you are registering a new formatter,
448 If you are registering a new formatter,
449 this will be the previous value (to enable restoring later).
449 this will be the previous value (to enable restoring later).
450 """
450 """
451 # if string given, interpret as 'pkg.module.class_name'
451 # if string given, interpret as 'pkg.module.class_name'
452 if isinstance(typ, string_types):
452 if isinstance(typ, string_types):
453 type_module, type_name = typ.rsplit('.', 1)
453 type_module, type_name = typ.rsplit('.', 1)
454 return self.for_type_by_name(type_module, type_name, func)
454 return self.for_type_by_name(type_module, type_name, func)
455
455
456 try:
456 try:
457 oldfunc = self.lookup_by_type(typ)
457 oldfunc = self.lookup_by_type(typ)
458 except KeyError:
458 except KeyError:
459 oldfunc = None
459 oldfunc = None
460
460
461 if func is not None:
461 if func is not None:
462 self.type_printers[typ] = func
462 self.type_printers[typ] = func
463
463
464 return oldfunc
464 return oldfunc
465
465
466 def for_type_by_name(self, type_module, type_name, func=None):
466 def for_type_by_name(self, type_module, type_name, func=None):
467 """Add a format function for a type specified by the full dotted
467 """Add a format function for a type specified by the full dotted
468 module and name of the type, rather than the type of the object.
468 module and name of the type, rather than the type of the object.
469
469
470 Parameters
470 Parameters
471 ----------
471 ----------
472 type_module : str
472 type_module : str
473 The full dotted name of the module the type is defined in, like
473 The full dotted name of the module the type is defined in, like
474 ``numpy``.
474 ``numpy``.
475 type_name : str
475 type_name : str
476 The name of the type (the class name), like ``dtype``
476 The name of the type (the class name), like ``dtype``
477 func : callable
477 func : callable
478 A callable for computing the format data.
478 A callable for computing the format data.
479 `func` will be called with the object to be formatted,
479 `func` will be called with the object to be formatted,
480 and will return the raw data in this formatter's format.
480 and will return the raw data in this formatter's format.
481 Subclasses may use a different call signature for the
481 Subclasses may use a different call signature for the
482 `func` argument.
482 `func` argument.
483
483
484 If `func` is None or unspecified, there will be no change,
484 If `func` is None or unspecified, there will be no change,
485 only returning the current value.
485 only returning the current value.
486
486
487 Returns
487 Returns
488 -------
488 -------
489 oldfunc : callable
489 oldfunc : callable
490 The currently registered callable.
490 The currently registered callable.
491 If you are registering a new formatter,
491 If you are registering a new formatter,
492 this will be the previous value (to enable restoring later).
492 this will be the previous value (to enable restoring later).
493 """
493 """
494 key = (type_module, type_name)
494 key = (type_module, type_name)
495
495
496 try:
496 try:
497 oldfunc = self.lookup_by_type("%s.%s" % key)
497 oldfunc = self.lookup_by_type("%s.%s" % key)
498 except KeyError:
498 except KeyError:
499 oldfunc = None
499 oldfunc = None
500
500
501 if func is not None:
501 if func is not None:
502 self.deferred_printers[key] = func
502 self.deferred_printers[key] = func
503 return oldfunc
503 return oldfunc
504
504
505 def pop(self, typ, default=_raise_key_error):
505 def pop(self, typ, default=_raise_key_error):
506 """Pop a formatter for the given type.
506 """Pop a formatter for the given type.
507
507
508 Parameters
508 Parameters
509 ----------
509 ----------
510 typ : type or '__module__.__name__' string for a type
510 typ : type or '__module__.__name__' string for a type
511 default : object
511 default : object
512 value to be returned if no formatter is registered for typ.
512 value to be returned if no formatter is registered for typ.
513
513
514 Returns
514 Returns
515 -------
515 -------
516 obj : object
516 obj : object
517 The last registered object for the type.
517 The last registered object for the type.
518
518
519 Raises
519 Raises
520 ------
520 ------
521 KeyError if the type is not registered and default is not specified.
521 KeyError if the type is not registered and default is not specified.
522 """
522 """
523
523
524 if isinstance(typ, string_types):
524 if isinstance(typ, string_types):
525 typ_key = tuple(typ.rsplit('.',1))
525 typ_key = tuple(typ.rsplit('.',1))
526 if typ_key not in self.deferred_printers:
526 if typ_key not in self.deferred_printers:
527 # We may have it cached in the type map. We will have to
527 # We may have it cached in the type map. We will have to
528 # iterate over all of the types to check.
528 # iterate over all of the types to check.
529 for cls in self.type_printers:
529 for cls in self.type_printers:
530 if _mod_name_key(cls) == typ_key:
530 if _mod_name_key(cls) == typ_key:
531 old = self.type_printers.pop(cls)
531 old = self.type_printers.pop(cls)
532 break
532 break
533 else:
533 else:
534 old = default
534 old = default
535 else:
535 else:
536 old = self.deferred_printers.pop(typ_key)
536 old = self.deferred_printers.pop(typ_key)
537 else:
537 else:
538 if typ in self.type_printers:
538 if typ in self.type_printers:
539 old = self.type_printers.pop(typ)
539 old = self.type_printers.pop(typ)
540 else:
540 else:
541 old = self.deferred_printers.pop(_mod_name_key(typ), default)
541 old = self.deferred_printers.pop(_mod_name_key(typ), default)
542 if old is _raise_key_error:
542 if old is _raise_key_error:
543 raise KeyError("No registered value for {0!r}".format(typ))
543 raise KeyError("No registered value for {0!r}".format(typ))
544 return old
544 return old
545
545
546 def _in_deferred_types(self, cls):
546 def _in_deferred_types(self, cls):
547 """
547 """
548 Check if the given class is specified in the deferred type registry.
548 Check if the given class is specified in the deferred type registry.
549
549
550 Successful matches will be moved to the regular type registry for future use.
550 Successful matches will be moved to the regular type registry for future use.
551 """
551 """
552 mod = getattr(cls, '__module__', None)
552 mod = getattr(cls, '__module__', None)
553 name = getattr(cls, '__name__', None)
553 name = getattr(cls, '__name__', None)
554 key = (mod, name)
554 key = (mod, name)
555 if key in self.deferred_printers:
555 if key in self.deferred_printers:
556 # Move the printer over to the regular registry.
556 # Move the printer over to the regular registry.
557 printer = self.deferred_printers.pop(key)
557 printer = self.deferred_printers.pop(key)
558 self.type_printers[cls] = printer
558 self.type_printers[cls] = printer
559 return True
559 return True
560 return False
560 return False
561
561
562
562
563 class PlainTextFormatter(BaseFormatter):
563 class PlainTextFormatter(BaseFormatter):
564 """The default pretty-printer.
564 """The default pretty-printer.
565
565
566 This uses :mod:`IPython.lib.pretty` to compute the format data of
566 This uses :mod:`IPython.lib.pretty` to compute the format data of
567 the object. If the object cannot be pretty printed, :func:`repr` is used.
567 the object. If the object cannot be pretty printed, :func:`repr` is used.
568 See the documentation of :mod:`IPython.lib.pretty` for details on
568 See the documentation of :mod:`IPython.lib.pretty` for details on
569 how to write pretty printers. Here is a simple example::
569 how to write pretty printers. Here is a simple example::
570
570
571 def dtype_pprinter(obj, p, cycle):
571 def dtype_pprinter(obj, p, cycle):
572 if cycle:
572 if cycle:
573 return p.text('dtype(...)')
573 return p.text('dtype(...)')
574 if hasattr(obj, 'fields'):
574 if hasattr(obj, 'fields'):
575 if obj.fields is None:
575 if obj.fields is None:
576 p.text(repr(obj))
576 p.text(repr(obj))
577 else:
577 else:
578 p.begin_group(7, 'dtype([')
578 p.begin_group(7, 'dtype([')
579 for i, field in enumerate(obj.descr):
579 for i, field in enumerate(obj.descr):
580 if i > 0:
580 if i > 0:
581 p.text(',')
581 p.text(',')
582 p.breakable()
582 p.breakable()
583 p.pretty(field)
583 p.pretty(field)
584 p.end_group(7, '])')
584 p.end_group(7, '])')
585 """
585 """
586
586
587 # The format type of data returned.
587 # The format type of data returned.
588 format_type = Unicode('text/plain')
588 format_type = Unicode('text/plain')
589
589
590 # This subclass ignores this attribute as it always need to return
590 # This subclass ignores this attribute as it always need to return
591 # something.
591 # something.
592 enabled = Bool(True, config=False)
592 enabled = Bool(True, config=False)
593
593
594 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH, config=True,
594 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH, config=True,
595 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
595 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
596
596
597 Set to 0 to disable truncation.
597 Set to 0 to disable truncation.
598 """
598 """
599 )
599 )
600
600
601 # Look for a _repr_pretty_ methods to use for pretty printing.
601 # Look for a _repr_pretty_ methods to use for pretty printing.
602 print_method = ObjectName('_repr_pretty_')
602 print_method = ObjectName('_repr_pretty_')
603
603
604 # Whether to pretty-print or not.
604 # Whether to pretty-print or not.
605 pprint = Bool(True, config=True)
605 pprint = Bool(True, config=True)
606
606
607 # Whether to be verbose or not.
607 # Whether to be verbose or not.
608 verbose = Bool(False, config=True)
608 verbose = Bool(False, config=True)
609
609
610 # The maximum width.
610 # The maximum width.
611 max_width = Integer(79, config=True)
611 max_width = Integer(79, config=True)
612
612
613 # The newline character.
613 # The newline character.
614 newline = Unicode('\n', config=True)
614 newline = Unicode('\n', config=True)
615
615
616 # format-string for pprinting floats
616 # format-string for pprinting floats
617 float_format = Unicode('%r')
617 float_format = Unicode('%r')
618 # setter for float precision, either int or direct format-string
618 # setter for float precision, either int or direct format-string
619 float_precision = CUnicode('', config=True)
619 float_precision = CUnicode('', config=True)
620
620
621 def _float_precision_changed(self, name, old, new):
621 def _float_precision_changed(self, name, old, new):
622 """float_precision changed, set float_format accordingly.
622 """float_precision changed, set float_format accordingly.
623
623
624 float_precision can be set by int or str.
624 float_precision can be set by int or str.
625 This will set float_format, after interpreting input.
625 This will set float_format, after interpreting input.
626 If numpy has been imported, numpy print precision will also be set.
626 If numpy has been imported, numpy print precision will also be set.
627
627
628 integer `n` sets format to '%.nf', otherwise, format set directly.
628 integer `n` sets format to '%.nf', otherwise, format set directly.
629
629
630 An empty string returns to defaults (repr for float, 8 for numpy).
630 An empty string returns to defaults (repr for float, 8 for numpy).
631
631
632 This parameter can be set via the '%precision' magic.
632 This parameter can be set via the '%precision' magic.
633 """
633 """
634
634
635 if '%' in new:
635 if '%' in new:
636 # got explicit format string
636 # got explicit format string
637 fmt = new
637 fmt = new
638 try:
638 try:
639 fmt%3.14159
639 fmt%3.14159
640 except Exception:
640 except Exception:
641 raise ValueError("Precision must be int or format string, not %r"%new)
641 raise ValueError("Precision must be int or format string, not %r"%new)
642 elif new:
642 elif new:
643 # otherwise, should be an int
643 # otherwise, should be an int
644 try:
644 try:
645 i = int(new)
645 i = int(new)
646 assert i >= 0
646 assert i >= 0
647 except ValueError:
647 except ValueError:
648 raise ValueError("Precision must be int or format string, not %r"%new)
648 raise ValueError("Precision must be int or format string, not %r"%new)
649 except AssertionError:
649 except AssertionError:
650 raise ValueError("int precision must be non-negative, not %r"%i)
650 raise ValueError("int precision must be non-negative, not %r"%i)
651
651
652 fmt = '%%.%if'%i
652 fmt = '%%.%if'%i
653 if 'numpy' in sys.modules:
653 if 'numpy' in sys.modules:
654 # set numpy precision if it has been imported
654 # set numpy precision if it has been imported
655 import numpy
655 import numpy
656 numpy.set_printoptions(precision=i)
656 numpy.set_printoptions(precision=i)
657 else:
657 else:
658 # default back to repr
658 # default back to repr
659 fmt = '%r'
659 fmt = '%r'
660 if 'numpy' in sys.modules:
660 if 'numpy' in sys.modules:
661 import numpy
661 import numpy
662 # numpy default is 8
662 # numpy default is 8
663 numpy.set_printoptions(precision=8)
663 numpy.set_printoptions(precision=8)
664 self.float_format = fmt
664 self.float_format = fmt
665
665
666 # Use the default pretty printers from IPython.lib.pretty.
666 # Use the default pretty printers from IPython.lib.pretty.
667 def _singleton_printers_default(self):
667 def _singleton_printers_default(self):
668 return pretty._singleton_pprinters.copy()
668 return pretty._singleton_pprinters.copy()
669
669
670 def _type_printers_default(self):
670 def _type_printers_default(self):
671 d = pretty._type_pprinters.copy()
671 d = pretty._type_pprinters.copy()
672 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
672 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
673 return d
673 return d
674
674
675 def _deferred_printers_default(self):
675 def _deferred_printers_default(self):
676 return pretty._deferred_type_pprinters.copy()
676 return pretty._deferred_type_pprinters.copy()
677
677
678 #### FormatterABC interface ####
678 #### FormatterABC interface ####
679
679
680 @catch_format_error
680 @catch_format_error
681 def __call__(self, obj):
681 def __call__(self, obj):
682 """Compute the pretty representation of the object."""
682 """Compute the pretty representation of the object."""
683 if not self.pprint:
683 if not self.pprint:
684 return repr(obj)
684 return repr(obj)
685 else:
685 else:
686 # handle str and unicode on Python 2
686 # handle str and unicode on Python 2
687 # io.StringIO only accepts unicode,
687 # io.StringIO only accepts unicode,
688 # cStringIO doesn't handle unicode on py2,
688 # cStringIO doesn't handle unicode on py2,
689 # StringIO allows str, unicode but only ascii str
689 # StringIO allows str, unicode but only ascii str
690 stream = pretty.CUnicodeIO()
690 stream = pretty.CUnicodeIO()
691 printer = pretty.RepresentationPrinter(stream, self.verbose,
691 printer = pretty.RepresentationPrinter(stream, self.verbose,
692 self.max_width, self.newline,
692 self.max_width, self.newline,
693 max_seq_length=self.max_seq_length,
693 max_seq_length=self.max_seq_length,
694 singleton_pprinters=self.singleton_printers,
694 singleton_pprinters=self.singleton_printers,
695 type_pprinters=self.type_printers,
695 type_pprinters=self.type_printers,
696 deferred_pprinters=self.deferred_printers)
696 deferred_pprinters=self.deferred_printers)
697 printer.pretty(obj)
697 printer.pretty(obj)
698 printer.flush()
698 printer.flush()
699 return stream.getvalue()
699 return stream.getvalue()
700
700
701
701
702 class HTMLFormatter(BaseFormatter):
702 class HTMLFormatter(BaseFormatter):
703 """An HTML formatter.
703 """An HTML formatter.
704
704
705 To define the callables that compute the HTML representation of your
705 To define the callables that compute the HTML representation of your
706 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
706 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
707 or :meth:`for_type_by_name` methods to register functions that handle
707 or :meth:`for_type_by_name` methods to register functions that handle
708 this.
708 this.
709
709
710 The return value of this formatter should be a valid HTML snippet that
710 The return value of this formatter should be a valid HTML snippet that
711 could be injected into an existing DOM. It should *not* include the
711 could be injected into an existing DOM. It should *not* include the
712 ```<html>`` or ```<body>`` tags.
712 ```<html>`` or ```<body>`` tags.
713 """
713 """
714 format_type = Unicode('text/html')
714 format_type = Unicode('text/html')
715
715
716 print_method = ObjectName('_repr_html_')
716 print_method = ObjectName('_repr_html_')
717
717
718
718
719 class MarkdownFormatter(BaseFormatter):
719 class MarkdownFormatter(BaseFormatter):
720 """A Markdown formatter.
720 """A Markdown formatter.
721
721
722 To define the callables that compute the Markdown representation of your
722 To define the callables that compute the Markdown representation of your
723 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
723 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
724 or :meth:`for_type_by_name` methods to register functions that handle
724 or :meth:`for_type_by_name` methods to register functions that handle
725 this.
725 this.
726
726
727 The return value of this formatter should be a valid Markdown.
727 The return value of this formatter should be a valid Markdown.
728 """
728 """
729 format_type = Unicode('text/markdown')
729 format_type = Unicode('text/markdown')
730
730
731 print_method = ObjectName('_repr_markdown_')
731 print_method = ObjectName('_repr_markdown_')
732
732
733 class SVGFormatter(BaseFormatter):
733 class SVGFormatter(BaseFormatter):
734 """An SVG formatter.
734 """An SVG formatter.
735
735
736 To define the callables that compute the SVG representation of your
736 To define the callables that compute the SVG representation of your
737 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
737 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
738 or :meth:`for_type_by_name` methods to register functions that handle
738 or :meth:`for_type_by_name` methods to register functions that handle
739 this.
739 this.
740
740
741 The return value of this formatter should be valid SVG enclosed in
741 The return value of this formatter should be valid SVG enclosed in
742 ```<svg>``` tags, that could be injected into an existing DOM. It should
742 ```<svg>``` tags, that could be injected into an existing DOM. It should
743 *not* include the ```<html>`` or ```<body>`` tags.
743 *not* include the ```<html>`` or ```<body>`` tags.
744 """
744 """
745 format_type = Unicode('image/svg+xml')
745 format_type = Unicode('image/svg+xml')
746
746
747 print_method = ObjectName('_repr_svg_')
747 print_method = ObjectName('_repr_svg_')
748
748
749
749
750 class PNGFormatter(BaseFormatter):
750 class PNGFormatter(BaseFormatter):
751 """A PNG formatter.
751 """A PNG formatter.
752
752
753 To define the callables that compute the PNG representation of your
753 To define the callables that compute the PNG representation of your
754 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
754 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
755 or :meth:`for_type_by_name` methods to register functions that handle
755 or :meth:`for_type_by_name` methods to register functions that handle
756 this.
756 this.
757
757
758 The return value of this formatter should be raw PNG data, *not*
758 The return value of this formatter should be raw PNG data, *not*
759 base64 encoded.
759 base64 encoded.
760 """
760 """
761 format_type = Unicode('image/png')
761 format_type = Unicode('image/png')
762
762
763 print_method = ObjectName('_repr_png_')
763 print_method = ObjectName('_repr_png_')
764
764
765 _return_type = (bytes, unicode_type)
765 _return_type = (bytes, unicode_type)
766
766
767
767
768 class JPEGFormatter(BaseFormatter):
768 class JPEGFormatter(BaseFormatter):
769 """A JPEG formatter.
769 """A JPEG formatter.
770
770
771 To define the callables that compute the JPEG representation of your
771 To define the callables that compute the JPEG representation of your
772 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
772 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
773 or :meth:`for_type_by_name` methods to register functions that handle
773 or :meth:`for_type_by_name` methods to register functions that handle
774 this.
774 this.
775
775
776 The return value of this formatter should be raw JPEG data, *not*
776 The return value of this formatter should be raw JPEG data, *not*
777 base64 encoded.
777 base64 encoded.
778 """
778 """
779 format_type = Unicode('image/jpeg')
779 format_type = Unicode('image/jpeg')
780
780
781 print_method = ObjectName('_repr_jpeg_')
781 print_method = ObjectName('_repr_jpeg_')
782
782
783 _return_type = (bytes, unicode_type)
783 _return_type = (bytes, unicode_type)
784
784
785
785
786 class LatexFormatter(BaseFormatter):
786 class LatexFormatter(BaseFormatter):
787 """A LaTeX formatter.
787 """A LaTeX formatter.
788
788
789 To define the callables that compute the LaTeX representation of your
789 To define the callables that compute the LaTeX representation of your
790 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
790 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
791 or :meth:`for_type_by_name` methods to register functions that handle
791 or :meth:`for_type_by_name` methods to register functions that handle
792 this.
792 this.
793
793
794 The return value of this formatter should be a valid LaTeX equation,
794 The return value of this formatter should be a valid LaTeX equation,
795 enclosed in either ```$```, ```$$``` or another LaTeX equation
795 enclosed in either ```$```, ```$$``` or another LaTeX equation
796 environment.
796 environment.
797 """
797 """
798 format_type = Unicode('text/latex')
798 format_type = Unicode('text/latex')
799
799
800 print_method = ObjectName('_repr_latex_')
800 print_method = ObjectName('_repr_latex_')
801
801
802
802
803 class JSONFormatter(BaseFormatter):
803 class JSONFormatter(BaseFormatter):
804 """A JSON string formatter.
804 """A JSON string formatter.
805
805
806 To define the callables that compute the JSONable representation of
806 To define the callables that compute the JSONable representation of
807 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
807 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
808 or :meth:`for_type_by_name` methods to register functions that handle
808 or :meth:`for_type_by_name` methods to register functions that handle
809 this.
809 this.
810
810
811 The return value of this formatter should be a JSONable list or dict.
811 The return value of this formatter should be a JSONable list or dict.
812 JSON scalars (None, number, string) are not allowed, only dict or list containers.
812 JSON scalars (None, number, string) are not allowed, only dict or list containers.
813 """
813 """
814 format_type = Unicode('application/json')
814 format_type = Unicode('application/json')
815 _return_type = (list, dict)
815 _return_type = (list, dict)
816
816
817 print_method = ObjectName('_repr_json_')
817 print_method = ObjectName('_repr_json_')
818
818
819 def _check_return(self, r, obj):
819 def _check_return(self, r, obj):
820 """Check that a return value is appropriate
820 """Check that a return value is appropriate
821
821
822 Return the value if so, None otherwise, warning if invalid.
822 Return the value if so, None otherwise, warning if invalid.
823 """
823 """
824 if r is None:
824 if r is None:
825 return
825 return
826 md = None
826 md = None
827 if isinstance(r, tuple):
827 if isinstance(r, tuple):
828 # unpack data, metadata tuple for type checking on first element
828 # unpack data, metadata tuple for type checking on first element
829 r, md = r
829 r, md = r
830
830
831 # handle deprecated JSON-as-string form from IPython < 3
831 # handle deprecated JSON-as-string form from IPython < 3
832 if isinstance(r, string_types):
832 if isinstance(r, string_types):
833 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
833 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
834 FormatterWarning)
834 FormatterWarning)
835 r = json.loads(r)
835 r = json.loads(r)
836
836
837 if md is not None:
837 if md is not None:
838 # put the tuple back together
838 # put the tuple back together
839 r = (r, md)
839 r = (r, md)
840 return super(JSONFormatter, self)._check_return(r, obj)
840 return super(JSONFormatter, self)._check_return(r, obj)
841
841
842
842
843 class JavascriptFormatter(BaseFormatter):
843 class JavascriptFormatter(BaseFormatter):
844 """A Javascript formatter.
844 """A Javascript formatter.
845
845
846 To define the callables that compute the Javascript representation of
846 To define the callables that compute the Javascript representation of
847 your objects, define a :meth:`_repr_javascript_` method or use the
847 your objects, define a :meth:`_repr_javascript_` method or use the
848 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
848 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
849 that handle this.
849 that handle this.
850
850
851 The return value of this formatter should be valid Javascript code and
851 The return value of this formatter should be valid Javascript code and
852 should *not* be enclosed in ```<script>``` tags.
852 should *not* be enclosed in ```<script>``` tags.
853 """
853 """
854 format_type = Unicode('application/javascript')
854 format_type = Unicode('application/javascript')
855
855
856 print_method = ObjectName('_repr_javascript_')
856 print_method = ObjectName('_repr_javascript_')
857
857
858
858
859 class PDFFormatter(BaseFormatter):
859 class PDFFormatter(BaseFormatter):
860 """A PDF formatter.
860 """A PDF formatter.
861
861
862 To define the callables that compute the PDF representation of your
862 To define the callables that compute the PDF representation of your
863 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
863 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
864 or :meth:`for_type_by_name` methods to register functions that handle
864 or :meth:`for_type_by_name` methods to register functions that handle
865 this.
865 this.
866
866
867 The return value of this formatter should be raw PDF data, *not*
867 The return value of this formatter should be raw PDF data, *not*
868 base64 encoded.
868 base64 encoded.
869 """
869 """
870 format_type = Unicode('application/pdf')
870 format_type = Unicode('application/pdf')
871
871
872 print_method = ObjectName('_repr_pdf_')
872 print_method = ObjectName('_repr_pdf_')
873
873
874 _return_type = (bytes, unicode_type)
874 _return_type = (bytes, unicode_type)
875
875
876 class IPythonDisplayFormatter(BaseFormatter):
876 class IPythonDisplayFormatter(BaseFormatter):
877 """A Formatter for objects that know how to display themselves.
877 """A Formatter for objects that know how to display themselves.
878
878
879 To define the callables that compute the representation of your
879 To define the callables that compute the representation of your
880 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
880 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
881 or :meth:`for_type_by_name` methods to register functions that handle
881 or :meth:`for_type_by_name` methods to register functions that handle
882 this. Unlike mime-type displays, this method should not return anything,
882 this. Unlike mime-type displays, this method should not return anything,
883 instead calling any appropriate display methods itself.
883 instead calling any appropriate display methods itself.
884
884
885 This display formatter has highest priority.
885 This display formatter has highest priority.
886 If it fires, no other display formatter will be called.
886 If it fires, no other display formatter will be called.
887 """
887 """
888 print_method = ObjectName('_ipython_display_')
888 print_method = ObjectName('_ipython_display_')
889 _return_type = (type(None), bool)
889 _return_type = (type(None), bool)
890
890
891
891
892 @catch_format_error
892 @catch_format_error
893 def __call__(self, obj):
893 def __call__(self, obj):
894 """Compute the format for an object."""
894 """Compute the format for an object."""
895 if self.enabled:
895 if self.enabled:
896 # lookup registered printer
896 # lookup registered printer
897 try:
897 try:
898 printer = self.lookup(obj)
898 printer = self.lookup(obj)
899 except KeyError:
899 except KeyError:
900 pass
900 pass
901 else:
901 else:
902 printer(obj)
902 printer(obj)
903 return True
903 return True
904 # Finally look for special method names
904 # Finally look for special method names
905 method = _safe_get_formatter_method(obj, self.print_method)
905 method = _safe_get_formatter_method(obj, self.print_method)
906 if method is not None:
906 if method is not None:
907 method()
907 method()
908 return True
908 return True
909
909
910
910
911 FormatterABC.register(BaseFormatter)
911 FormatterABC.register(BaseFormatter)
912 FormatterABC.register(PlainTextFormatter)
912 FormatterABC.register(PlainTextFormatter)
913 FormatterABC.register(HTMLFormatter)
913 FormatterABC.register(HTMLFormatter)
914 FormatterABC.register(MarkdownFormatter)
914 FormatterABC.register(MarkdownFormatter)
915 FormatterABC.register(SVGFormatter)
915 FormatterABC.register(SVGFormatter)
916 FormatterABC.register(PNGFormatter)
916 FormatterABC.register(PNGFormatter)
917 FormatterABC.register(PDFFormatter)
917 FormatterABC.register(PDFFormatter)
918 FormatterABC.register(JPEGFormatter)
918 FormatterABC.register(JPEGFormatter)
919 FormatterABC.register(LatexFormatter)
919 FormatterABC.register(LatexFormatter)
920 FormatterABC.register(JSONFormatter)
920 FormatterABC.register(JSONFormatter)
921 FormatterABC.register(JavascriptFormatter)
921 FormatterABC.register(JavascriptFormatter)
922 FormatterABC.register(IPythonDisplayFormatter)
922 FormatterABC.register(IPythonDisplayFormatter)
923
923
924
924
925 def format_display_data(obj, include=None, exclude=None):
925 def format_display_data(obj, include=None, exclude=None):
926 """Return a format data dict for an object.
926 """Return a format data dict for an object.
927
927
928 By default all format types will be computed.
928 By default all format types will be computed.
929
929
930 The following MIME types are currently implemented:
930 The following MIME types are currently implemented:
931
931
932 * text/plain
932 * text/plain
933 * text/html
933 * text/html
934 * text/markdown
934 * text/markdown
935 * text/latex
935 * text/latex
936 * application/json
936 * application/json
937 * application/javascript
937 * application/javascript
938 * application/pdf
938 * application/pdf
939 * image/png
939 * image/png
940 * image/jpeg
940 * image/jpeg
941 * image/svg+xml
941 * image/svg+xml
942
942
943 Parameters
943 Parameters
944 ----------
944 ----------
945 obj : object
945 obj : object
946 The Python object whose format data will be computed.
946 The Python object whose format data will be computed.
947
947
948 Returns
948 Returns
949 -------
949 -------
950 format_dict : dict
950 format_dict : dict
951 A dictionary of key/value pairs, one or each format that was
951 A dictionary of key/value pairs, one or each format that was
952 generated for the object. The keys are the format types, which
952 generated for the object. The keys are the format types, which
953 will usually be MIME type strings and the values and JSON'able
953 will usually be MIME type strings and the values and JSON'able
954 data structure containing the raw data for the representation in
954 data structure containing the raw data for the representation in
955 that format.
955 that format.
956 include : list or tuple, optional
956 include : list or tuple, optional
957 A list of format type strings (MIME types) to include in the
957 A list of format type strings (MIME types) to include in the
958 format data dict. If this is set *only* the format types included
958 format data dict. If this is set *only* the format types included
959 in this list will be computed.
959 in this list will be computed.
960 exclude : list or tuple, optional
960 exclude : list or tuple, optional
961 A list of format type string (MIME types) to exclue in the format
961 A list of format type string (MIME types) to exclue in the format
962 data dict. If this is set all format types will be computed,
962 data dict. If this is set all format types will be computed,
963 except for those included in this argument.
963 except for those included in this argument.
964 """
964 """
965 from IPython.core.interactiveshell import InteractiveShell
965 from IPython.core.interactiveshell import InteractiveShell
966
966
967 InteractiveShell.instance().display_formatter.format(
967 InteractiveShell.instance().display_formatter.format(
968 obj,
968 obj,
969 include,
969 include,
970 exclude
970 exclude
971 )
971 )
972
972
@@ -1,872 +1,872 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 IPython.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 IPython.utils.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 IPython.utils.warn 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 else:
73 else:
74 @undoc
74 @undoc
75 class DatabaseError(Exception):
75 class DatabaseError(Exception):
76 "Dummy exception when sqlite could not be imported. Should never occur."
76 "Dummy exception when sqlite could not be imported. Should never occur."
77
77
78 @decorator
78 @decorator
79 def catch_corrupt_db(f, self, *a, **kw):
79 def catch_corrupt_db(f, self, *a, **kw):
80 """A decorator which wraps HistoryAccessor method calls to catch errors from
80 """A decorator which wraps HistoryAccessor method calls to catch errors from
81 a corrupt SQLite database, move the old database out of the way, and create
81 a corrupt SQLite database, move the old database out of the way, and create
82 a new one.
82 a new one.
83 """
83 """
84 try:
84 try:
85 return f(self, *a, **kw)
85 return f(self, *a, **kw)
86 except DatabaseError:
86 except DatabaseError:
87 if os.path.isfile(self.hist_file):
87 if os.path.isfile(self.hist_file):
88 # Try to move the file out of the way
88 # Try to move the file out of the way
89 base,ext = os.path.splitext(self.hist_file)
89 base,ext = os.path.splitext(self.hist_file)
90 newpath = base + '-corrupt' + ext
90 newpath = base + '-corrupt' + ext
91 os.rename(self.hist_file, newpath)
91 os.rename(self.hist_file, newpath)
92 self.init_db()
92 self.init_db()
93 print("ERROR! History file wasn't a valid SQLite database.",
93 print("ERROR! History file wasn't a valid SQLite database.",
94 "It was moved to %s" % newpath, "and a new file created.")
94 "It was moved to %s" % newpath, "and a new file created.")
95 return []
95 return []
96
96
97 else:
97 else:
98 # The hist_file is probably :memory: or something else.
98 # The hist_file is probably :memory: or something else.
99 raise
99 raise
100
100
101 class HistoryAccessorBase(Configurable):
101 class HistoryAccessorBase(Configurable):
102 """An abstract class for History Accessors """
102 """An abstract class for History Accessors """
103
103
104 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
104 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
105 raise NotImplementedError
105 raise NotImplementedError
106
106
107 def search(self, pattern="*", raw=True, search_raw=True,
107 def search(self, pattern="*", raw=True, search_raw=True,
108 output=False, n=None, unique=False):
108 output=False, n=None, unique=False):
109 raise NotImplementedError
109 raise NotImplementedError
110
110
111 def get_range(self, session, start=1, stop=None, raw=True,output=False):
111 def get_range(self, session, start=1, stop=None, raw=True,output=False):
112 raise NotImplementedError
112 raise NotImplementedError
113
113
114 def get_range_by_str(self, rangestr, raw=True, output=False):
114 def get_range_by_str(self, rangestr, raw=True, output=False):
115 raise NotImplementedError
115 raise NotImplementedError
116
116
117
117
118 class HistoryAccessor(HistoryAccessorBase):
118 class HistoryAccessor(HistoryAccessorBase):
119 """Access the history database without adding to it.
119 """Access the history database without adding to it.
120
120
121 This is intended for use by standalone history tools. IPython shells use
121 This is intended for use by standalone history tools. IPython shells use
122 HistoryManager, below, which is a subclass of this."""
122 HistoryManager, below, which is a subclass of this."""
123
123
124 # String holding the path to the history file
124 # String holding the path to the history file
125 hist_file = Unicode(config=True,
125 hist_file = Unicode(config=True,
126 help="""Path to file to use for SQLite history database.
126 help="""Path to file to use for SQLite history database.
127
127
128 By default, IPython will put the history database in the IPython
128 By default, IPython will put the history database in the IPython
129 profile directory. If you would rather share one history among
129 profile directory. If you would rather share one history among
130 profiles, you can set this value in each, so that they are consistent.
130 profiles, you can set this value in each, so that they are consistent.
131
131
132 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
132 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
133 mounts. If you see IPython hanging, try setting this to something on a
133 mounts. If you see IPython hanging, try setting this to something on a
134 local disk, e.g::
134 local disk, e.g::
135
135
136 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
136 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
137
137
138 """)
138 """)
139
139
140 enabled = Bool(True, config=True,
140 enabled = Bool(True, config=True,
141 help="""enable the SQLite history
141 help="""enable the SQLite history
142
142
143 set enabled=False to disable the SQLite history,
143 set enabled=False to disable the SQLite history,
144 in which case there will be no stored history, no SQLite connection,
144 in which case there will be no stored history, no SQLite connection,
145 and no background saving thread. This may be necessary in some
145 and no background saving thread. This may be necessary in some
146 threaded environments where IPython is embedded.
146 threaded environments where IPython is embedded.
147 """
147 """
148 )
148 )
149
149
150 connection_options = Dict(config=True,
150 connection_options = Dict(config=True,
151 help="""Options for configuring the SQLite connection
151 help="""Options for configuring the SQLite connection
152
152
153 These options are passed as keyword args to sqlite3.connect
153 These options are passed as keyword args to sqlite3.connect
154 when establishing database conenctions.
154 when establishing database conenctions.
155 """
155 """
156 )
156 )
157
157
158 # The SQLite database
158 # The SQLite database
159 db = Any()
159 db = Any()
160 def _db_changed(self, name, old, new):
160 def _db_changed(self, name, old, new):
161 """validate the db, since it can be an Instance of two different types"""
161 """validate the db, since it can be an Instance of two different types"""
162 connection_types = (DummyDB,)
162 connection_types = (DummyDB,)
163 if sqlite3 is not None:
163 if sqlite3 is not None:
164 connection_types = (DummyDB, sqlite3.Connection)
164 connection_types = (DummyDB, sqlite3.Connection)
165 if not isinstance(new, connection_types):
165 if not isinstance(new, connection_types):
166 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
166 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
167 (self.__class__.__name__, new)
167 (self.__class__.__name__, new)
168 raise TraitError(msg)
168 raise TraitError(msg)
169
169
170 def __init__(self, profile='default', hist_file=u'', **traits):
170 def __init__(self, profile='default', hist_file=u'', **traits):
171 """Create a new history accessor.
171 """Create a new history accessor.
172
172
173 Parameters
173 Parameters
174 ----------
174 ----------
175 profile : str
175 profile : str
176 The name of the profile from which to open history.
176 The name of the profile from which to open history.
177 hist_file : str
177 hist_file : str
178 Path to an SQLite history database stored by IPython. If specified,
178 Path to an SQLite history database stored by IPython. If specified,
179 hist_file overrides profile.
179 hist_file overrides profile.
180 config : :class:`~IPython.config.loader.Config`
180 config : :class:`~traitlets.config.loader.Config`
181 Config object. hist_file can also be set through this.
181 Config object. hist_file can also be set through this.
182 """
182 """
183 # We need a pointer back to the shell for various tasks.
183 # We need a pointer back to the shell for various tasks.
184 super(HistoryAccessor, self).__init__(**traits)
184 super(HistoryAccessor, self).__init__(**traits)
185 # defer setting hist_file from kwarg until after init,
185 # defer setting hist_file from kwarg until after init,
186 # otherwise the default kwarg value would clobber any value
186 # otherwise the default kwarg value would clobber any value
187 # set by config
187 # set by config
188 if hist_file:
188 if hist_file:
189 self.hist_file = hist_file
189 self.hist_file = hist_file
190
190
191 if self.hist_file == u'':
191 if self.hist_file == u'':
192 # No one has set the hist_file, yet.
192 # No one has set the hist_file, yet.
193 self.hist_file = self._get_hist_file_name(profile)
193 self.hist_file = self._get_hist_file_name(profile)
194
194
195 if sqlite3 is None and self.enabled:
195 if sqlite3 is None and self.enabled:
196 warn("IPython History requires SQLite, your history will not be saved")
196 warn("IPython History requires SQLite, your history will not be saved")
197 self.enabled = False
197 self.enabled = False
198
198
199 self.init_db()
199 self.init_db()
200
200
201 def _get_hist_file_name(self, profile='default'):
201 def _get_hist_file_name(self, profile='default'):
202 """Find the history file for the given profile name.
202 """Find the history file for the given profile name.
203
203
204 This is overridden by the HistoryManager subclass, to use the shell's
204 This is overridden by the HistoryManager subclass, to use the shell's
205 active profile.
205 active profile.
206
206
207 Parameters
207 Parameters
208 ----------
208 ----------
209 profile : str
209 profile : str
210 The name of a profile which has a history file.
210 The name of a profile which has a history file.
211 """
211 """
212 return os.path.join(locate_profile(profile), 'history.sqlite')
212 return os.path.join(locate_profile(profile), 'history.sqlite')
213
213
214 @catch_corrupt_db
214 @catch_corrupt_db
215 def init_db(self):
215 def init_db(self):
216 """Connect to the database, and create tables if necessary."""
216 """Connect to the database, and create tables if necessary."""
217 if not self.enabled:
217 if not self.enabled:
218 self.db = DummyDB()
218 self.db = DummyDB()
219 return
219 return
220
220
221 # use detect_types so that timestamps return datetime objects
221 # use detect_types so that timestamps return datetime objects
222 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
222 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
223 kwargs.update(self.connection_options)
223 kwargs.update(self.connection_options)
224 self.db = sqlite3.connect(self.hist_file, **kwargs)
224 self.db = sqlite3.connect(self.hist_file, **kwargs)
225 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
225 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
226 primary key autoincrement, start timestamp,
226 primary key autoincrement, start timestamp,
227 end timestamp, num_cmds integer, remark text)""")
227 end timestamp, num_cmds integer, remark text)""")
228 self.db.execute("""CREATE TABLE IF NOT EXISTS history
228 self.db.execute("""CREATE TABLE IF NOT EXISTS history
229 (session integer, line integer, source text, source_raw text,
229 (session integer, line integer, source text, source_raw text,
230 PRIMARY KEY (session, line))""")
230 PRIMARY KEY (session, line))""")
231 # Output history is optional, but ensure the table's there so it can be
231 # Output history is optional, but ensure the table's there so it can be
232 # enabled later.
232 # enabled later.
233 self.db.execute("""CREATE TABLE IF NOT EXISTS output_history
233 self.db.execute("""CREATE TABLE IF NOT EXISTS output_history
234 (session integer, line integer, output text,
234 (session integer, line integer, output text,
235 PRIMARY KEY (session, line))""")
235 PRIMARY KEY (session, line))""")
236 self.db.commit()
236 self.db.commit()
237
237
238 def writeout_cache(self):
238 def writeout_cache(self):
239 """Overridden by HistoryManager to dump the cache before certain
239 """Overridden by HistoryManager to dump the cache before certain
240 database lookups."""
240 database lookups."""
241 pass
241 pass
242
242
243 ## -------------------------------
243 ## -------------------------------
244 ## Methods for retrieving history:
244 ## Methods for retrieving history:
245 ## -------------------------------
245 ## -------------------------------
246 def _run_sql(self, sql, params, raw=True, output=False):
246 def _run_sql(self, sql, params, raw=True, output=False):
247 """Prepares and runs an SQL query for the history database.
247 """Prepares and runs an SQL query for the history database.
248
248
249 Parameters
249 Parameters
250 ----------
250 ----------
251 sql : str
251 sql : str
252 Any filtering expressions to go after SELECT ... FROM ...
252 Any filtering expressions to go after SELECT ... FROM ...
253 params : tuple
253 params : tuple
254 Parameters passed to the SQL query (to replace "?")
254 Parameters passed to the SQL query (to replace "?")
255 raw, output : bool
255 raw, output : bool
256 See :meth:`get_range`
256 See :meth:`get_range`
257
257
258 Returns
258 Returns
259 -------
259 -------
260 Tuples as :meth:`get_range`
260 Tuples as :meth:`get_range`
261 """
261 """
262 toget = 'source_raw' if raw else 'source'
262 toget = 'source_raw' if raw else 'source'
263 sqlfrom = "history"
263 sqlfrom = "history"
264 if output:
264 if output:
265 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
265 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
266 toget = "history.%s, output_history.output" % toget
266 toget = "history.%s, output_history.output" % toget
267 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
267 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
268 (toget, sqlfrom) + sql, params)
268 (toget, sqlfrom) + sql, params)
269 if output: # Regroup into 3-tuples, and parse JSON
269 if output: # Regroup into 3-tuples, and parse JSON
270 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
270 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
271 return cur
271 return cur
272
272
273 @needs_sqlite
273 @needs_sqlite
274 @catch_corrupt_db
274 @catch_corrupt_db
275 def get_session_info(self, session):
275 def get_session_info(self, session):
276 """Get info about a session.
276 """Get info about a session.
277
277
278 Parameters
278 Parameters
279 ----------
279 ----------
280
280
281 session : int
281 session : int
282 Session number to retrieve.
282 Session number to retrieve.
283
283
284 Returns
284 Returns
285 -------
285 -------
286
286
287 session_id : int
287 session_id : int
288 Session ID number
288 Session ID number
289 start : datetime
289 start : datetime
290 Timestamp for the start of the session.
290 Timestamp for the start of the session.
291 end : datetime
291 end : datetime
292 Timestamp for the end of the session, or None if IPython crashed.
292 Timestamp for the end of the session, or None if IPython crashed.
293 num_cmds : int
293 num_cmds : int
294 Number of commands run, or None if IPython crashed.
294 Number of commands run, or None if IPython crashed.
295 remark : unicode
295 remark : unicode
296 A manually set description.
296 A manually set description.
297 """
297 """
298 query = "SELECT * from sessions where session == ?"
298 query = "SELECT * from sessions where session == ?"
299 return self.db.execute(query, (session,)).fetchone()
299 return self.db.execute(query, (session,)).fetchone()
300
300
301 @catch_corrupt_db
301 @catch_corrupt_db
302 def get_last_session_id(self):
302 def get_last_session_id(self):
303 """Get the last session ID currently in the database.
303 """Get the last session ID currently in the database.
304
304
305 Within IPython, this should be the same as the value stored in
305 Within IPython, this should be the same as the value stored in
306 :attr:`HistoryManager.session_number`.
306 :attr:`HistoryManager.session_number`.
307 """
307 """
308 for record in self.get_tail(n=1, include_latest=True):
308 for record in self.get_tail(n=1, include_latest=True):
309 return record[0]
309 return record[0]
310
310
311 @catch_corrupt_db
311 @catch_corrupt_db
312 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
312 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
313 """Get the last n lines from the history database.
313 """Get the last n lines from the history database.
314
314
315 Parameters
315 Parameters
316 ----------
316 ----------
317 n : int
317 n : int
318 The number of lines to get
318 The number of lines to get
319 raw, output : bool
319 raw, output : bool
320 See :meth:`get_range`
320 See :meth:`get_range`
321 include_latest : bool
321 include_latest : bool
322 If False (default), n+1 lines are fetched, and the latest one
322 If False (default), n+1 lines are fetched, and the latest one
323 is discarded. This is intended to be used where the function
323 is discarded. This is intended to be used where the function
324 is called by a user command, which it should not return.
324 is called by a user command, which it should not return.
325
325
326 Returns
326 Returns
327 -------
327 -------
328 Tuples as :meth:`get_range`
328 Tuples as :meth:`get_range`
329 """
329 """
330 self.writeout_cache()
330 self.writeout_cache()
331 if not include_latest:
331 if not include_latest:
332 n += 1
332 n += 1
333 cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?",
333 cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?",
334 (n,), raw=raw, output=output)
334 (n,), raw=raw, output=output)
335 if not include_latest:
335 if not include_latest:
336 return reversed(list(cur)[1:])
336 return reversed(list(cur)[1:])
337 return reversed(list(cur))
337 return reversed(list(cur))
338
338
339 @catch_corrupt_db
339 @catch_corrupt_db
340 def search(self, pattern="*", raw=True, search_raw=True,
340 def search(self, pattern="*", raw=True, search_raw=True,
341 output=False, n=None, unique=False):
341 output=False, n=None, unique=False):
342 """Search the database using unix glob-style matching (wildcards
342 """Search the database using unix glob-style matching (wildcards
343 * and ?).
343 * and ?).
344
344
345 Parameters
345 Parameters
346 ----------
346 ----------
347 pattern : str
347 pattern : str
348 The wildcarded pattern to match when searching
348 The wildcarded pattern to match when searching
349 search_raw : bool
349 search_raw : bool
350 If True, search the raw input, otherwise, the parsed input
350 If True, search the raw input, otherwise, the parsed input
351 raw, output : bool
351 raw, output : bool
352 See :meth:`get_range`
352 See :meth:`get_range`
353 n : None or int
353 n : None or int
354 If an integer is given, it defines the limit of
354 If an integer is given, it defines the limit of
355 returned entries.
355 returned entries.
356 unique : bool
356 unique : bool
357 When it is true, return only unique entries.
357 When it is true, return only unique entries.
358
358
359 Returns
359 Returns
360 -------
360 -------
361 Tuples as :meth:`get_range`
361 Tuples as :meth:`get_range`
362 """
362 """
363 tosearch = "source_raw" if search_raw else "source"
363 tosearch = "source_raw" if search_raw else "source"
364 if output:
364 if output:
365 tosearch = "history." + tosearch
365 tosearch = "history." + tosearch
366 self.writeout_cache()
366 self.writeout_cache()
367 sqlform = "WHERE %s GLOB ?" % tosearch
367 sqlform = "WHERE %s GLOB ?" % tosearch
368 params = (pattern,)
368 params = (pattern,)
369 if unique:
369 if unique:
370 sqlform += ' GROUP BY {0}'.format(tosearch)
370 sqlform += ' GROUP BY {0}'.format(tosearch)
371 if n is not None:
371 if n is not None:
372 sqlform += " ORDER BY session DESC, line DESC LIMIT ?"
372 sqlform += " ORDER BY session DESC, line DESC LIMIT ?"
373 params += (n,)
373 params += (n,)
374 elif unique:
374 elif unique:
375 sqlform += " ORDER BY session, line"
375 sqlform += " ORDER BY session, line"
376 cur = self._run_sql(sqlform, params, raw=raw, output=output)
376 cur = self._run_sql(sqlform, params, raw=raw, output=output)
377 if n is not None:
377 if n is not None:
378 return reversed(list(cur))
378 return reversed(list(cur))
379 return cur
379 return cur
380
380
381 @catch_corrupt_db
381 @catch_corrupt_db
382 def get_range(self, session, start=1, stop=None, raw=True,output=False):
382 def get_range(self, session, start=1, stop=None, raw=True,output=False):
383 """Retrieve input by session.
383 """Retrieve input by session.
384
384
385 Parameters
385 Parameters
386 ----------
386 ----------
387 session : int
387 session : int
388 Session number to retrieve.
388 Session number to retrieve.
389 start : int
389 start : int
390 First line to retrieve.
390 First line to retrieve.
391 stop : int
391 stop : int
392 End of line range (excluded from output itself). If None, retrieve
392 End of line range (excluded from output itself). If None, retrieve
393 to the end of the session.
393 to the end of the session.
394 raw : bool
394 raw : bool
395 If True, return untranslated input
395 If True, return untranslated input
396 output : bool
396 output : bool
397 If True, attempt to include output. This will be 'real' Python
397 If True, attempt to include output. This will be 'real' Python
398 objects for the current session, or text reprs from previous
398 objects for the current session, or text reprs from previous
399 sessions if db_log_output was enabled at the time. Where no output
399 sessions if db_log_output was enabled at the time. Where no output
400 is found, None is used.
400 is found, None is used.
401
401
402 Returns
402 Returns
403 -------
403 -------
404 entries
404 entries
405 An iterator over the desired lines. Each line is a 3-tuple, either
405 An iterator over the desired lines. Each line is a 3-tuple, either
406 (session, line, input) if output is False, or
406 (session, line, input) if output is False, or
407 (session, line, (input, output)) if output is True.
407 (session, line, (input, output)) if output is True.
408 """
408 """
409 if stop:
409 if stop:
410 lineclause = "line >= ? AND line < ?"
410 lineclause = "line >= ? AND line < ?"
411 params = (session, start, stop)
411 params = (session, start, stop)
412 else:
412 else:
413 lineclause = "line>=?"
413 lineclause = "line>=?"
414 params = (session, start)
414 params = (session, start)
415
415
416 return self._run_sql("WHERE session==? AND %s" % lineclause,
416 return self._run_sql("WHERE session==? AND %s" % lineclause,
417 params, raw=raw, output=output)
417 params, raw=raw, output=output)
418
418
419 def get_range_by_str(self, rangestr, raw=True, output=False):
419 def get_range_by_str(self, rangestr, raw=True, output=False):
420 """Get lines of history from a string of ranges, as used by magic
420 """Get lines of history from a string of ranges, as used by magic
421 commands %hist, %save, %macro, etc.
421 commands %hist, %save, %macro, etc.
422
422
423 Parameters
423 Parameters
424 ----------
424 ----------
425 rangestr : str
425 rangestr : str
426 A string specifying ranges, e.g. "5 ~2/1-4". See
426 A string specifying ranges, e.g. "5 ~2/1-4". See
427 :func:`magic_history` for full details.
427 :func:`magic_history` for full details.
428 raw, output : bool
428 raw, output : bool
429 As :meth:`get_range`
429 As :meth:`get_range`
430
430
431 Returns
431 Returns
432 -------
432 -------
433 Tuples as :meth:`get_range`
433 Tuples as :meth:`get_range`
434 """
434 """
435 for sess, s, e in extract_hist_ranges(rangestr):
435 for sess, s, e in extract_hist_ranges(rangestr):
436 for line in self.get_range(sess, s, e, raw=raw, output=output):
436 for line in self.get_range(sess, s, e, raw=raw, output=output):
437 yield line
437 yield line
438
438
439
439
440 class HistoryManager(HistoryAccessor):
440 class HistoryManager(HistoryAccessor):
441 """A class to organize all history-related functionality in one place.
441 """A class to organize all history-related functionality in one place.
442 """
442 """
443 # Public interface
443 # Public interface
444
444
445 # An instance of the IPython shell we are attached to
445 # An instance of the IPython shell we are attached to
446 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
446 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
447 allow_none=True)
447 allow_none=True)
448 # Lists to hold processed and raw history. These start with a blank entry
448 # Lists to hold processed and raw history. These start with a blank entry
449 # so that we can index them starting from 1
449 # so that we can index them starting from 1
450 input_hist_parsed = List([""])
450 input_hist_parsed = List([""])
451 input_hist_raw = List([""])
451 input_hist_raw = List([""])
452 # A list of directories visited during session
452 # A list of directories visited during session
453 dir_hist = List()
453 dir_hist = List()
454 def _dir_hist_default(self):
454 def _dir_hist_default(self):
455 try:
455 try:
456 return [py3compat.getcwd()]
456 return [py3compat.getcwd()]
457 except OSError:
457 except OSError:
458 return []
458 return []
459
459
460 # A dict of output history, keyed with ints from the shell's
460 # A dict of output history, keyed with ints from the shell's
461 # execution count.
461 # execution count.
462 output_hist = Dict()
462 output_hist = Dict()
463 # The text/plain repr of outputs.
463 # The text/plain repr of outputs.
464 output_hist_reprs = Dict()
464 output_hist_reprs = Dict()
465
465
466 # The number of the current session in the history database
466 # The number of the current session in the history database
467 session_number = Integer()
467 session_number = Integer()
468
468
469 db_log_output = Bool(False, config=True,
469 db_log_output = Bool(False, config=True,
470 help="Should the history database include output? (default: no)"
470 help="Should the history database include output? (default: no)"
471 )
471 )
472 db_cache_size = Integer(0, config=True,
472 db_cache_size = Integer(0, config=True,
473 help="Write to database every x commands (higher values save disk access & power).\n"
473 help="Write to database every x commands (higher values save disk access & power).\n"
474 "Values of 1 or less effectively disable caching."
474 "Values of 1 or less effectively disable caching."
475 )
475 )
476 # The input and output caches
476 # The input and output caches
477 db_input_cache = List()
477 db_input_cache = List()
478 db_output_cache = List()
478 db_output_cache = List()
479
479
480 # History saving in separate thread
480 # History saving in separate thread
481 save_thread = Instance('IPython.core.history.HistorySavingThread',
481 save_thread = Instance('IPython.core.history.HistorySavingThread',
482 allow_none=True)
482 allow_none=True)
483 try: # Event is a function returning an instance of _Event...
483 try: # Event is a function returning an instance of _Event...
484 save_flag = Instance(threading._Event, allow_none=True)
484 save_flag = Instance(threading._Event, allow_none=True)
485 except AttributeError: # ...until Python 3.3, when it's a class.
485 except AttributeError: # ...until Python 3.3, when it's a class.
486 save_flag = Instance(threading.Event, allow_none=True)
486 save_flag = Instance(threading.Event, allow_none=True)
487
487
488 # Private interface
488 # Private interface
489 # Variables used to store the three last inputs from the user. On each new
489 # Variables used to store the three last inputs from the user. On each new
490 # history update, we populate the user's namespace with these, shifted as
490 # history update, we populate the user's namespace with these, shifted as
491 # necessary.
491 # necessary.
492 _i00 = Unicode(u'')
492 _i00 = Unicode(u'')
493 _i = Unicode(u'')
493 _i = Unicode(u'')
494 _ii = Unicode(u'')
494 _ii = Unicode(u'')
495 _iii = Unicode(u'')
495 _iii = Unicode(u'')
496
496
497 # A regex matching all forms of the exit command, so that we don't store
497 # A regex matching all forms of the exit command, so that we don't store
498 # them in the history (it's annoying to rewind the first entry and land on
498 # them in the history (it's annoying to rewind the first entry and land on
499 # an exit call).
499 # an exit call).
500 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
500 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
501
501
502 def __init__(self, shell=None, config=None, **traits):
502 def __init__(self, shell=None, config=None, **traits):
503 """Create a new history manager associated with a shell instance.
503 """Create a new history manager associated with a shell instance.
504 """
504 """
505 # We need a pointer back to the shell for various tasks.
505 # We need a pointer back to the shell for various tasks.
506 super(HistoryManager, self).__init__(shell=shell, config=config,
506 super(HistoryManager, self).__init__(shell=shell, config=config,
507 **traits)
507 **traits)
508 self.save_flag = threading.Event()
508 self.save_flag = threading.Event()
509 self.db_input_cache_lock = threading.Lock()
509 self.db_input_cache_lock = threading.Lock()
510 self.db_output_cache_lock = threading.Lock()
510 self.db_output_cache_lock = threading.Lock()
511 if self.enabled and self.hist_file != ':memory:':
511 if self.enabled and self.hist_file != ':memory:':
512 self.save_thread = HistorySavingThread(self)
512 self.save_thread = HistorySavingThread(self)
513 self.save_thread.start()
513 self.save_thread.start()
514
514
515 self.new_session()
515 self.new_session()
516
516
517 def _get_hist_file_name(self, profile=None):
517 def _get_hist_file_name(self, profile=None):
518 """Get default history file name based on the Shell's profile.
518 """Get default history file name based on the Shell's profile.
519
519
520 The profile parameter is ignored, but must exist for compatibility with
520 The profile parameter is ignored, but must exist for compatibility with
521 the parent class."""
521 the parent class."""
522 profile_dir = self.shell.profile_dir.location
522 profile_dir = self.shell.profile_dir.location
523 return os.path.join(profile_dir, 'history.sqlite')
523 return os.path.join(profile_dir, 'history.sqlite')
524
524
525 @needs_sqlite
525 @needs_sqlite
526 def new_session(self, conn=None):
526 def new_session(self, conn=None):
527 """Get a new session number."""
527 """Get a new session number."""
528 if conn is None:
528 if conn is None:
529 conn = self.db
529 conn = self.db
530
530
531 with conn:
531 with conn:
532 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
532 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
533 NULL, "") """, (datetime.datetime.now(),))
533 NULL, "") """, (datetime.datetime.now(),))
534 self.session_number = cur.lastrowid
534 self.session_number = cur.lastrowid
535
535
536 def end_session(self):
536 def end_session(self):
537 """Close the database session, filling in the end time and line count."""
537 """Close the database session, filling in the end time and line count."""
538 self.writeout_cache()
538 self.writeout_cache()
539 with self.db:
539 with self.db:
540 self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE
540 self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE
541 session==?""", (datetime.datetime.now(),
541 session==?""", (datetime.datetime.now(),
542 len(self.input_hist_parsed)-1, self.session_number))
542 len(self.input_hist_parsed)-1, self.session_number))
543 self.session_number = 0
543 self.session_number = 0
544
544
545 def name_session(self, name):
545 def name_session(self, name):
546 """Give the current session a name in the history database."""
546 """Give the current session a name in the history database."""
547 with self.db:
547 with self.db:
548 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
548 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
549 (name, self.session_number))
549 (name, self.session_number))
550
550
551 def reset(self, new_session=True):
551 def reset(self, new_session=True):
552 """Clear the session history, releasing all object references, and
552 """Clear the session history, releasing all object references, and
553 optionally open a new session."""
553 optionally open a new session."""
554 self.output_hist.clear()
554 self.output_hist.clear()
555 # The directory history can't be completely empty
555 # The directory history can't be completely empty
556 self.dir_hist[:] = [py3compat.getcwd()]
556 self.dir_hist[:] = [py3compat.getcwd()]
557
557
558 if new_session:
558 if new_session:
559 if self.session_number:
559 if self.session_number:
560 self.end_session()
560 self.end_session()
561 self.input_hist_parsed[:] = [""]
561 self.input_hist_parsed[:] = [""]
562 self.input_hist_raw[:] = [""]
562 self.input_hist_raw[:] = [""]
563 self.new_session()
563 self.new_session()
564
564
565 # ------------------------------
565 # ------------------------------
566 # Methods for retrieving history
566 # Methods for retrieving history
567 # ------------------------------
567 # ------------------------------
568 def get_session_info(self, session=0):
568 def get_session_info(self, session=0):
569 """Get info about a session.
569 """Get info about a session.
570
570
571 Parameters
571 Parameters
572 ----------
572 ----------
573
573
574 session : int
574 session : int
575 Session number to retrieve. The current session is 0, and negative
575 Session number to retrieve. The current session is 0, and negative
576 numbers count back from current session, so -1 is the previous session.
576 numbers count back from current session, so -1 is the previous session.
577
577
578 Returns
578 Returns
579 -------
579 -------
580
580
581 session_id : int
581 session_id : int
582 Session ID number
582 Session ID number
583 start : datetime
583 start : datetime
584 Timestamp for the start of the session.
584 Timestamp for the start of the session.
585 end : datetime
585 end : datetime
586 Timestamp for the end of the session, or None if IPython crashed.
586 Timestamp for the end of the session, or None if IPython crashed.
587 num_cmds : int
587 num_cmds : int
588 Number of commands run, or None if IPython crashed.
588 Number of commands run, or None if IPython crashed.
589 remark : unicode
589 remark : unicode
590 A manually set description.
590 A manually set description.
591 """
591 """
592 if session <= 0:
592 if session <= 0:
593 session += self.session_number
593 session += self.session_number
594
594
595 return super(HistoryManager, self).get_session_info(session=session)
595 return super(HistoryManager, self).get_session_info(session=session)
596
596
597 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
597 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
598 """Get input and output history from the current session. Called by
598 """Get input and output history from the current session. Called by
599 get_range, and takes similar parameters."""
599 get_range, and takes similar parameters."""
600 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
600 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
601
601
602 n = len(input_hist)
602 n = len(input_hist)
603 if start < 0:
603 if start < 0:
604 start += n
604 start += n
605 if not stop or (stop > n):
605 if not stop or (stop > n):
606 stop = n
606 stop = n
607 elif stop < 0:
607 elif stop < 0:
608 stop += n
608 stop += n
609
609
610 for i in range(start, stop):
610 for i in range(start, stop):
611 if output:
611 if output:
612 line = (input_hist[i], self.output_hist_reprs.get(i))
612 line = (input_hist[i], self.output_hist_reprs.get(i))
613 else:
613 else:
614 line = input_hist[i]
614 line = input_hist[i]
615 yield (0, i, line)
615 yield (0, i, line)
616
616
617 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
617 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
618 """Retrieve input by session.
618 """Retrieve input by session.
619
619
620 Parameters
620 Parameters
621 ----------
621 ----------
622 session : int
622 session : int
623 Session number to retrieve. The current session is 0, and negative
623 Session number to retrieve. The current session is 0, and negative
624 numbers count back from current session, so -1 is previous session.
624 numbers count back from current session, so -1 is previous session.
625 start : int
625 start : int
626 First line to retrieve.
626 First line to retrieve.
627 stop : int
627 stop : int
628 End of line range (excluded from output itself). If None, retrieve
628 End of line range (excluded from output itself). If None, retrieve
629 to the end of the session.
629 to the end of the session.
630 raw : bool
630 raw : bool
631 If True, return untranslated input
631 If True, return untranslated input
632 output : bool
632 output : bool
633 If True, attempt to include output. This will be 'real' Python
633 If True, attempt to include output. This will be 'real' Python
634 objects for the current session, or text reprs from previous
634 objects for the current session, or text reprs from previous
635 sessions if db_log_output was enabled at the time. Where no output
635 sessions if db_log_output was enabled at the time. Where no output
636 is found, None is used.
636 is found, None is used.
637
637
638 Returns
638 Returns
639 -------
639 -------
640 entries
640 entries
641 An iterator over the desired lines. Each line is a 3-tuple, either
641 An iterator over the desired lines. Each line is a 3-tuple, either
642 (session, line, input) if output is False, or
642 (session, line, input) if output is False, or
643 (session, line, (input, output)) if output is True.
643 (session, line, (input, output)) if output is True.
644 """
644 """
645 if session <= 0:
645 if session <= 0:
646 session += self.session_number
646 session += self.session_number
647 if session==self.session_number: # Current session
647 if session==self.session_number: # Current session
648 return self._get_range_session(start, stop, raw, output)
648 return self._get_range_session(start, stop, raw, output)
649 return super(HistoryManager, self).get_range(session, start, stop, raw,
649 return super(HistoryManager, self).get_range(session, start, stop, raw,
650 output)
650 output)
651
651
652 ## ----------------------------
652 ## ----------------------------
653 ## Methods for storing history:
653 ## Methods for storing history:
654 ## ----------------------------
654 ## ----------------------------
655 def store_inputs(self, line_num, source, source_raw=None):
655 def store_inputs(self, line_num, source, source_raw=None):
656 """Store source and raw input in history and create input cache
656 """Store source and raw input in history and create input cache
657 variables ``_i*``.
657 variables ``_i*``.
658
658
659 Parameters
659 Parameters
660 ----------
660 ----------
661 line_num : int
661 line_num : int
662 The prompt number of this input.
662 The prompt number of this input.
663
663
664 source : str
664 source : str
665 Python input.
665 Python input.
666
666
667 source_raw : str, optional
667 source_raw : str, optional
668 If given, this is the raw input without any IPython transformations
668 If given, this is the raw input without any IPython transformations
669 applied to it. If not given, ``source`` is used.
669 applied to it. If not given, ``source`` is used.
670 """
670 """
671 if source_raw is None:
671 if source_raw is None:
672 source_raw = source
672 source_raw = source
673 source = source.rstrip('\n')
673 source = source.rstrip('\n')
674 source_raw = source_raw.rstrip('\n')
674 source_raw = source_raw.rstrip('\n')
675
675
676 # do not store exit/quit commands
676 # do not store exit/quit commands
677 if self._exit_re.match(source_raw.strip()):
677 if self._exit_re.match(source_raw.strip()):
678 return
678 return
679
679
680 self.input_hist_parsed.append(source)
680 self.input_hist_parsed.append(source)
681 self.input_hist_raw.append(source_raw)
681 self.input_hist_raw.append(source_raw)
682
682
683 with self.db_input_cache_lock:
683 with self.db_input_cache_lock:
684 self.db_input_cache.append((line_num, source, source_raw))
684 self.db_input_cache.append((line_num, source, source_raw))
685 # Trigger to flush cache and write to DB.
685 # Trigger to flush cache and write to DB.
686 if len(self.db_input_cache) >= self.db_cache_size:
686 if len(self.db_input_cache) >= self.db_cache_size:
687 self.save_flag.set()
687 self.save_flag.set()
688
688
689 # update the auto _i variables
689 # update the auto _i variables
690 self._iii = self._ii
690 self._iii = self._ii
691 self._ii = self._i
691 self._ii = self._i
692 self._i = self._i00
692 self._i = self._i00
693 self._i00 = source_raw
693 self._i00 = source_raw
694
694
695 # hackish access to user namespace to create _i1,_i2... dynamically
695 # hackish access to user namespace to create _i1,_i2... dynamically
696 new_i = '_i%s' % line_num
696 new_i = '_i%s' % line_num
697 to_main = {'_i': self._i,
697 to_main = {'_i': self._i,
698 '_ii': self._ii,
698 '_ii': self._ii,
699 '_iii': self._iii,
699 '_iii': self._iii,
700 new_i : self._i00 }
700 new_i : self._i00 }
701
701
702 if self.shell is not None:
702 if self.shell is not None:
703 self.shell.push(to_main, interactive=False)
703 self.shell.push(to_main, interactive=False)
704
704
705 def store_output(self, line_num):
705 def store_output(self, line_num):
706 """If database output logging is enabled, this saves all the
706 """If database output logging is enabled, this saves all the
707 outputs from the indicated prompt number to the database. It's
707 outputs from the indicated prompt number to the database. It's
708 called by run_cell after code has been executed.
708 called by run_cell after code has been executed.
709
709
710 Parameters
710 Parameters
711 ----------
711 ----------
712 line_num : int
712 line_num : int
713 The line number from which to save outputs
713 The line number from which to save outputs
714 """
714 """
715 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
715 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
716 return
716 return
717 output = self.output_hist_reprs[line_num]
717 output = self.output_hist_reprs[line_num]
718
718
719 with self.db_output_cache_lock:
719 with self.db_output_cache_lock:
720 self.db_output_cache.append((line_num, output))
720 self.db_output_cache.append((line_num, output))
721 if self.db_cache_size <= 1:
721 if self.db_cache_size <= 1:
722 self.save_flag.set()
722 self.save_flag.set()
723
723
724 def _writeout_input_cache(self, conn):
724 def _writeout_input_cache(self, conn):
725 with conn:
725 with conn:
726 for line in self.db_input_cache:
726 for line in self.db_input_cache:
727 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
727 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
728 (self.session_number,)+line)
728 (self.session_number,)+line)
729
729
730 def _writeout_output_cache(self, conn):
730 def _writeout_output_cache(self, conn):
731 with conn:
731 with conn:
732 for line in self.db_output_cache:
732 for line in self.db_output_cache:
733 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
733 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
734 (self.session_number,)+line)
734 (self.session_number,)+line)
735
735
736 @needs_sqlite
736 @needs_sqlite
737 def writeout_cache(self, conn=None):
737 def writeout_cache(self, conn=None):
738 """Write any entries in the cache to the database."""
738 """Write any entries in the cache to the database."""
739 if conn is None:
739 if conn is None:
740 conn = self.db
740 conn = self.db
741
741
742 with self.db_input_cache_lock:
742 with self.db_input_cache_lock:
743 try:
743 try:
744 self._writeout_input_cache(conn)
744 self._writeout_input_cache(conn)
745 except sqlite3.IntegrityError:
745 except sqlite3.IntegrityError:
746 self.new_session(conn)
746 self.new_session(conn)
747 print("ERROR! Session/line number was not unique in",
747 print("ERROR! Session/line number was not unique in",
748 "database. History logging moved to new session",
748 "database. History logging moved to new session",
749 self.session_number)
749 self.session_number)
750 try:
750 try:
751 # Try writing to the new session. If this fails, don't
751 # Try writing to the new session. If this fails, don't
752 # recurse
752 # recurse
753 self._writeout_input_cache(conn)
753 self._writeout_input_cache(conn)
754 except sqlite3.IntegrityError:
754 except sqlite3.IntegrityError:
755 pass
755 pass
756 finally:
756 finally:
757 self.db_input_cache = []
757 self.db_input_cache = []
758
758
759 with self.db_output_cache_lock:
759 with self.db_output_cache_lock:
760 try:
760 try:
761 self._writeout_output_cache(conn)
761 self._writeout_output_cache(conn)
762 except sqlite3.IntegrityError:
762 except sqlite3.IntegrityError:
763 print("!! Session/line number for output was not unique",
763 print("!! Session/line number for output was not unique",
764 "in database. Output will not be stored.")
764 "in database. Output will not be stored.")
765 finally:
765 finally:
766 self.db_output_cache = []
766 self.db_output_cache = []
767
767
768
768
769 class HistorySavingThread(threading.Thread):
769 class HistorySavingThread(threading.Thread):
770 """This thread takes care of writing history to the database, so that
770 """This thread takes care of writing history to the database, so that
771 the UI isn't held up while that happens.
771 the UI isn't held up while that happens.
772
772
773 It waits for the HistoryManager's save_flag to be set, then writes out
773 It waits for the HistoryManager's save_flag to be set, then writes out
774 the history cache. The main thread is responsible for setting the flag when
774 the history cache. The main thread is responsible for setting the flag when
775 the cache size reaches a defined threshold."""
775 the cache size reaches a defined threshold."""
776 daemon = True
776 daemon = True
777 stop_now = False
777 stop_now = False
778 enabled = True
778 enabled = True
779 def __init__(self, history_manager):
779 def __init__(self, history_manager):
780 super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
780 super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
781 self.history_manager = history_manager
781 self.history_manager = history_manager
782 self.enabled = history_manager.enabled
782 self.enabled = history_manager.enabled
783 atexit.register(self.stop)
783 atexit.register(self.stop)
784
784
785 @needs_sqlite
785 @needs_sqlite
786 def run(self):
786 def run(self):
787 # We need a separate db connection per thread:
787 # We need a separate db connection per thread:
788 try:
788 try:
789 self.db = sqlite3.connect(self.history_manager.hist_file,
789 self.db = sqlite3.connect(self.history_manager.hist_file,
790 **self.history_manager.connection_options
790 **self.history_manager.connection_options
791 )
791 )
792 while True:
792 while True:
793 self.history_manager.save_flag.wait()
793 self.history_manager.save_flag.wait()
794 if self.stop_now:
794 if self.stop_now:
795 self.db.close()
795 self.db.close()
796 return
796 return
797 self.history_manager.save_flag.clear()
797 self.history_manager.save_flag.clear()
798 self.history_manager.writeout_cache(self.db)
798 self.history_manager.writeout_cache(self.db)
799 except Exception as e:
799 except Exception as e:
800 print(("The history saving thread hit an unexpected error (%s)."
800 print(("The history saving thread hit an unexpected error (%s)."
801 "History will not be written to the database.") % repr(e))
801 "History will not be written to the database.") % repr(e))
802
802
803 def stop(self):
803 def stop(self):
804 """This can be called from the main thread to safely stop this thread.
804 """This can be called from the main thread to safely stop this thread.
805
805
806 Note that it does not attempt to write out remaining history before
806 Note that it does not attempt to write out remaining history before
807 exiting. That should be done by calling the HistoryManager's
807 exiting. That should be done by calling the HistoryManager's
808 end_session method."""
808 end_session method."""
809 self.stop_now = True
809 self.stop_now = True
810 self.history_manager.save_flag.set()
810 self.history_manager.save_flag.set()
811 self.join()
811 self.join()
812
812
813
813
814 # To match, e.g. ~5/8-~2/3
814 # To match, e.g. ~5/8-~2/3
815 range_re = re.compile(r"""
815 range_re = re.compile(r"""
816 ((?P<startsess>~?\d+)/)?
816 ((?P<startsess>~?\d+)/)?
817 (?P<start>\d+)?
817 (?P<start>\d+)?
818 ((?P<sep>[\-:])
818 ((?P<sep>[\-:])
819 ((?P<endsess>~?\d+)/)?
819 ((?P<endsess>~?\d+)/)?
820 (?P<end>\d+))?
820 (?P<end>\d+))?
821 $""", re.VERBOSE)
821 $""", re.VERBOSE)
822
822
823
823
824 def extract_hist_ranges(ranges_str):
824 def extract_hist_ranges(ranges_str):
825 """Turn a string of history ranges into 3-tuples of (session, start, stop).
825 """Turn a string of history ranges into 3-tuples of (session, start, stop).
826
826
827 Examples
827 Examples
828 --------
828 --------
829 >>> list(extract_hist_ranges("~8/5-~7/4 2"))
829 >>> list(extract_hist_ranges("~8/5-~7/4 2"))
830 [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
830 [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
831 """
831 """
832 for range_str in ranges_str.split():
832 for range_str in ranges_str.split():
833 rmatch = range_re.match(range_str)
833 rmatch = range_re.match(range_str)
834 if not rmatch:
834 if not rmatch:
835 continue
835 continue
836 start = rmatch.group("start")
836 start = rmatch.group("start")
837 if start:
837 if start:
838 start = int(start)
838 start = int(start)
839 end = rmatch.group("end")
839 end = rmatch.group("end")
840 # If no end specified, get (a, a + 1)
840 # If no end specified, get (a, a + 1)
841 end = int(end) if end else start + 1
841 end = int(end) if end else start + 1
842 else: # start not specified
842 else: # start not specified
843 if not rmatch.group('startsess'): # no startsess
843 if not rmatch.group('startsess'): # no startsess
844 continue
844 continue
845 start = 1
845 start = 1
846 end = None # provide the entire session hist
846 end = None # provide the entire session hist
847
847
848 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
848 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
849 end += 1
849 end += 1
850 startsess = rmatch.group("startsess") or "0"
850 startsess = rmatch.group("startsess") or "0"
851 endsess = rmatch.group("endsess") or startsess
851 endsess = rmatch.group("endsess") or startsess
852 startsess = int(startsess.replace("~","-"))
852 startsess = int(startsess.replace("~","-"))
853 endsess = int(endsess.replace("~","-"))
853 endsess = int(endsess.replace("~","-"))
854 assert endsess >= startsess, "start session must be earlier than end session"
854 assert endsess >= startsess, "start session must be earlier than end session"
855
855
856 if endsess == startsess:
856 if endsess == startsess:
857 yield (startsess, start, end)
857 yield (startsess, start, end)
858 continue
858 continue
859 # Multiple sessions in one range:
859 # Multiple sessions in one range:
860 yield (startsess, start, None)
860 yield (startsess, start, None)
861 for sess in range(startsess+1, endsess):
861 for sess in range(startsess+1, endsess):
862 yield (sess, 1, None)
862 yield (sess, 1, None)
863 yield (endsess, 1, end)
863 yield (endsess, 1, end)
864
864
865
865
866 def _format_lineno(session, line):
866 def _format_lineno(session, line):
867 """Helper function to format line numbers properly."""
867 """Helper function to format line numbers properly."""
868 if session == 0:
868 if session == 0:
869 return str(line)
869 return str(line)
870 return "%s#%s" % (session, line)
870 return "%s#%s" % (session, line)
871
871
872
872
@@ -1,159 +1,159 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for managing IPython history.
3 An application for managing IPython history.
4
4
5 To be invoked as the `ipython history` subcommand.
5 To be invoked as the `ipython history` subcommand.
6 """
6 """
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 import os
9 import os
10 import sqlite3
10 import sqlite3
11
11
12 from IPython.config.application import Application
12 from traitlets.config.application import Application
13 from IPython.core.application import BaseIPythonApplication
13 from IPython.core.application import BaseIPythonApplication
14 from IPython.utils.traitlets import Bool, Int, Dict
14 from traitlets import Bool, Int, Dict
15 from IPython.utils.io import ask_yes_no
15 from IPython.utils.io import ask_yes_no
16
16
17 trim_hist_help = """Trim the IPython history database to the last 1000 entries.
17 trim_hist_help = """Trim the IPython history database to the last 1000 entries.
18
18
19 This actually copies the last 1000 entries to a new database, and then replaces
19 This actually copies the last 1000 entries to a new database, and then replaces
20 the old file with the new. Use the `--keep=` argument to specify a number
20 the old file with the new. Use the `--keep=` argument to specify a number
21 other than 1000.
21 other than 1000.
22 """
22 """
23
23
24 clear_hist_help = """Clear the IPython history database, deleting all entries.
24 clear_hist_help = """Clear the IPython history database, deleting all entries.
25
25
26 Because this is a destructive operation, IPython will prompt the user if they
26 Because this is a destructive operation, IPython will prompt the user if they
27 really want to do this. Passing a `-f` flag will force clearing without a
27 really want to do this. Passing a `-f` flag will force clearing without a
28 prompt.
28 prompt.
29
29
30 This is an handy alias to `ipython history trim --keep=0`
30 This is an handy alias to `ipython history trim --keep=0`
31 """
31 """
32
32
33
33
34 class HistoryTrim(BaseIPythonApplication):
34 class HistoryTrim(BaseIPythonApplication):
35 description = trim_hist_help
35 description = trim_hist_help
36
36
37 backup = Bool(False, config=True,
37 backup = Bool(False, config=True,
38 help="Keep the old history file as history.sqlite.<N>")
38 help="Keep the old history file as history.sqlite.<N>")
39
39
40 keep = Int(1000, config=True,
40 keep = Int(1000, config=True,
41 help="Number of recent lines to keep in the database.")
41 help="Number of recent lines to keep in the database.")
42
42
43 flags = Dict(dict(
43 flags = Dict(dict(
44 backup = ({'HistoryTrim' : {'backup' : True}},
44 backup = ({'HistoryTrim' : {'backup' : True}},
45 backup.get_metadata('help')
45 backup.get_metadata('help')
46 )
46 )
47 ))
47 ))
48
48
49 aliases=Dict(dict(
49 aliases=Dict(dict(
50 keep = 'HistoryTrim.keep'
50 keep = 'HistoryTrim.keep'
51 ))
51 ))
52
52
53 def start(self):
53 def start(self):
54 profile_dir = self.profile_dir.location
54 profile_dir = self.profile_dir.location
55 hist_file = os.path.join(profile_dir, 'history.sqlite')
55 hist_file = os.path.join(profile_dir, 'history.sqlite')
56 con = sqlite3.connect(hist_file)
56 con = sqlite3.connect(hist_file)
57
57
58 # Grab the recent history from the current database.
58 # Grab the recent history from the current database.
59 inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
59 inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
60 'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
60 'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
61 if len(inputs) <= self.keep:
61 if len(inputs) <= self.keep:
62 print("There are already at most %d entries in the history database." % self.keep)
62 print("There are already at most %d entries in the history database." % self.keep)
63 print("Not doing anything. Use --keep= argument to keep fewer entries")
63 print("Not doing anything. Use --keep= argument to keep fewer entries")
64 return
64 return
65
65
66 print("Trimming history to the most recent %d entries." % self.keep)
66 print("Trimming history to the most recent %d entries." % self.keep)
67
67
68 inputs.pop() # Remove the extra element we got to check the length.
68 inputs.pop() # Remove the extra element we got to check the length.
69 inputs.reverse()
69 inputs.reverse()
70 if inputs:
70 if inputs:
71 first_session = inputs[0][0]
71 first_session = inputs[0][0]
72 outputs = list(con.execute('SELECT session, line, output FROM '
72 outputs = list(con.execute('SELECT session, line, output FROM '
73 'output_history WHERE session >= ?', (first_session,)))
73 'output_history WHERE session >= ?', (first_session,)))
74 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
74 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
75 'sessions WHERE session >= ?', (first_session,)))
75 'sessions WHERE session >= ?', (first_session,)))
76 con.close()
76 con.close()
77
77
78 # Create the new history database.
78 # Create the new history database.
79 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new')
79 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new')
80 i = 0
80 i = 0
81 while os.path.exists(new_hist_file):
81 while os.path.exists(new_hist_file):
82 # Make sure we don't interfere with an existing file.
82 # Make sure we don't interfere with an existing file.
83 i += 1
83 i += 1
84 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new'+str(i))
84 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new'+str(i))
85 new_db = sqlite3.connect(new_hist_file)
85 new_db = sqlite3.connect(new_hist_file)
86 new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
86 new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
87 primary key autoincrement, start timestamp,
87 primary key autoincrement, start timestamp,
88 end timestamp, num_cmds integer, remark text)""")
88 end timestamp, num_cmds integer, remark text)""")
89 new_db.execute("""CREATE TABLE IF NOT EXISTS history
89 new_db.execute("""CREATE TABLE IF NOT EXISTS history
90 (session integer, line integer, source text, source_raw text,
90 (session integer, line integer, source text, source_raw text,
91 PRIMARY KEY (session, line))""")
91 PRIMARY KEY (session, line))""")
92 new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
92 new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
93 (session integer, line integer, output text,
93 (session integer, line integer, output text,
94 PRIMARY KEY (session, line))""")
94 PRIMARY KEY (session, line))""")
95 new_db.commit()
95 new_db.commit()
96
96
97
97
98 if inputs:
98 if inputs:
99 with new_db:
99 with new_db:
100 # Add the recent history into the new database.
100 # Add the recent history into the new database.
101 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
101 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
102 new_db.executemany('insert into history values (?,?,?,?)', inputs)
102 new_db.executemany('insert into history values (?,?,?,?)', inputs)
103 new_db.executemany('insert into output_history values (?,?,?)', outputs)
103 new_db.executemany('insert into output_history values (?,?,?)', outputs)
104 new_db.close()
104 new_db.close()
105
105
106 if self.backup:
106 if self.backup:
107 i = 1
107 i = 1
108 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
108 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
109 while os.path.exists(backup_hist_file):
109 while os.path.exists(backup_hist_file):
110 i += 1
110 i += 1
111 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
111 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
112 os.rename(hist_file, backup_hist_file)
112 os.rename(hist_file, backup_hist_file)
113 print("Backed up longer history file to", backup_hist_file)
113 print("Backed up longer history file to", backup_hist_file)
114 else:
114 else:
115 os.remove(hist_file)
115 os.remove(hist_file)
116
116
117 os.rename(new_hist_file, hist_file)
117 os.rename(new_hist_file, hist_file)
118
118
119 class HistoryClear(HistoryTrim):
119 class HistoryClear(HistoryTrim):
120 description = clear_hist_help
120 description = clear_hist_help
121 keep = Int(0, config=False,
121 keep = Int(0, config=False,
122 help="Number of recent lines to keep in the database.")
122 help="Number of recent lines to keep in the database.")
123
123
124 force = Bool(False, config=True,
124 force = Bool(False, config=True,
125 help="Don't prompt user for confirmation")
125 help="Don't prompt user for confirmation")
126
126
127 flags = Dict(dict(
127 flags = Dict(dict(
128 force = ({'HistoryClear' : {'force' : True}},
128 force = ({'HistoryClear' : {'force' : True}},
129 force.get_metadata('help')),
129 force.get_metadata('help')),
130 f = ({'HistoryTrim' : {'force' : True}},
130 f = ({'HistoryTrim' : {'force' : True}},
131 force.get_metadata('help')
131 force.get_metadata('help')
132 )
132 )
133 ))
133 ))
134 aliases = Dict()
134 aliases = Dict()
135
135
136 def start(self):
136 def start(self):
137 if self.force or ask_yes_no("Really delete all ipython history? ",
137 if self.force or ask_yes_no("Really delete all ipython history? ",
138 default="no", interrupt="no"):
138 default="no", interrupt="no"):
139 HistoryTrim.start(self)
139 HistoryTrim.start(self)
140
140
141 class HistoryApp(Application):
141 class HistoryApp(Application):
142 name = u'ipython-history'
142 name = u'ipython-history'
143 description = "Manage the IPython history database."
143 description = "Manage the IPython history database."
144
144
145 subcommands = Dict(dict(
145 subcommands = Dict(dict(
146 trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
146 trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
147 clear = (HistoryClear, HistoryClear.description.splitlines()[0]),
147 clear = (HistoryClear, HistoryClear.description.splitlines()[0]),
148 ))
148 ))
149
149
150 def start(self):
150 def start(self):
151 if self.subapp is None:
151 if self.subapp is None:
152 print("No subcommand specified. Must specify one of: %s" % \
152 print("No subcommand specified. Must specify one of: %s" % \
153 (self.subcommands.keys()))
153 (self.subcommands.keys()))
154 print()
154 print()
155 self.print_description()
155 self.print_description()
156 self.print_subcommands()
156 self.print_subcommands()
157 self.exit(1)
157 self.exit(1)
158 else:
158 else:
159 return self.subapp.start()
159 return self.subapp.start()
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,702 +1,702 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 IPython.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 IPython.utils.traitlets import Bool, Dict, Instance, MetaHasTraits
35 from traitlets import Bool, Dict, Instance, MetaHasTraits
36 from IPython.utils.warn import error
36 from IPython.utils.warn 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 type(m) in (type, MetaHasTraits):
389 if type(m) in (type, MetaHasTraits):
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 Example::
436 Example::
437
437
438 def foo_impl(self, parameter_s=''):
438 def foo_impl(self, parameter_s=''):
439 'My very own magic!. (Use docstrings, IPython reads them).'
439 'My very own magic!. (Use docstrings, IPython reads them).'
440 print 'Magic function. Passed parameter is between < >:'
440 print 'Magic function. Passed parameter is between < >:'
441 print '<%s>' % parameter_s
441 print '<%s>' % parameter_s
442 print 'The self object is:', self
442 print 'The self object is:', self
443
443
444 ip.define_magic('foo',foo_impl)
444 ip.define_magic('foo',foo_impl)
445 """
445 """
446 meth = types.MethodType(func, self.user_magics)
446 meth = types.MethodType(func, self.user_magics)
447 setattr(self.user_magics, name, meth)
447 setattr(self.user_magics, name, meth)
448 record_magic(self.magics, 'line', name, meth)
448 record_magic(self.magics, 'line', name, meth)
449
449
450 def register_alias(self, alias_name, magic_name, magic_kind='line'):
450 def register_alias(self, alias_name, magic_name, magic_kind='line'):
451 """Register an alias to a magic function.
451 """Register an alias to a magic function.
452
452
453 The alias is an instance of :class:`MagicAlias`, which holds the
453 The alias is an instance of :class:`MagicAlias`, which holds the
454 name and kind of the magic it should call. Binding is done at
454 name and kind of the magic it should call. Binding is done at
455 call time, so if the underlying magic function is changed the alias
455 call time, so if the underlying magic function is changed the alias
456 will call the new function.
456 will call the new function.
457
457
458 Parameters
458 Parameters
459 ----------
459 ----------
460 alias_name : str
460 alias_name : str
461 The name of the magic to be registered.
461 The name of the magic to be registered.
462
462
463 magic_name : str
463 magic_name : str
464 The name of an existing magic.
464 The name of an existing magic.
465
465
466 magic_kind : str
466 magic_kind : str
467 Kind of magic, one of 'line' or 'cell'
467 Kind of magic, one of 'line' or 'cell'
468 """
468 """
469
469
470 # `validate_type` is too permissive, as it allows 'line_cell'
470 # `validate_type` is too permissive, as it allows 'line_cell'
471 # which we do not handle.
471 # which we do not handle.
472 if magic_kind not in magic_kinds:
472 if magic_kind not in magic_kinds:
473 raise ValueError('magic_kind must be one of %s, %s given' %
473 raise ValueError('magic_kind must be one of %s, %s given' %
474 magic_kinds, magic_kind)
474 magic_kinds, magic_kind)
475
475
476 alias = MagicAlias(self.shell, magic_name, magic_kind)
476 alias = MagicAlias(self.shell, magic_name, magic_kind)
477 setattr(self.user_magics, alias_name, alias)
477 setattr(self.user_magics, alias_name, alias)
478 record_magic(self.magics, magic_kind, alias_name, alias)
478 record_magic(self.magics, magic_kind, alias_name, alias)
479
479
480 # Key base class that provides the central functionality for magics.
480 # Key base class that provides the central functionality for magics.
481
481
482
482
483 class Magics(Configurable):
483 class Magics(Configurable):
484 """Base class for implementing magic functions.
484 """Base class for implementing magic functions.
485
485
486 Shell functions which can be reached as %function_name. All magic
486 Shell functions which can be reached as %function_name. All magic
487 functions should accept a string, which they can parse for their own
487 functions should accept a string, which they can parse for their own
488 needs. This can make some functions easier to type, eg `%cd ../`
488 needs. This can make some functions easier to type, eg `%cd ../`
489 vs. `%cd("../")`
489 vs. `%cd("../")`
490
490
491 Classes providing magic functions need to subclass this class, and they
491 Classes providing magic functions need to subclass this class, and they
492 MUST:
492 MUST:
493
493
494 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
494 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
495 individual methods as magic functions, AND
495 individual methods as magic functions, AND
496
496
497 - Use the class decorator `@magics_class` to ensure that the magic
497 - Use the class decorator `@magics_class` to ensure that the magic
498 methods are properly registered at the instance level upon instance
498 methods are properly registered at the instance level upon instance
499 initialization.
499 initialization.
500
500
501 See :mod:`magic_functions` for examples of actual implementation classes.
501 See :mod:`magic_functions` for examples of actual implementation classes.
502 """
502 """
503 # Dict holding all command-line options for each magic.
503 # Dict holding all command-line options for each magic.
504 options_table = None
504 options_table = None
505 # Dict for the mapping of magic names to methods, set by class decorator
505 # Dict for the mapping of magic names to methods, set by class decorator
506 magics = None
506 magics = None
507 # Flag to check that the class decorator was properly applied
507 # Flag to check that the class decorator was properly applied
508 registered = False
508 registered = False
509 # Instance of IPython shell
509 # Instance of IPython shell
510 shell = None
510 shell = None
511
511
512 def __init__(self, shell=None, **kwargs):
512 def __init__(self, shell=None, **kwargs):
513 if not(self.__class__.registered):
513 if not(self.__class__.registered):
514 raise ValueError('Magics subclass without registration - '
514 raise ValueError('Magics subclass without registration - '
515 'did you forget to apply @magics_class?')
515 'did you forget to apply @magics_class?')
516 if shell is not None:
516 if shell is not None:
517 if hasattr(shell, 'configurables'):
517 if hasattr(shell, 'configurables'):
518 shell.configurables.append(self)
518 shell.configurables.append(self)
519 if hasattr(shell, 'config'):
519 if hasattr(shell, 'config'):
520 kwargs.setdefault('parent', shell)
520 kwargs.setdefault('parent', shell)
521 kwargs['shell'] = shell
521 kwargs['shell'] = shell
522
522
523 self.shell = shell
523 self.shell = shell
524 self.options_table = {}
524 self.options_table = {}
525 # The method decorators are run when the instance doesn't exist yet, so
525 # The method decorators are run when the instance doesn't exist yet, so
526 # they can only record the names of the methods they are supposed to
526 # they can only record the names of the methods they are supposed to
527 # grab. Only now, that the instance exists, can we create the proper
527 # grab. Only now, that the instance exists, can we create the proper
528 # mapping to bound methods. So we read the info off the original names
528 # mapping to bound methods. So we read the info off the original names
529 # table and replace each method name by the actual bound method.
529 # table and replace each method name by the actual bound method.
530 # But we mustn't clobber the *class* mapping, in case of multiple instances.
530 # But we mustn't clobber the *class* mapping, in case of multiple instances.
531 class_magics = self.magics
531 class_magics = self.magics
532 self.magics = {}
532 self.magics = {}
533 for mtype in magic_kinds:
533 for mtype in magic_kinds:
534 tab = self.magics[mtype] = {}
534 tab = self.magics[mtype] = {}
535 cls_tab = class_magics[mtype]
535 cls_tab = class_magics[mtype]
536 for magic_name, meth_name in iteritems(cls_tab):
536 for magic_name, meth_name in iteritems(cls_tab):
537 if isinstance(meth_name, string_types):
537 if isinstance(meth_name, string_types):
538 # it's a method name, grab it
538 # it's a method name, grab it
539 tab[magic_name] = getattr(self, meth_name)
539 tab[magic_name] = getattr(self, meth_name)
540 else:
540 else:
541 # it's the real thing
541 # it's the real thing
542 tab[magic_name] = meth_name
542 tab[magic_name] = meth_name
543 # Configurable **needs** to be initiated at the end or the config
543 # Configurable **needs** to be initiated at the end or the config
544 # magics get screwed up.
544 # magics get screwed up.
545 super(Magics, self).__init__(**kwargs)
545 super(Magics, self).__init__(**kwargs)
546
546
547 def arg_err(self,func):
547 def arg_err(self,func):
548 """Print docstring if incorrect arguments were passed"""
548 """Print docstring if incorrect arguments were passed"""
549 print('Error in arguments:')
549 print('Error in arguments:')
550 print(oinspect.getdoc(func))
550 print(oinspect.getdoc(func))
551
551
552 def format_latex(self, strng):
552 def format_latex(self, strng):
553 """Format a string for latex inclusion."""
553 """Format a string for latex inclusion."""
554
554
555 # Characters that need to be escaped for latex:
555 # Characters that need to be escaped for latex:
556 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
556 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
557 # Magic command names as headers:
557 # Magic command names as headers:
558 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
558 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
559 re.MULTILINE)
559 re.MULTILINE)
560 # Magic commands
560 # Magic commands
561 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
561 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
562 re.MULTILINE)
562 re.MULTILINE)
563 # Paragraph continue
563 # Paragraph continue
564 par_re = re.compile(r'\\$',re.MULTILINE)
564 par_re = re.compile(r'\\$',re.MULTILINE)
565
565
566 # The "\n" symbol
566 # The "\n" symbol
567 newline_re = re.compile(r'\\n')
567 newline_re = re.compile(r'\\n')
568
568
569 # Now build the string for output:
569 # Now build the string for output:
570 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
570 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
571 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
571 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
572 strng)
572 strng)
573 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
573 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
574 strng = par_re.sub(r'\\\\',strng)
574 strng = par_re.sub(r'\\\\',strng)
575 strng = escape_re.sub(r'\\\1',strng)
575 strng = escape_re.sub(r'\\\1',strng)
576 strng = newline_re.sub(r'\\textbackslash{}n',strng)
576 strng = newline_re.sub(r'\\textbackslash{}n',strng)
577 return strng
577 return strng
578
578
579 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
579 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
580 """Parse options passed to an argument string.
580 """Parse options passed to an argument string.
581
581
582 The interface is similar to that of :func:`getopt.getopt`, but it
582 The interface is similar to that of :func:`getopt.getopt`, but it
583 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
583 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
584 and the stripped argument string still as a string.
584 and the stripped argument string still as a string.
585
585
586 arg_str is quoted as a true sys.argv vector by using shlex.split.
586 arg_str is quoted as a true sys.argv vector by using shlex.split.
587 This allows us to easily expand variables, glob files, quote
587 This allows us to easily expand variables, glob files, quote
588 arguments, etc.
588 arguments, etc.
589
589
590 Parameters
590 Parameters
591 ----------
591 ----------
592
592
593 arg_str : str
593 arg_str : str
594 The arguments to parse.
594 The arguments to parse.
595
595
596 opt_str : str
596 opt_str : str
597 The options specification.
597 The options specification.
598
598
599 mode : str, default 'string'
599 mode : str, default 'string'
600 If given as 'list', the argument string is returned as a list (split
600 If given as 'list', the argument string is returned as a list (split
601 on whitespace) instead of a string.
601 on whitespace) instead of a string.
602
602
603 list_all : bool, default False
603 list_all : bool, default False
604 Put all option values in lists. Normally only options
604 Put all option values in lists. Normally only options
605 appearing more than once are put in a list.
605 appearing more than once are put in a list.
606
606
607 posix : bool, default True
607 posix : bool, default True
608 Whether to split the input line in POSIX mode or not, as per the
608 Whether to split the input line in POSIX mode or not, as per the
609 conventions outlined in the :mod:`shlex` module from the standard
609 conventions outlined in the :mod:`shlex` module from the standard
610 library.
610 library.
611 """
611 """
612
612
613 # inject default options at the beginning of the input line
613 # inject default options at the beginning of the input line
614 caller = sys._getframe(1).f_code.co_name
614 caller = sys._getframe(1).f_code.co_name
615 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
615 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
616
616
617 mode = kw.get('mode','string')
617 mode = kw.get('mode','string')
618 if mode not in ['string','list']:
618 if mode not in ['string','list']:
619 raise ValueError('incorrect mode given: %s' % mode)
619 raise ValueError('incorrect mode given: %s' % mode)
620 # Get options
620 # Get options
621 list_all = kw.get('list_all',0)
621 list_all = kw.get('list_all',0)
622 posix = kw.get('posix', os.name == 'posix')
622 posix = kw.get('posix', os.name == 'posix')
623 strict = kw.get('strict', True)
623 strict = kw.get('strict', True)
624
624
625 # Check if we have more than one argument to warrant extra processing:
625 # Check if we have more than one argument to warrant extra processing:
626 odict = {} # Dictionary with options
626 odict = {} # Dictionary with options
627 args = arg_str.split()
627 args = arg_str.split()
628 if len(args) >= 1:
628 if len(args) >= 1:
629 # If the list of inputs only has 0 or 1 thing in it, there's no
629 # If the list of inputs only has 0 or 1 thing in it, there's no
630 # need to look for options
630 # need to look for options
631 argv = arg_split(arg_str, posix, strict)
631 argv = arg_split(arg_str, posix, strict)
632 # Do regular option processing
632 # Do regular option processing
633 try:
633 try:
634 opts,args = getopt(argv, opt_str, long_opts)
634 opts,args = getopt(argv, opt_str, long_opts)
635 except GetoptError as e:
635 except GetoptError as e:
636 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
636 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
637 " ".join(long_opts)))
637 " ".join(long_opts)))
638 for o,a in opts:
638 for o,a in opts:
639 if o.startswith('--'):
639 if o.startswith('--'):
640 o = o[2:]
640 o = o[2:]
641 else:
641 else:
642 o = o[1:]
642 o = o[1:]
643 try:
643 try:
644 odict[o].append(a)
644 odict[o].append(a)
645 except AttributeError:
645 except AttributeError:
646 odict[o] = [odict[o],a]
646 odict[o] = [odict[o],a]
647 except KeyError:
647 except KeyError:
648 if list_all:
648 if list_all:
649 odict[o] = [a]
649 odict[o] = [a]
650 else:
650 else:
651 odict[o] = a
651 odict[o] = a
652
652
653 # Prepare opts,args for return
653 # Prepare opts,args for return
654 opts = Struct(odict)
654 opts = Struct(odict)
655 if mode == 'string':
655 if mode == 'string':
656 args = ' '.join(args)
656 args = ' '.join(args)
657
657
658 return opts,args
658 return opts,args
659
659
660 def default_option(self, fn, optstr):
660 def default_option(self, fn, optstr):
661 """Make an entry in the options_table for fn, with value optstr"""
661 """Make an entry in the options_table for fn, with value optstr"""
662
662
663 if fn not in self.lsmagic():
663 if fn not in self.lsmagic():
664 error("%s is not a magic function" % fn)
664 error("%s is not a magic function" % fn)
665 self.options_table[fn] = optstr
665 self.options_table[fn] = optstr
666
666
667
667
668 class MagicAlias(object):
668 class MagicAlias(object):
669 """An alias to another magic function.
669 """An alias to another magic function.
670
670
671 An alias is determined by its magic name and magic kind. Lookup
671 An alias is determined by its magic name and magic kind. Lookup
672 is done at call time, so if the underlying magic changes the alias
672 is done at call time, so if the underlying magic changes the alias
673 will call the new function.
673 will call the new function.
674
674
675 Use the :meth:`MagicsManager.register_alias` method or the
675 Use the :meth:`MagicsManager.register_alias` method or the
676 `%alias_magic` magic function to create and register a new alias.
676 `%alias_magic` magic function to create and register a new alias.
677 """
677 """
678 def __init__(self, shell, magic_name, magic_kind):
678 def __init__(self, shell, magic_name, magic_kind):
679 self.shell = shell
679 self.shell = shell
680 self.magic_name = magic_name
680 self.magic_name = magic_name
681 self.magic_kind = magic_kind
681 self.magic_kind = magic_kind
682
682
683 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
683 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
684 self.__doc__ = "Alias for `%s`." % self.pretty_target
684 self.__doc__ = "Alias for `%s`." % self.pretty_target
685
685
686 self._in_call = False
686 self._in_call = False
687
687
688 def __call__(self, *args, **kwargs):
688 def __call__(self, *args, **kwargs):
689 """Call the magic alias."""
689 """Call the magic alias."""
690 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
690 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
691 if fn is None:
691 if fn is None:
692 raise UsageError("Magic `%s` not found." % self.pretty_target)
692 raise UsageError("Magic `%s` not found." % self.pretty_target)
693
693
694 # Protect against infinite recursion.
694 # Protect against infinite recursion.
695 if self._in_call:
695 if self._in_call:
696 raise UsageError("Infinite recursion detected; "
696 raise UsageError("Infinite recursion detected; "
697 "magic aliases cannot call themselves.")
697 "magic aliases cannot call themselves.")
698 self._in_call = True
698 self._in_call = True
699 try:
699 try:
700 return fn(*args, **kwargs)
700 return fn(*args, **kwargs)
701 finally:
701 finally:
702 self._in_call = False
702 self._in_call = False
@@ -1,613 +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 json
6 import json
7 import sys
7 import sys
8 from pprint import pformat
8 from pprint import pformat
9
9
10 from IPython.core import magic_arguments, page
10 from IPython.core import magic_arguments, page
11 from IPython.core.error import UsageError
11 from IPython.core.error import UsageError
12 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
12 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
13 from IPython.utils.text import format_screen, dedent, indent
13 from IPython.utils.text import format_screen, dedent, indent
14 from IPython.testing.skipdoctest import skip_doctest
14 from IPython.testing.skipdoctest import skip_doctest
15 from IPython.utils.ipstruct import Struct
15 from IPython.utils.ipstruct import Struct
16 from IPython.utils.path import unquote_filename
16 from IPython.utils.path import unquote_filename
17 from IPython.utils.py3compat import unicode_type
17 from IPython.utils.py3compat import unicode_type
18 from IPython.utils.warn import warn, error
18 from IPython.utils.warn import warn, error
19
19
20
20
21 class MagicsDisplay(object):
21 class MagicsDisplay(object):
22 def __init__(self, magics_manager):
22 def __init__(self, magics_manager):
23 self.magics_manager = magics_manager
23 self.magics_manager = magics_manager
24
24
25 def _lsmagic(self):
25 def _lsmagic(self):
26 """The main implementation of the %lsmagic"""
26 """The main implementation of the %lsmagic"""
27 mesc = magic_escapes['line']
27 mesc = magic_escapes['line']
28 cesc = magic_escapes['cell']
28 cesc = magic_escapes['cell']
29 mman = self.magics_manager
29 mman = self.magics_manager
30 magics = mman.lsmagic()
30 magics = mman.lsmagic()
31 out = ['Available line magics:',
31 out = ['Available line magics:',
32 mesc + (' '+mesc).join(sorted(magics['line'])),
32 mesc + (' '+mesc).join(sorted(magics['line'])),
33 '',
33 '',
34 'Available cell magics:',
34 'Available cell magics:',
35 cesc + (' '+cesc).join(sorted(magics['cell'])),
35 cesc + (' '+cesc).join(sorted(magics['cell'])),
36 '',
36 '',
37 mman.auto_status()]
37 mman.auto_status()]
38 return '\n'.join(out)
38 return '\n'.join(out)
39
39
40 def _repr_pretty_(self, p, cycle):
40 def _repr_pretty_(self, p, cycle):
41 p.text(self._lsmagic())
41 p.text(self._lsmagic())
42
42
43 def __str__(self):
43 def __str__(self):
44 return self._lsmagic()
44 return self._lsmagic()
45
45
46 def _jsonable(self):
46 def _jsonable(self):
47 """turn magics dict into jsonable dict of the same structure
47 """turn magics dict into jsonable dict of the same structure
48
48
49 replaces object instances with their class names as strings
49 replaces object instances with their class names as strings
50 """
50 """
51 magic_dict = {}
51 magic_dict = {}
52 mman = self.magics_manager
52 mman = self.magics_manager
53 magics = mman.lsmagic()
53 magics = mman.lsmagic()
54 for key, subdict in magics.items():
54 for key, subdict in magics.items():
55 d = {}
55 d = {}
56 magic_dict[key] = d
56 magic_dict[key] = d
57 for name, obj in subdict.items():
57 for name, obj in subdict.items():
58 try:
58 try:
59 classname = obj.__self__.__class__.__name__
59 classname = obj.__self__.__class__.__name__
60 except AttributeError:
60 except AttributeError:
61 classname = 'Other'
61 classname = 'Other'
62
62
63 d[name] = classname
63 d[name] = classname
64 return magic_dict
64 return magic_dict
65
65
66 def _repr_json_(self):
66 def _repr_json_(self):
67 return self._jsonable()
67 return self._jsonable()
68
68
69
69
70 @magics_class
70 @magics_class
71 class BasicMagics(Magics):
71 class BasicMagics(Magics):
72 """Magics that provide central IPython functionality.
72 """Magics that provide central IPython functionality.
73
73
74 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
75 are all part of the base 'IPython experience'."""
75 are all part of the base 'IPython experience'."""
76
76
77 @magic_arguments.magic_arguments()
77 @magic_arguments.magic_arguments()
78 @magic_arguments.argument(
78 @magic_arguments.argument(
79 '-l', '--line', action='store_true',
79 '-l', '--line', action='store_true',
80 help="""Create a line magic alias."""
80 help="""Create a line magic alias."""
81 )
81 )
82 @magic_arguments.argument(
82 @magic_arguments.argument(
83 '-c', '--cell', action='store_true',
83 '-c', '--cell', action='store_true',
84 help="""Create a cell magic alias."""
84 help="""Create a cell magic alias."""
85 )
85 )
86 @magic_arguments.argument(
86 @magic_arguments.argument(
87 'name',
87 'name',
88 help="""Name of the magic to be created."""
88 help="""Name of the magic to be created."""
89 )
89 )
90 @magic_arguments.argument(
90 @magic_arguments.argument(
91 'target',
91 'target',
92 help="""Name of the existing line or cell magic."""
92 help="""Name of the existing line or cell magic."""
93 )
93 )
94 @line_magic
94 @line_magic
95 def alias_magic(self, line=''):
95 def alias_magic(self, line=''):
96 """Create an alias for an existing line or cell magic.
96 """Create an alias for an existing line or cell magic.
97
97
98 Examples
98 Examples
99 --------
99 --------
100 ::
100 ::
101
101
102 In [1]: %alias_magic t timeit
102 In [1]: %alias_magic t 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 Created `%%t` as an alias for `%%timeit`.
105
105
106 In [2]: %t -n1 pass
106 In [2]: %t -n1 pass
107 1 loops, best of 3: 954 ns per loop
107 1 loops, best of 3: 954 ns per loop
108
108
109 In [3]: %%t -n1
109 In [3]: %%t -n1
110 ...: pass
110 ...: pass
111 ...:
111 ...:
112 1 loops, best of 3: 954 ns per loop
112 1 loops, best of 3: 954 ns per loop
113
113
114 In [4]: %alias_magic --cell whereami pwd
114 In [4]: %alias_magic --cell whereami pwd
115 UsageError: Cell magic function `%%pwd` not found.
115 UsageError: Cell magic function `%%pwd` not found.
116 In [5]: %alias_magic --line whereami pwd
116 In [5]: %alias_magic --line whereami pwd
117 Created `%whereami` as an alias for `%pwd`.
117 Created `%whereami` as an alias for `%pwd`.
118
118
119 In [6]: %whereami
119 In [6]: %whereami
120 Out[6]: u'/home/testuser'
120 Out[6]: u'/home/testuser'
121 """
121 """
122 args = magic_arguments.parse_argstring(self.alias_magic, line)
122 args = magic_arguments.parse_argstring(self.alias_magic, line)
123 shell = self.shell
123 shell = self.shell
124 mman = self.shell.magics_manager
124 mman = self.shell.magics_manager
125 escs = ''.join(magic_escapes.values())
125 escs = ''.join(magic_escapes.values())
126
126
127 target = args.target.lstrip(escs)
127 target = args.target.lstrip(escs)
128 name = args.name.lstrip(escs)
128 name = args.name.lstrip(escs)
129
129
130 # Find the requested magics.
130 # Find the requested magics.
131 m_line = shell.find_magic(target, 'line')
131 m_line = shell.find_magic(target, 'line')
132 m_cell = shell.find_magic(target, 'cell')
132 m_cell = shell.find_magic(target, 'cell')
133 if args.line and m_line is None:
133 if args.line and m_line is None:
134 raise UsageError('Line magic function `%s%s` not found.' %
134 raise UsageError('Line magic function `%s%s` not found.' %
135 (magic_escapes['line'], target))
135 (magic_escapes['line'], target))
136 if args.cell and m_cell is None:
136 if args.cell and m_cell is None:
137 raise UsageError('Cell magic function `%s%s` not found.' %
137 raise UsageError('Cell magic function `%s%s` not found.' %
138 (magic_escapes['cell'], target))
138 (magic_escapes['cell'], target))
139
139
140 # If --line and --cell are not specified, default to the ones
140 # If --line and --cell are not specified, default to the ones
141 # that are available.
141 # that are available.
142 if not args.line and not args.cell:
142 if not args.line and not args.cell:
143 if not m_line and not m_cell:
143 if not m_line and not m_cell:
144 raise UsageError(
144 raise UsageError(
145 'No line or cell magic with name `%s` found.' % target
145 'No line or cell magic with name `%s` found.' % target
146 )
146 )
147 args.line = bool(m_line)
147 args.line = bool(m_line)
148 args.cell = bool(m_cell)
148 args.cell = bool(m_cell)
149
149
150 if args.line:
150 if args.line:
151 mman.register_alias(name, target, 'line')
151 mman.register_alias(name, target, 'line')
152 print('Created `%s%s` as an alias for `%s%s`.' % (
152 print('Created `%s%s` as an alias for `%s%s`.' % (
153 magic_escapes['line'], name,
153 magic_escapes['line'], name,
154 magic_escapes['line'], target))
154 magic_escapes['line'], target))
155
155
156 if args.cell:
156 if args.cell:
157 mman.register_alias(name, target, 'cell')
157 mman.register_alias(name, target, 'cell')
158 print('Created `%s%s` as an alias for `%s%s`.' % (
158 print('Created `%s%s` as an alias for `%s%s`.' % (
159 magic_escapes['cell'], name,
159 magic_escapes['cell'], name,
160 magic_escapes['cell'], target))
160 magic_escapes['cell'], target))
161
161
162 @line_magic
162 @line_magic
163 def lsmagic(self, parameter_s=''):
163 def lsmagic(self, parameter_s=''):
164 """List currently available magic functions."""
164 """List currently available magic functions."""
165 return MagicsDisplay(self.shell.magics_manager)
165 return MagicsDisplay(self.shell.magics_manager)
166
166
167 def _magic_docs(self, brief=False, rest=False):
167 def _magic_docs(self, brief=False, rest=False):
168 """Return docstrings from magic functions."""
168 """Return docstrings from magic functions."""
169 mman = self.shell.magics_manager
169 mman = self.shell.magics_manager
170 docs = mman.lsmagic_docs(brief, missing='No documentation')
170 docs = mman.lsmagic_docs(brief, missing='No documentation')
171
171
172 if rest:
172 if rest:
173 format_string = '**%s%s**::\n\n%s\n\n'
173 format_string = '**%s%s**::\n\n%s\n\n'
174 else:
174 else:
175 format_string = '%s%s:\n%s\n'
175 format_string = '%s%s:\n%s\n'
176
176
177 return ''.join(
177 return ''.join(
178 [format_string % (magic_escapes['line'], fname,
178 [format_string % (magic_escapes['line'], fname,
179 indent(dedent(fndoc)))
179 indent(dedent(fndoc)))
180 for fname, fndoc in sorted(docs['line'].items())]
180 for fname, fndoc in sorted(docs['line'].items())]
181 +
181 +
182 [format_string % (magic_escapes['cell'], fname,
182 [format_string % (magic_escapes['cell'], fname,
183 indent(dedent(fndoc)))
183 indent(dedent(fndoc)))
184 for fname, fndoc in sorted(docs['cell'].items())]
184 for fname, fndoc in sorted(docs['cell'].items())]
185 )
185 )
186
186
187 @line_magic
187 @line_magic
188 def magic(self, parameter_s=''):
188 def magic(self, parameter_s=''):
189 """Print information about the magic function system.
189 """Print information about the magic function system.
190
190
191 Supported formats: -latex, -brief, -rest
191 Supported formats: -latex, -brief, -rest
192 """
192 """
193
193
194 mode = ''
194 mode = ''
195 try:
195 try:
196 mode = parameter_s.split()[0][1:]
196 mode = parameter_s.split()[0][1:]
197 if mode == 'rest':
197 if mode == 'rest':
198 rest_docs = []
198 rest_docs = []
199 except IndexError:
199 except IndexError:
200 pass
200 pass
201
201
202 brief = (mode == 'brief')
202 brief = (mode == 'brief')
203 rest = (mode == 'rest')
203 rest = (mode == 'rest')
204 magic_docs = self._magic_docs(brief, rest)
204 magic_docs = self._magic_docs(brief, rest)
205
205
206 if mode == 'latex':
206 if mode == 'latex':
207 print(self.format_latex(magic_docs))
207 print(self.format_latex(magic_docs))
208 return
208 return
209 else:
209 else:
210 magic_docs = format_screen(magic_docs)
210 magic_docs = format_screen(magic_docs)
211
211
212 out = ["""
212 out = ["""
213 IPython's 'magic' functions
213 IPython's 'magic' functions
214 ===========================
214 ===========================
215
215
216 The magic function system provides a series of functions which allow you to
216 The magic function system provides a series of functions which allow you to
217 control the behavior of IPython itself, plus a lot of system-type
217 control the behavior of IPython itself, plus a lot of system-type
218 features. There are two kinds of magics, line-oriented and cell-oriented.
218 features. There are two kinds of magics, line-oriented and cell-oriented.
219
219
220 Line magics are prefixed with the % character and work much like OS
220 Line magics are prefixed with the % character and work much like OS
221 command-line calls: they get as an argument the rest of the line, where
221 command-line calls: they get as an argument the rest of the line, where
222 arguments are passed without parentheses or quotes. For example, this will
222 arguments are passed without parentheses or quotes. For example, this will
223 time the given statement::
223 time the given statement::
224
224
225 %timeit range(1000)
225 %timeit range(1000)
226
226
227 Cell magics are prefixed with a double %%, and they are functions that get as
227 Cell magics are prefixed with a double %%, and they are functions that get as
228 an argument not only the rest of the line, but also the lines below it in a
228 an argument not only the rest of the line, but also the lines below it in a
229 separate argument. These magics are called with two arguments: the rest of the
229 separate argument. These magics are called with two arguments: the rest of the
230 call line and the body of the cell, consisting of the lines below the first.
230 call line and the body of the cell, consisting of the lines below the first.
231 For example::
231 For example::
232
232
233 %%timeit x = numpy.random.randn((100, 100))
233 %%timeit x = numpy.random.randn((100, 100))
234 numpy.linalg.svd(x)
234 numpy.linalg.svd(x)
235
235
236 will time the execution of the numpy svd routine, running the assignment of x
236 will time the execution of the numpy svd routine, running the assignment of x
237 as part of the setup phase, which is not timed.
237 as part of the setup phase, which is not timed.
238
238
239 In a line-oriented client (the terminal or Qt console IPython), starting a new
239 In a line-oriented client (the terminal or Qt console IPython), starting a new
240 input with %% will automatically enter cell mode, and IPython will continue
240 input with %% will automatically enter cell mode, and IPython will continue
241 reading input until a blank line is given. In the notebook, simply type the
241 reading input until a blank line is given. In the notebook, simply type the
242 whole cell as one entity, but keep in mind that the %% escape can only be at
242 whole cell as one entity, but keep in mind that the %% escape can only be at
243 the very start of the cell.
243 the very start of the cell.
244
244
245 NOTE: If you have 'automagic' enabled (via the command line option or with the
245 NOTE: If you have 'automagic' enabled (via the command line option or with the
246 %automagic function), you don't need to type in the % explicitly for line
246 %automagic function), you don't need to type in the % explicitly for line
247 magics; cell magics always require an explicit '%%' escape. By default,
247 magics; cell magics always require an explicit '%%' escape. By default,
248 IPython ships with automagic on, so you should only rarely need the % escape.
248 IPython ships with automagic on, so you should only rarely need the % escape.
249
249
250 Example: typing '%cd mydir' (without the quotes) changes you working directory
250 Example: typing '%cd mydir' (without the quotes) changes you working directory
251 to 'mydir', if it exists.
251 to 'mydir', if it exists.
252
252
253 For a list of the available magic functions, use %lsmagic. For a description
253 For a list of the available magic functions, use %lsmagic. For a description
254 of any of them, type %magic_name?, e.g. '%cd?'.
254 of any of them, type %magic_name?, e.g. '%cd?'.
255
255
256 Currently the magic system has the following functions:""",
256 Currently the magic system has the following functions:""",
257 magic_docs,
257 magic_docs,
258 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
258 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
259 str(self.lsmagic()),
259 str(self.lsmagic()),
260 ]
260 ]
261 page.page('\n'.join(out))
261 page.page('\n'.join(out))
262
262
263
263
264 @line_magic
264 @line_magic
265 def page(self, parameter_s=''):
265 def page(self, parameter_s=''):
266 """Pretty print the object and display it through a pager.
266 """Pretty print the object and display it through a pager.
267
267
268 %page [options] OBJECT
268 %page [options] OBJECT
269
269
270 If no object is given, use _ (last output).
270 If no object is given, use _ (last output).
271
271
272 Options:
272 Options:
273
273
274 -r: page str(object), don't pretty-print it."""
274 -r: page str(object), don't pretty-print it."""
275
275
276 # After a function contributed by Olivier Aubert, slightly modified.
276 # After a function contributed by Olivier Aubert, slightly modified.
277
277
278 # Process options/args
278 # Process options/args
279 opts, args = self.parse_options(parameter_s, 'r')
279 opts, args = self.parse_options(parameter_s, 'r')
280 raw = 'r' in opts
280 raw = 'r' in opts
281
281
282 oname = args and args or '_'
282 oname = args and args or '_'
283 info = self.shell._ofind(oname)
283 info = self.shell._ofind(oname)
284 if info['found']:
284 if info['found']:
285 txt = (raw and str or pformat)( info['obj'] )
285 txt = (raw and str or pformat)( info['obj'] )
286 page.page(txt)
286 page.page(txt)
287 else:
287 else:
288 print('Object `%s` not found' % oname)
288 print('Object `%s` not found' % oname)
289
289
290 @line_magic
290 @line_magic
291 def profile(self, parameter_s=''):
291 def profile(self, parameter_s=''):
292 """Print your currently active IPython profile.
292 """Print your currently active IPython profile.
293
293
294 See Also
294 See Also
295 --------
295 --------
296 prun : run code using the Python profiler
296 prun : run code using the Python profiler
297 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
297 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
298 """
298 """
299 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
299 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
300 from IPython.core.application import BaseIPythonApplication
300 from IPython.core.application import BaseIPythonApplication
301 if BaseIPythonApplication.initialized():
301 if BaseIPythonApplication.initialized():
302 print(BaseIPythonApplication.instance().profile)
302 print(BaseIPythonApplication.instance().profile)
303 else:
303 else:
304 error("profile is an application-level value, but you don't appear to be in an IPython application")
304 error("profile is an application-level value, but you don't appear to be in an IPython application")
305
305
306 @line_magic
306 @line_magic
307 def pprint(self, parameter_s=''):
307 def pprint(self, parameter_s=''):
308 """Toggle pretty printing on/off."""
308 """Toggle pretty printing on/off."""
309 ptformatter = self.shell.display_formatter.formatters['text/plain']
309 ptformatter = self.shell.display_formatter.formatters['text/plain']
310 ptformatter.pprint = bool(1 - ptformatter.pprint)
310 ptformatter.pprint = bool(1 - ptformatter.pprint)
311 print('Pretty printing has been turned',
311 print('Pretty printing has been turned',
312 ['OFF','ON'][ptformatter.pprint])
312 ['OFF','ON'][ptformatter.pprint])
313
313
314 @line_magic
314 @line_magic
315 def colors(self, parameter_s=''):
315 def colors(self, parameter_s=''):
316 """Switch color scheme for prompts, info system and exception handlers.
316 """Switch color scheme for prompts, info system and exception handlers.
317
317
318 Currently implemented schemes: NoColor, Linux, LightBG.
318 Currently implemented schemes: NoColor, Linux, LightBG.
319
319
320 Color scheme names are not case-sensitive.
320 Color scheme names are not case-sensitive.
321
321
322 Examples
322 Examples
323 --------
323 --------
324 To get a plain black and white terminal::
324 To get a plain black and white terminal::
325
325
326 %colors nocolor
326 %colors nocolor
327 """
327 """
328 def color_switch_err(name):
328 def color_switch_err(name):
329 warn('Error changing %s color schemes.\n%s' %
329 warn('Error changing %s color schemes.\n%s' %
330 (name, sys.exc_info()[1]))
330 (name, sys.exc_info()[1]))
331
331
332
332
333 new_scheme = parameter_s.strip()
333 new_scheme = parameter_s.strip()
334 if not new_scheme:
334 if not new_scheme:
335 raise UsageError(
335 raise UsageError(
336 "%colors: you must specify a color scheme. See '%colors?'")
336 "%colors: you must specify a color scheme. See '%colors?'")
337 # local shortcut
337 # local shortcut
338 shell = self.shell
338 shell = self.shell
339
339
340 import IPython.utils.rlineimpl as readline
340 import IPython.utils.rlineimpl as readline
341
341
342 if not shell.colors_force and \
342 if not shell.colors_force and \
343 not readline.have_readline and \
343 not readline.have_readline and \
344 (sys.platform == "win32" or sys.platform == "cli"):
344 (sys.platform == "win32" or sys.platform == "cli"):
345 msg = """\
345 msg = """\
346 Proper color support under MS Windows requires the pyreadline library.
346 Proper color support under MS Windows requires the pyreadline library.
347 You can find it at:
347 You can find it at:
348 http://ipython.org/pyreadline.html
348 http://ipython.org/pyreadline.html
349
349
350 Defaulting color scheme to 'NoColor'"""
350 Defaulting color scheme to 'NoColor'"""
351 new_scheme = 'NoColor'
351 new_scheme = 'NoColor'
352 warn(msg)
352 warn(msg)
353
353
354 # readline option is 0
354 # readline option is 0
355 if not shell.colors_force and not shell.has_readline:
355 if not shell.colors_force and not shell.has_readline:
356 new_scheme = 'NoColor'
356 new_scheme = 'NoColor'
357
357
358 # Set prompt colors
358 # Set prompt colors
359 try:
359 try:
360 shell.prompt_manager.color_scheme = new_scheme
360 shell.prompt_manager.color_scheme = new_scheme
361 except:
361 except:
362 color_switch_err('prompt')
362 color_switch_err('prompt')
363 else:
363 else:
364 shell.colors = \
364 shell.colors = \
365 shell.prompt_manager.color_scheme_table.active_scheme_name
365 shell.prompt_manager.color_scheme_table.active_scheme_name
366 # Set exception colors
366 # Set exception colors
367 try:
367 try:
368 shell.InteractiveTB.set_colors(scheme = new_scheme)
368 shell.InteractiveTB.set_colors(scheme = new_scheme)
369 shell.SyntaxTB.set_colors(scheme = new_scheme)
369 shell.SyntaxTB.set_colors(scheme = new_scheme)
370 except:
370 except:
371 color_switch_err('exception')
371 color_switch_err('exception')
372
372
373 # Set info (for 'object?') colors
373 # Set info (for 'object?') colors
374 if shell.color_info:
374 if shell.color_info:
375 try:
375 try:
376 shell.inspector.set_active_scheme(new_scheme)
376 shell.inspector.set_active_scheme(new_scheme)
377 except:
377 except:
378 color_switch_err('object inspector')
378 color_switch_err('object inspector')
379 else:
379 else:
380 shell.inspector.set_active_scheme('NoColor')
380 shell.inspector.set_active_scheme('NoColor')
381
381
382 @line_magic
382 @line_magic
383 def xmode(self, parameter_s=''):
383 def xmode(self, parameter_s=''):
384 """Switch modes for the exception handlers.
384 """Switch modes for the exception handlers.
385
385
386 Valid modes: Plain, Context and Verbose.
386 Valid modes: Plain, Context and Verbose.
387
387
388 If called without arguments, acts as a toggle."""
388 If called without arguments, acts as a toggle."""
389
389
390 def xmode_switch_err(name):
390 def xmode_switch_err(name):
391 warn('Error changing %s exception modes.\n%s' %
391 warn('Error changing %s exception modes.\n%s' %
392 (name,sys.exc_info()[1]))
392 (name,sys.exc_info()[1]))
393
393
394 shell = self.shell
394 shell = self.shell
395 new_mode = parameter_s.strip().capitalize()
395 new_mode = parameter_s.strip().capitalize()
396 try:
396 try:
397 shell.InteractiveTB.set_mode(mode=new_mode)
397 shell.InteractiveTB.set_mode(mode=new_mode)
398 print('Exception reporting mode:',shell.InteractiveTB.mode)
398 print('Exception reporting mode:',shell.InteractiveTB.mode)
399 except:
399 except:
400 xmode_switch_err('user')
400 xmode_switch_err('user')
401
401
402 @line_magic
402 @line_magic
403 def quickref(self,arg):
403 def quickref(self,arg):
404 """ Show a quick reference sheet """
404 """ Show a quick reference sheet """
405 from IPython.core.usage import quick_reference
405 from IPython.core.usage import quick_reference
406 qr = quick_reference + self._magic_docs(brief=True)
406 qr = quick_reference + self._magic_docs(brief=True)
407 page.page(qr)
407 page.page(qr)
408
408
409 @line_magic
409 @line_magic
410 def doctest_mode(self, parameter_s=''):
410 def doctest_mode(self, parameter_s=''):
411 """Toggle doctest mode on and off.
411 """Toggle doctest mode on and off.
412
412
413 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
414 plain Python shell, from the perspective of how its prompts, exceptions
414 plain Python shell, from the perspective of how its prompts, exceptions
415 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
416 session into doctests. It does so by:
416 session into doctests. It does so by:
417
417
418 - Changing the prompts to the classic ``>>>`` ones.
418 - Changing the prompts to the classic ``>>>`` ones.
419 - Changing the exception reporting mode to 'Plain'.
419 - Changing the exception reporting mode to 'Plain'.
420 - Disabling pretty-printing of output.
420 - Disabling pretty-printing of output.
421
421
422 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
423 leading '>>>' and '...' prompts in them. This means that you can paste
423 leading '>>>' and '...' prompts in them. This means that you can paste
424 doctests from files or docstrings (even if they have leading
424 doctests from files or docstrings (even if they have leading
425 whitespace), and the code will execute correctly. You can then use
425 whitespace), and the code will execute correctly. You can then use
426 '%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
427 input after removal of all the leading prompts and whitespace, which
427 input after removal of all the leading prompts and whitespace, which
428 can be pasted back into an editor.
428 can be pasted back into an editor.
429
429
430 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
431 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
432 your existing IPython session.
432 your existing IPython session.
433 """
433 """
434
434
435 # Shorthands
435 # Shorthands
436 shell = self.shell
436 shell = self.shell
437 pm = shell.prompt_manager
437 pm = shell.prompt_manager
438 meta = shell.meta
438 meta = shell.meta
439 disp_formatter = self.shell.display_formatter
439 disp_formatter = self.shell.display_formatter
440 ptformatter = disp_formatter.formatters['text/plain']
440 ptformatter = disp_formatter.formatters['text/plain']
441 # 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
442 # changes we make, so we can undo them later.
442 # changes we make, so we can undo them later.
443 dstore = meta.setdefault('doctest_mode',Struct())
443 dstore = meta.setdefault('doctest_mode',Struct())
444 save_dstore = dstore.setdefault
444 save_dstore = dstore.setdefault
445
445
446 # save a few values we'll need to recover later
446 # save a few values we'll need to recover later
447 mode = save_dstore('mode',False)
447 mode = save_dstore('mode',False)
448 save_dstore('rc_pprint',ptformatter.pprint)
448 save_dstore('rc_pprint',ptformatter.pprint)
449 save_dstore('xmode',shell.InteractiveTB.mode)
449 save_dstore('xmode',shell.InteractiveTB.mode)
450 save_dstore('rc_separate_out',shell.separate_out)
450 save_dstore('rc_separate_out',shell.separate_out)
451 save_dstore('rc_separate_out2',shell.separate_out2)
451 save_dstore('rc_separate_out2',shell.separate_out2)
452 save_dstore('rc_prompts_pad_left',pm.justify)
452 save_dstore('rc_prompts_pad_left',pm.justify)
453 save_dstore('rc_separate_in',shell.separate_in)
453 save_dstore('rc_separate_in',shell.separate_in)
454 save_dstore('rc_active_types',disp_formatter.active_types)
454 save_dstore('rc_active_types',disp_formatter.active_types)
455 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))
456
456
457 if mode == False:
457 if mode == False:
458 # turn on
458 # turn on
459 pm.in_template = '>>> '
459 pm.in_template = '>>> '
460 pm.in2_template = '... '
460 pm.in2_template = '... '
461 pm.out_template = ''
461 pm.out_template = ''
462
462
463 # Prompt separators like plain python
463 # Prompt separators like plain python
464 shell.separate_in = ''
464 shell.separate_in = ''
465 shell.separate_out = ''
465 shell.separate_out = ''
466 shell.separate_out2 = ''
466 shell.separate_out2 = ''
467
467
468 pm.justify = False
468 pm.justify = False
469
469
470 ptformatter.pprint = False
470 ptformatter.pprint = False
471 disp_formatter.active_types = ['text/plain']
471 disp_formatter.active_types = ['text/plain']
472
472
473 shell.magic('xmode Plain')
473 shell.magic('xmode Plain')
474 else:
474 else:
475 # turn off
475 # turn off
476 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
477
477
478 shell.separate_in = dstore.rc_separate_in
478 shell.separate_in = dstore.rc_separate_in
479
479
480 shell.separate_out = dstore.rc_separate_out
480 shell.separate_out = dstore.rc_separate_out
481 shell.separate_out2 = dstore.rc_separate_out2
481 shell.separate_out2 = dstore.rc_separate_out2
482
482
483 pm.justify = dstore.rc_prompts_pad_left
483 pm.justify = dstore.rc_prompts_pad_left
484
484
485 ptformatter.pprint = dstore.rc_pprint
485 ptformatter.pprint = dstore.rc_pprint
486 disp_formatter.active_types = dstore.rc_active_types
486 disp_formatter.active_types = dstore.rc_active_types
487
487
488 shell.magic('xmode ' + dstore.xmode)
488 shell.magic('xmode ' + dstore.xmode)
489
489
490 # Store new mode and inform
490 # Store new mode and inform
491 dstore.mode = bool(1-int(mode))
491 dstore.mode = bool(1-int(mode))
492 mode_label = ['OFF','ON'][dstore.mode]
492 mode_label = ['OFF','ON'][dstore.mode]
493 print('Doctest mode is:', mode_label)
493 print('Doctest mode is:', mode_label)
494
494
495 @line_magic
495 @line_magic
496 def gui(self, parameter_s=''):
496 def gui(self, parameter_s=''):
497 """Enable or disable IPython GUI event loop integration.
497 """Enable or disable IPython GUI event loop integration.
498
498
499 %gui [GUINAME]
499 %gui [GUINAME]
500
500
501 This magic replaces IPython's threaded shells that were activated
501 This magic replaces IPython's threaded shells that were activated
502 using the (pylab/wthread/etc.) command line flags. GUI toolkits
502 using the (pylab/wthread/etc.) command line flags. GUI toolkits
503 can now be enabled at runtime and keyboard
503 can now be enabled at runtime and keyboard
504 interrupts should work without any problems. The following toolkits
504 interrupts should work without any problems. The following toolkits
505 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
505 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
506
506
507 %gui wx # enable wxPython event loop integration
507 %gui wx # enable wxPython event loop integration
508 %gui qt4|qt # enable PyQt4 event loop integration
508 %gui qt4|qt # enable PyQt4 event loop integration
509 %gui qt5 # enable PyQt5 event loop integration
509 %gui qt5 # enable PyQt5 event loop integration
510 %gui gtk # enable PyGTK event loop integration
510 %gui gtk # enable PyGTK event loop integration
511 %gui gtk3 # enable Gtk3 event loop integration
511 %gui gtk3 # enable Gtk3 event loop integration
512 %gui tk # enable Tk event loop integration
512 %gui tk # enable Tk event loop integration
513 %gui osx # enable Cocoa event loop integration
513 %gui osx # enable Cocoa event loop integration
514 # (requires %matplotlib 1.1)
514 # (requires %matplotlib 1.1)
515 %gui # disable all event loop integration
515 %gui # disable all event loop integration
516
516
517 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
518 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
519 we have already handled that.
519 we have already handled that.
520 """
520 """
521 opts, arg = self.parse_options(parameter_s, '')
521 opts, arg = self.parse_options(parameter_s, '')
522 if arg=='': arg = None
522 if arg=='': arg = None
523 try:
523 try:
524 return self.shell.enable_gui(arg)
524 return self.shell.enable_gui(arg)
525 except Exception as e:
525 except Exception as e:
526 # print simple error message, rather than traceback if we can't
526 # print simple error message, rather than traceback if we can't
527 # hook up the GUI
527 # hook up the GUI
528 error(str(e))
528 error(str(e))
529
529
530 @skip_doctest
530 @skip_doctest
531 @line_magic
531 @line_magic
532 def precision(self, s=''):
532 def precision(self, s=''):
533 """Set floating point precision for pretty printing.
533 """Set floating point precision for pretty printing.
534
534
535 Can set either integer precision or a format string.
535 Can set either integer precision or a format string.
536
536
537 If numpy has been imported and precision is an int,
537 If numpy has been imported and precision is an int,
538 numpy display precision will also be set, via ``numpy.set_printoptions``.
538 numpy display precision will also be set, via ``numpy.set_printoptions``.
539
539
540 If no argument is given, defaults will be restored.
540 If no argument is given, defaults will be restored.
541
541
542 Examples
542 Examples
543 --------
543 --------
544 ::
544 ::
545
545
546 In [1]: from math import pi
546 In [1]: from math import pi
547
547
548 In [2]: %precision 3
548 In [2]: %precision 3
549 Out[2]: u'%.3f'
549 Out[2]: u'%.3f'
550
550
551 In [3]: pi
551 In [3]: pi
552 Out[3]: 3.142
552 Out[3]: 3.142
553
553
554 In [4]: %precision %i
554 In [4]: %precision %i
555 Out[4]: u'%i'
555 Out[4]: u'%i'
556
556
557 In [5]: pi
557 In [5]: pi
558 Out[5]: 3
558 Out[5]: 3
559
559
560 In [6]: %precision %e
560 In [6]: %precision %e
561 Out[6]: u'%e'
561 Out[6]: u'%e'
562
562
563 In [7]: pi**10
563 In [7]: pi**10
564 Out[7]: 9.364805e+04
564 Out[7]: 9.364805e+04
565
565
566 In [8]: %precision
566 In [8]: %precision
567 Out[8]: u'%r'
567 Out[8]: u'%r'
568
568
569 In [9]: pi**10
569 In [9]: pi**10
570 Out[9]: 93648.047476082982
570 Out[9]: 93648.047476082982
571 """
571 """
572 ptformatter = self.shell.display_formatter.formatters['text/plain']
572 ptformatter = self.shell.display_formatter.formatters['text/plain']
573 ptformatter.float_precision = s
573 ptformatter.float_precision = s
574 return ptformatter.float_format
574 return ptformatter.float_format
575
575
576 @magic_arguments.magic_arguments()
576 @magic_arguments.magic_arguments()
577 @magic_arguments.argument(
577 @magic_arguments.argument(
578 '-e', '--export', action='store_true', default=False,
578 '-e', '--export', action='store_true', default=False,
579 help='Export IPython history as a notebook. The filename argument '
579 help='Export IPython history as a notebook. The filename argument '
580 'is used to specify the notebook name and format. For example '
580 'is used to specify the notebook name and format. For example '
581 'a filename of notebook.ipynb will result in a notebook name '
581 'a filename of notebook.ipynb will result in a notebook name '
582 'of "notebook" and a format of "json". Likewise using a ".py" '
582 'of "notebook" and a format of "json". Likewise using a ".py" '
583 'file extension will write the notebook as a Python script'
583 'file extension will write the notebook as a Python script'
584 )
584 )
585 @magic_arguments.argument(
585 @magic_arguments.argument(
586 'filename', type=unicode_type,
586 'filename', type=unicode_type,
587 help='Notebook name or filename'
587 help='Notebook name or filename'
588 )
588 )
589 @line_magic
589 @line_magic
590 def notebook(self, s):
590 def notebook(self, s):
591 """Export and convert IPython notebooks.
591 """Export and convert IPython notebooks.
592
592
593 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.
594 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".
595 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".
596 """
596 """
597 args = magic_arguments.parse_argstring(self.notebook, s)
597 args = magic_arguments.parse_argstring(self.notebook, s)
598
598
599 from IPython.nbformat import write, v4
599 from jupyter_nbformat import write, v4
600 args.filename = unquote_filename(args.filename)
600 args.filename = unquote_filename(args.filename)
601 if args.export:
601 if args.export:
602 cells = []
602 cells = []
603 hist = list(self.shell.history_manager.get_range())
603 hist = list(self.shell.history_manager.get_range())
604 if(len(hist)<=1):
604 if(len(hist)<=1):
605 raise ValueError('History is empty, cannot export')
605 raise ValueError('History is empty, cannot export')
606 for session, execution_count, source in hist[:-1]:
606 for session, execution_count, source in hist[:-1]:
607 cells.append(v4.new_code_cell(
607 cells.append(v4.new_code_cell(
608 execution_count=execution_count,
608 execution_count=execution_count,
609 source=source
609 source=source
610 ))
610 ))
611 nb = v4.new_notebook(cells=cells)
611 nb = v4.new_notebook(cells=cells)
612 with io.open(args.filename, 'w', encoding='utf-8') as f:
612 with io.open(args.filename, 'w', encoding='utf-8') as f:
613 write(nb, f, version=4)
613 write(nb, f, version=4)
@@ -1,159 +1,159 b''
1 """Implementation of configuration-related magic functions.
1 """Implementation of configuration-related magic functions.
2 """
2 """
3 from __future__ import print_function
3 from __future__ import print_function
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2012 The IPython Development Team.
5 # Copyright (c) 2012 The IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 # Stdlib
16 # Stdlib
17 import re
17 import re
18
18
19 # Our own packages
19 # Our own packages
20 from IPython.core.error import UsageError
20 from IPython.core.error import UsageError
21 from IPython.core.magic import Magics, magics_class, line_magic
21 from IPython.core.magic import Magics, magics_class, line_magic
22 from IPython.utils.warn import error
22 from IPython.utils.warn import error
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Magic implementation classes
25 # Magic implementation classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 reg = re.compile('^\w+\.\w+$')
28 reg = re.compile('^\w+\.\w+$')
29 @magics_class
29 @magics_class
30 class ConfigMagics(Magics):
30 class ConfigMagics(Magics):
31
31
32 def __init__(self, shell):
32 def __init__(self, shell):
33 super(ConfigMagics, self).__init__(shell)
33 super(ConfigMagics, self).__init__(shell)
34 self.configurables = []
34 self.configurables = []
35
35
36 @line_magic
36 @line_magic
37 def config(self, s):
37 def config(self, s):
38 """configure IPython
38 """configure IPython
39
39
40 %config Class[.trait=value]
40 %config Class[.trait=value]
41
41
42 This magic exposes most of the IPython config system. Any
42 This magic exposes most of the IPython config system. Any
43 Configurable class should be able to be configured with the simple
43 Configurable class should be able to be configured with the simple
44 line::
44 line::
45
45
46 %config Class.trait=value
46 %config Class.trait=value
47
47
48 Where `value` will be resolved in the user's namespace, if it is an
48 Where `value` will be resolved in the user's namespace, if it is an
49 expression or variable name.
49 expression or variable name.
50
50
51 Examples
51 Examples
52 --------
52 --------
53
53
54 To see what classes are available for config, pass no arguments::
54 To see what classes are available for config, pass no arguments::
55
55
56 In [1]: %config
56 In [1]: %config
57 Available objects for config:
57 Available objects for config:
58 TerminalInteractiveShell
58 TerminalInteractiveShell
59 HistoryManager
59 HistoryManager
60 PrefilterManager
60 PrefilterManager
61 AliasManager
61 AliasManager
62 IPCompleter
62 IPCompleter
63 PromptManager
63 PromptManager
64 DisplayFormatter
64 DisplayFormatter
65
65
66 To view what is configurable on a given class, just pass the class
66 To view what is configurable on a given class, just pass the class
67 name::
67 name::
68
68
69 In [2]: %config IPCompleter
69 In [2]: %config IPCompleter
70 IPCompleter options
70 IPCompleter options
71 -----------------
71 -----------------
72 IPCompleter.omit__names=<Enum>
72 IPCompleter.omit__names=<Enum>
73 Current: 2
73 Current: 2
74 Choices: (0, 1, 2)
74 Choices: (0, 1, 2)
75 Instruct the completer to omit private method names
75 Instruct the completer to omit private method names
76 Specifically, when completing on ``object.<tab>``.
76 Specifically, when completing on ``object.<tab>``.
77 When 2 [default]: all names that start with '_' will be excluded.
77 When 2 [default]: all names that start with '_' will be excluded.
78 When 1: all 'magic' names (``__foo__``) will be excluded.
78 When 1: all 'magic' names (``__foo__``) will be excluded.
79 When 0: nothing will be excluded.
79 When 0: nothing will be excluded.
80 IPCompleter.merge_completions=<CBool>
80 IPCompleter.merge_completions=<CBool>
81 Current: True
81 Current: True
82 Whether to merge completion results into a single list
82 Whether to merge completion results into a single list
83 If False, only the completion results from the first non-empty
83 If False, only the completion results from the first non-empty
84 completer will be returned.
84 completer will be returned.
85 IPCompleter.limit_to__all__=<CBool>
85 IPCompleter.limit_to__all__=<CBool>
86 Current: False
86 Current: False
87 Instruct the completer to use __all__ for the completion
87 Instruct the completer to use __all__ for the completion
88 Specifically, when completing on ``object.<tab>``.
88 Specifically, when completing on ``object.<tab>``.
89 When True: only those names in obj.__all__ will be included.
89 When True: only those names in obj.__all__ will be included.
90 When False [default]: the __all__ attribute is ignored
90 When False [default]: the __all__ attribute is ignored
91 IPCompleter.greedy=<CBool>
91 IPCompleter.greedy=<CBool>
92 Current: False
92 Current: False
93 Activate greedy completion
93 Activate greedy completion
94 This will enable completion on elements of lists, results of
94 This will enable completion on elements of lists, results of
95 function calls, etc., but can be unsafe because the code is
95 function calls, etc., but can be unsafe because the code is
96 actually evaluated on TAB.
96 actually evaluated on TAB.
97
97
98 but the real use is in setting values::
98 but the real use is in setting values::
99
99
100 In [3]: %config IPCompleter.greedy = True
100 In [3]: %config IPCompleter.greedy = True
101
101
102 and these values are read from the user_ns if they are variables::
102 and these values are read from the user_ns if they are variables::
103
103
104 In [4]: feeling_greedy=False
104 In [4]: feeling_greedy=False
105
105
106 In [5]: %config IPCompleter.greedy = feeling_greedy
106 In [5]: %config IPCompleter.greedy = feeling_greedy
107
107
108 """
108 """
109 from IPython.config.loader import Config
109 from 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,155 +1,155 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 IPython.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 IPython.utils.warn 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_gui_arg
45 @magic_gui_arg
46 def matplotlib(self, line=''):
46 def matplotlib(self, line=''):
47 """Set up matplotlib to work interactively.
47 """Set up matplotlib to work interactively.
48
48
49 This function lets you activate matplotlib interactive support
49 This function lets you activate matplotlib interactive support
50 at any point during an IPython session. It does not import anything
50 at any point during an IPython session. It does not import anything
51 into the interactive namespace.
51 into the interactive namespace.
52
52
53 If you are using the inline matplotlib backend in the IPython Notebook
53 If you are using the inline matplotlib backend in the IPython Notebook
54 you can set which figure formats are enabled using the following::
54 you can set which figure formats are enabled using the following::
55
55
56 In [1]: from IPython.display import set_matplotlib_formats
56 In [1]: from IPython.display import set_matplotlib_formats
57
57
58 In [2]: set_matplotlib_formats('pdf', 'svg')
58 In [2]: set_matplotlib_formats('pdf', 'svg')
59
59
60 The default for inline figures sets `bbox_inches` to 'tight'. This can
60 The default for inline figures sets `bbox_inches` to 'tight'. This can
61 cause discrepancies between the displayed image and the identical
61 cause discrepancies between the displayed image and the identical
62 image created using `savefig`. This behavior can be disabled using the
62 image created using `savefig`. This behavior can be disabled using the
63 `%config` magic::
63 `%config` magic::
64
64
65 In [3]: %config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
65 In [3]: %config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
66
66
67 In addition, see the docstring of
67 In addition, see the docstring of
68 `IPython.display.set_matplotlib_formats` and
68 `IPython.display.set_matplotlib_formats` and
69 `IPython.display.set_matplotlib_close` for more information on
69 `IPython.display.set_matplotlib_close` for more information on
70 changing additional behaviors of the inline backend.
70 changing additional behaviors of the inline backend.
71
71
72 Examples
72 Examples
73 --------
73 --------
74 To enable the inline backend for usage with the IPython Notebook::
74 To enable the inline backend for usage with the IPython Notebook::
75
75
76 In [1]: %matplotlib inline
76 In [1]: %matplotlib inline
77
77
78 In this case, where the matplotlib default is TkAgg::
78 In this case, where the matplotlib default is TkAgg::
79
79
80 In [2]: %matplotlib
80 In [2]: %matplotlib
81 Using matplotlib backend: TkAgg
81 Using matplotlib backend: TkAgg
82
82
83 But you can explicitly request a different GUI backend::
83 But you can explicitly request a different GUI backend::
84
84
85 In [3]: %matplotlib qt
85 In [3]: %matplotlib qt
86 """
86 """
87 args = magic_arguments.parse_argstring(self.matplotlib, line)
87 args = magic_arguments.parse_argstring(self.matplotlib, line)
88 gui, backend = self.shell.enable_matplotlib(args.gui)
88 gui, backend = self.shell.enable_matplotlib(args.gui)
89 self._show_matplotlib_backend(args.gui, backend)
89 self._show_matplotlib_backend(args.gui, backend)
90
90
91 @skip_doctest
91 @skip_doctest
92 @line_magic
92 @line_magic
93 @magic_arguments.magic_arguments()
93 @magic_arguments.magic_arguments()
94 @magic_arguments.argument(
94 @magic_arguments.argument(
95 '--no-import-all', action='store_true', default=None,
95 '--no-import-all', action='store_true', default=None,
96 help="""Prevent IPython from performing ``import *`` into the interactive namespace.
96 help="""Prevent IPython from performing ``import *`` into the interactive namespace.
97
97
98 You can govern the default behavior of this flag with the
98 You can govern the default behavior of this flag with the
99 InteractiveShellApp.pylab_import_all configurable.
99 InteractiveShellApp.pylab_import_all configurable.
100 """
100 """
101 )
101 )
102 @magic_gui_arg
102 @magic_gui_arg
103 def pylab(self, line=''):
103 def pylab(self, line=''):
104 """Load numpy and matplotlib to work interactively.
104 """Load numpy and matplotlib to work interactively.
105
105
106 This function lets you activate pylab (matplotlib, numpy and
106 This function lets you activate pylab (matplotlib, numpy and
107 interactive support) at any point during an IPython session.
107 interactive support) at any point during an IPython session.
108
108
109 %pylab makes the following imports::
109 %pylab makes the following imports::
110
110
111 import numpy
111 import numpy
112 import matplotlib
112 import matplotlib
113 from matplotlib import pylab, mlab, pyplot
113 from matplotlib import pylab, mlab, pyplot
114 np = numpy
114 np = numpy
115 plt = pyplot
115 plt = pyplot
116
116
117 from IPython.display import display
117 from IPython.display import display
118 from IPython.core.pylabtools import figsize, getfigs
118 from IPython.core.pylabtools import figsize, getfigs
119
119
120 from pylab import *
120 from pylab import *
121 from numpy import *
121 from numpy import *
122
122
123 If you pass `--no-import-all`, the last two `*` imports will be excluded.
123 If you pass `--no-import-all`, the last two `*` imports will be excluded.
124
124
125 See the %matplotlib magic for more details about activating matplotlib
125 See the %matplotlib magic for more details about activating matplotlib
126 without affecting the interactive namespace.
126 without affecting the interactive namespace.
127 """
127 """
128 args = magic_arguments.parse_argstring(self.pylab, line)
128 args = magic_arguments.parse_argstring(self.pylab, line)
129 if args.no_import_all is None:
129 if args.no_import_all is None:
130 # get default from Application
130 # get default from Application
131 if Application.initialized():
131 if Application.initialized():
132 app = Application.instance()
132 app = Application.instance()
133 try:
133 try:
134 import_all = app.pylab_import_all
134 import_all = app.pylab_import_all
135 except AttributeError:
135 except AttributeError:
136 import_all = True
136 import_all = True
137 else:
137 else:
138 # nothing specified, no app - default True
138 # nothing specified, no app - default True
139 import_all = True
139 import_all = True
140 else:
140 else:
141 # invert no-import flag
141 # invert no-import flag
142 import_all = not args.no_import_all
142 import_all = not args.no_import_all
143
143
144 gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all)
144 gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all)
145 self._show_matplotlib_backend(args.gui, backend)
145 self._show_matplotlib_backend(args.gui, backend)
146 print ("Populating the interactive namespace from numpy and matplotlib")
146 print ("Populating the interactive namespace from numpy and matplotlib")
147 if clobbered:
147 if clobbered:
148 warn("pylab import has clobbered these variables: %s" % clobbered +
148 warn("pylab import has clobbered these variables: %s" % clobbered +
149 "\n`%matplotlib` prevents importing * from pylab and numpy"
149 "\n`%matplotlib` prevents importing * from pylab and numpy"
150 )
150 )
151
151
152 def _show_matplotlib_backend(self, gui, backend):
152 def _show_matplotlib_backend(self, gui, backend):
153 """show matplotlib message backend message"""
153 """show matplotlib message backend message"""
154 if not gui or gui == 'auto':
154 if not gui or gui == 'auto':
155 print("Using matplotlib backend: %s" % backend)
155 print("Using matplotlib backend: %s" % backend)
@@ -1,282 +1,282 b''
1 """Magic functions for running cells in various scripts."""
1 """Magic functions for running cells in various scripts."""
2 from __future__ import print_function
2 from __future__ import print_function
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 errno
16 import errno
17 import os
17 import os
18 import sys
18 import sys
19 import signal
19 import signal
20 import time
20 import time
21 from subprocess import Popen, PIPE
21 from subprocess import Popen, PIPE
22 import atexit
22 import atexit
23
23
24 # Our own packages
24 # Our own packages
25 from IPython.config.configurable import Configurable
25 from traitlets.config.configurable import Configurable
26 from IPython.core import magic_arguments
26 from IPython.core import magic_arguments
27 from IPython.core.magic import (
27 from IPython.core.magic import (
28 Magics, magics_class, line_magic, cell_magic
28 Magics, magics_class, line_magic, cell_magic
29 )
29 )
30 from IPython.lib.backgroundjobs import BackgroundJobManager
30 from IPython.lib.backgroundjobs import BackgroundJobManager
31 from IPython.utils import py3compat
31 from IPython.utils import py3compat
32 from IPython.utils.process import arg_split
32 from IPython.utils.process import arg_split
33 from IPython.utils.traitlets import List, Dict
33 from traitlets import List, Dict
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Magic implementation classes
36 # Magic implementation classes
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 def script_args(f):
39 def script_args(f):
40 """single decorator for adding script args"""
40 """single decorator for adding script args"""
41 args = [
41 args = [
42 magic_arguments.argument(
42 magic_arguments.argument(
43 '--out', type=str,
43 '--out', type=str,
44 help="""The variable in which to store stdout from the script.
44 help="""The variable in which to store stdout from the script.
45 If the script is backgrounded, this will be the stdout *pipe*,
45 If the script is backgrounded, this will be the stdout *pipe*,
46 instead of the stderr text itself.
46 instead of the stderr text itself.
47 """
47 """
48 ),
48 ),
49 magic_arguments.argument(
49 magic_arguments.argument(
50 '--err', type=str,
50 '--err', type=str,
51 help="""The variable in which to store stderr from the script.
51 help="""The variable in which to store stderr from the script.
52 If the script is backgrounded, this will be the stderr *pipe*,
52 If the script is backgrounded, this will be the stderr *pipe*,
53 instead of the stderr text itself.
53 instead of the stderr text itself.
54 """
54 """
55 ),
55 ),
56 magic_arguments.argument(
56 magic_arguments.argument(
57 '--bg', action="store_true",
57 '--bg', action="store_true",
58 help="""Whether to run the script in the background.
58 help="""Whether to run the script in the background.
59 If given, the only way to see the output of the command is
59 If given, the only way to see the output of the command is
60 with --out/err.
60 with --out/err.
61 """
61 """
62 ),
62 ),
63 magic_arguments.argument(
63 magic_arguments.argument(
64 '--proc', type=str,
64 '--proc', type=str,
65 help="""The variable in which to store Popen instance.
65 help="""The variable in which to store Popen instance.
66 This is used only when --bg option is given.
66 This is used only when --bg option is given.
67 """
67 """
68 ),
68 ),
69 ]
69 ]
70 for arg in args:
70 for arg in args:
71 f = arg(f)
71 f = arg(f)
72 return f
72 return f
73
73
74 @magics_class
74 @magics_class
75 class ScriptMagics(Magics):
75 class ScriptMagics(Magics):
76 """Magics for talking to scripts
76 """Magics for talking to scripts
77
77
78 This defines a base `%%script` cell magic for running a cell
78 This defines a base `%%script` cell magic for running a cell
79 with a program in a subprocess, and registers a few top-level
79 with a program in a subprocess, and registers a few top-level
80 magics that call %%script with common interpreters.
80 magics that call %%script with common interpreters.
81 """
81 """
82 script_magics = List(config=True,
82 script_magics = List(config=True,
83 help="""Extra script cell magics to define
83 help="""Extra script cell magics to define
84
84
85 This generates simple wrappers of `%%script foo` as `%%foo`.
85 This generates simple wrappers of `%%script foo` as `%%foo`.
86
86
87 If you want to add script magics that aren't on your path,
87 If you want to add script magics that aren't on your path,
88 specify them in script_paths
88 specify them in script_paths
89 """,
89 """,
90 )
90 )
91 def _script_magics_default(self):
91 def _script_magics_default(self):
92 """default to a common list of programs"""
92 """default to a common list of programs"""
93
93
94 defaults = [
94 defaults = [
95 'sh',
95 'sh',
96 'bash',
96 'bash',
97 'perl',
97 'perl',
98 'ruby',
98 'ruby',
99 'python',
99 'python',
100 'python2',
100 'python2',
101 'python3',
101 'python3',
102 'pypy',
102 'pypy',
103 ]
103 ]
104 if os.name == 'nt':
104 if os.name == 'nt':
105 defaults.extend([
105 defaults.extend([
106 'cmd',
106 'cmd',
107 ])
107 ])
108
108
109 return defaults
109 return defaults
110
110
111 script_paths = Dict(config=True,
111 script_paths = Dict(config=True,
112 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
112 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
113
113
114 Only necessary for items in script_magics where the default path will not
114 Only necessary for items in script_magics where the default path will not
115 find the right interpreter.
115 find the right interpreter.
116 """
116 """
117 )
117 )
118
118
119 def __init__(self, shell=None):
119 def __init__(self, shell=None):
120 super(ScriptMagics, self).__init__(shell=shell)
120 super(ScriptMagics, self).__init__(shell=shell)
121 self._generate_script_magics()
121 self._generate_script_magics()
122 self.job_manager = BackgroundJobManager()
122 self.job_manager = BackgroundJobManager()
123 self.bg_processes = []
123 self.bg_processes = []
124 atexit.register(self.kill_bg_processes)
124 atexit.register(self.kill_bg_processes)
125
125
126 def __del__(self):
126 def __del__(self):
127 self.kill_bg_processes()
127 self.kill_bg_processes()
128
128
129 def _generate_script_magics(self):
129 def _generate_script_magics(self):
130 cell_magics = self.magics['cell']
130 cell_magics = self.magics['cell']
131 for name in self.script_magics:
131 for name in self.script_magics:
132 cell_magics[name] = self._make_script_magic(name)
132 cell_magics[name] = self._make_script_magic(name)
133
133
134 def _make_script_magic(self, name):
134 def _make_script_magic(self, name):
135 """make a named magic, that calls %%script with a particular program"""
135 """make a named magic, that calls %%script with a particular program"""
136 # expand to explicit path if necessary:
136 # expand to explicit path if necessary:
137 script = self.script_paths.get(name, name)
137 script = self.script_paths.get(name, name)
138
138
139 @magic_arguments.magic_arguments()
139 @magic_arguments.magic_arguments()
140 @script_args
140 @script_args
141 def named_script_magic(line, cell):
141 def named_script_magic(line, cell):
142 # if line, add it as cl-flags
142 # if line, add it as cl-flags
143 if line:
143 if line:
144 line = "%s %s" % (script, line)
144 line = "%s %s" % (script, line)
145 else:
145 else:
146 line = script
146 line = script
147 return self.shebang(line, cell)
147 return self.shebang(line, cell)
148
148
149 # write a basic docstring:
149 # write a basic docstring:
150 named_script_magic.__doc__ = \
150 named_script_magic.__doc__ = \
151 """%%{name} script magic
151 """%%{name} script magic
152
152
153 Run cells with {script} in a subprocess.
153 Run cells with {script} in a subprocess.
154
154
155 This is a shortcut for `%%script {script}`
155 This is a shortcut for `%%script {script}`
156 """.format(**locals())
156 """.format(**locals())
157
157
158 return named_script_magic
158 return named_script_magic
159
159
160 @magic_arguments.magic_arguments()
160 @magic_arguments.magic_arguments()
161 @script_args
161 @script_args
162 @cell_magic("script")
162 @cell_magic("script")
163 def shebang(self, line, cell):
163 def shebang(self, line, cell):
164 """Run a cell via a shell command
164 """Run a cell via a shell command
165
165
166 The `%%script` line is like the #! line of script,
166 The `%%script` line is like the #! line of script,
167 specifying a program (bash, perl, ruby, etc.) with which to run.
167 specifying a program (bash, perl, ruby, etc.) with which to run.
168
168
169 The rest of the cell is run by that program.
169 The rest of the cell is run by that program.
170
170
171 Examples
171 Examples
172 --------
172 --------
173 ::
173 ::
174
174
175 In [1]: %%script bash
175 In [1]: %%script bash
176 ...: for i in 1 2 3; do
176 ...: for i in 1 2 3; do
177 ...: echo $i
177 ...: echo $i
178 ...: done
178 ...: done
179 1
179 1
180 2
180 2
181 3
181 3
182 """
182 """
183 argv = arg_split(line, posix = not sys.platform.startswith('win'))
183 argv = arg_split(line, posix = not sys.platform.startswith('win'))
184 args, cmd = self.shebang.parser.parse_known_args(argv)
184 args, cmd = self.shebang.parser.parse_known_args(argv)
185
185
186 try:
186 try:
187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
188 except OSError as e:
188 except OSError as e:
189 if e.errno == errno.ENOENT:
189 if e.errno == errno.ENOENT:
190 print("Couldn't find program: %r" % cmd[0])
190 print("Couldn't find program: %r" % cmd[0])
191 return
191 return
192 else:
192 else:
193 raise
193 raise
194
194
195 if not cell.endswith('\n'):
195 if not cell.endswith('\n'):
196 cell += '\n'
196 cell += '\n'
197 cell = cell.encode('utf8', 'replace')
197 cell = cell.encode('utf8', 'replace')
198 if args.bg:
198 if args.bg:
199 self.bg_processes.append(p)
199 self.bg_processes.append(p)
200 self._gc_bg_processes()
200 self._gc_bg_processes()
201 if args.out:
201 if args.out:
202 self.shell.user_ns[args.out] = p.stdout
202 self.shell.user_ns[args.out] = p.stdout
203 if args.err:
203 if args.err:
204 self.shell.user_ns[args.err] = p.stderr
204 self.shell.user_ns[args.err] = p.stderr
205 self.job_manager.new(self._run_script, p, cell, daemon=True)
205 self.job_manager.new(self._run_script, p, cell, daemon=True)
206 if args.proc:
206 if args.proc:
207 self.shell.user_ns[args.proc] = p
207 self.shell.user_ns[args.proc] = p
208 return
208 return
209
209
210 try:
210 try:
211 out, err = p.communicate(cell)
211 out, err = p.communicate(cell)
212 except KeyboardInterrupt:
212 except KeyboardInterrupt:
213 try:
213 try:
214 p.send_signal(signal.SIGINT)
214 p.send_signal(signal.SIGINT)
215 time.sleep(0.1)
215 time.sleep(0.1)
216 if p.poll() is not None:
216 if p.poll() is not None:
217 print("Process is interrupted.")
217 print("Process is interrupted.")
218 return
218 return
219 p.terminate()
219 p.terminate()
220 time.sleep(0.1)
220 time.sleep(0.1)
221 if p.poll() is not None:
221 if p.poll() is not None:
222 print("Process is terminated.")
222 print("Process is terminated.")
223 return
223 return
224 p.kill()
224 p.kill()
225 print("Process is killed.")
225 print("Process is killed.")
226 except OSError:
226 except OSError:
227 pass
227 pass
228 except Exception as e:
228 except Exception as e:
229 print("Error while terminating subprocess (pid=%i): %s" \
229 print("Error while terminating subprocess (pid=%i): %s" \
230 % (p.pid, e))
230 % (p.pid, e))
231 return
231 return
232 out = py3compat.bytes_to_str(out)
232 out = py3compat.bytes_to_str(out)
233 err = py3compat.bytes_to_str(err)
233 err = py3compat.bytes_to_str(err)
234 if args.out:
234 if args.out:
235 self.shell.user_ns[args.out] = out
235 self.shell.user_ns[args.out] = out
236 else:
236 else:
237 sys.stdout.write(out)
237 sys.stdout.write(out)
238 sys.stdout.flush()
238 sys.stdout.flush()
239 if args.err:
239 if args.err:
240 self.shell.user_ns[args.err] = err
240 self.shell.user_ns[args.err] = err
241 else:
241 else:
242 sys.stderr.write(err)
242 sys.stderr.write(err)
243 sys.stderr.flush()
243 sys.stderr.flush()
244
244
245 def _run_script(self, p, cell):
245 def _run_script(self, p, cell):
246 """callback for running the script in the background"""
246 """callback for running the script in the background"""
247 p.stdin.write(cell)
247 p.stdin.write(cell)
248 p.stdin.close()
248 p.stdin.close()
249 p.wait()
249 p.wait()
250
250
251 @line_magic("killbgscripts")
251 @line_magic("killbgscripts")
252 def killbgscripts(self, _nouse_=''):
252 def killbgscripts(self, _nouse_=''):
253 """Kill all BG processes started by %%script and its family."""
253 """Kill all BG processes started by %%script and its family."""
254 self.kill_bg_processes()
254 self.kill_bg_processes()
255 print("All background processes were killed.")
255 print("All background processes were killed.")
256
256
257 def kill_bg_processes(self):
257 def kill_bg_processes(self):
258 """Kill all BG processes which are still running."""
258 """Kill all BG processes which are still running."""
259 for p in self.bg_processes:
259 for p in self.bg_processes:
260 if p.poll() is None:
260 if p.poll() is None:
261 try:
261 try:
262 p.send_signal(signal.SIGINT)
262 p.send_signal(signal.SIGINT)
263 except:
263 except:
264 pass
264 pass
265 time.sleep(0.1)
265 time.sleep(0.1)
266 for p in self.bg_processes:
266 for p in self.bg_processes:
267 if p.poll() is None:
267 if p.poll() is None:
268 try:
268 try:
269 p.terminate()
269 p.terminate()
270 except:
270 except:
271 pass
271 pass
272 time.sleep(0.1)
272 time.sleep(0.1)
273 for p in self.bg_processes:
273 for p in self.bg_processes:
274 if p.poll() is None:
274 if p.poll() is None:
275 try:
275 try:
276 p.kill()
276 p.kill()
277 except:
277 except:
278 pass
278 pass
279 self._gc_bg_processes()
279 self._gc_bg_processes()
280
280
281 def _gc_bg_processes(self):
281 def _gc_bg_processes(self):
282 self.bg_processes = [p for p in self.bg_processes if p.poll() is None]
282 self.bg_processes = [p for p in self.bg_processes if p.poll() is None]
@@ -1,55 +1,55 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Payload system for IPython.
2 """Payload system for IPython.
3
3
4 Authors:
4 Authors:
5
5
6 * Fernando Perez
6 * Fernando Perez
7 * Brian Granger
7 * Brian Granger
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2011 The IPython Development Team
11 # Copyright (C) 2008-2011 The IPython Development Team
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 from IPython.config.configurable import Configurable
21 from traitlets.config.configurable import Configurable
22 from IPython.utils.traitlets import List
22 from traitlets import List
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Main payload class
25 # Main payload class
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class PayloadManager(Configurable):
28 class PayloadManager(Configurable):
29
29
30 _payload = List([])
30 _payload = List([])
31
31
32 def write_payload(self, data, single=True):
32 def write_payload(self, data, single=True):
33 """Include or update the specified `data` payload in the PayloadManager.
33 """Include or update the specified `data` payload in the PayloadManager.
34
34
35 If a previous payload with the same source exists and `single` is True,
35 If a previous payload with the same source exists and `single` is True,
36 it will be overwritten with the new one.
36 it will be overwritten with the new one.
37 """
37 """
38
38
39 if not isinstance(data, dict):
39 if not isinstance(data, dict):
40 raise TypeError('Each payload write must be a dict, got: %r' % data)
40 raise TypeError('Each payload write must be a dict, got: %r' % data)
41
41
42 if single and 'source' in data:
42 if single and 'source' in data:
43 source = data['source']
43 source = data['source']
44 for i, pl in enumerate(self._payload):
44 for i, pl in enumerate(self._payload):
45 if 'source' in pl and pl['source'] == source:
45 if 'source' in pl and pl['source'] == source:
46 self._payload[i] = data
46 self._payload[i] = data
47 return
47 return
48
48
49 self._payload.append(data)
49 self._payload.append(data)
50
50
51 def read_payload(self):
51 def read_payload(self):
52 return self._payload
52 return self._payload
53
53
54 def clear_payload(self):
54 def clear_payload(self):
55 self._payload = []
55 self._payload = []
@@ -1,715 +1,715 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Prefiltering components.
3 Prefiltering components.
4
4
5 Prefilters transform user input before it is exec'd by Python. These
5 Prefilters transform user input before it is exec'd by Python. These
6 transforms are used to implement additional syntax such as !ls and %magic.
6 transforms are used to implement additional syntax such as !ls and %magic.
7
7
8 Authors:
8 Authors:
9
9
10 * Brian Granger
10 * Brian Granger
11 * Fernando Perez
11 * Fernando Perez
12 * Dan Milstein
12 * Dan Milstein
13 * Ville Vainio
13 * Ville Vainio
14 """
14 """
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Copyright (C) 2008-2011 The IPython Development Team
17 # Copyright (C) 2008-2011 The IPython Development Team
18 #
18 #
19 # Distributed under the terms of the BSD License. The full license is in
19 # Distributed under the terms of the BSD License. The full license is in
20 # the file COPYING, distributed as part of this software.
20 # the file COPYING, distributed as part of this software.
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Imports
24 # Imports
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 from keyword import iskeyword
27 from keyword import iskeyword
28 import re
28 import re
29
29
30 from IPython.core.autocall import IPyAutocall
30 from IPython.core.autocall import IPyAutocall
31 from IPython.config.configurable import Configurable
31 from traitlets.config.configurable import Configurable
32 from IPython.core.inputsplitter import (
32 from IPython.core.inputsplitter import (
33 ESC_MAGIC,
33 ESC_MAGIC,
34 ESC_QUOTE,
34 ESC_QUOTE,
35 ESC_QUOTE2,
35 ESC_QUOTE2,
36 ESC_PAREN,
36 ESC_PAREN,
37 )
37 )
38 from IPython.core.macro import Macro
38 from IPython.core.macro import Macro
39 from IPython.core.splitinput import LineInfo
39 from IPython.core.splitinput import LineInfo
40
40
41 from IPython.utils.traitlets import (
41 from traitlets import (
42 List, Integer, Unicode, CBool, Bool, Instance, CRegExp
42 List, Integer, Unicode, CBool, Bool, Instance, CRegExp
43 )
43 )
44
44
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46 # Global utilities, errors and constants
46 # Global utilities, errors and constants
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48
48
49
49
50 class PrefilterError(Exception):
50 class PrefilterError(Exception):
51 pass
51 pass
52
52
53
53
54 # RegExp to identify potential function names
54 # RegExp to identify potential function names
55 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
55 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
56
56
57 # RegExp to exclude strings with this start from autocalling. In
57 # RegExp to exclude strings with this start from autocalling. In
58 # particular, all binary operators should be excluded, so that if foo is
58 # particular, all binary operators should be excluded, so that if foo is
59 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
59 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
60 # characters '!=()' don't need to be checked for, as the checkPythonChars
60 # characters '!=()' don't need to be checked for, as the checkPythonChars
61 # routine explicitely does so, to catch direct calls and rebindings of
61 # routine explicitely does so, to catch direct calls and rebindings of
62 # existing names.
62 # existing names.
63
63
64 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
64 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
65 # it affects the rest of the group in square brackets.
65 # it affects the rest of the group in square brackets.
66 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
66 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
67 r'|^is |^not |^in |^and |^or ')
67 r'|^is |^not |^in |^and |^or ')
68
68
69 # try to catch also methods for stuff in lists/tuples/dicts: off
69 # try to catch also methods for stuff in lists/tuples/dicts: off
70 # (experimental). For this to work, the line_split regexp would need
70 # (experimental). For this to work, the line_split regexp would need
71 # to be modified so it wouldn't break things at '['. That line is
71 # to be modified so it wouldn't break things at '['. That line is
72 # nasty enough that I shouldn't change it until I can test it _well_.
72 # nasty enough that I shouldn't change it until I can test it _well_.
73 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
73 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
74
74
75
75
76 # Handler Check Utilities
76 # Handler Check Utilities
77 def is_shadowed(identifier, ip):
77 def is_shadowed(identifier, ip):
78 """Is the given identifier defined in one of the namespaces which shadow
78 """Is the given identifier defined in one of the namespaces which shadow
79 the alias and magic namespaces? Note that an identifier is different
79 the alias and magic namespaces? Note that an identifier is different
80 than ifun, because it can not contain a '.' character."""
80 than ifun, because it can not contain a '.' character."""
81 # This is much safer than calling ofind, which can change state
81 # This is much safer than calling ofind, which can change state
82 return (identifier in ip.user_ns \
82 return (identifier in ip.user_ns \
83 or identifier in ip.user_global_ns \
83 or identifier in ip.user_global_ns \
84 or identifier in ip.ns_table['builtin']\
84 or identifier in ip.ns_table['builtin']\
85 or iskeyword(identifier))
85 or iskeyword(identifier))
86
86
87
87
88 #-----------------------------------------------------------------------------
88 #-----------------------------------------------------------------------------
89 # Main Prefilter manager
89 # Main Prefilter manager
90 #-----------------------------------------------------------------------------
90 #-----------------------------------------------------------------------------
91
91
92
92
93 class PrefilterManager(Configurable):
93 class PrefilterManager(Configurable):
94 """Main prefilter component.
94 """Main prefilter component.
95
95
96 The IPython prefilter is run on all user input before it is run. The
96 The IPython prefilter is run on all user input before it is run. The
97 prefilter consumes lines of input and produces transformed lines of
97 prefilter consumes lines of input and produces transformed lines of
98 input.
98 input.
99
99
100 The iplementation consists of two phases:
100 The iplementation consists of two phases:
101
101
102 1. Transformers
102 1. Transformers
103 2. Checkers and handlers
103 2. Checkers and handlers
104
104
105 Over time, we plan on deprecating the checkers and handlers and doing
105 Over time, we plan on deprecating the checkers and handlers and doing
106 everything in the transformers.
106 everything in the transformers.
107
107
108 The transformers are instances of :class:`PrefilterTransformer` and have
108 The transformers are instances of :class:`PrefilterTransformer` and have
109 a single method :meth:`transform` that takes a line and returns a
109 a single method :meth:`transform` that takes a line and returns a
110 transformed line. The transformation can be accomplished using any
110 transformed line. The transformation can be accomplished using any
111 tool, but our current ones use regular expressions for speed.
111 tool, but our current ones use regular expressions for speed.
112
112
113 After all the transformers have been run, the line is fed to the checkers,
113 After all the transformers have been run, the line is fed to the checkers,
114 which are instances of :class:`PrefilterChecker`. The line is passed to
114 which are instances of :class:`PrefilterChecker`. The line is passed to
115 the :meth:`check` method, which either returns `None` or a
115 the :meth:`check` method, which either returns `None` or a
116 :class:`PrefilterHandler` instance. If `None` is returned, the other
116 :class:`PrefilterHandler` instance. If `None` is returned, the other
117 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
117 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
118 the line is passed to the :meth:`handle` method of the returned
118 the line is passed to the :meth:`handle` method of the returned
119 handler and no further checkers are tried.
119 handler and no further checkers are tried.
120
120
121 Both transformers and checkers have a `priority` attribute, that determines
121 Both transformers and checkers have a `priority` attribute, that determines
122 the order in which they are called. Smaller priorities are tried first.
122 the order in which they are called. Smaller priorities are tried first.
123
123
124 Both transformers and checkers also have `enabled` attribute, which is
124 Both transformers and checkers also have `enabled` attribute, which is
125 a boolean that determines if the instance is used.
125 a boolean that determines if the instance is used.
126
126
127 Users or developers can change the priority or enabled attribute of
127 Users or developers can change the priority or enabled attribute of
128 transformers or checkers, but they must call the :meth:`sort_checkers`
128 transformers or checkers, but they must call the :meth:`sort_checkers`
129 or :meth:`sort_transformers` method after changing the priority.
129 or :meth:`sort_transformers` method after changing the priority.
130 """
130 """
131
131
132 multi_line_specials = CBool(True, config=True)
132 multi_line_specials = CBool(True, config=True)
133 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
133 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
134
134
135 def __init__(self, shell=None, **kwargs):
135 def __init__(self, shell=None, **kwargs):
136 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
136 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
137 self.shell = shell
137 self.shell = shell
138 self.init_transformers()
138 self.init_transformers()
139 self.init_handlers()
139 self.init_handlers()
140 self.init_checkers()
140 self.init_checkers()
141
141
142 #-------------------------------------------------------------------------
142 #-------------------------------------------------------------------------
143 # API for managing transformers
143 # API for managing transformers
144 #-------------------------------------------------------------------------
144 #-------------------------------------------------------------------------
145
145
146 def init_transformers(self):
146 def init_transformers(self):
147 """Create the default transformers."""
147 """Create the default transformers."""
148 self._transformers = []
148 self._transformers = []
149 for transformer_cls in _default_transformers:
149 for transformer_cls in _default_transformers:
150 transformer_cls(
150 transformer_cls(
151 shell=self.shell, prefilter_manager=self, parent=self
151 shell=self.shell, prefilter_manager=self, parent=self
152 )
152 )
153
153
154 def sort_transformers(self):
154 def sort_transformers(self):
155 """Sort the transformers by priority.
155 """Sort the transformers by priority.
156
156
157 This must be called after the priority of a transformer is changed.
157 This must be called after the priority of a transformer is changed.
158 The :meth:`register_transformer` method calls this automatically.
158 The :meth:`register_transformer` method calls this automatically.
159 """
159 """
160 self._transformers.sort(key=lambda x: x.priority)
160 self._transformers.sort(key=lambda x: x.priority)
161
161
162 @property
162 @property
163 def transformers(self):
163 def transformers(self):
164 """Return a list of checkers, sorted by priority."""
164 """Return a list of checkers, sorted by priority."""
165 return self._transformers
165 return self._transformers
166
166
167 def register_transformer(self, transformer):
167 def register_transformer(self, transformer):
168 """Register a transformer instance."""
168 """Register a transformer instance."""
169 if transformer not in self._transformers:
169 if transformer not in self._transformers:
170 self._transformers.append(transformer)
170 self._transformers.append(transformer)
171 self.sort_transformers()
171 self.sort_transformers()
172
172
173 def unregister_transformer(self, transformer):
173 def unregister_transformer(self, transformer):
174 """Unregister a transformer instance."""
174 """Unregister a transformer instance."""
175 if transformer in self._transformers:
175 if transformer in self._transformers:
176 self._transformers.remove(transformer)
176 self._transformers.remove(transformer)
177
177
178 #-------------------------------------------------------------------------
178 #-------------------------------------------------------------------------
179 # API for managing checkers
179 # API for managing checkers
180 #-------------------------------------------------------------------------
180 #-------------------------------------------------------------------------
181
181
182 def init_checkers(self):
182 def init_checkers(self):
183 """Create the default checkers."""
183 """Create the default checkers."""
184 self._checkers = []
184 self._checkers = []
185 for checker in _default_checkers:
185 for checker in _default_checkers:
186 checker(
186 checker(
187 shell=self.shell, prefilter_manager=self, parent=self
187 shell=self.shell, prefilter_manager=self, parent=self
188 )
188 )
189
189
190 def sort_checkers(self):
190 def sort_checkers(self):
191 """Sort the checkers by priority.
191 """Sort the checkers by priority.
192
192
193 This must be called after the priority of a checker is changed.
193 This must be called after the priority of a checker is changed.
194 The :meth:`register_checker` method calls this automatically.
194 The :meth:`register_checker` method calls this automatically.
195 """
195 """
196 self._checkers.sort(key=lambda x: x.priority)
196 self._checkers.sort(key=lambda x: x.priority)
197
197
198 @property
198 @property
199 def checkers(self):
199 def checkers(self):
200 """Return a list of checkers, sorted by priority."""
200 """Return a list of checkers, sorted by priority."""
201 return self._checkers
201 return self._checkers
202
202
203 def register_checker(self, checker):
203 def register_checker(self, checker):
204 """Register a checker instance."""
204 """Register a checker instance."""
205 if checker not in self._checkers:
205 if checker not in self._checkers:
206 self._checkers.append(checker)
206 self._checkers.append(checker)
207 self.sort_checkers()
207 self.sort_checkers()
208
208
209 def unregister_checker(self, checker):
209 def unregister_checker(self, checker):
210 """Unregister a checker instance."""
210 """Unregister a checker instance."""
211 if checker in self._checkers:
211 if checker in self._checkers:
212 self._checkers.remove(checker)
212 self._checkers.remove(checker)
213
213
214 #-------------------------------------------------------------------------
214 #-------------------------------------------------------------------------
215 # API for managing handlers
215 # API for managing handlers
216 #-------------------------------------------------------------------------
216 #-------------------------------------------------------------------------
217
217
218 def init_handlers(self):
218 def init_handlers(self):
219 """Create the default handlers."""
219 """Create the default handlers."""
220 self._handlers = {}
220 self._handlers = {}
221 self._esc_handlers = {}
221 self._esc_handlers = {}
222 for handler in _default_handlers:
222 for handler in _default_handlers:
223 handler(
223 handler(
224 shell=self.shell, prefilter_manager=self, parent=self
224 shell=self.shell, prefilter_manager=self, parent=self
225 )
225 )
226
226
227 @property
227 @property
228 def handlers(self):
228 def handlers(self):
229 """Return a dict of all the handlers."""
229 """Return a dict of all the handlers."""
230 return self._handlers
230 return self._handlers
231
231
232 def register_handler(self, name, handler, esc_strings):
232 def register_handler(self, name, handler, esc_strings):
233 """Register a handler instance by name with esc_strings."""
233 """Register a handler instance by name with esc_strings."""
234 self._handlers[name] = handler
234 self._handlers[name] = handler
235 for esc_str in esc_strings:
235 for esc_str in esc_strings:
236 self._esc_handlers[esc_str] = handler
236 self._esc_handlers[esc_str] = handler
237
237
238 def unregister_handler(self, name, handler, esc_strings):
238 def unregister_handler(self, name, handler, esc_strings):
239 """Unregister a handler instance by name with esc_strings."""
239 """Unregister a handler instance by name with esc_strings."""
240 try:
240 try:
241 del self._handlers[name]
241 del self._handlers[name]
242 except KeyError:
242 except KeyError:
243 pass
243 pass
244 for esc_str in esc_strings:
244 for esc_str in esc_strings:
245 h = self._esc_handlers.get(esc_str)
245 h = self._esc_handlers.get(esc_str)
246 if h is handler:
246 if h is handler:
247 del self._esc_handlers[esc_str]
247 del self._esc_handlers[esc_str]
248
248
249 def get_handler_by_name(self, name):
249 def get_handler_by_name(self, name):
250 """Get a handler by its name."""
250 """Get a handler by its name."""
251 return self._handlers.get(name)
251 return self._handlers.get(name)
252
252
253 def get_handler_by_esc(self, esc_str):
253 def get_handler_by_esc(self, esc_str):
254 """Get a handler by its escape string."""
254 """Get a handler by its escape string."""
255 return self._esc_handlers.get(esc_str)
255 return self._esc_handlers.get(esc_str)
256
256
257 #-------------------------------------------------------------------------
257 #-------------------------------------------------------------------------
258 # Main prefiltering API
258 # Main prefiltering API
259 #-------------------------------------------------------------------------
259 #-------------------------------------------------------------------------
260
260
261 def prefilter_line_info(self, line_info):
261 def prefilter_line_info(self, line_info):
262 """Prefilter a line that has been converted to a LineInfo object.
262 """Prefilter a line that has been converted to a LineInfo object.
263
263
264 This implements the checker/handler part of the prefilter pipe.
264 This implements the checker/handler part of the prefilter pipe.
265 """
265 """
266 # print "prefilter_line_info: ", line_info
266 # print "prefilter_line_info: ", line_info
267 handler = self.find_handler(line_info)
267 handler = self.find_handler(line_info)
268 return handler.handle(line_info)
268 return handler.handle(line_info)
269
269
270 def find_handler(self, line_info):
270 def find_handler(self, line_info):
271 """Find a handler for the line_info by trying checkers."""
271 """Find a handler for the line_info by trying checkers."""
272 for checker in self.checkers:
272 for checker in self.checkers:
273 if checker.enabled:
273 if checker.enabled:
274 handler = checker.check(line_info)
274 handler = checker.check(line_info)
275 if handler:
275 if handler:
276 return handler
276 return handler
277 return self.get_handler_by_name('normal')
277 return self.get_handler_by_name('normal')
278
278
279 def transform_line(self, line, continue_prompt):
279 def transform_line(self, line, continue_prompt):
280 """Calls the enabled transformers in order of increasing priority."""
280 """Calls the enabled transformers in order of increasing priority."""
281 for transformer in self.transformers:
281 for transformer in self.transformers:
282 if transformer.enabled:
282 if transformer.enabled:
283 line = transformer.transform(line, continue_prompt)
283 line = transformer.transform(line, continue_prompt)
284 return line
284 return line
285
285
286 def prefilter_line(self, line, continue_prompt=False):
286 def prefilter_line(self, line, continue_prompt=False):
287 """Prefilter a single input line as text.
287 """Prefilter a single input line as text.
288
288
289 This method prefilters a single line of text by calling the
289 This method prefilters a single line of text by calling the
290 transformers and then the checkers/handlers.
290 transformers and then the checkers/handlers.
291 """
291 """
292
292
293 # print "prefilter_line: ", line, continue_prompt
293 # print "prefilter_line: ", line, continue_prompt
294 # All handlers *must* return a value, even if it's blank ('').
294 # All handlers *must* return a value, even if it's blank ('').
295
295
296 # save the line away in case we crash, so the post-mortem handler can
296 # save the line away in case we crash, so the post-mortem handler can
297 # record it
297 # record it
298 self.shell._last_input_line = line
298 self.shell._last_input_line = line
299
299
300 if not line:
300 if not line:
301 # Return immediately on purely empty lines, so that if the user
301 # Return immediately on purely empty lines, so that if the user
302 # previously typed some whitespace that started a continuation
302 # previously typed some whitespace that started a continuation
303 # prompt, he can break out of that loop with just an empty line.
303 # prompt, he can break out of that loop with just an empty line.
304 # This is how the default python prompt works.
304 # This is how the default python prompt works.
305 return ''
305 return ''
306
306
307 # At this point, we invoke our transformers.
307 # At this point, we invoke our transformers.
308 if not continue_prompt or (continue_prompt and self.multi_line_specials):
308 if not continue_prompt or (continue_prompt and self.multi_line_specials):
309 line = self.transform_line(line, continue_prompt)
309 line = self.transform_line(line, continue_prompt)
310
310
311 # Now we compute line_info for the checkers and handlers
311 # Now we compute line_info for the checkers and handlers
312 line_info = LineInfo(line, continue_prompt)
312 line_info = LineInfo(line, continue_prompt)
313
313
314 # the input history needs to track even empty lines
314 # the input history needs to track even empty lines
315 stripped = line.strip()
315 stripped = line.strip()
316
316
317 normal_handler = self.get_handler_by_name('normal')
317 normal_handler = self.get_handler_by_name('normal')
318 if not stripped:
318 if not stripped:
319 return normal_handler.handle(line_info)
319 return normal_handler.handle(line_info)
320
320
321 # special handlers are only allowed for single line statements
321 # special handlers are only allowed for single line statements
322 if continue_prompt and not self.multi_line_specials:
322 if continue_prompt and not self.multi_line_specials:
323 return normal_handler.handle(line_info)
323 return normal_handler.handle(line_info)
324
324
325 prefiltered = self.prefilter_line_info(line_info)
325 prefiltered = self.prefilter_line_info(line_info)
326 # print "prefiltered line: %r" % prefiltered
326 # print "prefiltered line: %r" % prefiltered
327 return prefiltered
327 return prefiltered
328
328
329 def prefilter_lines(self, lines, continue_prompt=False):
329 def prefilter_lines(self, lines, continue_prompt=False):
330 """Prefilter multiple input lines of text.
330 """Prefilter multiple input lines of text.
331
331
332 This is the main entry point for prefiltering multiple lines of
332 This is the main entry point for prefiltering multiple lines of
333 input. This simply calls :meth:`prefilter_line` for each line of
333 input. This simply calls :meth:`prefilter_line` for each line of
334 input.
334 input.
335
335
336 This covers cases where there are multiple lines in the user entry,
336 This covers cases where there are multiple lines in the user entry,
337 which is the case when the user goes back to a multiline history
337 which is the case when the user goes back to a multiline history
338 entry and presses enter.
338 entry and presses enter.
339 """
339 """
340 llines = lines.rstrip('\n').split('\n')
340 llines = lines.rstrip('\n').split('\n')
341 # We can get multiple lines in one shot, where multiline input 'blends'
341 # We can get multiple lines in one shot, where multiline input 'blends'
342 # into one line, in cases like recalling from the readline history
342 # into one line, in cases like recalling from the readline history
343 # buffer. We need to make sure that in such cases, we correctly
343 # buffer. We need to make sure that in such cases, we correctly
344 # communicate downstream which line is first and which are continuation
344 # communicate downstream which line is first and which are continuation
345 # ones.
345 # ones.
346 if len(llines) > 1:
346 if len(llines) > 1:
347 out = '\n'.join([self.prefilter_line(line, lnum>0)
347 out = '\n'.join([self.prefilter_line(line, lnum>0)
348 for lnum, line in enumerate(llines) ])
348 for lnum, line in enumerate(llines) ])
349 else:
349 else:
350 out = self.prefilter_line(llines[0], continue_prompt)
350 out = self.prefilter_line(llines[0], continue_prompt)
351
351
352 return out
352 return out
353
353
354 #-----------------------------------------------------------------------------
354 #-----------------------------------------------------------------------------
355 # Prefilter transformers
355 # Prefilter transformers
356 #-----------------------------------------------------------------------------
356 #-----------------------------------------------------------------------------
357
357
358
358
359 class PrefilterTransformer(Configurable):
359 class PrefilterTransformer(Configurable):
360 """Transform a line of user input."""
360 """Transform a line of user input."""
361
361
362 priority = Integer(100, config=True)
362 priority = Integer(100, config=True)
363 # Transformers don't currently use shell or prefilter_manager, but as we
363 # Transformers don't currently use shell or prefilter_manager, but as we
364 # move away from checkers and handlers, they will need them.
364 # move away from checkers and handlers, they will need them.
365 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
365 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
366 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
366 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
367 enabled = Bool(True, config=True)
367 enabled = Bool(True, config=True)
368
368
369 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
369 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
370 super(PrefilterTransformer, self).__init__(
370 super(PrefilterTransformer, self).__init__(
371 shell=shell, prefilter_manager=prefilter_manager, **kwargs
371 shell=shell, prefilter_manager=prefilter_manager, **kwargs
372 )
372 )
373 self.prefilter_manager.register_transformer(self)
373 self.prefilter_manager.register_transformer(self)
374
374
375 def transform(self, line, continue_prompt):
375 def transform(self, line, continue_prompt):
376 """Transform a line, returning the new one."""
376 """Transform a line, returning the new one."""
377 return None
377 return None
378
378
379 def __repr__(self):
379 def __repr__(self):
380 return "<%s(priority=%r, enabled=%r)>" % (
380 return "<%s(priority=%r, enabled=%r)>" % (
381 self.__class__.__name__, self.priority, self.enabled)
381 self.__class__.__name__, self.priority, self.enabled)
382
382
383
383
384 #-----------------------------------------------------------------------------
384 #-----------------------------------------------------------------------------
385 # Prefilter checkers
385 # Prefilter checkers
386 #-----------------------------------------------------------------------------
386 #-----------------------------------------------------------------------------
387
387
388
388
389 class PrefilterChecker(Configurable):
389 class PrefilterChecker(Configurable):
390 """Inspect an input line and return a handler for that line."""
390 """Inspect an input line and return a handler for that line."""
391
391
392 priority = Integer(100, config=True)
392 priority = Integer(100, config=True)
393 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
393 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
394 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
394 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
395 enabled = Bool(True, config=True)
395 enabled = Bool(True, config=True)
396
396
397 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
397 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
398 super(PrefilterChecker, self).__init__(
398 super(PrefilterChecker, self).__init__(
399 shell=shell, prefilter_manager=prefilter_manager, **kwargs
399 shell=shell, prefilter_manager=prefilter_manager, **kwargs
400 )
400 )
401 self.prefilter_manager.register_checker(self)
401 self.prefilter_manager.register_checker(self)
402
402
403 def check(self, line_info):
403 def check(self, line_info):
404 """Inspect line_info and return a handler instance or None."""
404 """Inspect line_info and return a handler instance or None."""
405 return None
405 return None
406
406
407 def __repr__(self):
407 def __repr__(self):
408 return "<%s(priority=%r, enabled=%r)>" % (
408 return "<%s(priority=%r, enabled=%r)>" % (
409 self.__class__.__name__, self.priority, self.enabled)
409 self.__class__.__name__, self.priority, self.enabled)
410
410
411
411
412 class EmacsChecker(PrefilterChecker):
412 class EmacsChecker(PrefilterChecker):
413
413
414 priority = Integer(100, config=True)
414 priority = Integer(100, config=True)
415 enabled = Bool(False, config=True)
415 enabled = Bool(False, config=True)
416
416
417 def check(self, line_info):
417 def check(self, line_info):
418 "Emacs ipython-mode tags certain input lines."
418 "Emacs ipython-mode tags certain input lines."
419 if line_info.line.endswith('# PYTHON-MODE'):
419 if line_info.line.endswith('# PYTHON-MODE'):
420 return self.prefilter_manager.get_handler_by_name('emacs')
420 return self.prefilter_manager.get_handler_by_name('emacs')
421 else:
421 else:
422 return None
422 return None
423
423
424
424
425 class MacroChecker(PrefilterChecker):
425 class MacroChecker(PrefilterChecker):
426
426
427 priority = Integer(250, config=True)
427 priority = Integer(250, config=True)
428
428
429 def check(self, line_info):
429 def check(self, line_info):
430 obj = self.shell.user_ns.get(line_info.ifun)
430 obj = self.shell.user_ns.get(line_info.ifun)
431 if isinstance(obj, Macro):
431 if isinstance(obj, Macro):
432 return self.prefilter_manager.get_handler_by_name('macro')
432 return self.prefilter_manager.get_handler_by_name('macro')
433 else:
433 else:
434 return None
434 return None
435
435
436
436
437 class IPyAutocallChecker(PrefilterChecker):
437 class IPyAutocallChecker(PrefilterChecker):
438
438
439 priority = Integer(300, config=True)
439 priority = Integer(300, config=True)
440
440
441 def check(self, line_info):
441 def check(self, line_info):
442 "Instances of IPyAutocall in user_ns get autocalled immediately"
442 "Instances of IPyAutocall in user_ns get autocalled immediately"
443 obj = self.shell.user_ns.get(line_info.ifun, None)
443 obj = self.shell.user_ns.get(line_info.ifun, None)
444 if isinstance(obj, IPyAutocall):
444 if isinstance(obj, IPyAutocall):
445 obj.set_ip(self.shell)
445 obj.set_ip(self.shell)
446 return self.prefilter_manager.get_handler_by_name('auto')
446 return self.prefilter_manager.get_handler_by_name('auto')
447 else:
447 else:
448 return None
448 return None
449
449
450
450
451 class AssignmentChecker(PrefilterChecker):
451 class AssignmentChecker(PrefilterChecker):
452
452
453 priority = Integer(600, config=True)
453 priority = Integer(600, config=True)
454
454
455 def check(self, line_info):
455 def check(self, line_info):
456 """Check to see if user is assigning to a var for the first time, in
456 """Check to see if user is assigning to a var for the first time, in
457 which case we want to avoid any sort of automagic / autocall games.
457 which case we want to avoid any sort of automagic / autocall games.
458
458
459 This allows users to assign to either alias or magic names true python
459 This allows users to assign to either alias or magic names true python
460 variables (the magic/alias systems always take second seat to true
460 variables (the magic/alias systems always take second seat to true
461 python code). E.g. ls='hi', or ls,that=1,2"""
461 python code). E.g. ls='hi', or ls,that=1,2"""
462 if line_info.the_rest:
462 if line_info.the_rest:
463 if line_info.the_rest[0] in '=,':
463 if line_info.the_rest[0] in '=,':
464 return self.prefilter_manager.get_handler_by_name('normal')
464 return self.prefilter_manager.get_handler_by_name('normal')
465 else:
465 else:
466 return None
466 return None
467
467
468
468
469 class AutoMagicChecker(PrefilterChecker):
469 class AutoMagicChecker(PrefilterChecker):
470
470
471 priority = Integer(700, config=True)
471 priority = Integer(700, config=True)
472
472
473 def check(self, line_info):
473 def check(self, line_info):
474 """If the ifun is magic, and automagic is on, run it. Note: normal,
474 """If the ifun is magic, and automagic is on, run it. Note: normal,
475 non-auto magic would already have been triggered via '%' in
475 non-auto magic would already have been triggered via '%' in
476 check_esc_chars. This just checks for automagic. Also, before
476 check_esc_chars. This just checks for automagic. Also, before
477 triggering the magic handler, make sure that there is nothing in the
477 triggering the magic handler, make sure that there is nothing in the
478 user namespace which could shadow it."""
478 user namespace which could shadow it."""
479 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
479 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
480 return None
480 return None
481
481
482 # We have a likely magic method. Make sure we should actually call it.
482 # We have a likely magic method. Make sure we should actually call it.
483 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
483 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
484 return None
484 return None
485
485
486 head = line_info.ifun.split('.',1)[0]
486 head = line_info.ifun.split('.',1)[0]
487 if is_shadowed(head, self.shell):
487 if is_shadowed(head, self.shell):
488 return None
488 return None
489
489
490 return self.prefilter_manager.get_handler_by_name('magic')
490 return self.prefilter_manager.get_handler_by_name('magic')
491
491
492
492
493 class PythonOpsChecker(PrefilterChecker):
493 class PythonOpsChecker(PrefilterChecker):
494
494
495 priority = Integer(900, config=True)
495 priority = Integer(900, config=True)
496
496
497 def check(self, line_info):
497 def check(self, line_info):
498 """If the 'rest' of the line begins with a function call or pretty much
498 """If the 'rest' of the line begins with a function call or pretty much
499 any python operator, we should simply execute the line (regardless of
499 any python operator, we should simply execute the line (regardless of
500 whether or not there's a possible autocall expansion). This avoids
500 whether or not there's a possible autocall expansion). This avoids
501 spurious (and very confusing) geattr() accesses."""
501 spurious (and very confusing) geattr() accesses."""
502 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
502 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
503 return self.prefilter_manager.get_handler_by_name('normal')
503 return self.prefilter_manager.get_handler_by_name('normal')
504 else:
504 else:
505 return None
505 return None
506
506
507
507
508 class AutocallChecker(PrefilterChecker):
508 class AutocallChecker(PrefilterChecker):
509
509
510 priority = Integer(1000, config=True)
510 priority = Integer(1000, config=True)
511
511
512 function_name_regexp = CRegExp(re_fun_name, config=True,
512 function_name_regexp = CRegExp(re_fun_name, config=True,
513 help="RegExp to identify potential function names.")
513 help="RegExp to identify potential function names.")
514 exclude_regexp = CRegExp(re_exclude_auto, config=True,
514 exclude_regexp = CRegExp(re_exclude_auto, config=True,
515 help="RegExp to exclude strings with this start from autocalling.")
515 help="RegExp to exclude strings with this start from autocalling.")
516
516
517 def check(self, line_info):
517 def check(self, line_info):
518 "Check if the initial word/function is callable and autocall is on."
518 "Check if the initial word/function is callable and autocall is on."
519 if not self.shell.autocall:
519 if not self.shell.autocall:
520 return None
520 return None
521
521
522 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
522 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
523 if not oinfo['found']:
523 if not oinfo['found']:
524 return None
524 return None
525
525
526 if callable(oinfo['obj']) \
526 if callable(oinfo['obj']) \
527 and (not self.exclude_regexp.match(line_info.the_rest)) \
527 and (not self.exclude_regexp.match(line_info.the_rest)) \
528 and self.function_name_regexp.match(line_info.ifun):
528 and self.function_name_regexp.match(line_info.ifun):
529 return self.prefilter_manager.get_handler_by_name('auto')
529 return self.prefilter_manager.get_handler_by_name('auto')
530 else:
530 else:
531 return None
531 return None
532
532
533
533
534 #-----------------------------------------------------------------------------
534 #-----------------------------------------------------------------------------
535 # Prefilter handlers
535 # Prefilter handlers
536 #-----------------------------------------------------------------------------
536 #-----------------------------------------------------------------------------
537
537
538
538
539 class PrefilterHandler(Configurable):
539 class PrefilterHandler(Configurable):
540
540
541 handler_name = Unicode('normal')
541 handler_name = Unicode('normal')
542 esc_strings = List([])
542 esc_strings = List([])
543 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
543 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
544 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
544 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
545
545
546 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
546 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
547 super(PrefilterHandler, self).__init__(
547 super(PrefilterHandler, self).__init__(
548 shell=shell, prefilter_manager=prefilter_manager, **kwargs
548 shell=shell, prefilter_manager=prefilter_manager, **kwargs
549 )
549 )
550 self.prefilter_manager.register_handler(
550 self.prefilter_manager.register_handler(
551 self.handler_name,
551 self.handler_name,
552 self,
552 self,
553 self.esc_strings
553 self.esc_strings
554 )
554 )
555
555
556 def handle(self, line_info):
556 def handle(self, line_info):
557 # print "normal: ", line_info
557 # print "normal: ", line_info
558 """Handle normal input lines. Use as a template for handlers."""
558 """Handle normal input lines. Use as a template for handlers."""
559
559
560 # With autoindent on, we need some way to exit the input loop, and I
560 # With autoindent on, we need some way to exit the input loop, and I
561 # don't want to force the user to have to backspace all the way to
561 # don't want to force the user to have to backspace all the way to
562 # clear the line. The rule will be in this case, that either two
562 # clear the line. The rule will be in this case, that either two
563 # lines of pure whitespace in a row, or a line of pure whitespace but
563 # lines of pure whitespace in a row, or a line of pure whitespace but
564 # of a size different to the indent level, will exit the input loop.
564 # of a size different to the indent level, will exit the input loop.
565 line = line_info.line
565 line = line_info.line
566 continue_prompt = line_info.continue_prompt
566 continue_prompt = line_info.continue_prompt
567
567
568 if (continue_prompt and
568 if (continue_prompt and
569 self.shell.autoindent and
569 self.shell.autoindent and
570 line.isspace() and
570 line.isspace() and
571 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
571 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
572 line = ''
572 line = ''
573
573
574 return line
574 return line
575
575
576 def __str__(self):
576 def __str__(self):
577 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
577 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
578
578
579
579
580 class MacroHandler(PrefilterHandler):
580 class MacroHandler(PrefilterHandler):
581 handler_name = Unicode("macro")
581 handler_name = Unicode("macro")
582
582
583 def handle(self, line_info):
583 def handle(self, line_info):
584 obj = self.shell.user_ns.get(line_info.ifun)
584 obj = self.shell.user_ns.get(line_info.ifun)
585 pre_space = line_info.pre_whitespace
585 pre_space = line_info.pre_whitespace
586 line_sep = "\n" + pre_space
586 line_sep = "\n" + pre_space
587 return pre_space + line_sep.join(obj.value.splitlines())
587 return pre_space + line_sep.join(obj.value.splitlines())
588
588
589
589
590 class MagicHandler(PrefilterHandler):
590 class MagicHandler(PrefilterHandler):
591
591
592 handler_name = Unicode('magic')
592 handler_name = Unicode('magic')
593 esc_strings = List([ESC_MAGIC])
593 esc_strings = List([ESC_MAGIC])
594
594
595 def handle(self, line_info):
595 def handle(self, line_info):
596 """Execute magic functions."""
596 """Execute magic functions."""
597 ifun = line_info.ifun
597 ifun = line_info.ifun
598 the_rest = line_info.the_rest
598 the_rest = line_info.the_rest
599 cmd = '%sget_ipython().magic(%r)' % (line_info.pre_whitespace,
599 cmd = '%sget_ipython().magic(%r)' % (line_info.pre_whitespace,
600 (ifun + " " + the_rest))
600 (ifun + " " + the_rest))
601 return cmd
601 return cmd
602
602
603
603
604 class AutoHandler(PrefilterHandler):
604 class AutoHandler(PrefilterHandler):
605
605
606 handler_name = Unicode('auto')
606 handler_name = Unicode('auto')
607 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
607 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
608
608
609 def handle(self, line_info):
609 def handle(self, line_info):
610 """Handle lines which can be auto-executed, quoting if requested."""
610 """Handle lines which can be auto-executed, quoting if requested."""
611 line = line_info.line
611 line = line_info.line
612 ifun = line_info.ifun
612 ifun = line_info.ifun
613 the_rest = line_info.the_rest
613 the_rest = line_info.the_rest
614 pre = line_info.pre
614 pre = line_info.pre
615 esc = line_info.esc
615 esc = line_info.esc
616 continue_prompt = line_info.continue_prompt
616 continue_prompt = line_info.continue_prompt
617 obj = line_info.ofind(self.shell)['obj']
617 obj = line_info.ofind(self.shell)['obj']
618 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
618 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
619
619
620 # This should only be active for single-line input!
620 # This should only be active for single-line input!
621 if continue_prompt:
621 if continue_prompt:
622 return line
622 return line
623
623
624 force_auto = isinstance(obj, IPyAutocall)
624 force_auto = isinstance(obj, IPyAutocall)
625
625
626 # User objects sometimes raise exceptions on attribute access other
626 # User objects sometimes raise exceptions on attribute access other
627 # than AttributeError (we've seen it in the past), so it's safest to be
627 # than AttributeError (we've seen it in the past), so it's safest to be
628 # ultra-conservative here and catch all.
628 # ultra-conservative here and catch all.
629 try:
629 try:
630 auto_rewrite = obj.rewrite
630 auto_rewrite = obj.rewrite
631 except Exception:
631 except Exception:
632 auto_rewrite = True
632 auto_rewrite = True
633
633
634 if esc == ESC_QUOTE:
634 if esc == ESC_QUOTE:
635 # Auto-quote splitting on whitespace
635 # Auto-quote splitting on whitespace
636 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
636 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
637 elif esc == ESC_QUOTE2:
637 elif esc == ESC_QUOTE2:
638 # Auto-quote whole string
638 # Auto-quote whole string
639 newcmd = '%s("%s")' % (ifun,the_rest)
639 newcmd = '%s("%s")' % (ifun,the_rest)
640 elif esc == ESC_PAREN:
640 elif esc == ESC_PAREN:
641 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
641 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
642 else:
642 else:
643 # Auto-paren.
643 # Auto-paren.
644 if force_auto:
644 if force_auto:
645 # Don't rewrite if it is already a call.
645 # Don't rewrite if it is already a call.
646 do_rewrite = not the_rest.startswith('(')
646 do_rewrite = not the_rest.startswith('(')
647 else:
647 else:
648 if not the_rest:
648 if not the_rest:
649 # We only apply it to argument-less calls if the autocall
649 # We only apply it to argument-less calls if the autocall
650 # parameter is set to 2.
650 # parameter is set to 2.
651 do_rewrite = (self.shell.autocall >= 2)
651 do_rewrite = (self.shell.autocall >= 2)
652 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
652 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
653 # Don't autocall in this case: item access for an object
653 # Don't autocall in this case: item access for an object
654 # which is BOTH callable and implements __getitem__.
654 # which is BOTH callable and implements __getitem__.
655 do_rewrite = False
655 do_rewrite = False
656 else:
656 else:
657 do_rewrite = True
657 do_rewrite = True
658
658
659 # Figure out the rewritten command
659 # Figure out the rewritten command
660 if do_rewrite:
660 if do_rewrite:
661 if the_rest.endswith(';'):
661 if the_rest.endswith(';'):
662 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
662 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
663 else:
663 else:
664 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
664 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
665 else:
665 else:
666 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
666 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
667 return normal_handler.handle(line_info)
667 return normal_handler.handle(line_info)
668
668
669 # Display the rewritten call
669 # Display the rewritten call
670 if auto_rewrite:
670 if auto_rewrite:
671 self.shell.auto_rewrite_input(newcmd)
671 self.shell.auto_rewrite_input(newcmd)
672
672
673 return newcmd
673 return newcmd
674
674
675
675
676 class EmacsHandler(PrefilterHandler):
676 class EmacsHandler(PrefilterHandler):
677
677
678 handler_name = Unicode('emacs')
678 handler_name = Unicode('emacs')
679 esc_strings = List([])
679 esc_strings = List([])
680
680
681 def handle(self, line_info):
681 def handle(self, line_info):
682 """Handle input lines marked by python-mode."""
682 """Handle input lines marked by python-mode."""
683
683
684 # Currently, nothing is done. Later more functionality can be added
684 # Currently, nothing is done. Later more functionality can be added
685 # here if needed.
685 # here if needed.
686
686
687 # The input cache shouldn't be updated
687 # The input cache shouldn't be updated
688 return line_info.line
688 return line_info.line
689
689
690
690
691 #-----------------------------------------------------------------------------
691 #-----------------------------------------------------------------------------
692 # Defaults
692 # Defaults
693 #-----------------------------------------------------------------------------
693 #-----------------------------------------------------------------------------
694
694
695
695
696 _default_transformers = [
696 _default_transformers = [
697 ]
697 ]
698
698
699 _default_checkers = [
699 _default_checkers = [
700 EmacsChecker,
700 EmacsChecker,
701 MacroChecker,
701 MacroChecker,
702 IPyAutocallChecker,
702 IPyAutocallChecker,
703 AssignmentChecker,
703 AssignmentChecker,
704 AutoMagicChecker,
704 AutoMagicChecker,
705 PythonOpsChecker,
705 PythonOpsChecker,
706 AutocallChecker
706 AutocallChecker
707 ]
707 ]
708
708
709 _default_handlers = [
709 _default_handlers = [
710 PrefilterHandler,
710 PrefilterHandler,
711 MacroHandler,
711 MacroHandler,
712 MagicHandler,
712 MagicHandler,
713 AutoHandler,
713 AutoHandler,
714 EmacsHandler
714 EmacsHandler
715 ]
715 ]
@@ -1,317 +1,311 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for managing IPython profiles.
3 An application for managing IPython profiles.
4
4
5 To be invoked as the `ipython profile` subcommand.
5 To be invoked as the `ipython profile` subcommand.
6
6
7 Authors:
7 Authors:
8
8
9 * Min RK
9 * Min RK
10
10
11 """
11 """
12 from __future__ import print_function
12 from __future__ import print_function
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Copyright (C) 2008 The IPython Development Team
15 # Copyright (C) 2008 The IPython Development Team
16 #
16 #
17 # Distributed under the terms of the BSD License. The full license is in
17 # Distributed under the terms of the BSD License. The full license is in
18 # the file COPYING, distributed as part of this software.
18 # the file COPYING, distributed as part of this software.
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Imports
22 # Imports
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 import os
25 import os
26
26
27 from IPython.config.application import Application
27 from traitlets.config.application import Application
28 from IPython.core.application import (
28 from IPython.core.application import (
29 BaseIPythonApplication, base_flags
29 BaseIPythonApplication, base_flags
30 )
30 )
31 from IPython.core.profiledir import ProfileDir
31 from IPython.core.profiledir import ProfileDir
32 from IPython.utils.importstring import import_item
32 from IPython.utils.importstring import import_item
33 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
33 from IPython.paths import get_ipython_dir, get_ipython_package_dir
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35 from IPython.utils.traitlets import Unicode, Bool, Dict
35 from traitlets import Unicode, Bool, Dict
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Constants
38 # Constants
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40
40
41 create_help = """Create an IPython profile by name
41 create_help = """Create an IPython profile by name
42
42
43 Create an ipython profile directory by its name or
43 Create an ipython profile directory by its name or
44 profile directory path. Profile directories contain
44 profile directory path. Profile directories contain
45 configuration, log and security related files and are named
45 configuration, log and security related files and are named
46 using the convention 'profile_<name>'. By default they are
46 using the convention 'profile_<name>'. By default they are
47 located in your ipython directory. Once created, you will
47 located in your ipython directory. Once created, you will
48 can edit the configuration files in the profile
48 can edit the configuration files in the profile
49 directory to configure IPython. Most users will create a
49 directory to configure IPython. Most users will create a
50 profile directory by name,
50 profile directory by name,
51 `ipython profile create myprofile`, which will put the directory
51 `ipython profile create myprofile`, which will put the directory
52 in `<ipython_dir>/profile_myprofile`.
52 in `<ipython_dir>/profile_myprofile`.
53 """
53 """
54 list_help = """List available IPython profiles
54 list_help = """List available IPython profiles
55
55
56 List all available profiles, by profile location, that can
56 List all available profiles, by profile location, that can
57 be found in the current working directly or in the ipython
57 be found in the current working directly or in the ipython
58 directory. Profile directories are named using the convention
58 directory. Profile directories are named using the convention
59 'profile_<profile>'.
59 'profile_<profile>'.
60 """
60 """
61 profile_help = """Manage IPython profiles
61 profile_help = """Manage IPython profiles
62
62
63 Profile directories contain
63 Profile directories contain
64 configuration, log and security related files and are named
64 configuration, log and security related files and are named
65 using the convention 'profile_<name>'. By default they are
65 using the convention 'profile_<name>'. By default they are
66 located in your ipython directory. You can create profiles
66 located in your ipython directory. You can create profiles
67 with `ipython profile create <name>`, or see the profiles you
67 with `ipython profile create <name>`, or see the profiles you
68 already have with `ipython profile list`
68 already have with `ipython profile list`
69
69
70 To get started configuring IPython, simply do:
70 To get started configuring IPython, simply do:
71
71
72 $> ipython profile create
72 $> ipython profile create
73
73
74 and IPython will create the default profile in <ipython_dir>/profile_default,
74 and IPython will create the default profile in <ipython_dir>/profile_default,
75 where you can edit ipython_config.py to start configuring IPython.
75 where you can edit ipython_config.py to start configuring IPython.
76
76
77 """
77 """
78
78
79 _list_examples = "ipython profile list # list all profiles"
79 _list_examples = "ipython profile list # list all profiles"
80
80
81 _create_examples = """
81 _create_examples = """
82 ipython profile create foo # create profile foo w/ default config files
82 ipython profile create foo # create profile foo w/ default config files
83 ipython profile create foo --reset # restage default config files over current
83 ipython profile create foo --reset # restage default config files over current
84 ipython profile create foo --parallel # also stage parallel config files
84 ipython profile create foo --parallel # also stage parallel config files
85 """
85 """
86
86
87 _main_examples = """
87 _main_examples = """
88 ipython profile create -h # show the help string for the create subcommand
88 ipython profile create -h # show the help string for the create subcommand
89 ipython profile list -h # show the help string for the list subcommand
89 ipython profile list -h # show the help string for the list subcommand
90
90
91 ipython locate profile foo # print the path to the directory for profile 'foo'
91 ipython locate profile foo # print the path to the directory for profile 'foo'
92 """
92 """
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Profile Application Class (for `ipython profile` subcommand)
95 # Profile Application Class (for `ipython profile` subcommand)
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97
97
98
98
99 def list_profiles_in(path):
99 def list_profiles_in(path):
100 """list profiles in a given root directory"""
100 """list profiles in a given root directory"""
101 files = os.listdir(path)
101 files = os.listdir(path)
102 profiles = []
102 profiles = []
103 for f in files:
103 for f in files:
104 try:
104 try:
105 full_path = os.path.join(path, f)
105 full_path = os.path.join(path, f)
106 except UnicodeError:
106 except UnicodeError:
107 continue
107 continue
108 if os.path.isdir(full_path) and f.startswith('profile_'):
108 if os.path.isdir(full_path) and f.startswith('profile_'):
109 profiles.append(f.split('_',1)[-1])
109 profiles.append(f.split('_',1)[-1])
110 return profiles
110 return profiles
111
111
112
112
113 def list_bundled_profiles():
113 def list_bundled_profiles():
114 """list profiles that are bundled with IPython."""
114 """list profiles that are bundled with IPython."""
115 path = os.path.join(get_ipython_package_dir(), u'core', u'profile')
115 path = os.path.join(get_ipython_package_dir(), u'core', u'profile')
116 files = os.listdir(path)
116 files = os.listdir(path)
117 profiles = []
117 profiles = []
118 for profile in files:
118 for profile in files:
119 full_path = os.path.join(path, profile)
119 full_path = os.path.join(path, profile)
120 if os.path.isdir(full_path) and profile != "__pycache__":
120 if os.path.isdir(full_path) and profile != "__pycache__":
121 profiles.append(profile)
121 profiles.append(profile)
122 return profiles
122 return profiles
123
123
124
124
125 class ProfileLocate(BaseIPythonApplication):
125 class ProfileLocate(BaseIPythonApplication):
126 description = """print the path to an IPython profile dir"""
126 description = """print the path to an IPython profile dir"""
127
127
128 def parse_command_line(self, argv=None):
128 def parse_command_line(self, argv=None):
129 super(ProfileLocate, self).parse_command_line(argv)
129 super(ProfileLocate, self).parse_command_line(argv)
130 if self.extra_args:
130 if self.extra_args:
131 self.profile = self.extra_args[0]
131 self.profile = self.extra_args[0]
132
132
133 def start(self):
133 def start(self):
134 print(self.profile_dir.location)
134 print(self.profile_dir.location)
135
135
136
136
137 class ProfileList(Application):
137 class ProfileList(Application):
138 name = u'ipython-profile'
138 name = u'ipython-profile'
139 description = list_help
139 description = list_help
140 examples = _list_examples
140 examples = _list_examples
141
141
142 aliases = Dict({
142 aliases = Dict({
143 'ipython-dir' : 'ProfileList.ipython_dir',
143 'ipython-dir' : 'ProfileList.ipython_dir',
144 'log-level' : 'Application.log_level',
144 'log-level' : 'Application.log_level',
145 })
145 })
146 flags = Dict(dict(
146 flags = Dict(dict(
147 debug = ({'Application' : {'log_level' : 0}},
147 debug = ({'Application' : {'log_level' : 0}},
148 "Set Application.log_level to 0, maximizing log output."
148 "Set Application.log_level to 0, maximizing log output."
149 )
149 )
150 ))
150 ))
151
151
152 ipython_dir = Unicode(get_ipython_dir(), config=True,
152 ipython_dir = Unicode(get_ipython_dir(), config=True,
153 help="""
153 help="""
154 The name of the IPython directory. This directory is used for logging
154 The name of the IPython directory. This directory is used for logging
155 configuration (through profiles), history storage, etc. The default
155 configuration (through profiles), history storage, etc. The default
156 is usually $HOME/.ipython. This options can also be specified through
156 is usually $HOME/.ipython. This options can also be specified through
157 the environment variable IPYTHONDIR.
157 the environment variable IPYTHONDIR.
158 """
158 """
159 )
159 )
160
160
161
161
162 def _print_profiles(self, profiles):
162 def _print_profiles(self, profiles):
163 """print list of profiles, indented."""
163 """print list of profiles, indented."""
164 for profile in profiles:
164 for profile in profiles:
165 print(' %s' % profile)
165 print(' %s' % profile)
166
166
167 def list_profile_dirs(self):
167 def list_profile_dirs(self):
168 profiles = list_bundled_profiles()
168 profiles = list_bundled_profiles()
169 if profiles:
169 if profiles:
170 print()
170 print()
171 print("Available profiles in IPython:")
171 print("Available profiles in IPython:")
172 self._print_profiles(profiles)
172 self._print_profiles(profiles)
173 print()
173 print()
174 print(" The first request for a bundled profile will copy it")
174 print(" The first request for a bundled profile will copy it")
175 print(" into your IPython directory (%s)," % self.ipython_dir)
175 print(" into your IPython directory (%s)," % self.ipython_dir)
176 print(" where you can customize it.")
176 print(" where you can customize it.")
177
177
178 profiles = list_profiles_in(self.ipython_dir)
178 profiles = list_profiles_in(self.ipython_dir)
179 if profiles:
179 if profiles:
180 print()
180 print()
181 print("Available profiles in %s:" % self.ipython_dir)
181 print("Available profiles in %s:" % self.ipython_dir)
182 self._print_profiles(profiles)
182 self._print_profiles(profiles)
183
183
184 profiles = list_profiles_in(py3compat.getcwd())
184 profiles = list_profiles_in(py3compat.getcwd())
185 if profiles:
185 if profiles:
186 print()
186 print()
187 print("Available profiles in current directory (%s):" % py3compat.getcwd())
187 print("Available profiles in current directory (%s):" % py3compat.getcwd())
188 self._print_profiles(profiles)
188 self._print_profiles(profiles)
189
189
190 print()
190 print()
191 print("To use any of the above profiles, start IPython with:")
191 print("To use any of the above profiles, start IPython with:")
192 print(" ipython --profile=<name>")
192 print(" ipython --profile=<name>")
193 print()
193 print()
194
194
195 def start(self):
195 def start(self):
196 self.list_profile_dirs()
196 self.list_profile_dirs()
197
197
198
198
199 create_flags = {}
199 create_flags = {}
200 create_flags.update(base_flags)
200 create_flags.update(base_flags)
201 # don't include '--init' flag, which implies running profile create in other apps
201 # don't include '--init' flag, which implies running profile create in other apps
202 create_flags.pop('init')
202 create_flags.pop('init')
203 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
203 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
204 "reset config files in this profile to the defaults.")
204 "reset config files in this profile to the defaults.")
205 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
205 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
206 "Include the config files for parallel "
206 "Include the config files for parallel "
207 "computing apps (ipengine, ipcontroller, etc.)")
207 "computing apps (ipengine, ipcontroller, etc.)")
208
208
209
209
210 class ProfileCreate(BaseIPythonApplication):
210 class ProfileCreate(BaseIPythonApplication):
211 name = u'ipython-profile'
211 name = u'ipython-profile'
212 description = create_help
212 description = create_help
213 examples = _create_examples
213 examples = _create_examples
214 auto_create = Bool(True, config=False)
214 auto_create = Bool(True, config=False)
215 def _log_format_default(self):
215 def _log_format_default(self):
216 return "[%(name)s] %(message)s"
216 return "[%(name)s] %(message)s"
217
217
218 def _copy_config_files_default(self):
218 def _copy_config_files_default(self):
219 return True
219 return True
220
220
221 parallel = Bool(False, config=True,
221 parallel = Bool(False, config=True,
222 help="whether to include parallel computing config files")
222 help="whether to include parallel computing config files")
223 def _parallel_changed(self, name, old, new):
223 def _parallel_changed(self, name, old, new):
224 parallel_files = [ 'ipcontroller_config.py',
224 parallel_files = [ 'ipcontroller_config.py',
225 'ipengine_config.py',
225 'ipengine_config.py',
226 'ipcluster_config.py'
226 'ipcluster_config.py'
227 ]
227 ]
228 if new:
228 if new:
229 for cf in parallel_files:
229 for cf in parallel_files:
230 self.config_files.append(cf)
230 self.config_files.append(cf)
231 else:
231 else:
232 for cf in parallel_files:
232 for cf in parallel_files:
233 if cf in self.config_files:
233 if cf in self.config_files:
234 self.config_files.remove(cf)
234 self.config_files.remove(cf)
235
235
236 def parse_command_line(self, argv):
236 def parse_command_line(self, argv):
237 super(ProfileCreate, self).parse_command_line(argv)
237 super(ProfileCreate, self).parse_command_line(argv)
238 # accept positional arg as profile name
238 # accept positional arg as profile name
239 if self.extra_args:
239 if self.extra_args:
240 self.profile = self.extra_args[0]
240 self.profile = self.extra_args[0]
241
241
242 flags = Dict(create_flags)
242 flags = Dict(create_flags)
243
243
244 classes = [ProfileDir]
244 classes = [ProfileDir]
245
245
246 def _import_app(self, app_path):
246 def _import_app(self, app_path):
247 """import an app class"""
247 """import an app class"""
248 app = None
248 app = None
249 name = app_path.rsplit('.', 1)[-1]
249 name = app_path.rsplit('.', 1)[-1]
250 try:
250 try:
251 app = import_item(app_path)
251 app = import_item(app_path)
252 except ImportError:
252 except ImportError:
253 self.log.info("Couldn't import %s, config file will be excluded", name)
253 self.log.info("Couldn't import %s, config file will be excluded", name)
254 except Exception:
254 except Exception:
255 self.log.warn('Unexpected error importing %s', name, exc_info=True)
255 self.log.warn('Unexpected error importing %s', name, exc_info=True)
256 return app
256 return app
257
257
258 def init_config_files(self):
258 def init_config_files(self):
259 super(ProfileCreate, self).init_config_files()
259 super(ProfileCreate, self).init_config_files()
260 # use local imports, since these classes may import from here
260 # use local imports, since these classes may import from here
261 from IPython.terminal.ipapp import TerminalIPythonApp
261 from IPython.terminal.ipapp import TerminalIPythonApp
262 apps = [TerminalIPythonApp]
262 apps = [TerminalIPythonApp]
263 for app_path in (
263 for app_path in (
264 'IPython.kernel.zmq.kernelapp.IPKernelApp',
264 'ipython_kernel.kernelapp.IPKernelApp',
265 'IPython.terminal.console.app.ZMQTerminalIPythonApp',
266 'IPython.qt.console.qtconsoleapp.IPythonQtConsoleApp',
267 'IPython.html.notebookapp.NotebookApp',
268 'IPython.nbconvert.nbconvertapp.NbConvertApp',
269 ):
265 ):
270 app = self._import_app(app_path)
266 app = self._import_app(app_path)
271 if app is not None:
267 if app is not None:
272 apps.append(app)
268 apps.append(app)
273 if self.parallel:
269 if self.parallel:
274 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
270 from ipython_parallel.apps.ipcontrollerapp import IPControllerApp
275 from IPython.parallel.apps.ipengineapp import IPEngineApp
271 from ipython_parallel.apps.ipengineapp import IPEngineApp
276 from IPython.parallel.apps.ipclusterapp import IPClusterStart
272 from ipython_parallel.apps.ipclusterapp import IPClusterStart
277 from IPython.parallel.apps.iploggerapp import IPLoggerApp
278 apps.extend([
273 apps.extend([
279 IPControllerApp,
274 IPControllerApp,
280 IPEngineApp,
275 IPEngineApp,
281 IPClusterStart,
276 IPClusterStart,
282 IPLoggerApp,
283 ])
277 ])
284 for App in apps:
278 for App in apps:
285 app = App()
279 app = App()
286 app.config.update(self.config)
280 app.config.update(self.config)
287 app.log = self.log
281 app.log = self.log
288 app.overwrite = self.overwrite
282 app.overwrite = self.overwrite
289 app.copy_config_files=True
283 app.copy_config_files=True
290 app.ipython_dir=self.ipython_dir
284 app.ipython_dir=self.ipython_dir
291 app.profile_dir=self.profile_dir
285 app.profile_dir=self.profile_dir
292 app.init_config_files()
286 app.init_config_files()
293
287
294 def stage_default_config_file(self):
288 def stage_default_config_file(self):
295 pass
289 pass
296
290
297
291
298 class ProfileApp(Application):
292 class ProfileApp(Application):
299 name = u'ipython profile'
293 name = u'ipython profile'
300 description = profile_help
294 description = profile_help
301 examples = _main_examples
295 examples = _main_examples
302
296
303 subcommands = Dict(dict(
297 subcommands = Dict(dict(
304 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
298 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
305 list = (ProfileList, ProfileList.description.splitlines()[0]),
299 list = (ProfileList, ProfileList.description.splitlines()[0]),
306 locate = (ProfileLocate, ProfileLocate.description.splitlines()[0]),
300 locate = (ProfileLocate, ProfileLocate.description.splitlines()[0]),
307 ))
301 ))
308
302
309 def start(self):
303 def start(self):
310 if self.subapp is None:
304 if self.subapp is None:
311 print("No subcommand specified. Must specify one of: %s"%(self.subcommands.keys()))
305 print("No subcommand specified. Must specify one of: %s"%(self.subcommands.keys()))
312 print()
306 print()
313 self.print_description()
307 self.print_description()
314 self.print_subcommands()
308 self.print_subcommands()
315 self.exit(1)
309 self.exit(1)
316 else:
310 else:
317 return self.subapp.start()
311 return self.subapp.start()
@@ -1,252 +1,235 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """An object for managing IPython profile directories."""
2 """An object for managing IPython profile directories."""
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 import os
7 import os
8 import shutil
8 import shutil
9 import errno
9 import errno
10
10
11 from IPython.config.configurable import LoggingConfigurable
11 from traitlets.config.configurable import LoggingConfigurable
12 from IPython.utils.path import get_ipython_package_dir, expand_path, ensure_dir_exists
12 from IPython.paths import get_ipython_package_dir
13 from IPython.utils.path import expand_path, ensure_dir_exists
13 from IPython.utils import py3compat
14 from IPython.utils import py3compat
14 from IPython.utils.traitlets import Unicode, Bool
15 from traitlets import Unicode, Bool
15
16
16 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
17 # Module errors
18 # Module errors
18 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
19
20
20 class ProfileDirError(Exception):
21 class ProfileDirError(Exception):
21 pass
22 pass
22
23
23
24
24 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
25 # Class for managing profile directories
26 # Class for managing profile directories
26 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
27
28
28 class ProfileDir(LoggingConfigurable):
29 class ProfileDir(LoggingConfigurable):
29 """An object to manage the profile directory and its resources.
30 """An object to manage the profile directory and its resources.
30
31
31 The profile directory is used by all IPython applications, to manage
32 The profile directory is used by all IPython applications, to manage
32 configuration, logging and security.
33 configuration, logging and security.
33
34
34 This object knows how to find, create and manage these directories. This
35 This object knows how to find, create and manage these directories. This
35 should be used by any code that wants to handle profiles.
36 should be used by any code that wants to handle profiles.
36 """
37 """
37
38
38 security_dir_name = Unicode('security')
39 security_dir_name = Unicode('security')
39 log_dir_name = Unicode('log')
40 log_dir_name = Unicode('log')
40 startup_dir_name = Unicode('startup')
41 startup_dir_name = Unicode('startup')
41 pid_dir_name = Unicode('pid')
42 pid_dir_name = Unicode('pid')
42 static_dir_name = Unicode('static')
43 static_dir_name = Unicode('static')
43 security_dir = Unicode(u'')
44 security_dir = Unicode(u'')
44 log_dir = Unicode(u'')
45 log_dir = Unicode(u'')
45 startup_dir = Unicode(u'')
46 startup_dir = Unicode(u'')
46 pid_dir = Unicode(u'')
47 pid_dir = Unicode(u'')
47 static_dir = Unicode(u'')
48 static_dir = Unicode(u'')
48
49
49 location = Unicode(u'', config=True,
50 location = Unicode(u'', config=True,
50 help="""Set the profile location directly. This overrides the logic used by the
51 help="""Set the profile location directly. This overrides the logic used by the
51 `profile` option.""",
52 `profile` option.""",
52 )
53 )
53
54
54 _location_isset = Bool(False) # flag for detecting multiply set location
55 _location_isset = Bool(False) # flag for detecting multiply set location
55
56
56 def _location_changed(self, name, old, new):
57 def _location_changed(self, name, old, new):
57 if self._location_isset:
58 if self._location_isset:
58 raise RuntimeError("Cannot set profile location more than once.")
59 raise RuntimeError("Cannot set profile location more than once.")
59 self._location_isset = True
60 self._location_isset = True
60 ensure_dir_exists(new)
61 ensure_dir_exists(new)
61
62
62 # ensure config files exist:
63 # ensure config files exist:
63 self.security_dir = os.path.join(new, self.security_dir_name)
64 self.security_dir = os.path.join(new, self.security_dir_name)
64 self.log_dir = os.path.join(new, self.log_dir_name)
65 self.log_dir = os.path.join(new, self.log_dir_name)
65 self.startup_dir = os.path.join(new, self.startup_dir_name)
66 self.startup_dir = os.path.join(new, self.startup_dir_name)
66 self.pid_dir = os.path.join(new, self.pid_dir_name)
67 self.pid_dir = os.path.join(new, self.pid_dir_name)
67 self.static_dir = os.path.join(new, self.static_dir_name)
68 self.static_dir = os.path.join(new, self.static_dir_name)
68 self.check_dirs()
69 self.check_dirs()
69
70
70 def _log_dir_changed(self, name, old, new):
71 def _log_dir_changed(self, name, old, new):
71 self.check_log_dir()
72 self.check_log_dir()
72
73
73 def _mkdir(self, path, mode=None):
74 def _mkdir(self, path, mode=None):
74 """ensure a directory exists at a given path
75 """ensure a directory exists at a given path
75
76
76 This is a version of os.mkdir, with the following differences:
77 This is a version of os.mkdir, with the following differences:
77
78
78 - returns True if it created the directory, False otherwise
79 - returns True if it created the directory, False otherwise
79 - ignores EEXIST, protecting against race conditions where
80 - ignores EEXIST, protecting against race conditions where
80 the dir may have been created in between the check and
81 the dir may have been created in between the check and
81 the creation
82 the creation
82 - sets permissions if requested and the dir already exists
83 - sets permissions if requested and the dir already exists
83 """
84 """
84 if os.path.exists(path):
85 if os.path.exists(path):
85 if mode and os.stat(path).st_mode != mode:
86 if mode and os.stat(path).st_mode != mode:
86 try:
87 try:
87 os.chmod(path, mode)
88 os.chmod(path, mode)
88 except OSError:
89 except OSError:
89 self.log.warn(
90 self.log.warn(
90 "Could not set permissions on %s",
91 "Could not set permissions on %s",
91 path
92 path
92 )
93 )
93 return False
94 return False
94 try:
95 try:
95 if mode:
96 if mode:
96 os.mkdir(path, mode)
97 os.mkdir(path, mode)
97 else:
98 else:
98 os.mkdir(path)
99 os.mkdir(path)
99 except OSError as e:
100 except OSError as e:
100 if e.errno == errno.EEXIST:
101 if e.errno == errno.EEXIST:
101 return False
102 return False
102 else:
103 else:
103 raise
104 raise
104
105
105 return True
106 return True
106
107
107 def check_log_dir(self):
108 def check_log_dir(self):
108 self._mkdir(self.log_dir)
109 self._mkdir(self.log_dir)
109
110
110 def _startup_dir_changed(self, name, old, new):
111 def _startup_dir_changed(self, name, old, new):
111 self.check_startup_dir()
112 self.check_startup_dir()
112
113
113 def check_startup_dir(self):
114 def check_startup_dir(self):
114 self._mkdir(self.startup_dir)
115 self._mkdir(self.startup_dir)
115
116
116 readme = os.path.join(self.startup_dir, 'README')
117 readme = os.path.join(self.startup_dir, 'README')
117 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
118 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
118
119
119 if not os.path.exists(src):
120 if not os.path.exists(src):
120 self.log.warn("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
121 self.log.warn("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
121
122
122 if os.path.exists(src) and not os.path.exists(readme):
123 if os.path.exists(src) and not os.path.exists(readme):
123 shutil.copy(src, readme)
124 shutil.copy(src, readme)
124
125
125 def _security_dir_changed(self, name, old, new):
126 def _security_dir_changed(self, name, old, new):
126 self.check_security_dir()
127 self.check_security_dir()
127
128
128 def check_security_dir(self):
129 def check_security_dir(self):
129 self._mkdir(self.security_dir, 0o40700)
130 self._mkdir(self.security_dir, 0o40700)
130
131
131 def _pid_dir_changed(self, name, old, new):
132 def _pid_dir_changed(self, name, old, new):
132 self.check_pid_dir()
133 self.check_pid_dir()
133
134
134 def check_pid_dir(self):
135 def check_pid_dir(self):
135 self._mkdir(self.pid_dir, 0o40700)
136 self._mkdir(self.pid_dir, 0o40700)
136
137
137 def _static_dir_changed(self, name, old, new):
138 def _static_dir_changed(self, name, old, new):
138 self.check_startup_dir()
139 self.check_startup_dir()
139
140
140 def check_static_dir(self):
141 self._mkdir(self.static_dir)
142 custom = os.path.join(self.static_dir, 'custom')
143 self._mkdir(custom)
144 try:
145 from jupyter_notebook import DEFAULT_STATIC_FILES_PATH
146 except ImportError:
147 return
148 for fname in ('custom.js', 'custom.css'):
149 src = os.path.join(DEFAULT_STATIC_FILES_PATH, 'custom', fname)
150 dest = os.path.join(custom, fname)
151 if not os.path.exists(src):
152 self.log.warn("Could not copy default file to static dir. Source file %s does not exist.", src)
153 continue
154 if not os.path.exists(dest):
155 shutil.copy(src, dest)
156
157 def check_dirs(self):
141 def check_dirs(self):
158 self.check_security_dir()
142 self.check_security_dir()
159 self.check_log_dir()
143 self.check_log_dir()
160 self.check_pid_dir()
144 self.check_pid_dir()
161 self.check_startup_dir()
145 self.check_startup_dir()
162 self.check_static_dir()
163
146
164 def copy_config_file(self, config_file, path=None, overwrite=False):
147 def copy_config_file(self, config_file, path=None, overwrite=False):
165 """Copy a default config file into the active profile directory.
148 """Copy a default config file into the active profile directory.
166
149
167 Default configuration files are kept in :mod:`IPython.config.default`.
150 Default configuration files are kept in :mod:`IPython.core.profile`.
168 This function moves these from that location to the working profile
151 This function moves these from that location to the working profile
169 directory.
152 directory.
170 """
153 """
171 dst = os.path.join(self.location, config_file)
154 dst = os.path.join(self.location, config_file)
172 if os.path.isfile(dst) and not overwrite:
155 if os.path.isfile(dst) and not overwrite:
173 return False
156 return False
174 if path is None:
157 if path is None:
175 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
158 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
176 src = os.path.join(path, config_file)
159 src = os.path.join(path, config_file)
177 shutil.copy(src, dst)
160 shutil.copy(src, dst)
178 return True
161 return True
179
162
180 @classmethod
163 @classmethod
181 def create_profile_dir(cls, profile_dir, config=None):
164 def create_profile_dir(cls, profile_dir, config=None):
182 """Create a new profile directory given a full path.
165 """Create a new profile directory given a full path.
183
166
184 Parameters
167 Parameters
185 ----------
168 ----------
186 profile_dir : str
169 profile_dir : str
187 The full path to the profile directory. If it does exist, it will
170 The full path to the profile directory. If it does exist, it will
188 be used. If not, it will be created.
171 be used. If not, it will be created.
189 """
172 """
190 return cls(location=profile_dir, config=config)
173 return cls(location=profile_dir, config=config)
191
174
192 @classmethod
175 @classmethod
193 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
176 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
194 """Create a profile dir by profile name and path.
177 """Create a profile dir by profile name and path.
195
178
196 Parameters
179 Parameters
197 ----------
180 ----------
198 path : unicode
181 path : unicode
199 The path (directory) to put the profile directory in.
182 The path (directory) to put the profile directory in.
200 name : unicode
183 name : unicode
201 The name of the profile. The name of the profile directory will
184 The name of the profile. The name of the profile directory will
202 be "profile_<profile>".
185 be "profile_<profile>".
203 """
186 """
204 if not os.path.isdir(path):
187 if not os.path.isdir(path):
205 raise ProfileDirError('Directory not found: %s' % path)
188 raise ProfileDirError('Directory not found: %s' % path)
206 profile_dir = os.path.join(path, u'profile_' + name)
189 profile_dir = os.path.join(path, u'profile_' + name)
207 return cls(location=profile_dir, config=config)
190 return cls(location=profile_dir, config=config)
208
191
209 @classmethod
192 @classmethod
210 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
193 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
211 """Find an existing profile dir by profile name, return its ProfileDir.
194 """Find an existing profile dir by profile name, return its ProfileDir.
212
195
213 This searches through a sequence of paths for a profile dir. If it
196 This searches through a sequence of paths for a profile dir. If it
214 is not found, a :class:`ProfileDirError` exception will be raised.
197 is not found, a :class:`ProfileDirError` exception will be raised.
215
198
216 The search path algorithm is:
199 The search path algorithm is:
217 1. ``py3compat.getcwd()``
200 1. ``py3compat.getcwd()``
218 2. ``ipython_dir``
201 2. ``ipython_dir``
219
202
220 Parameters
203 Parameters
221 ----------
204 ----------
222 ipython_dir : unicode or str
205 ipython_dir : unicode or str
223 The IPython directory to use.
206 The IPython directory to use.
224 name : unicode or str
207 name : unicode or str
225 The name of the profile. The name of the profile directory
208 The name of the profile. The name of the profile directory
226 will be "profile_<profile>".
209 will be "profile_<profile>".
227 """
210 """
228 dirname = u'profile_' + name
211 dirname = u'profile_' + name
229 paths = [py3compat.getcwd(), ipython_dir]
212 paths = [py3compat.getcwd(), ipython_dir]
230 for p in paths:
213 for p in paths:
231 profile_dir = os.path.join(p, dirname)
214 profile_dir = os.path.join(p, dirname)
232 if os.path.isdir(profile_dir):
215 if os.path.isdir(profile_dir):
233 return cls(location=profile_dir, config=config)
216 return cls(location=profile_dir, config=config)
234 else:
217 else:
235 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
218 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
236
219
237 @classmethod
220 @classmethod
238 def find_profile_dir(cls, profile_dir, config=None):
221 def find_profile_dir(cls, profile_dir, config=None):
239 """Find/create a profile dir and return its ProfileDir.
222 """Find/create a profile dir and return its ProfileDir.
240
223
241 This will create the profile directory if it doesn't exist.
224 This will create the profile directory if it doesn't exist.
242
225
243 Parameters
226 Parameters
244 ----------
227 ----------
245 profile_dir : unicode or str
228 profile_dir : unicode or str
246 The path of the profile directory. This is expanded using
229 The path of the profile directory. This is expanded using
247 :func:`IPython.utils.genutils.expand_path`.
230 :func:`IPython.utils.genutils.expand_path`.
248 """
231 """
249 profile_dir = expand_path(profile_dir)
232 profile_dir = expand_path(profile_dir)
250 if not os.path.isdir(profile_dir):
233 if not os.path.isdir(profile_dir):
251 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
234 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
252 return cls(location=profile_dir, config=config)
235 return cls(location=profile_dir, config=config)
@@ -1,442 +1,442 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Classes for handling input/output prompts.
2 """Classes for handling input/output prompts.
3
3
4 Authors:
4 Authors:
5
5
6 * Fernando Perez
6 * Fernando Perez
7 * Brian Granger
7 * Brian Granger
8 * Thomas Kluyver
8 * Thomas Kluyver
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 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
13 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 import re
24 import re
25 import socket
25 import socket
26 import sys
26 import sys
27 import time
27 import time
28
28
29 from string import Formatter
29 from string import Formatter
30
30
31 from IPython.config.configurable import Configurable
31 from traitlets.config.configurable import Configurable
32 from IPython.core import release
32 from IPython.core import release
33 from IPython.utils import coloransi, py3compat
33 from IPython.utils import coloransi, py3compat
34 from IPython.utils.traitlets import (Unicode, Instance, Dict, Bool, Int)
34 from traitlets import (Unicode, Instance, Dict, Bool, Int)
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # Color schemes for prompts
37 # Color schemes for prompts
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 InputColors = coloransi.InputTermColors # just a shorthand
40 InputColors = coloransi.InputTermColors # just a shorthand
41 Colors = coloransi.TermColors # just a shorthand
41 Colors = coloransi.TermColors # just a shorthand
42
42
43 color_lists = dict(normal=Colors(), inp=InputColors(), nocolor=coloransi.NoColors())
43 color_lists = dict(normal=Colors(), inp=InputColors(), nocolor=coloransi.NoColors())
44
44
45 PColNoColors = coloransi.ColorScheme(
45 PColNoColors = coloransi.ColorScheme(
46 'NoColor',
46 'NoColor',
47 in_prompt = InputColors.NoColor, # Input prompt
47 in_prompt = InputColors.NoColor, # Input prompt
48 in_number = InputColors.NoColor, # Input prompt number
48 in_number = InputColors.NoColor, # Input prompt number
49 in_prompt2 = InputColors.NoColor, # Continuation prompt
49 in_prompt2 = InputColors.NoColor, # Continuation prompt
50 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
50 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
51
51
52 out_prompt = Colors.NoColor, # Output prompt
52 out_prompt = Colors.NoColor, # Output prompt
53 out_number = Colors.NoColor, # Output prompt number
53 out_number = Colors.NoColor, # Output prompt number
54
54
55 normal = Colors.NoColor # color off (usu. Colors.Normal)
55 normal = Colors.NoColor # color off (usu. Colors.Normal)
56 )
56 )
57
57
58 # make some schemes as instances so we can copy them for modification easily:
58 # make some schemes as instances so we can copy them for modification easily:
59 PColLinux = coloransi.ColorScheme(
59 PColLinux = coloransi.ColorScheme(
60 'Linux',
60 'Linux',
61 in_prompt = InputColors.Green,
61 in_prompt = InputColors.Green,
62 in_number = InputColors.LightGreen,
62 in_number = InputColors.LightGreen,
63 in_prompt2 = InputColors.Green,
63 in_prompt2 = InputColors.Green,
64 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
64 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
65
65
66 out_prompt = Colors.Red,
66 out_prompt = Colors.Red,
67 out_number = Colors.LightRed,
67 out_number = Colors.LightRed,
68
68
69 normal = Colors.Normal
69 normal = Colors.Normal
70 )
70 )
71
71
72 # Slightly modified Linux for light backgrounds
72 # Slightly modified Linux for light backgrounds
73 PColLightBG = PColLinux.copy('LightBG')
73 PColLightBG = PColLinux.copy('LightBG')
74
74
75 PColLightBG.colors.update(
75 PColLightBG.colors.update(
76 in_prompt = InputColors.Blue,
76 in_prompt = InputColors.Blue,
77 in_number = InputColors.LightBlue,
77 in_number = InputColors.LightBlue,
78 in_prompt2 = InputColors.Blue
78 in_prompt2 = InputColors.Blue
79 )
79 )
80
80
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82 # Utilities
82 # Utilities
83 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
84
84
85 class LazyEvaluate(object):
85 class LazyEvaluate(object):
86 """This is used for formatting strings with values that need to be updated
86 """This is used for formatting strings with values that need to be updated
87 at that time, such as the current time or working directory."""
87 at that time, such as the current time or working directory."""
88 def __init__(self, func, *args, **kwargs):
88 def __init__(self, func, *args, **kwargs):
89 self.func = func
89 self.func = func
90 self.args = args
90 self.args = args
91 self.kwargs = kwargs
91 self.kwargs = kwargs
92
92
93 def __call__(self, **kwargs):
93 def __call__(self, **kwargs):
94 self.kwargs.update(kwargs)
94 self.kwargs.update(kwargs)
95 return self.func(*self.args, **self.kwargs)
95 return self.func(*self.args, **self.kwargs)
96
96
97 def __str__(self):
97 def __str__(self):
98 return str(self())
98 return str(self())
99
99
100 def __unicode__(self):
100 def __unicode__(self):
101 return py3compat.unicode_type(self())
101 return py3compat.unicode_type(self())
102
102
103 def __format__(self, format_spec):
103 def __format__(self, format_spec):
104 return format(self(), format_spec)
104 return format(self(), format_spec)
105
105
106 def multiple_replace(dict, text):
106 def multiple_replace(dict, text):
107 """ Replace in 'text' all occurences of any key in the given
107 """ Replace in 'text' all occurences of any key in the given
108 dictionary by its corresponding value. Returns the new string."""
108 dictionary by its corresponding value. Returns the new string."""
109
109
110 # Function by Xavier Defrang, originally found at:
110 # Function by Xavier Defrang, originally found at:
111 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
111 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
112
112
113 # Create a regular expression from the dictionary keys
113 # Create a regular expression from the dictionary keys
114 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
114 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
115 # For each match, look-up corresponding value in dictionary
115 # For each match, look-up corresponding value in dictionary
116 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
116 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
117
117
118 #-----------------------------------------------------------------------------
118 #-----------------------------------------------------------------------------
119 # Special characters that can be used in prompt templates, mainly bash-like
119 # Special characters that can be used in prompt templates, mainly bash-like
120 #-----------------------------------------------------------------------------
120 #-----------------------------------------------------------------------------
121
121
122 # If $HOME isn't defined (Windows), make it an absurd string so that it can
122 # If $HOME isn't defined (Windows), make it an absurd string so that it can
123 # never be expanded out into '~'. Basically anything which can never be a
123 # never be expanded out into '~'. Basically anything which can never be a
124 # reasonable directory name will do, we just want the $HOME -> '~' operation
124 # reasonable directory name will do, we just want the $HOME -> '~' operation
125 # to become a no-op. We pre-compute $HOME here so it's not done on every
125 # to become a no-op. We pre-compute $HOME here so it's not done on every
126 # prompt call.
126 # prompt call.
127
127
128 # FIXME:
128 # FIXME:
129
129
130 # - This should be turned into a class which does proper namespace management,
130 # - This should be turned into a class which does proper namespace management,
131 # since the prompt specials need to be evaluated in a certain namespace.
131 # since the prompt specials need to be evaluated in a certain namespace.
132 # Currently it's just globals, which need to be managed manually by code
132 # Currently it's just globals, which need to be managed manually by code
133 # below.
133 # below.
134
134
135 # - I also need to split up the color schemes from the prompt specials
135 # - I also need to split up the color schemes from the prompt specials
136 # somehow. I don't have a clean design for that quite yet.
136 # somehow. I don't have a clean design for that quite yet.
137
137
138 HOME = py3compat.str_to_unicode(os.environ.get("HOME","//////:::::ZZZZZ,,,~~~"))
138 HOME = py3compat.str_to_unicode(os.environ.get("HOME","//////:::::ZZZZZ,,,~~~"))
139
139
140 # This is needed on FreeBSD, and maybe other systems which symlink /home to
140 # This is needed on FreeBSD, and maybe other systems which symlink /home to
141 # /usr/home, but retain the $HOME variable as pointing to /home
141 # /usr/home, but retain the $HOME variable as pointing to /home
142 HOME = os.path.realpath(HOME)
142 HOME = os.path.realpath(HOME)
143
143
144 # We precompute a few more strings here for the prompt_specials, which are
144 # We precompute a few more strings here for the prompt_specials, which are
145 # fixed once ipython starts. This reduces the runtime overhead of computing
145 # fixed once ipython starts. This reduces the runtime overhead of computing
146 # prompt strings.
146 # prompt strings.
147 USER = py3compat.str_to_unicode(os.environ.get("USER",''))
147 USER = py3compat.str_to_unicode(os.environ.get("USER",''))
148 HOSTNAME = py3compat.str_to_unicode(socket.gethostname())
148 HOSTNAME = py3compat.str_to_unicode(socket.gethostname())
149 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
149 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
150
150
151 # IronPython doesn't currently have os.getuid() even if
151 # IronPython doesn't currently have os.getuid() even if
152 # os.name == 'posix'; 2/8/2014
152 # os.name == 'posix'; 2/8/2014
153 ROOT_SYMBOL = "#" if (os.name=='nt' or sys.platform=='cli' or os.getuid()==0) else "$"
153 ROOT_SYMBOL = "#" if (os.name=='nt' or sys.platform=='cli' or os.getuid()==0) else "$"
154
154
155 prompt_abbreviations = {
155 prompt_abbreviations = {
156 # Prompt/history count
156 # Prompt/history count
157 '%n' : '{color.number}' '{count}' '{color.prompt}',
157 '%n' : '{color.number}' '{count}' '{color.prompt}',
158 r'\#': '{color.number}' '{count}' '{color.prompt}',
158 r'\#': '{color.number}' '{count}' '{color.prompt}',
159 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
159 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
160 # can get numbers displayed in whatever color they want.
160 # can get numbers displayed in whatever color they want.
161 r'\N': '{count}',
161 r'\N': '{count}',
162
162
163 # Prompt/history count, with the actual digits replaced by dots. Used
163 # Prompt/history count, with the actual digits replaced by dots. Used
164 # mainly in continuation prompts (prompt_in2)
164 # mainly in continuation prompts (prompt_in2)
165 r'\D': '{dots}',
165 r'\D': '{dots}',
166
166
167 # Current time
167 # Current time
168 r'\T' : '{time}',
168 r'\T' : '{time}',
169 # Current working directory
169 # Current working directory
170 r'\w': '{cwd}',
170 r'\w': '{cwd}',
171 # Basename of current working directory.
171 # Basename of current working directory.
172 # (use os.sep to make this portable across OSes)
172 # (use os.sep to make this portable across OSes)
173 r'\W' : '{cwd_last}',
173 r'\W' : '{cwd_last}',
174 # These X<N> are an extension to the normal bash prompts. They return
174 # These X<N> are an extension to the normal bash prompts. They return
175 # N terms of the path, after replacing $HOME with '~'
175 # N terms of the path, after replacing $HOME with '~'
176 r'\X0': '{cwd_x[0]}',
176 r'\X0': '{cwd_x[0]}',
177 r'\X1': '{cwd_x[1]}',
177 r'\X1': '{cwd_x[1]}',
178 r'\X2': '{cwd_x[2]}',
178 r'\X2': '{cwd_x[2]}',
179 r'\X3': '{cwd_x[3]}',
179 r'\X3': '{cwd_x[3]}',
180 r'\X4': '{cwd_x[4]}',
180 r'\X4': '{cwd_x[4]}',
181 r'\X5': '{cwd_x[5]}',
181 r'\X5': '{cwd_x[5]}',
182 # Y<N> are similar to X<N>, but they show '~' if it's the directory
182 # Y<N> are similar to X<N>, but they show '~' if it's the directory
183 # N+1 in the list. Somewhat like %cN in tcsh.
183 # N+1 in the list. Somewhat like %cN in tcsh.
184 r'\Y0': '{cwd_y[0]}',
184 r'\Y0': '{cwd_y[0]}',
185 r'\Y1': '{cwd_y[1]}',
185 r'\Y1': '{cwd_y[1]}',
186 r'\Y2': '{cwd_y[2]}',
186 r'\Y2': '{cwd_y[2]}',
187 r'\Y3': '{cwd_y[3]}',
187 r'\Y3': '{cwd_y[3]}',
188 r'\Y4': '{cwd_y[4]}',
188 r'\Y4': '{cwd_y[4]}',
189 r'\Y5': '{cwd_y[5]}',
189 r'\Y5': '{cwd_y[5]}',
190 # Hostname up to first .
190 # Hostname up to first .
191 r'\h': HOSTNAME_SHORT,
191 r'\h': HOSTNAME_SHORT,
192 # Full hostname
192 # Full hostname
193 r'\H': HOSTNAME,
193 r'\H': HOSTNAME,
194 # Username of current user
194 # Username of current user
195 r'\u': USER,
195 r'\u': USER,
196 # Escaped '\'
196 # Escaped '\'
197 '\\\\': '\\',
197 '\\\\': '\\',
198 # Newline
198 # Newline
199 r'\n': '\n',
199 r'\n': '\n',
200 # Carriage return
200 # Carriage return
201 r'\r': '\r',
201 r'\r': '\r',
202 # Release version
202 # Release version
203 r'\v': release.version,
203 r'\v': release.version,
204 # Root symbol ($ or #)
204 # Root symbol ($ or #)
205 r'\$': ROOT_SYMBOL,
205 r'\$': ROOT_SYMBOL,
206 }
206 }
207
207
208 #-----------------------------------------------------------------------------
208 #-----------------------------------------------------------------------------
209 # More utilities
209 # More utilities
210 #-----------------------------------------------------------------------------
210 #-----------------------------------------------------------------------------
211
211
212 def cwd_filt(depth):
212 def cwd_filt(depth):
213 """Return the last depth elements of the current working directory.
213 """Return the last depth elements of the current working directory.
214
214
215 $HOME is always replaced with '~'.
215 $HOME is always replaced with '~'.
216 If depth==0, the full path is returned."""
216 If depth==0, the full path is returned."""
217
217
218 cwd = py3compat.getcwd().replace(HOME,"~")
218 cwd = py3compat.getcwd().replace(HOME,"~")
219 out = os.sep.join(cwd.split(os.sep)[-depth:])
219 out = os.sep.join(cwd.split(os.sep)[-depth:])
220 return out or os.sep
220 return out or os.sep
221
221
222 def cwd_filt2(depth):
222 def cwd_filt2(depth):
223 """Return the last depth elements of the current working directory.
223 """Return the last depth elements of the current working directory.
224
224
225 $HOME is always replaced with '~'.
225 $HOME is always replaced with '~'.
226 If depth==0, the full path is returned."""
226 If depth==0, the full path is returned."""
227
227
228 full_cwd = py3compat.getcwd()
228 full_cwd = py3compat.getcwd()
229 cwd = full_cwd.replace(HOME,"~").split(os.sep)
229 cwd = full_cwd.replace(HOME,"~").split(os.sep)
230 if '~' in cwd and len(cwd) == depth+1:
230 if '~' in cwd and len(cwd) == depth+1:
231 depth += 1
231 depth += 1
232 drivepart = ''
232 drivepart = ''
233 if sys.platform == 'win32' and len(cwd) > depth:
233 if sys.platform == 'win32' and len(cwd) > depth:
234 drivepart = os.path.splitdrive(full_cwd)[0]
234 drivepart = os.path.splitdrive(full_cwd)[0]
235 out = drivepart + '/'.join(cwd[-depth:])
235 out = drivepart + '/'.join(cwd[-depth:])
236
236
237 return out or os.sep
237 return out or os.sep
238
238
239 #-----------------------------------------------------------------------------
239 #-----------------------------------------------------------------------------
240 # Prompt classes
240 # Prompt classes
241 #-----------------------------------------------------------------------------
241 #-----------------------------------------------------------------------------
242
242
243 lazily_evaluate = {'time': LazyEvaluate(time.strftime, "%H:%M:%S"),
243 lazily_evaluate = {'time': LazyEvaluate(time.strftime, "%H:%M:%S"),
244 'cwd': LazyEvaluate(py3compat.getcwd),
244 'cwd': LazyEvaluate(py3compat.getcwd),
245 'cwd_last': LazyEvaluate(lambda: py3compat.getcwd().split(os.sep)[-1]),
245 'cwd_last': LazyEvaluate(lambda: py3compat.getcwd().split(os.sep)[-1]),
246 'cwd_x': [LazyEvaluate(lambda: py3compat.getcwd().replace(HOME,"~"))] +\
246 'cwd_x': [LazyEvaluate(lambda: py3compat.getcwd().replace(HOME,"~"))] +\
247 [LazyEvaluate(cwd_filt, x) for x in range(1,6)],
247 [LazyEvaluate(cwd_filt, x) for x in range(1,6)],
248 'cwd_y': [LazyEvaluate(cwd_filt2, x) for x in range(6)]
248 'cwd_y': [LazyEvaluate(cwd_filt2, x) for x in range(6)]
249 }
249 }
250
250
251 def _lenlastline(s):
251 def _lenlastline(s):
252 """Get the length of the last line. More intelligent than
252 """Get the length of the last line. More intelligent than
253 len(s.splitlines()[-1]).
253 len(s.splitlines()[-1]).
254 """
254 """
255 if not s or s.endswith(('\n', '\r')):
255 if not s or s.endswith(('\n', '\r')):
256 return 0
256 return 0
257 return len(s.splitlines()[-1])
257 return len(s.splitlines()[-1])
258
258
259
259
260 class UserNSFormatter(Formatter):
260 class UserNSFormatter(Formatter):
261 """A Formatter that falls back on a shell's user_ns and __builtins__ for name resolution"""
261 """A Formatter that falls back on a shell's user_ns and __builtins__ for name resolution"""
262 def __init__(self, shell):
262 def __init__(self, shell):
263 self.shell = shell
263 self.shell = shell
264
264
265 def get_value(self, key, args, kwargs):
265 def get_value(self, key, args, kwargs):
266 # try regular formatting first:
266 # try regular formatting first:
267 try:
267 try:
268 return Formatter.get_value(self, key, args, kwargs)
268 return Formatter.get_value(self, key, args, kwargs)
269 except Exception:
269 except Exception:
270 pass
270 pass
271 # next, look in user_ns and builtins:
271 # next, look in user_ns and builtins:
272 for container in (self.shell.user_ns, __builtins__):
272 for container in (self.shell.user_ns, __builtins__):
273 if key in container:
273 if key in container:
274 return container[key]
274 return container[key]
275 # nothing found, put error message in its place
275 # nothing found, put error message in its place
276 return "<ERROR: '%s' not found>" % key
276 return "<ERROR: '%s' not found>" % key
277
277
278
278
279 class PromptManager(Configurable):
279 class PromptManager(Configurable):
280 """This is the primary interface for producing IPython's prompts."""
280 """This is the primary interface for producing IPython's prompts."""
281 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
281 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
282
282
283 color_scheme_table = Instance(coloransi.ColorSchemeTable, allow_none=True)
283 color_scheme_table = Instance(coloransi.ColorSchemeTable, allow_none=True)
284 color_scheme = Unicode('Linux', config=True)
284 color_scheme = Unicode('Linux', config=True)
285 def _color_scheme_changed(self, name, new_value):
285 def _color_scheme_changed(self, name, new_value):
286 self.color_scheme_table.set_active_scheme(new_value)
286 self.color_scheme_table.set_active_scheme(new_value)
287 for pname in ['in', 'in2', 'out', 'rewrite']:
287 for pname in ['in', 'in2', 'out', 'rewrite']:
288 # We need to recalculate the number of invisible characters
288 # We need to recalculate the number of invisible characters
289 self.update_prompt(pname)
289 self.update_prompt(pname)
290
290
291 lazy_evaluate_fields = Dict(help="""
291 lazy_evaluate_fields = Dict(help="""
292 This maps field names used in the prompt templates to functions which
292 This maps field names used in the prompt templates to functions which
293 will be called when the prompt is rendered. This allows us to include
293 will be called when the prompt is rendered. This allows us to include
294 things like the current time in the prompts. Functions are only called
294 things like the current time in the prompts. Functions are only called
295 if they are used in the prompt.
295 if they are used in the prompt.
296 """)
296 """)
297 def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
297 def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
298
298
299 in_template = Unicode('In [\\#]: ', config=True,
299 in_template = Unicode('In [\\#]: ', config=True,
300 help="Input prompt. '\\#' will be transformed to the prompt number")
300 help="Input prompt. '\\#' will be transformed to the prompt number")
301 in2_template = Unicode(' .\\D.: ', config=True,
301 in2_template = Unicode(' .\\D.: ', config=True,
302 help="Continuation prompt.")
302 help="Continuation prompt.")
303 out_template = Unicode('Out[\\#]: ', config=True,
303 out_template = Unicode('Out[\\#]: ', config=True,
304 help="Output prompt. '\\#' will be transformed to the prompt number")
304 help="Output prompt. '\\#' will be transformed to the prompt number")
305
305
306 justify = Bool(True, config=True, help="""
306 justify = Bool(True, config=True, help="""
307 If True (default), each prompt will be right-aligned with the
307 If True (default), each prompt will be right-aligned with the
308 preceding one.
308 preceding one.
309 """)
309 """)
310
310
311 # We actually store the expanded templates here:
311 # We actually store the expanded templates here:
312 templates = Dict()
312 templates = Dict()
313
313
314 # The number of characters in the last prompt rendered, not including
314 # The number of characters in the last prompt rendered, not including
315 # colour characters.
315 # colour characters.
316 width = Int()
316 width = Int()
317 txtwidth = Int() # Not including right-justification
317 txtwidth = Int() # Not including right-justification
318
318
319 # The number of characters in each prompt which don't contribute to width
319 # The number of characters in each prompt which don't contribute to width
320 invisible_chars = Dict()
320 invisible_chars = Dict()
321 def _invisible_chars_default(self):
321 def _invisible_chars_default(self):
322 return {'in': 0, 'in2': 0, 'out': 0, 'rewrite':0}
322 return {'in': 0, 'in2': 0, 'out': 0, 'rewrite':0}
323
323
324 def __init__(self, shell, **kwargs):
324 def __init__(self, shell, **kwargs):
325 super(PromptManager, self).__init__(shell=shell, **kwargs)
325 super(PromptManager, self).__init__(shell=shell, **kwargs)
326
326
327 # Prepare colour scheme table
327 # Prepare colour scheme table
328 self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors,
328 self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors,
329 PColLinux, PColLightBG], self.color_scheme)
329 PColLinux, PColLightBG], self.color_scheme)
330
330
331 self._formatter = UserNSFormatter(shell)
331 self._formatter = UserNSFormatter(shell)
332 # Prepare templates & numbers of invisible characters
332 # Prepare templates & numbers of invisible characters
333 self.update_prompt('in', self.in_template)
333 self.update_prompt('in', self.in_template)
334 self.update_prompt('in2', self.in2_template)
334 self.update_prompt('in2', self.in2_template)
335 self.update_prompt('out', self.out_template)
335 self.update_prompt('out', self.out_template)
336 self.update_prompt('rewrite')
336 self.update_prompt('rewrite')
337 self.on_trait_change(self._update_prompt_trait, ['in_template',
337 self.on_trait_change(self._update_prompt_trait, ['in_template',
338 'in2_template', 'out_template'])
338 'in2_template', 'out_template'])
339
339
340 def update_prompt(self, name, new_template=None):
340 def update_prompt(self, name, new_template=None):
341 """This is called when a prompt template is updated. It processes
341 """This is called when a prompt template is updated. It processes
342 abbreviations used in the prompt template (like \#) and calculates how
342 abbreviations used in the prompt template (like \#) and calculates how
343 many invisible characters (ANSI colour escapes) the resulting prompt
343 many invisible characters (ANSI colour escapes) the resulting prompt
344 contains.
344 contains.
345
345
346 It is also called for each prompt on changing the colour scheme. In both
346 It is also called for each prompt on changing the colour scheme. In both
347 cases, traitlets should take care of calling this automatically.
347 cases, traitlets should take care of calling this automatically.
348 """
348 """
349 if new_template is not None:
349 if new_template is not None:
350 self.templates[name] = multiple_replace(prompt_abbreviations, new_template)
350 self.templates[name] = multiple_replace(prompt_abbreviations, new_template)
351 # We count invisible characters (colour escapes) on the last line of the
351 # We count invisible characters (colour escapes) on the last line of the
352 # prompt, to calculate the width for lining up subsequent prompts.
352 # prompt, to calculate the width for lining up subsequent prompts.
353 invis_chars = _lenlastline(self._render(name, color=True)) - \
353 invis_chars = _lenlastline(self._render(name, color=True)) - \
354 _lenlastline(self._render(name, color=False))
354 _lenlastline(self._render(name, color=False))
355 self.invisible_chars[name] = invis_chars
355 self.invisible_chars[name] = invis_chars
356
356
357 def _update_prompt_trait(self, traitname, new_template):
357 def _update_prompt_trait(self, traitname, new_template):
358 name = traitname[:-9] # Cut off '_template'
358 name = traitname[:-9] # Cut off '_template'
359 self.update_prompt(name, new_template)
359 self.update_prompt(name, new_template)
360
360
361 def _render(self, name, color=True, **kwargs):
361 def _render(self, name, color=True, **kwargs):
362 """Render but don't justify, or update the width or txtwidth attributes.
362 """Render but don't justify, or update the width or txtwidth attributes.
363 """
363 """
364 if name == 'rewrite':
364 if name == 'rewrite':
365 return self._render_rewrite(color=color)
365 return self._render_rewrite(color=color)
366
366
367 if color:
367 if color:
368 scheme = self.color_scheme_table.active_colors
368 scheme = self.color_scheme_table.active_colors
369 if name=='out':
369 if name=='out':
370 colors = color_lists['normal']
370 colors = color_lists['normal']
371 colors.number, colors.prompt, colors.normal = \
371 colors.number, colors.prompt, colors.normal = \
372 scheme.out_number, scheme.out_prompt, scheme.normal
372 scheme.out_number, scheme.out_prompt, scheme.normal
373 else:
373 else:
374 colors = color_lists['inp']
374 colors = color_lists['inp']
375 colors.number, colors.prompt, colors.normal = \
375 colors.number, colors.prompt, colors.normal = \
376 scheme.in_number, scheme.in_prompt, scheme.in_normal
376 scheme.in_number, scheme.in_prompt, scheme.in_normal
377 if name=='in2':
377 if name=='in2':
378 colors.prompt = scheme.in_prompt2
378 colors.prompt = scheme.in_prompt2
379 else:
379 else:
380 # No color
380 # No color
381 colors = color_lists['nocolor']
381 colors = color_lists['nocolor']
382 colors.number, colors.prompt, colors.normal = '', '', ''
382 colors.number, colors.prompt, colors.normal = '', '', ''
383
383
384 count = self.shell.execution_count # Shorthand
384 count = self.shell.execution_count # Shorthand
385 # Build the dictionary to be passed to string formatting
385 # Build the dictionary to be passed to string formatting
386 fmtargs = dict(color=colors, count=count,
386 fmtargs = dict(color=colors, count=count,
387 dots="."*len(str(count)),
387 dots="."*len(str(count)),
388 width=self.width, txtwidth=self.txtwidth )
388 width=self.width, txtwidth=self.txtwidth )
389 fmtargs.update(self.lazy_evaluate_fields)
389 fmtargs.update(self.lazy_evaluate_fields)
390 fmtargs.update(kwargs)
390 fmtargs.update(kwargs)
391
391
392 # Prepare the prompt
392 # Prepare the prompt
393 prompt = colors.prompt + self.templates[name] + colors.normal
393 prompt = colors.prompt + self.templates[name] + colors.normal
394
394
395 # Fill in required fields
395 # Fill in required fields
396 return self._formatter.format(prompt, **fmtargs)
396 return self._formatter.format(prompt, **fmtargs)
397
397
398 def _render_rewrite(self, color=True):
398 def _render_rewrite(self, color=True):
399 """Render the ---> rewrite prompt."""
399 """Render the ---> rewrite prompt."""
400 if color:
400 if color:
401 scheme = self.color_scheme_table.active_colors
401 scheme = self.color_scheme_table.active_colors
402 # We need a non-input version of these escapes
402 # We need a non-input version of these escapes
403 color_prompt = scheme.in_prompt.replace("\001","").replace("\002","")
403 color_prompt = scheme.in_prompt.replace("\001","").replace("\002","")
404 color_normal = scheme.normal
404 color_normal = scheme.normal
405 else:
405 else:
406 color_prompt, color_normal = '', ''
406 color_prompt, color_normal = '', ''
407
407
408 return color_prompt + "-> ".rjust(self.txtwidth, "-") + color_normal
408 return color_prompt + "-> ".rjust(self.txtwidth, "-") + color_normal
409
409
410 def render(self, name, color=True, just=None, **kwargs):
410 def render(self, name, color=True, just=None, **kwargs):
411 """
411 """
412 Render the selected prompt.
412 Render the selected prompt.
413
413
414 Parameters
414 Parameters
415 ----------
415 ----------
416 name : str
416 name : str
417 Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
417 Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
418 color : bool
418 color : bool
419 If True (default), include ANSI escape sequences for a coloured prompt.
419 If True (default), include ANSI escape sequences for a coloured prompt.
420 just : bool
420 just : bool
421 If True, justify the prompt to the width of the last prompt. The
421 If True, justify the prompt to the width of the last prompt. The
422 default is stored in self.justify.
422 default is stored in self.justify.
423 **kwargs :
423 **kwargs :
424 Additional arguments will be passed to the string formatting operation,
424 Additional arguments will be passed to the string formatting operation,
425 so they can override the values that would otherwise fill in the
425 so they can override the values that would otherwise fill in the
426 template.
426 template.
427
427
428 Returns
428 Returns
429 -------
429 -------
430 A string containing the rendered prompt.
430 A string containing the rendered prompt.
431 """
431 """
432 res = self._render(name, color=color, **kwargs)
432 res = self._render(name, color=color, **kwargs)
433
433
434 # Handle justification of prompt
434 # Handle justification of prompt
435 invis_chars = self.invisible_chars[name] if color else 0
435 invis_chars = self.invisible_chars[name] if color else 0
436 self.txtwidth = _lenlastline(res) - invis_chars
436 self.txtwidth = _lenlastline(res) - invis_chars
437 just = self.justify if (just is None) else just
437 just = self.justify if (just is None) else just
438 # If the prompt spans more than one line, don't try to justify it:
438 # If the prompt spans more than one line, don't try to justify it:
439 if just and name != 'in' and ('\n' not in res) and ('\r' not in res):
439 if just and name != 'in' and ('\n' not in res) and ('\r' not in res):
440 res = res.rjust(self.width + invis_chars)
440 res = res.rjust(self.width + invis_chars)
441 self.width = _lenlastline(res) - invis_chars
441 self.width = _lenlastline(res) - invis_chars
442 return res
442 return res
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
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 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now