##// END OF EJS Templates
Change absolute imports to relative imports to facilitate processes embedding kernel or debugger
Srinivas Reddy Thatiparthy -
Show More
@@ -1,19 +1,19 b''
1 """
1 """
2 Shim to maintain backwards compatibility with old IPython.config imports.
2 Shim to maintain backwards compatibility with old IPython.config imports.
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 sys
7 import sys
8 from warnings import warn
8 from warnings import warn
9
9
10 from IPython.utils.shimmodule import ShimModule, ShimWarning
10 from .utils.shimmodule import ShimModule, ShimWarning
11
11
12 warn("The `IPython.config` package has been deprecated since IPython 4.0. "
12 warn("The `IPython.config` package has been deprecated since IPython 4.0. "
13 "You should import from traitlets.config instead.", ShimWarning)
13 "You should import from traitlets.config instead.", ShimWarning)
14
14
15
15
16 # Unconditionally insert the shim into sys.modules so that further import calls
16 # Unconditionally insert the shim into sys.modules so that further import calls
17 # trigger the custom attribute access above
17 # trigger the custom attribute access above
18
18
19 sys.modules['IPython.config'] = ShimModule(src='IPython.config', mirror='traitlets.config')
19 sys.modules['IPython.config'] = ShimModule(src='IPython.config', mirror='traitlets.config')
@@ -1,69 +1,69 b''
1 import types
1 import types
2 import sys
2 import sys
3 import builtins
3 import builtins
4 import os
4 import os
5 import pytest
5 import pytest
6 import pathlib
6 import pathlib
7 import shutil
7 import shutil
8
8
9 from IPython.testing import tools
9 from .testing import tools
10
10
11
11
12 def get_ipython():
12 def get_ipython():
13 from IPython.terminal.interactiveshell import TerminalInteractiveShell
13 from .terminal.interactiveshell import TerminalInteractiveShell
14 if TerminalInteractiveShell._instance:
14 if TerminalInteractiveShell._instance:
15 return TerminalInteractiveShell.instance()
15 return TerminalInteractiveShell.instance()
16
16
17 config = tools.default_config()
17 config = tools.default_config()
18 config.TerminalInteractiveShell.simple_prompt = True
18 config.TerminalInteractiveShell.simple_prompt = True
19
19
20 # Create and initialize our test-friendly IPython instance.
20 # Create and initialize our test-friendly IPython instance.
21 shell = TerminalInteractiveShell.instance(config=config)
21 shell = TerminalInteractiveShell.instance(config=config)
22 return shell
22 return shell
23
23
24
24
25 @pytest.fixture(scope='session', autouse=True)
25 @pytest.fixture(scope='session', autouse=True)
26 def work_path():
26 def work_path():
27 path = pathlib.Path("./tmp-ipython-pytest-profiledir")
27 path = pathlib.Path("./tmp-ipython-pytest-profiledir")
28 os.environ["IPYTHONDIR"] = str(path.absolute())
28 os.environ["IPYTHONDIR"] = str(path.absolute())
29 if path.exists():
29 if path.exists():
30 raise ValueError('IPython dir temporary path already exists ! Did previous test run exit successfully ?')
30 raise ValueError('IPython dir temporary path already exists ! Did previous test run exit successfully ?')
31 path.mkdir()
31 path.mkdir()
32 yield
32 yield
33 shutil.rmtree(str(path.resolve()))
33 shutil.rmtree(str(path.resolve()))
34
34
35
35
36 def nopage(strng, start=0, screen_lines=0, pager_cmd=None):
36 def nopage(strng, start=0, screen_lines=0, pager_cmd=None):
37 if isinstance(strng, dict):
37 if isinstance(strng, dict):
38 strng = strng.get("text/plain", "")
38 strng = strng.get("text/plain", "")
39 print(strng)
39 print(strng)
40
40
41
41
42 def xsys(self, cmd):
42 def xsys(self, cmd):
43 """Replace the default system call with a capturing one for doctest.
43 """Replace the default system call with a capturing one for doctest.
44 """
44 """
45 # We use getoutput, but we need to strip it because pexpect captures
45 # We use getoutput, but we need to strip it because pexpect captures
46 # the trailing newline differently from commands.getoutput
46 # the trailing newline differently from commands.getoutput
47 print(self.getoutput(cmd, split=False, depth=1).rstrip(), end="", file=sys.stdout)
47 print(self.getoutput(cmd, split=False, depth=1).rstrip(), end="", file=sys.stdout)
48 sys.stdout.flush()
48 sys.stdout.flush()
49
49
50
50
51 # for things to work correctly we would need this as a session fixture;
51 # for things to work correctly we would need this as a session fixture;
52 # unfortunately this will fail on some test that get executed as _collection_
52 # unfortunately this will fail on some test that get executed as _collection_
53 # time (before the fixture run), in particular parametrized test that contain
53 # time (before the fixture run), in particular parametrized test that contain
54 # yields. so for now execute at import time.
54 # yields. so for now execute at import time.
55 #@pytest.fixture(autouse=True, scope='session')
55 #@pytest.fixture(autouse=True, scope='session')
56 def inject():
56 def inject():
57
57
58 builtins.get_ipython = get_ipython
58 builtins.get_ipython = get_ipython
59 builtins._ip = get_ipython()
59 builtins._ip = get_ipython()
60 builtins.ip = get_ipython()
60 builtins.ip = get_ipython()
61 builtins.ip.system = types.MethodType(xsys, ip)
61 builtins.ip.system = types.MethodType(xsys, ip)
62 builtins.ip.builtin_trap.activate()
62 builtins.ip.builtin_trap.activate()
63 from IPython.core import page
63 from .core import page
64
64
65 page.pager_page = nopage
65 page.pager_page = nopage
66 # yield
66 # yield
67
67
68
68
69 inject()
69 inject()
@@ -1,258 +1,258 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 System command aliases.
3 System command aliases.
4
4
5 Authors:
5 Authors:
6
6
7 * Fernando Perez
7 * Fernando Perez
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2011 The IPython Development Team
12 # Copyright (C) 2008-2011 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License.
14 # Distributed under the terms of the BSD License.
15 #
15 #
16 # The full license is in the file COPYING.txt, distributed with this software.
16 # The full license is in the file COPYING.txt, distributed with this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 import re
24 import re
25 import sys
25 import sys
26
26
27 from traitlets.config.configurable import Configurable
27 from traitlets.config.configurable import Configurable
28 from IPython.core.error import UsageError
28 from .error import UsageError
29
29
30 from traitlets import List, Instance
30 from traitlets import List, Instance
31 from logging import error
31 from logging import error
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Utilities
34 # Utilities
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 # This is used as the pattern for calls to split_user_input.
37 # This is used as the pattern for calls to split_user_input.
38 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
38 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
39
39
40 def default_aliases():
40 def default_aliases():
41 """Return list of shell aliases to auto-define.
41 """Return list of shell aliases to auto-define.
42 """
42 """
43 # Note: the aliases defined here should be safe to use on a kernel
43 # Note: the aliases defined here should be safe to use on a kernel
44 # regardless of what frontend it is attached to. Frontends that use a
44 # regardless of what frontend it is attached to. Frontends that use a
45 # kernel in-process can define additional aliases that will only work in
45 # kernel in-process can define additional aliases that will only work in
46 # their case. For example, things like 'less' or 'clear' that manipulate
46 # their case. For example, things like 'less' or 'clear' that manipulate
47 # the terminal should NOT be declared here, as they will only work if the
47 # the terminal should NOT be declared here, as they will only work if the
48 # kernel is running inside a true terminal, and not over the network.
48 # kernel is running inside a true terminal, and not over the network.
49
49
50 if os.name == 'posix':
50 if os.name == 'posix':
51 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
51 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
52 ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'),
52 ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'),
53 ('cat', 'cat'),
53 ('cat', 'cat'),
54 ]
54 ]
55 # Useful set of ls aliases. The GNU and BSD options are a little
55 # Useful set of ls aliases. The GNU and BSD options are a little
56 # different, so we make aliases that provide as similar as possible
56 # different, so we make aliases that provide as similar as possible
57 # behavior in ipython, by passing the right flags for each platform
57 # behavior in ipython, by passing the right flags for each platform
58 if sys.platform.startswith('linux'):
58 if sys.platform.startswith('linux'):
59 ls_aliases = [('ls', 'ls -F --color'),
59 ls_aliases = [('ls', 'ls -F --color'),
60 # long ls
60 # long ls
61 ('ll', 'ls -F -o --color'),
61 ('ll', 'ls -F -o --color'),
62 # ls normal files only
62 # ls normal files only
63 ('lf', 'ls -F -o --color %l | grep ^-'),
63 ('lf', 'ls -F -o --color %l | grep ^-'),
64 # ls symbolic links
64 # ls symbolic links
65 ('lk', 'ls -F -o --color %l | grep ^l'),
65 ('lk', 'ls -F -o --color %l | grep ^l'),
66 # directories or links to directories,
66 # directories or links to directories,
67 ('ldir', 'ls -F -o --color %l | grep /$'),
67 ('ldir', 'ls -F -o --color %l | grep /$'),
68 # things which are executable
68 # things which are executable
69 ('lx', 'ls -F -o --color %l | grep ^-..x'),
69 ('lx', 'ls -F -o --color %l | grep ^-..x'),
70 ]
70 ]
71 elif sys.platform.startswith('openbsd') or sys.platform.startswith('netbsd'):
71 elif sys.platform.startswith('openbsd') or sys.platform.startswith('netbsd'):
72 # OpenBSD, NetBSD. The ls implementation on these platforms do not support
72 # OpenBSD, NetBSD. The ls implementation on these platforms do not support
73 # the -G switch and lack the ability to use colorized output.
73 # the -G switch and lack the ability to use colorized output.
74 ls_aliases = [('ls', 'ls -F'),
74 ls_aliases = [('ls', 'ls -F'),
75 # long ls
75 # long ls
76 ('ll', 'ls -F -l'),
76 ('ll', 'ls -F -l'),
77 # ls normal files only
77 # ls normal files only
78 ('lf', 'ls -F -l %l | grep ^-'),
78 ('lf', 'ls -F -l %l | grep ^-'),
79 # ls symbolic links
79 # ls symbolic links
80 ('lk', 'ls -F -l %l | grep ^l'),
80 ('lk', 'ls -F -l %l | grep ^l'),
81 # directories or links to directories,
81 # directories or links to directories,
82 ('ldir', 'ls -F -l %l | grep /$'),
82 ('ldir', 'ls -F -l %l | grep /$'),
83 # things which are executable
83 # things which are executable
84 ('lx', 'ls -F -l %l | grep ^-..x'),
84 ('lx', 'ls -F -l %l | grep ^-..x'),
85 ]
85 ]
86 else:
86 else:
87 # BSD, OSX, etc.
87 # BSD, OSX, etc.
88 ls_aliases = [('ls', 'ls -F -G'),
88 ls_aliases = [('ls', 'ls -F -G'),
89 # long ls
89 # long ls
90 ('ll', 'ls -F -l -G'),
90 ('ll', 'ls -F -l -G'),
91 # ls normal files only
91 # ls normal files only
92 ('lf', 'ls -F -l -G %l | grep ^-'),
92 ('lf', 'ls -F -l -G %l | grep ^-'),
93 # ls symbolic links
93 # ls symbolic links
94 ('lk', 'ls -F -l -G %l | grep ^l'),
94 ('lk', 'ls -F -l -G %l | grep ^l'),
95 # directories or links to directories,
95 # directories or links to directories,
96 ('ldir', 'ls -F -G -l %l | grep /$'),
96 ('ldir', 'ls -F -G -l %l | grep /$'),
97 # things which are executable
97 # things which are executable
98 ('lx', 'ls -F -l -G %l | grep ^-..x'),
98 ('lx', 'ls -F -l -G %l | grep ^-..x'),
99 ]
99 ]
100 default_aliases = default_aliases + ls_aliases
100 default_aliases = default_aliases + ls_aliases
101 elif os.name in ['nt', 'dos']:
101 elif os.name in ['nt', 'dos']:
102 default_aliases = [('ls', 'dir /on'),
102 default_aliases = [('ls', 'dir /on'),
103 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
103 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
104 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
104 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
105 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
105 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
106 ]
106 ]
107 else:
107 else:
108 default_aliases = []
108 default_aliases = []
109
109
110 return default_aliases
110 return default_aliases
111
111
112
112
113 class AliasError(Exception):
113 class AliasError(Exception):
114 pass
114 pass
115
115
116
116
117 class InvalidAliasError(AliasError):
117 class InvalidAliasError(AliasError):
118 pass
118 pass
119
119
120 class Alias(object):
120 class Alias(object):
121 """Callable object storing the details of one alias.
121 """Callable object storing the details of one alias.
122
122
123 Instances are registered as magic functions to allow use of aliases.
123 Instances are registered as magic functions to allow use of aliases.
124 """
124 """
125
125
126 # Prepare blacklist
126 # Prepare blacklist
127 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
127 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
128
128
129 def __init__(self, shell, name, cmd):
129 def __init__(self, shell, name, cmd):
130 self.shell = shell
130 self.shell = shell
131 self.name = name
131 self.name = name
132 self.cmd = cmd
132 self.cmd = cmd
133 self.__doc__ = "Alias for `!{}`".format(cmd)
133 self.__doc__ = "Alias for `!{}`".format(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, str)):
150 if not (isinstance(self.cmd, str)):
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()).tag(config=True)
194 default_aliases = List(default_aliases()).tag(config=True)
195 user_aliases = List(default_value=[]).tag(config=True)
195 user_aliases = List(default_value=[]).tag(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 if cmd.startswith('ls ') and self.shell.colors == 'NoColor':
207 if cmd.startswith('ls ') and self.shell.colors == 'NoColor':
208 cmd = cmd.replace(' --color', '')
208 cmd = cmd.replace(' --color', '')
209 self.soft_define_alias(name, cmd)
209 self.soft_define_alias(name, cmd)
210
210
211 @property
211 @property
212 def aliases(self):
212 def aliases(self):
213 return [(n, func.cmd) for (n, func) in self.linemagics.items()
213 return [(n, func.cmd) for (n, func) in self.linemagics.items()
214 if isinstance(func, Alias)]
214 if isinstance(func, Alias)]
215
215
216 def soft_define_alias(self, name, cmd):
216 def soft_define_alias(self, name, cmd):
217 """Define an alias, but don't raise on an AliasError."""
217 """Define an alias, but don't raise on an AliasError."""
218 try:
218 try:
219 self.define_alias(name, cmd)
219 self.define_alias(name, cmd)
220 except AliasError as e:
220 except AliasError as e:
221 error("Invalid alias: %s" % e)
221 error("Invalid alias: %s" % e)
222
222
223 def define_alias(self, name, cmd):
223 def define_alias(self, name, cmd):
224 """Define a new alias after validating it.
224 """Define a new alias after validating it.
225
225
226 This will raise an :exc:`AliasError` if there are validation
226 This will raise an :exc:`AliasError` if there are validation
227 problems.
227 problems.
228 """
228 """
229 caller = Alias(shell=self.shell, name=name, cmd=cmd)
229 caller = Alias(shell=self.shell, name=name, cmd=cmd)
230 self.shell.magics_manager.register_function(caller, magic_kind='line',
230 self.shell.magics_manager.register_function(caller, magic_kind='line',
231 magic_name=name)
231 magic_name=name)
232
232
233 def get_alias(self, name):
233 def get_alias(self, name):
234 """Return an alias, or None if no alias by that name exists."""
234 """Return an alias, or None if no alias by that name exists."""
235 aname = self.linemagics.get(name, None)
235 aname = self.linemagics.get(name, None)
236 return aname if isinstance(aname, Alias) else None
236 return aname if isinstance(aname, Alias) else None
237
237
238 def is_alias(self, name):
238 def is_alias(self, name):
239 """Return whether or not a given name has been defined as an alias"""
239 """Return whether or not a given name has been defined as an alias"""
240 return self.get_alias(name) is not None
240 return self.get_alias(name) is not None
241
241
242 def undefine_alias(self, name):
242 def undefine_alias(self, name):
243 if self.is_alias(name):
243 if self.is_alias(name):
244 del self.linemagics[name]
244 del self.linemagics[name]
245 else:
245 else:
246 raise ValueError('%s is not an alias' % name)
246 raise ValueError('%s is not an alias' % name)
247
247
248 def clear_aliases(self):
248 def clear_aliases(self):
249 for name, cmd in self.aliases:
249 for name, cmd in self.aliases:
250 self.undefine_alias(name)
250 self.undefine_alias(name)
251
251
252 def retrieve_alias(self, name):
252 def retrieve_alias(self, name):
253 """Retrieve the command to which an alias expands."""
253 """Retrieve the command to which an alias expands."""
254 caller = self.get_alias(name)
254 caller = self.get_alias(name)
255 if caller:
255 if caller:
256 return caller.cmd
256 return caller.cmd
257 else:
257 else:
258 raise ValueError('%s is not an alias' % name)
258 raise ValueError('%s is not an alias' % name)
@@ -1,354 +1,354 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Implementations for various useful completers.
2 """Implementations for various useful completers.
3
3
4 These are all loaded by default by IPython.
4 These are all loaded by default by IPython.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2010-2011 The IPython Development Team.
7 # Copyright (C) 2010-2011 The IPython Development Team.
8 #
8 #
9 # Distributed under the terms of the BSD License.
9 # Distributed under the terms of the BSD License.
10 #
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Stdlib imports
18 # Stdlib imports
19 import glob
19 import glob
20 import inspect
20 import inspect
21 import os
21 import os
22 import re
22 import re
23 import sys
23 import sys
24 from importlib import import_module
24 from importlib import import_module
25 from importlib.machinery import all_suffixes
25 from importlib.machinery import all_suffixes
26
26
27
27
28 # Third-party imports
28 # Third-party imports
29 from time import time
29 from time import time
30 from zipimport import zipimporter
30 from zipimport import zipimporter
31
31
32 # Our own imports
32 # Our own imports
33 from IPython.core.completer import expand_user, compress_user
33 from .completer import expand_user, compress_user
34 from IPython.core.error import TryNext
34 from .error import TryNext
35 from IPython.utils._process_common import arg_split
35 from ..utils._process_common import arg_split
36
36
37 # FIXME: this should be pulled in with the right call via the component system
37 # FIXME: this should be pulled in with the right call via the component system
38 from IPython import get_ipython
38 from IPython import get_ipython
39
39
40 from typing import List
40 from typing import List
41
41
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43 # Globals and constants
43 # Globals and constants
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 _suffixes = all_suffixes()
45 _suffixes = all_suffixes()
46
46
47 # Time in seconds after which the rootmodules will be stored permanently in the
47 # Time in seconds after which the rootmodules will be stored permanently in the
48 # ipython ip.db database (kept in the user's .ipython dir).
48 # ipython ip.db database (kept in the user's .ipython dir).
49 TIMEOUT_STORAGE = 2
49 TIMEOUT_STORAGE = 2
50
50
51 # Time in seconds after which we give up
51 # Time in seconds after which we give up
52 TIMEOUT_GIVEUP = 20
52 TIMEOUT_GIVEUP = 20
53
53
54 # Regular expression for the python import statement
54 # Regular expression for the python import statement
55 import_re = re.compile(r'(?P<name>[a-zA-Z_][a-zA-Z0-9_]*?)'
55 import_re = re.compile(r'(?P<name>[a-zA-Z_][a-zA-Z0-9_]*?)'
56 r'(?P<package>[/\\]__init__)?'
56 r'(?P<package>[/\\]__init__)?'
57 r'(?P<suffix>%s)$' %
57 r'(?P<suffix>%s)$' %
58 r'|'.join(re.escape(s) for s in _suffixes))
58 r'|'.join(re.escape(s) for s in _suffixes))
59
59
60 # RE for the ipython %run command (python + ipython scripts)
60 # RE for the ipython %run command (python + ipython scripts)
61 magic_run_re = re.compile(r'.*(\.ipy|\.ipynb|\.py[w]?)$')
61 magic_run_re = re.compile(r'.*(\.ipy|\.ipynb|\.py[w]?)$')
62
62
63 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
64 # Local utilities
64 # Local utilities
65 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
66
66
67 def module_list(path):
67 def module_list(path):
68 """
68 """
69 Return the list containing the names of the modules available in the given
69 Return the list containing the names of the modules available in the given
70 folder.
70 folder.
71 """
71 """
72 # sys.path has the cwd as an empty string, but isdir/listdir need it as '.'
72 # sys.path has the cwd as an empty string, but isdir/listdir need it as '.'
73 if path == '':
73 if path == '':
74 path = '.'
74 path = '.'
75
75
76 # A few local constants to be used in loops below
76 # A few local constants to be used in loops below
77 pjoin = os.path.join
77 pjoin = os.path.join
78
78
79 if os.path.isdir(path):
79 if os.path.isdir(path):
80 # Build a list of all files in the directory and all files
80 # Build a list of all files in the directory and all files
81 # in its subdirectories. For performance reasons, do not
81 # in its subdirectories. For performance reasons, do not
82 # recurse more than one level into subdirectories.
82 # recurse more than one level into subdirectories.
83 files = []
83 files = []
84 for root, dirs, nondirs in os.walk(path, followlinks=True):
84 for root, dirs, nondirs in os.walk(path, followlinks=True):
85 subdir = root[len(path)+1:]
85 subdir = root[len(path)+1:]
86 if subdir:
86 if subdir:
87 files.extend(pjoin(subdir, f) for f in nondirs)
87 files.extend(pjoin(subdir, f) for f in nondirs)
88 dirs[:] = [] # Do not recurse into additional subdirectories.
88 dirs[:] = [] # Do not recurse into additional subdirectories.
89 else:
89 else:
90 files.extend(nondirs)
90 files.extend(nondirs)
91
91
92 else:
92 else:
93 try:
93 try:
94 files = list(zipimporter(path)._files.keys())
94 files = list(zipimporter(path)._files.keys())
95 except:
95 except:
96 files = []
96 files = []
97
97
98 # Build a list of modules which match the import_re regex.
98 # Build a list of modules which match the import_re regex.
99 modules = []
99 modules = []
100 for f in files:
100 for f in files:
101 m = import_re.match(f)
101 m = import_re.match(f)
102 if m:
102 if m:
103 modules.append(m.group('name'))
103 modules.append(m.group('name'))
104 return list(set(modules))
104 return list(set(modules))
105
105
106
106
107 def get_root_modules():
107 def get_root_modules():
108 """
108 """
109 Returns a list containing the names of all the modules available in the
109 Returns a list containing the names of all the modules available in the
110 folders of the pythonpath.
110 folders of the pythonpath.
111
111
112 ip.db['rootmodules_cache'] maps sys.path entries to list of modules.
112 ip.db['rootmodules_cache'] maps sys.path entries to list of modules.
113 """
113 """
114 ip = get_ipython()
114 ip = get_ipython()
115 if ip is None:
115 if ip is None:
116 # No global shell instance to store cached list of modules.
116 # No global shell instance to store cached list of modules.
117 # Don't try to scan for modules every time.
117 # Don't try to scan for modules every time.
118 return list(sys.builtin_module_names)
118 return list(sys.builtin_module_names)
119
119
120 rootmodules_cache = ip.db.get('rootmodules_cache', {})
120 rootmodules_cache = ip.db.get('rootmodules_cache', {})
121 rootmodules = list(sys.builtin_module_names)
121 rootmodules = list(sys.builtin_module_names)
122 start_time = time()
122 start_time = time()
123 store = False
123 store = False
124 for path in sys.path:
124 for path in sys.path:
125 try:
125 try:
126 modules = rootmodules_cache[path]
126 modules = rootmodules_cache[path]
127 except KeyError:
127 except KeyError:
128 modules = module_list(path)
128 modules = module_list(path)
129 try:
129 try:
130 modules.remove('__init__')
130 modules.remove('__init__')
131 except ValueError:
131 except ValueError:
132 pass
132 pass
133 if path not in ('', '.'): # cwd modules should not be cached
133 if path not in ('', '.'): # cwd modules should not be cached
134 rootmodules_cache[path] = modules
134 rootmodules_cache[path] = modules
135 if time() - start_time > TIMEOUT_STORAGE and not store:
135 if time() - start_time > TIMEOUT_STORAGE and not store:
136 store = True
136 store = True
137 print("\nCaching the list of root modules, please wait!")
137 print("\nCaching the list of root modules, please wait!")
138 print("(This will only be done once - type '%rehashx' to "
138 print("(This will only be done once - type '%rehashx' to "
139 "reset cache!)\n")
139 "reset cache!)\n")
140 sys.stdout.flush()
140 sys.stdout.flush()
141 if time() - start_time > TIMEOUT_GIVEUP:
141 if time() - start_time > TIMEOUT_GIVEUP:
142 print("This is taking too long, we give up.\n")
142 print("This is taking too long, we give up.\n")
143 return []
143 return []
144 rootmodules.extend(modules)
144 rootmodules.extend(modules)
145 if store:
145 if store:
146 ip.db['rootmodules_cache'] = rootmodules_cache
146 ip.db['rootmodules_cache'] = rootmodules_cache
147 rootmodules = list(set(rootmodules))
147 rootmodules = list(set(rootmodules))
148 return rootmodules
148 return rootmodules
149
149
150
150
151 def is_importable(module, attr, only_modules):
151 def is_importable(module, attr, only_modules):
152 if only_modules:
152 if only_modules:
153 return inspect.ismodule(getattr(module, attr))
153 return inspect.ismodule(getattr(module, attr))
154 else:
154 else:
155 return not(attr[:2] == '__' and attr[-2:] == '__')
155 return not(attr[:2] == '__' and attr[-2:] == '__')
156
156
157
157
158 def try_import(mod: str, only_modules=False) -> List[str]:
158 def try_import(mod: str, only_modules=False) -> List[str]:
159 """
159 """
160 Try to import given module and return list of potential completions.
160 Try to import given module and return list of potential completions.
161 """
161 """
162 mod = mod.rstrip('.')
162 mod = mod.rstrip('.')
163 try:
163 try:
164 m = import_module(mod)
164 m = import_module(mod)
165 except:
165 except:
166 return []
166 return []
167
167
168 m_is_init = '__init__' in (getattr(m, '__file__', '') or '')
168 m_is_init = '__init__' in (getattr(m, '__file__', '') or '')
169
169
170 completions = []
170 completions = []
171 if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
171 if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
172 completions.extend( [attr for attr in dir(m) if
172 completions.extend( [attr for attr in dir(m) if
173 is_importable(m, attr, only_modules)])
173 is_importable(m, attr, only_modules)])
174
174
175 completions.extend(getattr(m, '__all__', []))
175 completions.extend(getattr(m, '__all__', []))
176 if m_is_init:
176 if m_is_init:
177 completions.extend(module_list(os.path.dirname(m.__file__)))
177 completions.extend(module_list(os.path.dirname(m.__file__)))
178 completions_set = {c for c in completions if isinstance(c, str)}
178 completions_set = {c for c in completions if isinstance(c, str)}
179 completions_set.discard('__init__')
179 completions_set.discard('__init__')
180 return list(completions_set)
180 return list(completions_set)
181
181
182
182
183 #-----------------------------------------------------------------------------
183 #-----------------------------------------------------------------------------
184 # Completion-related functions.
184 # Completion-related functions.
185 #-----------------------------------------------------------------------------
185 #-----------------------------------------------------------------------------
186
186
187 def quick_completer(cmd, completions):
187 def quick_completer(cmd, completions):
188 r""" Easily create a trivial completer for a command.
188 r""" Easily create a trivial completer for a command.
189
189
190 Takes either a list of completions, or all completions in string (that will
190 Takes either a list of completions, or all completions in string (that will
191 be split on whitespace).
191 be split on whitespace).
192
192
193 Example::
193 Example::
194
194
195 [d:\ipython]|1> import ipy_completers
195 [d:\ipython]|1> import ipy_completers
196 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
196 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
197 [d:\ipython]|3> foo b<TAB>
197 [d:\ipython]|3> foo b<TAB>
198 bar baz
198 bar baz
199 [d:\ipython]|3> foo ba
199 [d:\ipython]|3> foo ba
200 """
200 """
201
201
202 if isinstance(completions, str):
202 if isinstance(completions, str):
203 completions = completions.split()
203 completions = completions.split()
204
204
205 def do_complete(self, event):
205 def do_complete(self, event):
206 return completions
206 return completions
207
207
208 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
208 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
209
209
210 def module_completion(line):
210 def module_completion(line):
211 """
211 """
212 Returns a list containing the completion possibilities for an import line.
212 Returns a list containing the completion possibilities for an import line.
213
213
214 The line looks like this :
214 The line looks like this :
215 'import xml.d'
215 'import xml.d'
216 'from xml.dom import'
216 'from xml.dom import'
217 """
217 """
218
218
219 words = line.split(' ')
219 words = line.split(' ')
220 nwords = len(words)
220 nwords = len(words)
221
221
222 # from whatever <tab> -> 'import '
222 # from whatever <tab> -> 'import '
223 if nwords == 3 and words[0] == 'from':
223 if nwords == 3 and words[0] == 'from':
224 return ['import ']
224 return ['import ']
225
225
226 # 'from xy<tab>' or 'import xy<tab>'
226 # 'from xy<tab>' or 'import xy<tab>'
227 if nwords < 3 and (words[0] in {'%aimport', 'import', 'from'}) :
227 if nwords < 3 and (words[0] in {'%aimport', 'import', 'from'}) :
228 if nwords == 1:
228 if nwords == 1:
229 return get_root_modules()
229 return get_root_modules()
230 mod = words[1].split('.')
230 mod = words[1].split('.')
231 if len(mod) < 2:
231 if len(mod) < 2:
232 return get_root_modules()
232 return get_root_modules()
233 completion_list = try_import('.'.join(mod[:-1]), True)
233 completion_list = try_import('.'.join(mod[:-1]), True)
234 return ['.'.join(mod[:-1] + [el]) for el in completion_list]
234 return ['.'.join(mod[:-1] + [el]) for el in completion_list]
235
235
236 # 'from xyz import abc<tab>'
236 # 'from xyz import abc<tab>'
237 if nwords >= 3 and words[0] == 'from':
237 if nwords >= 3 and words[0] == 'from':
238 mod = words[1]
238 mod = words[1]
239 return try_import(mod)
239 return try_import(mod)
240
240
241 #-----------------------------------------------------------------------------
241 #-----------------------------------------------------------------------------
242 # Completers
242 # Completers
243 #-----------------------------------------------------------------------------
243 #-----------------------------------------------------------------------------
244 # These all have the func(self, event) signature to be used as custom
244 # These all have the func(self, event) signature to be used as custom
245 # completers
245 # completers
246
246
247 def module_completer(self,event):
247 def module_completer(self,event):
248 """Give completions after user has typed 'import ...' or 'from ...'"""
248 """Give completions after user has typed 'import ...' or 'from ...'"""
249
249
250 # This works in all versions of python. While 2.5 has
250 # This works in all versions of python. While 2.5 has
251 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
251 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
252 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
252 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
253 # of possibly problematic side effects.
253 # of possibly problematic side effects.
254 # This search the folders in the sys.path for available modules.
254 # This search the folders in the sys.path for available modules.
255
255
256 return module_completion(event.line)
256 return module_completion(event.line)
257
257
258 # FIXME: there's a lot of logic common to the run, cd and builtin file
258 # FIXME: there's a lot of logic common to the run, cd and builtin file
259 # completers, that is currently reimplemented in each.
259 # completers, that is currently reimplemented in each.
260
260
261 def magic_run_completer(self, event):
261 def magic_run_completer(self, event):
262 """Complete files that end in .py or .ipy or .ipynb for the %run command.
262 """Complete files that end in .py or .ipy or .ipynb for the %run command.
263 """
263 """
264 comps = arg_split(event.line, strict=False)
264 comps = arg_split(event.line, strict=False)
265 # relpath should be the current token that we need to complete.
265 # relpath should be the current token that we need to complete.
266 if (len(comps) > 1) and (not event.line.endswith(' ')):
266 if (len(comps) > 1) and (not event.line.endswith(' ')):
267 relpath = comps[-1].strip("'\"")
267 relpath = comps[-1].strip("'\"")
268 else:
268 else:
269 relpath = ''
269 relpath = ''
270
270
271 #print("\nev=", event) # dbg
271 #print("\nev=", event) # dbg
272 #print("rp=", relpath) # dbg
272 #print("rp=", relpath) # dbg
273 #print('comps=', comps) # dbg
273 #print('comps=', comps) # dbg
274
274
275 lglob = glob.glob
275 lglob = glob.glob
276 isdir = os.path.isdir
276 isdir = os.path.isdir
277 relpath, tilde_expand, tilde_val = expand_user(relpath)
277 relpath, tilde_expand, tilde_val = expand_user(relpath)
278
278
279 # Find if the user has already typed the first filename, after which we
279 # Find if the user has already typed the first filename, after which we
280 # should complete on all files, since after the first one other files may
280 # should complete on all files, since after the first one other files may
281 # be arguments to the input script.
281 # be arguments to the input script.
282
282
283 if any(magic_run_re.match(c) for c in comps):
283 if any(magic_run_re.match(c) for c in comps):
284 matches = [f.replace('\\','/') + ('/' if isdir(f) else '')
284 matches = [f.replace('\\','/') + ('/' if isdir(f) else '')
285 for f in lglob(relpath+'*')]
285 for f in lglob(relpath+'*')]
286 else:
286 else:
287 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
287 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
288 pys = [f.replace('\\','/')
288 pys = [f.replace('\\','/')
289 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
289 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
290 lglob(relpath+'*.ipynb') + lglob(relpath + '*.pyw')]
290 lglob(relpath+'*.ipynb') + lglob(relpath + '*.pyw')]
291
291
292 matches = dirs + pys
292 matches = dirs + pys
293
293
294 #print('run comp:', dirs+pys) # dbg
294 #print('run comp:', dirs+pys) # dbg
295 return [compress_user(p, tilde_expand, tilde_val) for p in matches]
295 return [compress_user(p, tilde_expand, tilde_val) for p in matches]
296
296
297
297
298 def cd_completer(self, event):
298 def cd_completer(self, event):
299 """Completer function for cd, which only returns directories."""
299 """Completer function for cd, which only returns directories."""
300 ip = get_ipython()
300 ip = get_ipython()
301 relpath = event.symbol
301 relpath = event.symbol
302
302
303 #print(event) # dbg
303 #print(event) # dbg
304 if event.line.endswith('-b') or ' -b ' in event.line:
304 if event.line.endswith('-b') or ' -b ' in event.line:
305 # return only bookmark completions
305 # return only bookmark completions
306 bkms = self.db.get('bookmarks', None)
306 bkms = self.db.get('bookmarks', None)
307 if bkms:
307 if bkms:
308 return bkms.keys()
308 return bkms.keys()
309 else:
309 else:
310 return []
310 return []
311
311
312 if event.symbol == '-':
312 if event.symbol == '-':
313 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
313 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
314 # jump in directory history by number
314 # jump in directory history by number
315 fmt = '-%0' + width_dh +'d [%s]'
315 fmt = '-%0' + width_dh +'d [%s]'
316 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
316 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
317 if len(ents) > 1:
317 if len(ents) > 1:
318 return ents
318 return ents
319 return []
319 return []
320
320
321 if event.symbol.startswith('--'):
321 if event.symbol.startswith('--'):
322 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
322 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
323
323
324 # Expand ~ in path and normalize directory separators.
324 # Expand ~ in path and normalize directory separators.
325 relpath, tilde_expand, tilde_val = expand_user(relpath)
325 relpath, tilde_expand, tilde_val = expand_user(relpath)
326 relpath = relpath.replace('\\','/')
326 relpath = relpath.replace('\\','/')
327
327
328 found = []
328 found = []
329 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
329 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
330 if os.path.isdir(f)]:
330 if os.path.isdir(f)]:
331 if ' ' in d:
331 if ' ' in d:
332 # we don't want to deal with any of that, complex code
332 # we don't want to deal with any of that, complex code
333 # for this is elsewhere
333 # for this is elsewhere
334 raise TryNext
334 raise TryNext
335
335
336 found.append(d)
336 found.append(d)
337
337
338 if not found:
338 if not found:
339 if os.path.isdir(relpath):
339 if os.path.isdir(relpath):
340 return [compress_user(relpath, tilde_expand, tilde_val)]
340 return [compress_user(relpath, tilde_expand, tilde_val)]
341
341
342 # if no completions so far, try bookmarks
342 # if no completions so far, try bookmarks
343 bks = self.db.get('bookmarks',{})
343 bks = self.db.get('bookmarks',{})
344 bkmatches = [s for s in bks if s.startswith(event.symbol)]
344 bkmatches = [s for s in bks if s.startswith(event.symbol)]
345 if bkmatches:
345 if bkmatches:
346 return bkmatches
346 return bkmatches
347
347
348 raise TryNext
348 raise TryNext
349
349
350 return [compress_user(p, tilde_expand, tilde_val) for p in found]
350 return [compress_user(p, tilde_expand, tilde_val) for p in found]
351
351
352 def reset_completer(self, event):
352 def reset_completer(self, event):
353 "A completer for %reset magic"
353 "A completer for %reset magic"
354 return '-f -s in out array dhist'.split()
354 return '-f -s in out array dhist'.split()
@@ -1,1024 +1,1024 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 json
14 import json
15 import sys
15 import sys
16 import traceback
16 import traceback
17 import warnings
17 import warnings
18 from io import StringIO
18 from io import StringIO
19
19
20 from decorator import decorator
20 from decorator import decorator
21
21
22 from traitlets.config.configurable import Configurable
22 from traitlets.config.configurable import Configurable
23 from IPython.core.getipython import get_ipython
23 from .getipython import get_ipython
24 from IPython.utils.sentinel import Sentinel
24 from ..utils.sentinel import Sentinel
25 from IPython.utils.dir2 import get_real_method
25 from ..utils.dir2 import get_real_method
26 from IPython.lib import pretty
26 from ..lib import pretty
27 from traitlets import (
27 from traitlets import (
28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
29 ForwardDeclaredInstance,
29 ForwardDeclaredInstance,
30 default, observe,
30 default, observe,
31 )
31 )
32
32
33
33
34 class DisplayFormatter(Configurable):
34 class DisplayFormatter(Configurable):
35
35
36 active_types = List(Unicode(),
36 active_types = List(Unicode(),
37 help="""List of currently active mime-types to display.
37 help="""List of currently active mime-types to display.
38 You can use this to set a white-list for formats to display.
38 You can use this to set a white-list for formats to display.
39
39
40 Most users will not need to change this value.
40 Most users will not need to change this value.
41 """).tag(config=True)
41 """).tag(config=True)
42
42
43 @default('active_types')
43 @default('active_types')
44 def _active_types_default(self):
44 def _active_types_default(self):
45 return self.format_types
45 return self.format_types
46
46
47 @observe('active_types')
47 @observe('active_types')
48 def _active_types_changed(self, change):
48 def _active_types_changed(self, change):
49 for key, formatter in self.formatters.items():
49 for key, formatter in self.formatters.items():
50 if key in change['new']:
50 if key in change['new']:
51 formatter.enabled = True
51 formatter.enabled = True
52 else:
52 else:
53 formatter.enabled = False
53 formatter.enabled = False
54
54
55 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
55 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
56 @default('ipython_display_formatter')
56 @default('ipython_display_formatter')
57 def _default_formatter(self):
57 def _default_formatter(self):
58 return IPythonDisplayFormatter(parent=self)
58 return IPythonDisplayFormatter(parent=self)
59
59
60 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
60 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
61 @default('mimebundle_formatter')
61 @default('mimebundle_formatter')
62 def _default_mime_formatter(self):
62 def _default_mime_formatter(self):
63 return MimeBundleFormatter(parent=self)
63 return MimeBundleFormatter(parent=self)
64
64
65 # A dict of formatter whose keys are format types (MIME types) and whose
65 # A dict of formatter whose keys are format types (MIME types) and whose
66 # values are subclasses of BaseFormatter.
66 # values are subclasses of BaseFormatter.
67 formatters = Dict()
67 formatters = Dict()
68 @default('formatters')
68 @default('formatters')
69 def _formatters_default(self):
69 def _formatters_default(self):
70 """Activate the default formatters."""
70 """Activate the default formatters."""
71 formatter_classes = [
71 formatter_classes = [
72 PlainTextFormatter,
72 PlainTextFormatter,
73 HTMLFormatter,
73 HTMLFormatter,
74 MarkdownFormatter,
74 MarkdownFormatter,
75 SVGFormatter,
75 SVGFormatter,
76 PNGFormatter,
76 PNGFormatter,
77 PDFFormatter,
77 PDFFormatter,
78 JPEGFormatter,
78 JPEGFormatter,
79 LatexFormatter,
79 LatexFormatter,
80 JSONFormatter,
80 JSONFormatter,
81 JavascriptFormatter
81 JavascriptFormatter
82 ]
82 ]
83 d = {}
83 d = {}
84 for cls in formatter_classes:
84 for cls in formatter_classes:
85 f = cls(parent=self)
85 f = cls(parent=self)
86 d[f.format_type] = f
86 d[f.format_type] = f
87 return d
87 return d
88
88
89 def format(self, obj, include=None, exclude=None):
89 def format(self, obj, include=None, exclude=None):
90 """Return a format data dict for an object.
90 """Return a format data dict for an object.
91
91
92 By default all format types will be computed.
92 By default all format types will be computed.
93
93
94 The following MIME types are usually implemented:
94 The following MIME types are usually implemented:
95
95
96 * text/plain
96 * text/plain
97 * text/html
97 * text/html
98 * text/markdown
98 * text/markdown
99 * text/latex
99 * text/latex
100 * application/json
100 * application/json
101 * application/javascript
101 * application/javascript
102 * application/pdf
102 * application/pdf
103 * image/png
103 * image/png
104 * image/jpeg
104 * image/jpeg
105 * image/svg+xml
105 * image/svg+xml
106
106
107 Parameters
107 Parameters
108 ----------
108 ----------
109 obj : object
109 obj : object
110 The Python object whose format data will be computed.
110 The Python object whose format data will be computed.
111 include : list, tuple or set; optional
111 include : list, tuple or set; optional
112 A list of format type strings (MIME types) to include in the
112 A list of format type strings (MIME types) to include in the
113 format data dict. If this is set *only* the format types included
113 format data dict. If this is set *only* the format types included
114 in this list will be computed.
114 in this list will be computed.
115 exclude : list, tuple or set; optional
115 exclude : list, tuple or set; optional
116 A list of format type string (MIME types) to exclude in the format
116 A list of format type string (MIME types) to exclude in the format
117 data dict. If this is set all format types will be computed,
117 data dict. If this is set all format types will be computed,
118 except for those included in this argument.
118 except for those included in this argument.
119 Mimetypes present in exclude will take precedence over the ones in include
119 Mimetypes present in exclude will take precedence over the ones in include
120
120
121 Returns
121 Returns
122 -------
122 -------
123 (format_dict, metadata_dict) : tuple of two dicts
123 (format_dict, metadata_dict) : tuple of two dicts
124
124
125 format_dict is a dictionary of key/value pairs, one of each format that was
125 format_dict is a dictionary of key/value pairs, one of each format that was
126 generated for the object. The keys are the format types, which
126 generated for the object. The keys are the format types, which
127 will usually be MIME type strings and the values and JSON'able
127 will usually be MIME type strings and the values and JSON'able
128 data structure containing the raw data for the representation in
128 data structure containing the raw data for the representation in
129 that format.
129 that format.
130
130
131 metadata_dict is a dictionary of metadata about each mime-type output.
131 metadata_dict is a dictionary of metadata about each mime-type output.
132 Its keys will be a strict subset of the keys in format_dict.
132 Its keys will be a strict subset of the keys in format_dict.
133
133
134 Notes
134 Notes
135 -----
135 -----
136
136
137 If an object implement `_repr_mimebundle_` as well as various
137 If an object implement `_repr_mimebundle_` as well as various
138 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
138 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
139 precedence and the corresponding `_repr_*_` for this mimetype will
139 precedence and the corresponding `_repr_*_` for this mimetype will
140 not be called.
140 not be called.
141
141
142 """
142 """
143 format_dict = {}
143 format_dict = {}
144 md_dict = {}
144 md_dict = {}
145
145
146 if self.ipython_display_formatter(obj):
146 if self.ipython_display_formatter(obj):
147 # object handled itself, don't proceed
147 # object handled itself, don't proceed
148 return {}, {}
148 return {}, {}
149
149
150 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
150 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
151
151
152 if format_dict or md_dict:
152 if format_dict or md_dict:
153 if include:
153 if include:
154 format_dict = {k:v for k,v in format_dict.items() if k in include}
154 format_dict = {k:v for k,v in format_dict.items() if k in include}
155 md_dict = {k:v for k,v in md_dict.items() if k in include}
155 md_dict = {k:v for k,v in md_dict.items() if k in include}
156 if exclude:
156 if exclude:
157 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
157 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
158 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
158 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
159
159
160 for format_type, formatter in self.formatters.items():
160 for format_type, formatter in self.formatters.items():
161 if format_type in format_dict:
161 if format_type in format_dict:
162 # already got it from mimebundle, maybe don't render again.
162 # already got it from mimebundle, maybe don't render again.
163 # exception: manually registered per-mime renderer
163 # exception: manually registered per-mime renderer
164 # check priority:
164 # check priority:
165 # 1. user-registered per-mime formatter
165 # 1. user-registered per-mime formatter
166 # 2. mime-bundle (user-registered or repr method)
166 # 2. mime-bundle (user-registered or repr method)
167 # 3. default per-mime formatter (e.g. repr method)
167 # 3. default per-mime formatter (e.g. repr method)
168 try:
168 try:
169 formatter.lookup(obj)
169 formatter.lookup(obj)
170 except KeyError:
170 except KeyError:
171 # no special formatter, use mime-bundle-provided value
171 # no special formatter, use mime-bundle-provided value
172 continue
172 continue
173 if include and format_type not in include:
173 if include and format_type not in include:
174 continue
174 continue
175 if exclude and format_type in exclude:
175 if exclude and format_type in exclude:
176 continue
176 continue
177
177
178 md = None
178 md = None
179 try:
179 try:
180 data = formatter(obj)
180 data = formatter(obj)
181 except:
181 except:
182 # FIXME: log the exception
182 # FIXME: log the exception
183 raise
183 raise
184
184
185 # formatters can return raw data or (data, metadata)
185 # formatters can return raw data or (data, metadata)
186 if isinstance(data, tuple) and len(data) == 2:
186 if isinstance(data, tuple) and len(data) == 2:
187 data, md = data
187 data, md = data
188
188
189 if data is not None:
189 if data is not None:
190 format_dict[format_type] = data
190 format_dict[format_type] = data
191 if md is not None:
191 if md is not None:
192 md_dict[format_type] = md
192 md_dict[format_type] = md
193 return format_dict, md_dict
193 return format_dict, md_dict
194
194
195 @property
195 @property
196 def format_types(self):
196 def format_types(self):
197 """Return the format types (MIME types) of the active formatters."""
197 """Return the format types (MIME types) of the active formatters."""
198 return list(self.formatters.keys())
198 return list(self.formatters.keys())
199
199
200
200
201 #-----------------------------------------------------------------------------
201 #-----------------------------------------------------------------------------
202 # Formatters for specific format types (text, html, svg, etc.)
202 # Formatters for specific format types (text, html, svg, etc.)
203 #-----------------------------------------------------------------------------
203 #-----------------------------------------------------------------------------
204
204
205
205
206 def _safe_repr(obj):
206 def _safe_repr(obj):
207 """Try to return a repr of an object
207 """Try to return a repr of an object
208
208
209 always returns a string, at least.
209 always returns a string, at least.
210 """
210 """
211 try:
211 try:
212 return repr(obj)
212 return repr(obj)
213 except Exception as e:
213 except Exception as e:
214 return "un-repr-able object (%r)" % e
214 return "un-repr-able object (%r)" % e
215
215
216
216
217 class FormatterWarning(UserWarning):
217 class FormatterWarning(UserWarning):
218 """Warning class for errors in formatters"""
218 """Warning class for errors in formatters"""
219
219
220 @decorator
220 @decorator
221 def catch_format_error(method, self, *args, **kwargs):
221 def catch_format_error(method, self, *args, **kwargs):
222 """show traceback on failed format call"""
222 """show traceback on failed format call"""
223 try:
223 try:
224 r = method(self, *args, **kwargs)
224 r = method(self, *args, **kwargs)
225 except NotImplementedError:
225 except NotImplementedError:
226 # don't warn on NotImplementedErrors
226 # don't warn on NotImplementedErrors
227 return self._check_return(None, args[0])
227 return self._check_return(None, args[0])
228 except Exception:
228 except Exception:
229 exc_info = sys.exc_info()
229 exc_info = sys.exc_info()
230 ip = get_ipython()
230 ip = get_ipython()
231 if ip is not None:
231 if ip is not None:
232 ip.showtraceback(exc_info)
232 ip.showtraceback(exc_info)
233 else:
233 else:
234 traceback.print_exception(*exc_info)
234 traceback.print_exception(*exc_info)
235 return self._check_return(None, args[0])
235 return self._check_return(None, args[0])
236 return self._check_return(r, args[0])
236 return self._check_return(r, args[0])
237
237
238
238
239 class FormatterABC(metaclass=abc.ABCMeta):
239 class FormatterABC(metaclass=abc.ABCMeta):
240 """ Abstract base class for Formatters.
240 """ Abstract base class for Formatters.
241
241
242 A formatter is a callable class that is responsible for computing the
242 A formatter is a callable class that is responsible for computing the
243 raw format data for a particular format type (MIME type). For example,
243 raw format data for a particular format type (MIME type). For example,
244 an HTML formatter would have a format type of `text/html` and would return
244 an HTML formatter would have a format type of `text/html` and would return
245 the HTML representation of the object when called.
245 the HTML representation of the object when called.
246 """
246 """
247
247
248 # The format type of the data returned, usually a MIME type.
248 # The format type of the data returned, usually a MIME type.
249 format_type = 'text/plain'
249 format_type = 'text/plain'
250
250
251 # Is the formatter enabled...
251 # Is the formatter enabled...
252 enabled = True
252 enabled = True
253
253
254 @abc.abstractmethod
254 @abc.abstractmethod
255 def __call__(self, obj):
255 def __call__(self, obj):
256 """Return a JSON'able representation of the object.
256 """Return a JSON'able representation of the object.
257
257
258 If the object cannot be formatted by this formatter,
258 If the object cannot be formatted by this formatter,
259 warn and return None.
259 warn and return None.
260 """
260 """
261 return repr(obj)
261 return repr(obj)
262
262
263
263
264 def _mod_name_key(typ):
264 def _mod_name_key(typ):
265 """Return a (__module__, __name__) tuple for a type.
265 """Return a (__module__, __name__) tuple for a type.
266
266
267 Used as key in Formatter.deferred_printers.
267 Used as key in Formatter.deferred_printers.
268 """
268 """
269 module = getattr(typ, '__module__', None)
269 module = getattr(typ, '__module__', None)
270 name = getattr(typ, '__name__', None)
270 name = getattr(typ, '__name__', None)
271 return (module, name)
271 return (module, name)
272
272
273
273
274 def _get_type(obj):
274 def _get_type(obj):
275 """Return the type of an instance (old and new-style)"""
275 """Return the type of an instance (old and new-style)"""
276 return getattr(obj, '__class__', None) or type(obj)
276 return getattr(obj, '__class__', None) or type(obj)
277
277
278
278
279 _raise_key_error = Sentinel('_raise_key_error', __name__,
279 _raise_key_error = Sentinel('_raise_key_error', __name__,
280 """
280 """
281 Special value to raise a KeyError
281 Special value to raise a KeyError
282
282
283 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
283 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
284 """)
284 """)
285
285
286
286
287 class BaseFormatter(Configurable):
287 class BaseFormatter(Configurable):
288 """A base formatter class that is configurable.
288 """A base formatter class that is configurable.
289
289
290 This formatter should usually be used as the base class of all formatters.
290 This formatter should usually be used as the base class of all formatters.
291 It is a traited :class:`Configurable` class and includes an extensible
291 It is a traited :class:`Configurable` class and includes an extensible
292 API for users to determine how their objects are formatted. The following
292 API for users to determine how their objects are formatted. The following
293 logic is used to find a function to format an given object.
293 logic is used to find a function to format an given object.
294
294
295 1. The object is introspected to see if it has a method with the name
295 1. The object is introspected to see if it has a method with the name
296 :attr:`print_method`. If is does, that object is passed to that method
296 :attr:`print_method`. If is does, that object is passed to that method
297 for formatting.
297 for formatting.
298 2. If no print method is found, three internal dictionaries are consulted
298 2. If no print method is found, three internal dictionaries are consulted
299 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
299 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
300 and :attr:`deferred_printers`.
300 and :attr:`deferred_printers`.
301
301
302 Users should use these dictionaries to register functions that will be
302 Users should use these dictionaries to register functions that will be
303 used to compute the format data for their objects (if those objects don't
303 used to compute the format data for their objects (if those objects don't
304 have the special print methods). The easiest way of using these
304 have the special print methods). The easiest way of using these
305 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
305 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
306 methods.
306 methods.
307
307
308 If no function/callable is found to compute the format data, ``None`` is
308 If no function/callable is found to compute the format data, ``None`` is
309 returned and this format type is not used.
309 returned and this format type is not used.
310 """
310 """
311
311
312 format_type = Unicode('text/plain')
312 format_type = Unicode('text/plain')
313 _return_type = str
313 _return_type = str
314
314
315 enabled = Bool(True).tag(config=True)
315 enabled = Bool(True).tag(config=True)
316
316
317 print_method = ObjectName('__repr__')
317 print_method = ObjectName('__repr__')
318
318
319 # The singleton printers.
319 # The singleton printers.
320 # Maps the IDs of the builtin singleton objects to the format functions.
320 # Maps the IDs of the builtin singleton objects to the format functions.
321 singleton_printers = Dict().tag(config=True)
321 singleton_printers = Dict().tag(config=True)
322
322
323 # The type-specific printers.
323 # The type-specific printers.
324 # Map type objects to the format functions.
324 # Map type objects to the format functions.
325 type_printers = Dict().tag(config=True)
325 type_printers = Dict().tag(config=True)
326
326
327 # The deferred-import type-specific printers.
327 # The deferred-import type-specific printers.
328 # Map (modulename, classname) pairs to the format functions.
328 # Map (modulename, classname) pairs to the format functions.
329 deferred_printers = Dict().tag(config=True)
329 deferred_printers = Dict().tag(config=True)
330
330
331 @catch_format_error
331 @catch_format_error
332 def __call__(self, obj):
332 def __call__(self, obj):
333 """Compute the format for an object."""
333 """Compute the format for an object."""
334 if self.enabled:
334 if self.enabled:
335 # lookup registered printer
335 # lookup registered printer
336 try:
336 try:
337 printer = self.lookup(obj)
337 printer = self.lookup(obj)
338 except KeyError:
338 except KeyError:
339 pass
339 pass
340 else:
340 else:
341 return printer(obj)
341 return printer(obj)
342 # Finally look for special method names
342 # Finally look for special method names
343 method = get_real_method(obj, self.print_method)
343 method = get_real_method(obj, self.print_method)
344 if method is not None:
344 if method is not None:
345 return method()
345 return method()
346 return None
346 return None
347 else:
347 else:
348 return None
348 return None
349
349
350 def __contains__(self, typ):
350 def __contains__(self, typ):
351 """map in to lookup_by_type"""
351 """map in to lookup_by_type"""
352 try:
352 try:
353 self.lookup_by_type(typ)
353 self.lookup_by_type(typ)
354 except KeyError:
354 except KeyError:
355 return False
355 return False
356 else:
356 else:
357 return True
357 return True
358
358
359 def _check_return(self, r, obj):
359 def _check_return(self, r, obj):
360 """Check that a return value is appropriate
360 """Check that a return value is appropriate
361
361
362 Return the value if so, None otherwise, warning if invalid.
362 Return the value if so, None otherwise, warning if invalid.
363 """
363 """
364 if r is None or isinstance(r, self._return_type) or \
364 if r is None or isinstance(r, self._return_type) or \
365 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
365 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
366 return r
366 return r
367 else:
367 else:
368 warnings.warn(
368 warnings.warn(
369 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
369 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
370 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
370 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
371 FormatterWarning
371 FormatterWarning
372 )
372 )
373
373
374 def lookup(self, obj):
374 def lookup(self, obj):
375 """Look up the formatter for a given instance.
375 """Look up the formatter for a given instance.
376
376
377 Parameters
377 Parameters
378 ----------
378 ----------
379 obj : object instance
379 obj : object instance
380
380
381 Returns
381 Returns
382 -------
382 -------
383 f : callable
383 f : callable
384 The registered formatting callable for the type.
384 The registered formatting callable for the type.
385
385
386 Raises
386 Raises
387 ------
387 ------
388 KeyError if the type has not been registered.
388 KeyError if the type has not been registered.
389 """
389 """
390 # look for singleton first
390 # look for singleton first
391 obj_id = id(obj)
391 obj_id = id(obj)
392 if obj_id in self.singleton_printers:
392 if obj_id in self.singleton_printers:
393 return self.singleton_printers[obj_id]
393 return self.singleton_printers[obj_id]
394 # then lookup by type
394 # then lookup by type
395 return self.lookup_by_type(_get_type(obj))
395 return self.lookup_by_type(_get_type(obj))
396
396
397 def lookup_by_type(self, typ):
397 def lookup_by_type(self, typ):
398 """Look up the registered formatter for a type.
398 """Look up the registered formatter for a type.
399
399
400 Parameters
400 Parameters
401 ----------
401 ----------
402 typ : type or '__module__.__name__' string for a type
402 typ : type or '__module__.__name__' string for a type
403
403
404 Returns
404 Returns
405 -------
405 -------
406 f : callable
406 f : callable
407 The registered formatting callable for the type.
407 The registered formatting callable for the type.
408
408
409 Raises
409 Raises
410 ------
410 ------
411 KeyError if the type has not been registered.
411 KeyError if the type has not been registered.
412 """
412 """
413 if isinstance(typ, str):
413 if isinstance(typ, str):
414 typ_key = tuple(typ.rsplit('.',1))
414 typ_key = tuple(typ.rsplit('.',1))
415 if typ_key not in self.deferred_printers:
415 if typ_key not in self.deferred_printers:
416 # We may have it cached in the type map. We will have to
416 # We may have it cached in the type map. We will have to
417 # iterate over all of the types to check.
417 # iterate over all of the types to check.
418 for cls in self.type_printers:
418 for cls in self.type_printers:
419 if _mod_name_key(cls) == typ_key:
419 if _mod_name_key(cls) == typ_key:
420 return self.type_printers[cls]
420 return self.type_printers[cls]
421 else:
421 else:
422 return self.deferred_printers[typ_key]
422 return self.deferred_printers[typ_key]
423 else:
423 else:
424 for cls in pretty._get_mro(typ):
424 for cls in pretty._get_mro(typ):
425 if cls in self.type_printers or self._in_deferred_types(cls):
425 if cls in self.type_printers or self._in_deferred_types(cls):
426 return self.type_printers[cls]
426 return self.type_printers[cls]
427
427
428 # If we have reached here, the lookup failed.
428 # If we have reached here, the lookup failed.
429 raise KeyError("No registered printer for {0!r}".format(typ))
429 raise KeyError("No registered printer for {0!r}".format(typ))
430
430
431 def for_type(self, typ, func=None):
431 def for_type(self, typ, func=None):
432 """Add a format function for a given type.
432 """Add a format function for a given type.
433
433
434 Parameters
434 Parameters
435 -----------
435 -----------
436 typ : type or '__module__.__name__' string for a type
436 typ : type or '__module__.__name__' string for a type
437 The class of the object that will be formatted using `func`.
437 The class of the object that will be formatted using `func`.
438 func : callable
438 func : callable
439 A callable for computing the format data.
439 A callable for computing the format data.
440 `func` will be called with the object to be formatted,
440 `func` will be called with the object to be formatted,
441 and will return the raw data in this formatter's format.
441 and will return the raw data in this formatter's format.
442 Subclasses may use a different call signature for the
442 Subclasses may use a different call signature for the
443 `func` argument.
443 `func` argument.
444
444
445 If `func` is None or not specified, there will be no change,
445 If `func` is None or not specified, there will be no change,
446 only returning the current value.
446 only returning the current value.
447
447
448 Returns
448 Returns
449 -------
449 -------
450 oldfunc : callable
450 oldfunc : callable
451 The currently registered callable.
451 The currently registered callable.
452 If you are registering a new formatter,
452 If you are registering a new formatter,
453 this will be the previous value (to enable restoring later).
453 this will be the previous value (to enable restoring later).
454 """
454 """
455 # if string given, interpret as 'pkg.module.class_name'
455 # if string given, interpret as 'pkg.module.class_name'
456 if isinstance(typ, str):
456 if isinstance(typ, str):
457 type_module, type_name = typ.rsplit('.', 1)
457 type_module, type_name = typ.rsplit('.', 1)
458 return self.for_type_by_name(type_module, type_name, func)
458 return self.for_type_by_name(type_module, type_name, func)
459
459
460 try:
460 try:
461 oldfunc = self.lookup_by_type(typ)
461 oldfunc = self.lookup_by_type(typ)
462 except KeyError:
462 except KeyError:
463 oldfunc = None
463 oldfunc = None
464
464
465 if func is not None:
465 if func is not None:
466 self.type_printers[typ] = func
466 self.type_printers[typ] = func
467
467
468 return oldfunc
468 return oldfunc
469
469
470 def for_type_by_name(self, type_module, type_name, func=None):
470 def for_type_by_name(self, type_module, type_name, func=None):
471 """Add a format function for a type specified by the full dotted
471 """Add a format function for a type specified by the full dotted
472 module and name of the type, rather than the type of the object.
472 module and name of the type, rather than the type of the object.
473
473
474 Parameters
474 Parameters
475 ----------
475 ----------
476 type_module : str
476 type_module : str
477 The full dotted name of the module the type is defined in, like
477 The full dotted name of the module the type is defined in, like
478 ``numpy``.
478 ``numpy``.
479 type_name : str
479 type_name : str
480 The name of the type (the class name), like ``dtype``
480 The name of the type (the class name), like ``dtype``
481 func : callable
481 func : callable
482 A callable for computing the format data.
482 A callable for computing the format data.
483 `func` will be called with the object to be formatted,
483 `func` will be called with the object to be formatted,
484 and will return the raw data in this formatter's format.
484 and will return the raw data in this formatter's format.
485 Subclasses may use a different call signature for the
485 Subclasses may use a different call signature for the
486 `func` argument.
486 `func` argument.
487
487
488 If `func` is None or unspecified, there will be no change,
488 If `func` is None or unspecified, there will be no change,
489 only returning the current value.
489 only returning the current value.
490
490
491 Returns
491 Returns
492 -------
492 -------
493 oldfunc : callable
493 oldfunc : callable
494 The currently registered callable.
494 The currently registered callable.
495 If you are registering a new formatter,
495 If you are registering a new formatter,
496 this will be the previous value (to enable restoring later).
496 this will be the previous value (to enable restoring later).
497 """
497 """
498 key = (type_module, type_name)
498 key = (type_module, type_name)
499
499
500 try:
500 try:
501 oldfunc = self.lookup_by_type("%s.%s" % key)
501 oldfunc = self.lookup_by_type("%s.%s" % key)
502 except KeyError:
502 except KeyError:
503 oldfunc = None
503 oldfunc = None
504
504
505 if func is not None:
505 if func is not None:
506 self.deferred_printers[key] = func
506 self.deferred_printers[key] = func
507 return oldfunc
507 return oldfunc
508
508
509 def pop(self, typ, default=_raise_key_error):
509 def pop(self, typ, default=_raise_key_error):
510 """Pop a formatter for the given type.
510 """Pop a formatter for the given type.
511
511
512 Parameters
512 Parameters
513 ----------
513 ----------
514 typ : type or '__module__.__name__' string for a type
514 typ : type or '__module__.__name__' string for a type
515 default : object
515 default : object
516 value to be returned if no formatter is registered for typ.
516 value to be returned if no formatter is registered for typ.
517
517
518 Returns
518 Returns
519 -------
519 -------
520 obj : object
520 obj : object
521 The last registered object for the type.
521 The last registered object for the type.
522
522
523 Raises
523 Raises
524 ------
524 ------
525 KeyError if the type is not registered and default is not specified.
525 KeyError if the type is not registered and default is not specified.
526 """
526 """
527
527
528 if isinstance(typ, str):
528 if isinstance(typ, str):
529 typ_key = tuple(typ.rsplit('.',1))
529 typ_key = tuple(typ.rsplit('.',1))
530 if typ_key not in self.deferred_printers:
530 if typ_key not in self.deferred_printers:
531 # We may have it cached in the type map. We will have to
531 # We may have it cached in the type map. We will have to
532 # iterate over all of the types to check.
532 # iterate over all of the types to check.
533 for cls in self.type_printers:
533 for cls in self.type_printers:
534 if _mod_name_key(cls) == typ_key:
534 if _mod_name_key(cls) == typ_key:
535 old = self.type_printers.pop(cls)
535 old = self.type_printers.pop(cls)
536 break
536 break
537 else:
537 else:
538 old = default
538 old = default
539 else:
539 else:
540 old = self.deferred_printers.pop(typ_key)
540 old = self.deferred_printers.pop(typ_key)
541 else:
541 else:
542 if typ in self.type_printers:
542 if typ in self.type_printers:
543 old = self.type_printers.pop(typ)
543 old = self.type_printers.pop(typ)
544 else:
544 else:
545 old = self.deferred_printers.pop(_mod_name_key(typ), default)
545 old = self.deferred_printers.pop(_mod_name_key(typ), default)
546 if old is _raise_key_error:
546 if old is _raise_key_error:
547 raise KeyError("No registered value for {0!r}".format(typ))
547 raise KeyError("No registered value for {0!r}".format(typ))
548 return old
548 return old
549
549
550 def _in_deferred_types(self, cls):
550 def _in_deferred_types(self, cls):
551 """
551 """
552 Check if the given class is specified in the deferred type registry.
552 Check if the given class is specified in the deferred type registry.
553
553
554 Successful matches will be moved to the regular type registry for future use.
554 Successful matches will be moved to the regular type registry for future use.
555 """
555 """
556 mod = getattr(cls, '__module__', None)
556 mod = getattr(cls, '__module__', None)
557 name = getattr(cls, '__name__', None)
557 name = getattr(cls, '__name__', None)
558 key = (mod, name)
558 key = (mod, name)
559 if key in self.deferred_printers:
559 if key in self.deferred_printers:
560 # Move the printer over to the regular registry.
560 # Move the printer over to the regular registry.
561 printer = self.deferred_printers.pop(key)
561 printer = self.deferred_printers.pop(key)
562 self.type_printers[cls] = printer
562 self.type_printers[cls] = printer
563 return True
563 return True
564 return False
564 return False
565
565
566
566
567 class PlainTextFormatter(BaseFormatter):
567 class PlainTextFormatter(BaseFormatter):
568 """The default pretty-printer.
568 """The default pretty-printer.
569
569
570 This uses :mod:`IPython.lib.pretty` to compute the format data of
570 This uses :mod:`IPython.lib.pretty` to compute the format data of
571 the object. If the object cannot be pretty printed, :func:`repr` is used.
571 the object. If the object cannot be pretty printed, :func:`repr` is used.
572 See the documentation of :mod:`IPython.lib.pretty` for details on
572 See the documentation of :mod:`IPython.lib.pretty` for details on
573 how to write pretty printers. Here is a simple example::
573 how to write pretty printers. Here is a simple example::
574
574
575 def dtype_pprinter(obj, p, cycle):
575 def dtype_pprinter(obj, p, cycle):
576 if cycle:
576 if cycle:
577 return p.text('dtype(...)')
577 return p.text('dtype(...)')
578 if hasattr(obj, 'fields'):
578 if hasattr(obj, 'fields'):
579 if obj.fields is None:
579 if obj.fields is None:
580 p.text(repr(obj))
580 p.text(repr(obj))
581 else:
581 else:
582 p.begin_group(7, 'dtype([')
582 p.begin_group(7, 'dtype([')
583 for i, field in enumerate(obj.descr):
583 for i, field in enumerate(obj.descr):
584 if i > 0:
584 if i > 0:
585 p.text(',')
585 p.text(',')
586 p.breakable()
586 p.breakable()
587 p.pretty(field)
587 p.pretty(field)
588 p.end_group(7, '])')
588 p.end_group(7, '])')
589 """
589 """
590
590
591 # The format type of data returned.
591 # The format type of data returned.
592 format_type = Unicode('text/plain')
592 format_type = Unicode('text/plain')
593
593
594 # This subclass ignores this attribute as it always need to return
594 # This subclass ignores this attribute as it always need to return
595 # something.
595 # something.
596 enabled = Bool(True).tag(config=False)
596 enabled = Bool(True).tag(config=False)
597
597
598 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
598 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
599 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
599 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
600
600
601 Set to 0 to disable truncation.
601 Set to 0 to disable truncation.
602 """
602 """
603 ).tag(config=True)
603 ).tag(config=True)
604
604
605 # Look for a _repr_pretty_ methods to use for pretty printing.
605 # Look for a _repr_pretty_ methods to use for pretty printing.
606 print_method = ObjectName('_repr_pretty_')
606 print_method = ObjectName('_repr_pretty_')
607
607
608 # Whether to pretty-print or not.
608 # Whether to pretty-print or not.
609 pprint = Bool(True).tag(config=True)
609 pprint = Bool(True).tag(config=True)
610
610
611 # Whether to be verbose or not.
611 # Whether to be verbose or not.
612 verbose = Bool(False).tag(config=True)
612 verbose = Bool(False).tag(config=True)
613
613
614 # The maximum width.
614 # The maximum width.
615 max_width = Integer(79).tag(config=True)
615 max_width = Integer(79).tag(config=True)
616
616
617 # The newline character.
617 # The newline character.
618 newline = Unicode('\n').tag(config=True)
618 newline = Unicode('\n').tag(config=True)
619
619
620 # format-string for pprinting floats
620 # format-string for pprinting floats
621 float_format = Unicode('%r')
621 float_format = Unicode('%r')
622 # setter for float precision, either int or direct format-string
622 # setter for float precision, either int or direct format-string
623 float_precision = CUnicode('').tag(config=True)
623 float_precision = CUnicode('').tag(config=True)
624
624
625 @observe('float_precision')
625 @observe('float_precision')
626 def _float_precision_changed(self, change):
626 def _float_precision_changed(self, change):
627 """float_precision changed, set float_format accordingly.
627 """float_precision changed, set float_format accordingly.
628
628
629 float_precision can be set by int or str.
629 float_precision can be set by int or str.
630 This will set float_format, after interpreting input.
630 This will set float_format, after interpreting input.
631 If numpy has been imported, numpy print precision will also be set.
631 If numpy has been imported, numpy print precision will also be set.
632
632
633 integer `n` sets format to '%.nf', otherwise, format set directly.
633 integer `n` sets format to '%.nf', otherwise, format set directly.
634
634
635 An empty string returns to defaults (repr for float, 8 for numpy).
635 An empty string returns to defaults (repr for float, 8 for numpy).
636
636
637 This parameter can be set via the '%precision' magic.
637 This parameter can be set via the '%precision' magic.
638 """
638 """
639
639
640 new = change['new']
640 new = change['new']
641 if '%' in new:
641 if '%' in new:
642 # got explicit format string
642 # got explicit format string
643 fmt = new
643 fmt = new
644 try:
644 try:
645 fmt%3.14159
645 fmt%3.14159
646 except Exception:
646 except Exception:
647 raise ValueError("Precision must be int or format string, not %r"%new)
647 raise ValueError("Precision must be int or format string, not %r"%new)
648 elif new:
648 elif new:
649 # otherwise, should be an int
649 # otherwise, should be an int
650 try:
650 try:
651 i = int(new)
651 i = int(new)
652 assert i >= 0
652 assert i >= 0
653 except ValueError:
653 except ValueError:
654 raise ValueError("Precision must be int or format string, not %r"%new)
654 raise ValueError("Precision must be int or format string, not %r"%new)
655 except AssertionError:
655 except AssertionError:
656 raise ValueError("int precision must be non-negative, not %r"%i)
656 raise ValueError("int precision must be non-negative, not %r"%i)
657
657
658 fmt = '%%.%if'%i
658 fmt = '%%.%if'%i
659 if 'numpy' in sys.modules:
659 if 'numpy' in sys.modules:
660 # set numpy precision if it has been imported
660 # set numpy precision if it has been imported
661 import numpy
661 import numpy
662 numpy.set_printoptions(precision=i)
662 numpy.set_printoptions(precision=i)
663 else:
663 else:
664 # default back to repr
664 # default back to repr
665 fmt = '%r'
665 fmt = '%r'
666 if 'numpy' in sys.modules:
666 if 'numpy' in sys.modules:
667 import numpy
667 import numpy
668 # numpy default is 8
668 # numpy default is 8
669 numpy.set_printoptions(precision=8)
669 numpy.set_printoptions(precision=8)
670 self.float_format = fmt
670 self.float_format = fmt
671
671
672 # Use the default pretty printers from IPython.lib.pretty.
672 # Use the default pretty printers from IPython.lib.pretty.
673 @default('singleton_printers')
673 @default('singleton_printers')
674 def _singleton_printers_default(self):
674 def _singleton_printers_default(self):
675 return pretty._singleton_pprinters.copy()
675 return pretty._singleton_pprinters.copy()
676
676
677 @default('type_printers')
677 @default('type_printers')
678 def _type_printers_default(self):
678 def _type_printers_default(self):
679 d = pretty._type_pprinters.copy()
679 d = pretty._type_pprinters.copy()
680 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
680 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
681 return d
681 return d
682
682
683 @default('deferred_printers')
683 @default('deferred_printers')
684 def _deferred_printers_default(self):
684 def _deferred_printers_default(self):
685 return pretty._deferred_type_pprinters.copy()
685 return pretty._deferred_type_pprinters.copy()
686
686
687 #### FormatterABC interface ####
687 #### FormatterABC interface ####
688
688
689 @catch_format_error
689 @catch_format_error
690 def __call__(self, obj):
690 def __call__(self, obj):
691 """Compute the pretty representation of the object."""
691 """Compute the pretty representation of the object."""
692 if not self.pprint:
692 if not self.pprint:
693 return repr(obj)
693 return repr(obj)
694 else:
694 else:
695 stream = StringIO()
695 stream = StringIO()
696 printer = pretty.RepresentationPrinter(stream, self.verbose,
696 printer = pretty.RepresentationPrinter(stream, self.verbose,
697 self.max_width, self.newline,
697 self.max_width, self.newline,
698 max_seq_length=self.max_seq_length,
698 max_seq_length=self.max_seq_length,
699 singleton_pprinters=self.singleton_printers,
699 singleton_pprinters=self.singleton_printers,
700 type_pprinters=self.type_printers,
700 type_pprinters=self.type_printers,
701 deferred_pprinters=self.deferred_printers)
701 deferred_pprinters=self.deferred_printers)
702 printer.pretty(obj)
702 printer.pretty(obj)
703 printer.flush()
703 printer.flush()
704 return stream.getvalue()
704 return stream.getvalue()
705
705
706
706
707 class HTMLFormatter(BaseFormatter):
707 class HTMLFormatter(BaseFormatter):
708 """An HTML formatter.
708 """An HTML formatter.
709
709
710 To define the callables that compute the HTML representation of your
710 To define the callables that compute the HTML representation of your
711 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
711 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
712 or :meth:`for_type_by_name` methods to register functions that handle
712 or :meth:`for_type_by_name` methods to register functions that handle
713 this.
713 this.
714
714
715 The return value of this formatter should be a valid HTML snippet that
715 The return value of this formatter should be a valid HTML snippet that
716 could be injected into an existing DOM. It should *not* include the
716 could be injected into an existing DOM. It should *not* include the
717 ```<html>`` or ```<body>`` tags.
717 ```<html>`` or ```<body>`` tags.
718 """
718 """
719 format_type = Unicode('text/html')
719 format_type = Unicode('text/html')
720
720
721 print_method = ObjectName('_repr_html_')
721 print_method = ObjectName('_repr_html_')
722
722
723
723
724 class MarkdownFormatter(BaseFormatter):
724 class MarkdownFormatter(BaseFormatter):
725 """A Markdown formatter.
725 """A Markdown formatter.
726
726
727 To define the callables that compute the Markdown representation of your
727 To define the callables that compute the Markdown representation of your
728 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
728 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
729 or :meth:`for_type_by_name` methods to register functions that handle
729 or :meth:`for_type_by_name` methods to register functions that handle
730 this.
730 this.
731
731
732 The return value of this formatter should be a valid Markdown.
732 The return value of this formatter should be a valid Markdown.
733 """
733 """
734 format_type = Unicode('text/markdown')
734 format_type = Unicode('text/markdown')
735
735
736 print_method = ObjectName('_repr_markdown_')
736 print_method = ObjectName('_repr_markdown_')
737
737
738 class SVGFormatter(BaseFormatter):
738 class SVGFormatter(BaseFormatter):
739 """An SVG formatter.
739 """An SVG formatter.
740
740
741 To define the callables that compute the SVG representation of your
741 To define the callables that compute the SVG representation of your
742 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
742 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
743 or :meth:`for_type_by_name` methods to register functions that handle
743 or :meth:`for_type_by_name` methods to register functions that handle
744 this.
744 this.
745
745
746 The return value of this formatter should be valid SVG enclosed in
746 The return value of this formatter should be valid SVG enclosed in
747 ```<svg>``` tags, that could be injected into an existing DOM. It should
747 ```<svg>``` tags, that could be injected into an existing DOM. It should
748 *not* include the ```<html>`` or ```<body>`` tags.
748 *not* include the ```<html>`` or ```<body>`` tags.
749 """
749 """
750 format_type = Unicode('image/svg+xml')
750 format_type = Unicode('image/svg+xml')
751
751
752 print_method = ObjectName('_repr_svg_')
752 print_method = ObjectName('_repr_svg_')
753
753
754
754
755 class PNGFormatter(BaseFormatter):
755 class PNGFormatter(BaseFormatter):
756 """A PNG formatter.
756 """A PNG formatter.
757
757
758 To define the callables that compute the PNG representation of your
758 To define the callables that compute the PNG representation of your
759 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
759 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
760 or :meth:`for_type_by_name` methods to register functions that handle
760 or :meth:`for_type_by_name` methods to register functions that handle
761 this.
761 this.
762
762
763 The return value of this formatter should be raw PNG data, *not*
763 The return value of this formatter should be raw PNG data, *not*
764 base64 encoded.
764 base64 encoded.
765 """
765 """
766 format_type = Unicode('image/png')
766 format_type = Unicode('image/png')
767
767
768 print_method = ObjectName('_repr_png_')
768 print_method = ObjectName('_repr_png_')
769
769
770 _return_type = (bytes, str)
770 _return_type = (bytes, str)
771
771
772
772
773 class JPEGFormatter(BaseFormatter):
773 class JPEGFormatter(BaseFormatter):
774 """A JPEG formatter.
774 """A JPEG formatter.
775
775
776 To define the callables that compute the JPEG representation of your
776 To define the callables that compute the JPEG representation of your
777 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
777 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
778 or :meth:`for_type_by_name` methods to register functions that handle
778 or :meth:`for_type_by_name` methods to register functions that handle
779 this.
779 this.
780
780
781 The return value of this formatter should be raw JPEG data, *not*
781 The return value of this formatter should be raw JPEG data, *not*
782 base64 encoded.
782 base64 encoded.
783 """
783 """
784 format_type = Unicode('image/jpeg')
784 format_type = Unicode('image/jpeg')
785
785
786 print_method = ObjectName('_repr_jpeg_')
786 print_method = ObjectName('_repr_jpeg_')
787
787
788 _return_type = (bytes, str)
788 _return_type = (bytes, str)
789
789
790
790
791 class LatexFormatter(BaseFormatter):
791 class LatexFormatter(BaseFormatter):
792 """A LaTeX formatter.
792 """A LaTeX formatter.
793
793
794 To define the callables that compute the LaTeX representation of your
794 To define the callables that compute the LaTeX representation of your
795 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
795 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
796 or :meth:`for_type_by_name` methods to register functions that handle
796 or :meth:`for_type_by_name` methods to register functions that handle
797 this.
797 this.
798
798
799 The return value of this formatter should be a valid LaTeX equation,
799 The return value of this formatter should be a valid LaTeX equation,
800 enclosed in either ```$```, ```$$``` or another LaTeX equation
800 enclosed in either ```$```, ```$$``` or another LaTeX equation
801 environment.
801 environment.
802 """
802 """
803 format_type = Unicode('text/latex')
803 format_type = Unicode('text/latex')
804
804
805 print_method = ObjectName('_repr_latex_')
805 print_method = ObjectName('_repr_latex_')
806
806
807
807
808 class JSONFormatter(BaseFormatter):
808 class JSONFormatter(BaseFormatter):
809 """A JSON string formatter.
809 """A JSON string formatter.
810
810
811 To define the callables that compute the JSONable representation of
811 To define the callables that compute the JSONable representation of
812 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
812 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
813 or :meth:`for_type_by_name` methods to register functions that handle
813 or :meth:`for_type_by_name` methods to register functions that handle
814 this.
814 this.
815
815
816 The return value of this formatter should be a JSONable list or dict.
816 The return value of this formatter should be a JSONable list or dict.
817 JSON scalars (None, number, string) are not allowed, only dict or list containers.
817 JSON scalars (None, number, string) are not allowed, only dict or list containers.
818 """
818 """
819 format_type = Unicode('application/json')
819 format_type = Unicode('application/json')
820 _return_type = (list, dict)
820 _return_type = (list, dict)
821
821
822 print_method = ObjectName('_repr_json_')
822 print_method = ObjectName('_repr_json_')
823
823
824 def _check_return(self, r, obj):
824 def _check_return(self, r, obj):
825 """Check that a return value is appropriate
825 """Check that a return value is appropriate
826
826
827 Return the value if so, None otherwise, warning if invalid.
827 Return the value if so, None otherwise, warning if invalid.
828 """
828 """
829 if r is None:
829 if r is None:
830 return
830 return
831 md = None
831 md = None
832 if isinstance(r, tuple):
832 if isinstance(r, tuple):
833 # unpack data, metadata tuple for type checking on first element
833 # unpack data, metadata tuple for type checking on first element
834 r, md = r
834 r, md = r
835
835
836 # handle deprecated JSON-as-string form from IPython < 3
836 # handle deprecated JSON-as-string form from IPython < 3
837 if isinstance(r, str):
837 if isinstance(r, str):
838 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
838 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
839 FormatterWarning)
839 FormatterWarning)
840 r = json.loads(r)
840 r = json.loads(r)
841
841
842 if md is not None:
842 if md is not None:
843 # put the tuple back together
843 # put the tuple back together
844 r = (r, md)
844 r = (r, md)
845 return super(JSONFormatter, self)._check_return(r, obj)
845 return super(JSONFormatter, self)._check_return(r, obj)
846
846
847
847
848 class JavascriptFormatter(BaseFormatter):
848 class JavascriptFormatter(BaseFormatter):
849 """A Javascript formatter.
849 """A Javascript formatter.
850
850
851 To define the callables that compute the Javascript representation of
851 To define the callables that compute the Javascript representation of
852 your objects, define a :meth:`_repr_javascript_` method or use the
852 your objects, define a :meth:`_repr_javascript_` method or use the
853 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
853 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
854 that handle this.
854 that handle this.
855
855
856 The return value of this formatter should be valid Javascript code and
856 The return value of this formatter should be valid Javascript code and
857 should *not* be enclosed in ```<script>``` tags.
857 should *not* be enclosed in ```<script>``` tags.
858 """
858 """
859 format_type = Unicode('application/javascript')
859 format_type = Unicode('application/javascript')
860
860
861 print_method = ObjectName('_repr_javascript_')
861 print_method = ObjectName('_repr_javascript_')
862
862
863
863
864 class PDFFormatter(BaseFormatter):
864 class PDFFormatter(BaseFormatter):
865 """A PDF formatter.
865 """A PDF formatter.
866
866
867 To define the callables that compute the PDF representation of your
867 To define the callables that compute the PDF representation of your
868 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
868 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
869 or :meth:`for_type_by_name` methods to register functions that handle
869 or :meth:`for_type_by_name` methods to register functions that handle
870 this.
870 this.
871
871
872 The return value of this formatter should be raw PDF data, *not*
872 The return value of this formatter should be raw PDF data, *not*
873 base64 encoded.
873 base64 encoded.
874 """
874 """
875 format_type = Unicode('application/pdf')
875 format_type = Unicode('application/pdf')
876
876
877 print_method = ObjectName('_repr_pdf_')
877 print_method = ObjectName('_repr_pdf_')
878
878
879 _return_type = (bytes, str)
879 _return_type = (bytes, str)
880
880
881 class IPythonDisplayFormatter(BaseFormatter):
881 class IPythonDisplayFormatter(BaseFormatter):
882 """An escape-hatch Formatter for objects that know how to display themselves.
882 """An escape-hatch Formatter for objects that know how to display themselves.
883
883
884 To define the callables that compute the representation of your
884 To define the callables that compute the representation of your
885 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
885 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
886 or :meth:`for_type_by_name` methods to register functions that handle
886 or :meth:`for_type_by_name` methods to register functions that handle
887 this. Unlike mime-type displays, this method should not return anything,
887 this. Unlike mime-type displays, this method should not return anything,
888 instead calling any appropriate display methods itself.
888 instead calling any appropriate display methods itself.
889
889
890 This display formatter has highest priority.
890 This display formatter has highest priority.
891 If it fires, no other display formatter will be called.
891 If it fires, no other display formatter will be called.
892
892
893 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
893 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
894 without registering a new Formatter.
894 without registering a new Formatter.
895
895
896 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
896 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
897 so `_ipython_display_` should only be used for objects that require unusual
897 so `_ipython_display_` should only be used for objects that require unusual
898 display patterns, such as multiple display calls.
898 display patterns, such as multiple display calls.
899 """
899 """
900 print_method = ObjectName('_ipython_display_')
900 print_method = ObjectName('_ipython_display_')
901 _return_type = (type(None), bool)
901 _return_type = (type(None), bool)
902
902
903 @catch_format_error
903 @catch_format_error
904 def __call__(self, obj):
904 def __call__(self, obj):
905 """Compute the format for an object."""
905 """Compute the format for an object."""
906 if self.enabled:
906 if self.enabled:
907 # lookup registered printer
907 # lookup registered printer
908 try:
908 try:
909 printer = self.lookup(obj)
909 printer = self.lookup(obj)
910 except KeyError:
910 except KeyError:
911 pass
911 pass
912 else:
912 else:
913 printer(obj)
913 printer(obj)
914 return True
914 return True
915 # Finally look for special method names
915 # Finally look for special method names
916 method = get_real_method(obj, self.print_method)
916 method = get_real_method(obj, self.print_method)
917 if method is not None:
917 if method is not None:
918 method()
918 method()
919 return True
919 return True
920
920
921
921
922 class MimeBundleFormatter(BaseFormatter):
922 class MimeBundleFormatter(BaseFormatter):
923 """A Formatter for arbitrary mime-types.
923 """A Formatter for arbitrary mime-types.
924
924
925 Unlike other `_repr_<mimetype>_` methods,
925 Unlike other `_repr_<mimetype>_` methods,
926 `_repr_mimebundle_` should return mime-bundle data,
926 `_repr_mimebundle_` should return mime-bundle data,
927 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
927 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
928 Any mime-type is valid.
928 Any mime-type is valid.
929
929
930 To define the callables that compute the mime-bundle representation of your
930 To define the callables that compute the mime-bundle representation of your
931 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
931 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
932 or :meth:`for_type_by_name` methods to register functions that handle
932 or :meth:`for_type_by_name` methods to register functions that handle
933 this.
933 this.
934
934
935 .. versionadded:: 6.1
935 .. versionadded:: 6.1
936 """
936 """
937 print_method = ObjectName('_repr_mimebundle_')
937 print_method = ObjectName('_repr_mimebundle_')
938 _return_type = dict
938 _return_type = dict
939
939
940 def _check_return(self, r, obj):
940 def _check_return(self, r, obj):
941 r = super(MimeBundleFormatter, self)._check_return(r, obj)
941 r = super(MimeBundleFormatter, self)._check_return(r, obj)
942 # always return (data, metadata):
942 # always return (data, metadata):
943 if r is None:
943 if r is None:
944 return {}, {}
944 return {}, {}
945 if not isinstance(r, tuple):
945 if not isinstance(r, tuple):
946 return r, {}
946 return r, {}
947 return r
947 return r
948
948
949 @catch_format_error
949 @catch_format_error
950 def __call__(self, obj, include=None, exclude=None):
950 def __call__(self, obj, include=None, exclude=None):
951 """Compute the format for an object.
951 """Compute the format for an object.
952
952
953 Identical to parent's method but we pass extra parameters to the method.
953 Identical to parent's method but we pass extra parameters to the method.
954
954
955 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
955 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
956 particular `include` and `exclude`.
956 particular `include` and `exclude`.
957 """
957 """
958 if self.enabled:
958 if self.enabled:
959 # lookup registered printer
959 # lookup registered printer
960 try:
960 try:
961 printer = self.lookup(obj)
961 printer = self.lookup(obj)
962 except KeyError:
962 except KeyError:
963 pass
963 pass
964 else:
964 else:
965 return printer(obj)
965 return printer(obj)
966 # Finally look for special method names
966 # Finally look for special method names
967 method = get_real_method(obj, self.print_method)
967 method = get_real_method(obj, self.print_method)
968
968
969 if method is not None:
969 if method is not None:
970 return method(include=include, exclude=exclude)
970 return method(include=include, exclude=exclude)
971 return None
971 return None
972 else:
972 else:
973 return None
973 return None
974
974
975
975
976 FormatterABC.register(BaseFormatter)
976 FormatterABC.register(BaseFormatter)
977 FormatterABC.register(PlainTextFormatter)
977 FormatterABC.register(PlainTextFormatter)
978 FormatterABC.register(HTMLFormatter)
978 FormatterABC.register(HTMLFormatter)
979 FormatterABC.register(MarkdownFormatter)
979 FormatterABC.register(MarkdownFormatter)
980 FormatterABC.register(SVGFormatter)
980 FormatterABC.register(SVGFormatter)
981 FormatterABC.register(PNGFormatter)
981 FormatterABC.register(PNGFormatter)
982 FormatterABC.register(PDFFormatter)
982 FormatterABC.register(PDFFormatter)
983 FormatterABC.register(JPEGFormatter)
983 FormatterABC.register(JPEGFormatter)
984 FormatterABC.register(LatexFormatter)
984 FormatterABC.register(LatexFormatter)
985 FormatterABC.register(JSONFormatter)
985 FormatterABC.register(JSONFormatter)
986 FormatterABC.register(JavascriptFormatter)
986 FormatterABC.register(JavascriptFormatter)
987 FormatterABC.register(IPythonDisplayFormatter)
987 FormatterABC.register(IPythonDisplayFormatter)
988 FormatterABC.register(MimeBundleFormatter)
988 FormatterABC.register(MimeBundleFormatter)
989
989
990
990
991 def format_display_data(obj, include=None, exclude=None):
991 def format_display_data(obj, include=None, exclude=None):
992 """Return a format data dict for an object.
992 """Return a format data dict for an object.
993
993
994 By default all format types will be computed.
994 By default all format types will be computed.
995
995
996 Parameters
996 Parameters
997 ----------
997 ----------
998 obj : object
998 obj : object
999 The Python object whose format data will be computed.
999 The Python object whose format data will be computed.
1000
1000
1001 Returns
1001 Returns
1002 -------
1002 -------
1003 format_dict : dict
1003 format_dict : dict
1004 A dictionary of key/value pairs, one or each format that was
1004 A dictionary of key/value pairs, one or each format that was
1005 generated for the object. The keys are the format types, which
1005 generated for the object. The keys are the format types, which
1006 will usually be MIME type strings and the values and JSON'able
1006 will usually be MIME type strings and the values and JSON'able
1007 data structure containing the raw data for the representation in
1007 data structure containing the raw data for the representation in
1008 that format.
1008 that format.
1009 include : list or tuple, optional
1009 include : list or tuple, optional
1010 A list of format type strings (MIME types) to include in the
1010 A list of format type strings (MIME types) to include in the
1011 format data dict. If this is set *only* the format types included
1011 format data dict. If this is set *only* the format types included
1012 in this list will be computed.
1012 in this list will be computed.
1013 exclude : list or tuple, optional
1013 exclude : list or tuple, optional
1014 A list of format type string (MIME types) to exclude in the format
1014 A list of format type string (MIME types) to exclude in the format
1015 data dict. If this is set all format types will be computed,
1015 data dict. If this is set all format types will be computed,
1016 except for those included in this argument.
1016 except for those included in this argument.
1017 """
1017 """
1018 from IPython.core.interactiveshell import InteractiveShell
1018 from .interactiveshell import InteractiveShell
1019
1019
1020 return InteractiveShell.instance().display_formatter.format(
1020 return InteractiveShell.instance().display_formatter.format(
1021 obj,
1021 obj,
1022 include,
1022 include,
1023 exclude
1023 exclude
1024 )
1024 )
@@ -1,161 +1,161 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
7
8 import os
8 import os
9 import sqlite3
9 import sqlite3
10
10
11 from traitlets.config.application import Application
11 from traitlets.config.application import Application
12 from IPython.core.application import BaseIPythonApplication
12 from .application import BaseIPythonApplication
13 from traitlets import Bool, Int, Dict
13 from traitlets import Bool, Int, Dict
14 from IPython.utils.io import ask_yes_no
14 from ..utils.io import ask_yes_no
15
15
16 trim_hist_help = """Trim the IPython history database to the last 1000 entries.
16 trim_hist_help = """Trim the IPython history database to the last 1000 entries.
17
17
18 This actually copies the last 1000 entries to a new database, and then replaces
18 This actually copies the last 1000 entries to a new database, and then replaces
19 the old file with the new. Use the `--keep=` argument to specify a number
19 the old file with the new. Use the `--keep=` argument to specify a number
20 other than 1000.
20 other than 1000.
21 """
21 """
22
22
23 clear_hist_help = """Clear the IPython history database, deleting all entries.
23 clear_hist_help = """Clear the IPython history database, deleting all entries.
24
24
25 Because this is a destructive operation, IPython will prompt the user if they
25 Because this is a destructive operation, IPython will prompt the user if they
26 really want to do this. Passing a `-f` flag will force clearing without a
26 really want to do this. Passing a `-f` flag will force clearing without a
27 prompt.
27 prompt.
28
28
29 This is an handy alias to `ipython history trim --keep=0`
29 This is an handy alias to `ipython history trim --keep=0`
30 """
30 """
31
31
32
32
33 class HistoryTrim(BaseIPythonApplication):
33 class HistoryTrim(BaseIPythonApplication):
34 description = trim_hist_help
34 description = trim_hist_help
35
35
36 backup = Bool(False,
36 backup = Bool(False,
37 help="Keep the old history file as history.sqlite.<N>"
37 help="Keep the old history file as history.sqlite.<N>"
38 ).tag(config=True)
38 ).tag(config=True)
39
39
40 keep = Int(1000,
40 keep = Int(1000,
41 help="Number of recent lines to keep in the database."
41 help="Number of recent lines to keep in the database."
42 ).tag(config=True)
42 ).tag(config=True)
43
43
44 flags = Dict(dict(
44 flags = Dict(dict(
45 backup = ({'HistoryTrim' : {'backup' : True}},
45 backup = ({'HistoryTrim' : {'backup' : True}},
46 backup.help
46 backup.help
47 )
47 )
48 ))
48 ))
49
49
50 aliases=Dict(dict(
50 aliases=Dict(dict(
51 keep = 'HistoryTrim.keep'
51 keep = 'HistoryTrim.keep'
52 ))
52 ))
53
53
54 def start(self):
54 def start(self):
55 profile_dir = self.profile_dir.location
55 profile_dir = self.profile_dir.location
56 hist_file = os.path.join(profile_dir, 'history.sqlite')
56 hist_file = os.path.join(profile_dir, 'history.sqlite')
57 con = sqlite3.connect(hist_file)
57 con = sqlite3.connect(hist_file)
58
58
59 # Grab the recent history from the current database.
59 # Grab the recent history from the current database.
60 inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
60 inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
61 'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
61 'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
62 if len(inputs) <= self.keep:
62 if len(inputs) <= self.keep:
63 print("There are already at most %d entries in the history database." % self.keep)
63 print("There are already at most %d entries in the history database." % self.keep)
64 print("Not doing anything. Use --keep= argument to keep fewer entries")
64 print("Not doing anything. Use --keep= argument to keep fewer entries")
65 return
65 return
66
66
67 print("Trimming history to the most recent %d entries." % self.keep)
67 print("Trimming history to the most recent %d entries." % self.keep)
68
68
69 inputs.pop() # Remove the extra element we got to check the length.
69 inputs.pop() # Remove the extra element we got to check the length.
70 inputs.reverse()
70 inputs.reverse()
71 if inputs:
71 if inputs:
72 first_session = inputs[0][0]
72 first_session = inputs[0][0]
73 outputs = list(con.execute('SELECT session, line, output FROM '
73 outputs = list(con.execute('SELECT session, line, output FROM '
74 'output_history WHERE session >= ?', (first_session,)))
74 'output_history WHERE session >= ?', (first_session,)))
75 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
75 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
76 'sessions WHERE session >= ?', (first_session,)))
76 'sessions WHERE session >= ?', (first_session,)))
77 con.close()
77 con.close()
78
78
79 # Create the new history database.
79 # Create the new history database.
80 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new')
80 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new')
81 i = 0
81 i = 0
82 while os.path.exists(new_hist_file):
82 while os.path.exists(new_hist_file):
83 # Make sure we don't interfere with an existing file.
83 # Make sure we don't interfere with an existing file.
84 i += 1
84 i += 1
85 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new'+str(i))
85 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new'+str(i))
86 new_db = sqlite3.connect(new_hist_file)
86 new_db = sqlite3.connect(new_hist_file)
87 new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
87 new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
88 primary key autoincrement, start timestamp,
88 primary key autoincrement, start timestamp,
89 end timestamp, num_cmds integer, remark text)""")
89 end timestamp, num_cmds integer, remark text)""")
90 new_db.execute("""CREATE TABLE IF NOT EXISTS history
90 new_db.execute("""CREATE TABLE IF NOT EXISTS history
91 (session integer, line integer, source text, source_raw text,
91 (session integer, line integer, source text, source_raw text,
92 PRIMARY KEY (session, line))""")
92 PRIMARY KEY (session, line))""")
93 new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
93 new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
94 (session integer, line integer, output text,
94 (session integer, line integer, output text,
95 PRIMARY KEY (session, line))""")
95 PRIMARY KEY (session, line))""")
96 new_db.commit()
96 new_db.commit()
97
97
98
98
99 if inputs:
99 if inputs:
100 with new_db:
100 with new_db:
101 # Add the recent history into the new database.
101 # Add the recent history into the new database.
102 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
102 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
103 new_db.executemany('insert into history values (?,?,?,?)', inputs)
103 new_db.executemany('insert into history values (?,?,?,?)', inputs)
104 new_db.executemany('insert into output_history values (?,?,?)', outputs)
104 new_db.executemany('insert into output_history values (?,?,?)', outputs)
105 new_db.close()
105 new_db.close()
106
106
107 if self.backup:
107 if self.backup:
108 i = 1
108 i = 1
109 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
109 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
110 while os.path.exists(backup_hist_file):
110 while os.path.exists(backup_hist_file):
111 i += 1
111 i += 1
112 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
112 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
113 os.rename(hist_file, backup_hist_file)
113 os.rename(hist_file, backup_hist_file)
114 print("Backed up longer history file to", backup_hist_file)
114 print("Backed up longer history file to", backup_hist_file)
115 else:
115 else:
116 os.remove(hist_file)
116 os.remove(hist_file)
117
117
118 os.rename(new_hist_file, hist_file)
118 os.rename(new_hist_file, hist_file)
119
119
120 class HistoryClear(HistoryTrim):
120 class HistoryClear(HistoryTrim):
121 description = clear_hist_help
121 description = clear_hist_help
122 keep = Int(0,
122 keep = Int(0,
123 help="Number of recent lines to keep in the database.")
123 help="Number of recent lines to keep in the database.")
124
124
125 force = Bool(False,
125 force = Bool(False,
126 help="Don't prompt user for confirmation"
126 help="Don't prompt user for confirmation"
127 ).tag(config=True)
127 ).tag(config=True)
128
128
129 flags = Dict(dict(
129 flags = Dict(dict(
130 force = ({'HistoryClear' : {'force' : True}},
130 force = ({'HistoryClear' : {'force' : True}},
131 force.help),
131 force.help),
132 f = ({'HistoryTrim' : {'force' : True}},
132 f = ({'HistoryTrim' : {'force' : True}},
133 force.help
133 force.help
134 )
134 )
135 ))
135 ))
136 aliases = Dict()
136 aliases = Dict()
137
137
138 def start(self):
138 def start(self):
139 if self.force or ask_yes_no("Really delete all ipython history? ",
139 if self.force or ask_yes_no("Really delete all ipython history? ",
140 default="no", interrupt="no"):
140 default="no", interrupt="no"):
141 HistoryTrim.start(self)
141 HistoryTrim.start(self)
142
142
143 class HistoryApp(Application):
143 class HistoryApp(Application):
144 name = u'ipython-history'
144 name = u'ipython-history'
145 description = "Manage the IPython history database."
145 description = "Manage the IPython history database."
146
146
147 subcommands = Dict(dict(
147 subcommands = Dict(dict(
148 trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
148 trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
149 clear = (HistoryClear, HistoryClear.description.splitlines()[0]),
149 clear = (HistoryClear, HistoryClear.description.splitlines()[0]),
150 ))
150 ))
151
151
152 def start(self):
152 def start(self):
153 if self.subapp is None:
153 if self.subapp is None:
154 print("No subcommand specified. Must specify one of: %s" % \
154 print("No subcommand specified. Must specify one of: %s" % \
155 (self.subcommands.keys()))
155 (self.subcommands.keys()))
156 print()
156 print()
157 self.print_description()
157 self.print_description()
158 self.print_subcommands()
158 self.print_subcommands()
159 self.exit(1)
159 self.exit(1)
160 else:
160 else:
161 return self.subapp.start()
161 return self.subapp.start()
@@ -1,229 +1,229 b''
1 """Hooks for IPython.
1 """Hooks for IPython.
2
2
3 In Python, it is possible to overwrite any method of any object if you really
3 In Python, it is possible to overwrite any method of any object if you really
4 want to. But IPython exposes a few 'hooks', methods which are *designed* to
4 want to. But IPython exposes a few 'hooks', methods which are *designed* to
5 be overwritten by users for customization purposes. This module defines the
5 be overwritten by users for customization purposes. This module defines the
6 default versions of all such hooks, which get used by IPython if not
6 default versions of all such hooks, which get used by IPython if not
7 overridden by the user.
7 overridden by the user.
8
8
9 Hooks are simple functions, but they should be declared with ``self`` as their
9 Hooks are simple functions, but they should be declared with ``self`` as their
10 first argument, because when activated they are registered into IPython as
10 first argument, because when activated they are registered into IPython as
11 instance methods. The self argument will be the IPython running instance
11 instance methods. The self argument will be the IPython running instance
12 itself, so hooks have full access to the entire IPython object.
12 itself, so hooks have full access to the entire IPython object.
13
13
14 If you wish to define a new hook and activate it, you can make an :doc:`extension
14 If you wish to define a new hook and activate it, you can make an :doc:`extension
15 </config/extensions/index>` or a :ref:`startup script <startup_files>`. For
15 </config/extensions/index>` or a :ref:`startup script <startup_files>`. For
16 example, you could use a startup file like this::
16 example, you could use a startup file like this::
17
17
18 import os
18 import os
19
19
20 def calljed(self,filename, linenum):
20 def calljed(self,filename, linenum):
21 "My editor hook calls the jed editor directly."
21 "My editor hook calls the jed editor directly."
22 print "Calling my own editor, jed ..."
22 print "Calling my own editor, jed ..."
23 if os.system('jed +%d %s' % (linenum,filename)) != 0:
23 if os.system('jed +%d %s' % (linenum,filename)) != 0:
24 raise TryNext()
24 raise TryNext()
25
25
26 def load_ipython_extension(ip):
26 def load_ipython_extension(ip):
27 ip.set_hook('editor', calljed)
27 ip.set_hook('editor', calljed)
28
28
29 """
29 """
30
30
31 #*****************************************************************************
31 #*****************************************************************************
32 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
32 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
33 #
33 #
34 # Distributed under the terms of the BSD License. The full license is in
34 # Distributed under the terms of the BSD License. The full license is in
35 # the file COPYING, distributed as part of this software.
35 # the file COPYING, distributed as part of this software.
36 #*****************************************************************************
36 #*****************************************************************************
37
37
38 import os
38 import os
39 import subprocess
39 import subprocess
40 import warnings
40 import warnings
41 import sys
41 import sys
42
42
43 from IPython.core.error import TryNext
43 from .error import TryNext
44
44
45 # List here all the default hooks. For now it's just the editor functions
45 # List here all the default hooks. For now it's just the editor functions
46 # but over time we'll move here all the public API for user-accessible things.
46 # but over time we'll move here all the public API for user-accessible things.
47
47
48 __all__ = ['editor', 'synchronize_with_editor',
48 __all__ = ['editor', 'synchronize_with_editor',
49 'shutdown_hook', 'late_startup_hook',
49 'shutdown_hook', 'late_startup_hook',
50 'show_in_pager','pre_prompt_hook',
50 'show_in_pager','pre_prompt_hook',
51 'pre_run_code_hook', 'clipboard_get']
51 'pre_run_code_hook', 'clipboard_get']
52
52
53 deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event",
53 deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event",
54 'late_startup_hook': "a callback for the 'shell_initialized' event",
54 'late_startup_hook': "a callback for the 'shell_initialized' event",
55 'shutdown_hook': "the atexit module",
55 'shutdown_hook': "the atexit module",
56 }
56 }
57
57
58 def editor(self, filename, linenum=None, wait=True):
58 def editor(self, filename, linenum=None, wait=True):
59 """Open the default editor at the given filename and linenumber.
59 """Open the default editor at the given filename and linenumber.
60
60
61 This is IPython's default editor hook, you can use it as an example to
61 This is IPython's default editor hook, you can use it as an example to
62 write your own modified one. To set your own editor function as the
62 write your own modified one. To set your own editor function as the
63 new editor hook, call ip.set_hook('editor',yourfunc)."""
63 new editor hook, call ip.set_hook('editor',yourfunc)."""
64
64
65 # IPython configures a default editor at startup by reading $EDITOR from
65 # IPython configures a default editor at startup by reading $EDITOR from
66 # the environment, and falling back on vi (unix) or notepad (win32).
66 # the environment, and falling back on vi (unix) or notepad (win32).
67 editor = self.editor
67 editor = self.editor
68
68
69 # marker for at which line to open the file (for existing objects)
69 # marker for at which line to open the file (for existing objects)
70 if linenum is None or editor=='notepad':
70 if linenum is None or editor=='notepad':
71 linemark = ''
71 linemark = ''
72 else:
72 else:
73 linemark = '+%d' % int(linenum)
73 linemark = '+%d' % int(linenum)
74
74
75 # Enclose in quotes if necessary and legal
75 # Enclose in quotes if necessary and legal
76 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
76 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
77 editor = '"%s"' % editor
77 editor = '"%s"' % editor
78
78
79 # Call the actual editor
79 # Call the actual editor
80 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
80 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
81 shell=True)
81 shell=True)
82 if wait and proc.wait() != 0:
82 if wait and proc.wait() != 0:
83 raise TryNext()
83 raise TryNext()
84
84
85 import tempfile
85 import tempfile
86 from IPython.utils.decorators import undoc
86 from ..utils.decorators import undoc
87
87
88 @undoc
88 @undoc
89 def fix_error_editor(self,filename,linenum,column,msg):
89 def fix_error_editor(self,filename,linenum,column,msg):
90 """DEPRECATED
90 """DEPRECATED
91
91
92 Open the editor at the given filename, linenumber, column and
92 Open the editor at the given filename, linenumber, column and
93 show an error message. This is used for correcting syntax errors.
93 show an error message. This is used for correcting syntax errors.
94 The current implementation only has special support for the VIM editor,
94 The current implementation only has special support for the VIM editor,
95 and falls back on the 'editor' hook if VIM is not used.
95 and falls back on the 'editor' hook if VIM is not used.
96
96
97 Call ip.set_hook('fix_error_editor',yourfunc) to use your own function,
97 Call ip.set_hook('fix_error_editor',yourfunc) to use your own function,
98 """
98 """
99
99
100 warnings.warn("""
100 warnings.warn("""
101 `fix_error_editor` is deprecated as of IPython 6.0 and will be removed
101 `fix_error_editor` is deprecated as of IPython 6.0 and will be removed
102 in future versions. It appears to be used only for automatically fixing syntax
102 in future versions. It appears to be used only for automatically fixing syntax
103 error that has been broken for a few years and has thus been removed. If you
103 error that has been broken for a few years and has thus been removed. If you
104 happened to use this function and still need it please make your voice heard on
104 happened to use this function and still need it please make your voice heard on
105 the mailing list ipython-dev@python.org , or on the GitHub Issue tracker:
105 the mailing list ipython-dev@python.org , or on the GitHub Issue tracker:
106 https://github.com/ipython/ipython/issues/9649 """, UserWarning)
106 https://github.com/ipython/ipython/issues/9649 """, UserWarning)
107
107
108 def vim_quickfix_file():
108 def vim_quickfix_file():
109 t = tempfile.NamedTemporaryFile()
109 t = tempfile.NamedTemporaryFile()
110 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
110 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
111 t.flush()
111 t.flush()
112 return t
112 return t
113 if os.path.basename(self.editor) != 'vim':
113 if os.path.basename(self.editor) != 'vim':
114 self.hooks.editor(filename,linenum)
114 self.hooks.editor(filename,linenum)
115 return
115 return
116 t = vim_quickfix_file()
116 t = vim_quickfix_file()
117 try:
117 try:
118 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
118 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
119 raise TryNext()
119 raise TryNext()
120 finally:
120 finally:
121 t.close()
121 t.close()
122
122
123
123
124 def synchronize_with_editor(self, filename, linenum, column):
124 def synchronize_with_editor(self, filename, linenum, column):
125 pass
125 pass
126
126
127
127
128 class CommandChainDispatcher:
128 class CommandChainDispatcher:
129 """ Dispatch calls to a chain of commands until some func can handle it
129 """ Dispatch calls to a chain of commands until some func can handle it
130
130
131 Usage: instantiate, execute "add" to add commands (with optional
131 Usage: instantiate, execute "add" to add commands (with optional
132 priority), execute normally via f() calling mechanism.
132 priority), execute normally via f() calling mechanism.
133
133
134 """
134 """
135 def __init__(self,commands=None):
135 def __init__(self,commands=None):
136 if commands is None:
136 if commands is None:
137 self.chain = []
137 self.chain = []
138 else:
138 else:
139 self.chain = commands
139 self.chain = commands
140
140
141
141
142 def __call__(self,*args, **kw):
142 def __call__(self,*args, **kw):
143 """ Command chain is called just like normal func.
143 """ Command chain is called just like normal func.
144
144
145 This will call all funcs in chain with the same args as were given to
145 This will call all funcs in chain with the same args as were given to
146 this function, and return the result of first func that didn't raise
146 this function, and return the result of first func that didn't raise
147 TryNext"""
147 TryNext"""
148 last_exc = TryNext()
148 last_exc = TryNext()
149 for prio,cmd in self.chain:
149 for prio,cmd in self.chain:
150 #print "prio",prio,"cmd",cmd #dbg
150 #print "prio",prio,"cmd",cmd #dbg
151 try:
151 try:
152 return cmd(*args, **kw)
152 return cmd(*args, **kw)
153 except TryNext as exc:
153 except TryNext as exc:
154 last_exc = exc
154 last_exc = exc
155 # if no function will accept it, raise TryNext up to the caller
155 # if no function will accept it, raise TryNext up to the caller
156 raise last_exc
156 raise last_exc
157
157
158 def __str__(self):
158 def __str__(self):
159 return str(self.chain)
159 return str(self.chain)
160
160
161 def add(self, func, priority=0):
161 def add(self, func, priority=0):
162 """ Add a func to the cmd chain with given priority """
162 """ Add a func to the cmd chain with given priority """
163 self.chain.append((priority, func))
163 self.chain.append((priority, func))
164 self.chain.sort(key=lambda x: x[0])
164 self.chain.sort(key=lambda x: x[0])
165
165
166 def __iter__(self):
166 def __iter__(self):
167 """ Return all objects in chain.
167 """ Return all objects in chain.
168
168
169 Handy if the objects are not callable.
169 Handy if the objects are not callable.
170 """
170 """
171 return iter(self.chain)
171 return iter(self.chain)
172
172
173
173
174 def shutdown_hook(self):
174 def shutdown_hook(self):
175 """ default shutdown hook
175 """ default shutdown hook
176
176
177 Typically, shutdown hooks should raise TryNext so all shutdown ops are done
177 Typically, shutdown hooks should raise TryNext so all shutdown ops are done
178 """
178 """
179
179
180 #print "default shutdown hook ok" # dbg
180 #print "default shutdown hook ok" # dbg
181 return
181 return
182
182
183
183
184 def late_startup_hook(self):
184 def late_startup_hook(self):
185 """ Executed after ipython has been constructed and configured
185 """ Executed after ipython has been constructed and configured
186
186
187 """
187 """
188 #print "default startup hook ok" # dbg
188 #print "default startup hook ok" # dbg
189
189
190
190
191 def show_in_pager(self, data, start, screen_lines):
191 def show_in_pager(self, data, start, screen_lines):
192 """ Run a string through pager """
192 """ Run a string through pager """
193 # raising TryNext here will use the default paging functionality
193 # raising TryNext here will use the default paging functionality
194 raise TryNext
194 raise TryNext
195
195
196
196
197 def pre_prompt_hook(self):
197 def pre_prompt_hook(self):
198 """ Run before displaying the next prompt
198 """ Run before displaying the next prompt
199
199
200 Use this e.g. to display output from asynchronous operations (in order
200 Use this e.g. to display output from asynchronous operations (in order
201 to not mess up text entry)
201 to not mess up text entry)
202 """
202 """
203
203
204 return None
204 return None
205
205
206
206
207 def pre_run_code_hook(self):
207 def pre_run_code_hook(self):
208 """ Executed before running the (prefiltered) code in IPython """
208 """ Executed before running the (prefiltered) code in IPython """
209 return None
209 return None
210
210
211
211
212 def clipboard_get(self):
212 def clipboard_get(self):
213 """ Get text from the clipboard.
213 """ Get text from the clipboard.
214 """
214 """
215 from IPython.lib.clipboard import (
215 from ..lib.clipboard import (
216 osx_clipboard_get, tkinter_clipboard_get,
216 osx_clipboard_get, tkinter_clipboard_get,
217 win32_clipboard_get
217 win32_clipboard_get
218 )
218 )
219 if sys.platform == 'win32':
219 if sys.platform == 'win32':
220 chain = [win32_clipboard_get, tkinter_clipboard_get]
220 chain = [win32_clipboard_get, tkinter_clipboard_get]
221 elif sys.platform == 'darwin':
221 elif sys.platform == 'darwin':
222 chain = [osx_clipboard_get, tkinter_clipboard_get]
222 chain = [osx_clipboard_get, tkinter_clipboard_get]
223 else:
223 else:
224 chain = [tkinter_clipboard_get]
224 chain = [tkinter_clipboard_get]
225 dispatcher = CommandChainDispatcher()
225 dispatcher = CommandChainDispatcher()
226 for func in chain:
226 for func in chain:
227 dispatcher.add(func)
227 dispatcher.add(func)
228 text = dispatcher()
228 text = dispatcher()
229 return text
229 return text
@@ -1,703 +1,703 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Magic functions for InteractiveShell.
2 """Magic functions for InteractiveShell.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2008 The IPython Development Team
8 # Copyright (C) 2008 The IPython Development Team
9
9
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 import os
14 import os
15 import re
15 import re
16 import sys
16 import sys
17 from getopt import getopt, GetoptError
17 from getopt import getopt, GetoptError
18
18
19 from traitlets.config.configurable import Configurable
19 from traitlets.config.configurable import Configurable
20 from IPython.core import oinspect
20 from . import oinspect
21 from IPython.core.error import UsageError
21 from .error import UsageError
22 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
22 from .inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
23 from decorator import decorator
23 from decorator import decorator
24 from IPython.utils.ipstruct import Struct
24 from ..utils.ipstruct import Struct
25 from IPython.utils.process import arg_split
25 from ..utils.process import arg_split
26 from IPython.utils.text import dedent
26 from ..utils.text import dedent
27 from traitlets import Bool, Dict, Instance, observe
27 from traitlets import Bool, Dict, Instance, observe
28 from logging import error
28 from logging import error
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Globals
31 # Globals
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34 # A dict we'll use for each class that has magics, used as temporary storage to
34 # A dict we'll use for each class that has magics, used as temporary storage to
35 # pass information between the @line/cell_magic method decorators and the
35 # pass information between the @line/cell_magic method decorators and the
36 # @magics_class class decorator, because the method decorators have no
36 # @magics_class class decorator, because the method decorators have no
37 # access to the class when they run. See for more details:
37 # access to the class when they run. See for more details:
38 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
38 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
39
39
40 magics = dict(line={}, cell={})
40 magics = dict(line={}, cell={})
41
41
42 magic_kinds = ('line', 'cell')
42 magic_kinds = ('line', 'cell')
43 magic_spec = ('line', 'cell', 'line_cell')
43 magic_spec = ('line', 'cell', 'line_cell')
44 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
44 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Utility classes and functions
47 # Utility classes and functions
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 class Bunch: pass
50 class Bunch: pass
51
51
52
52
53 def on_off(tag):
53 def on_off(tag):
54 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
54 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
55 return ['OFF','ON'][tag]
55 return ['OFF','ON'][tag]
56
56
57
57
58 def compress_dhist(dh):
58 def compress_dhist(dh):
59 """Compress a directory history into a new one with at most 20 entries.
59 """Compress a directory history into a new one with at most 20 entries.
60
60
61 Return a new list made from the first and last 10 elements of dhist after
61 Return a new list made from the first and last 10 elements of dhist after
62 removal of duplicates.
62 removal of duplicates.
63 """
63 """
64 head, tail = dh[:-10], dh[-10:]
64 head, tail = dh[:-10], dh[-10:]
65
65
66 newhead = []
66 newhead = []
67 done = set()
67 done = set()
68 for h in head:
68 for h in head:
69 if h in done:
69 if h in done:
70 continue
70 continue
71 newhead.append(h)
71 newhead.append(h)
72 done.add(h)
72 done.add(h)
73
73
74 return newhead + tail
74 return newhead + tail
75
75
76
76
77 def needs_local_scope(func):
77 def needs_local_scope(func):
78 """Decorator to mark magic functions which need to local scope to run."""
78 """Decorator to mark magic functions which need to local scope to run."""
79 func.needs_local_scope = True
79 func.needs_local_scope = True
80 return func
80 return func
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Class and method decorators for registering magics
83 # Class and method decorators for registering magics
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85
85
86 def magics_class(cls):
86 def magics_class(cls):
87 """Class decorator for all subclasses of the main Magics class.
87 """Class decorator for all subclasses of the main Magics class.
88
88
89 Any class that subclasses Magics *must* also apply this decorator, to
89 Any class that subclasses Magics *must* also apply this decorator, to
90 ensure that all the methods that have been decorated as line/cell magics
90 ensure that all the methods that have been decorated as line/cell magics
91 get correctly registered in the class instance. This is necessary because
91 get correctly registered in the class instance. This is necessary because
92 when method decorators run, the class does not exist yet, so they
92 when method decorators run, the class does not exist yet, so they
93 temporarily store their information into a module global. Application of
93 temporarily store their information into a module global. Application of
94 this class decorator copies that global data to the class instance and
94 this class decorator copies that global data to the class instance and
95 clears the global.
95 clears the global.
96
96
97 Obviously, this mechanism is not thread-safe, which means that the
97 Obviously, this mechanism is not thread-safe, which means that the
98 *creation* of subclasses of Magic should only be done in a single-thread
98 *creation* of subclasses of Magic should only be done in a single-thread
99 context. Instantiation of the classes has no restrictions. Given that
99 context. Instantiation of the classes has no restrictions. Given that
100 these classes are typically created at IPython startup time and before user
100 these classes are typically created at IPython startup time and before user
101 application code becomes active, in practice this should not pose any
101 application code becomes active, in practice this should not pose any
102 problems.
102 problems.
103 """
103 """
104 cls.registered = True
104 cls.registered = True
105 cls.magics = dict(line = magics['line'],
105 cls.magics = dict(line = magics['line'],
106 cell = magics['cell'])
106 cell = magics['cell'])
107 magics['line'] = {}
107 magics['line'] = {}
108 magics['cell'] = {}
108 magics['cell'] = {}
109 return cls
109 return cls
110
110
111
111
112 def record_magic(dct, magic_kind, magic_name, func):
112 def record_magic(dct, magic_kind, magic_name, func):
113 """Utility function to store a function as a magic of a specific kind.
113 """Utility function to store a function as a magic of a specific kind.
114
114
115 Parameters
115 Parameters
116 ----------
116 ----------
117 dct : dict
117 dct : dict
118 A dictionary with 'line' and 'cell' subdicts.
118 A dictionary with 'line' and 'cell' subdicts.
119
119
120 magic_kind : str
120 magic_kind : str
121 Kind of magic to be stored.
121 Kind of magic to be stored.
122
122
123 magic_name : str
123 magic_name : str
124 Key to store the magic as.
124 Key to store the magic as.
125
125
126 func : function
126 func : function
127 Callable object to store.
127 Callable object to store.
128 """
128 """
129 if magic_kind == 'line_cell':
129 if magic_kind == 'line_cell':
130 dct['line'][magic_name] = dct['cell'][magic_name] = func
130 dct['line'][magic_name] = dct['cell'][magic_name] = func
131 else:
131 else:
132 dct[magic_kind][magic_name] = func
132 dct[magic_kind][magic_name] = func
133
133
134
134
135 def validate_type(magic_kind):
135 def validate_type(magic_kind):
136 """Ensure that the given magic_kind is valid.
136 """Ensure that the given magic_kind is valid.
137
137
138 Check that the given magic_kind is one of the accepted spec types (stored
138 Check that the given magic_kind is one of the accepted spec types (stored
139 in the global `magic_spec`), raise ValueError otherwise.
139 in the global `magic_spec`), raise ValueError otherwise.
140 """
140 """
141 if magic_kind not in magic_spec:
141 if magic_kind not in magic_spec:
142 raise ValueError('magic_kind must be one of %s, %s given' %
142 raise ValueError('magic_kind must be one of %s, %s given' %
143 magic_kinds, magic_kind)
143 magic_kinds, magic_kind)
144
144
145
145
146 # The docstrings for the decorator below will be fairly similar for the two
146 # The docstrings for the decorator below will be fairly similar for the two
147 # types (method and function), so we generate them here once and reuse the
147 # types (method and function), so we generate them here once and reuse the
148 # templates below.
148 # templates below.
149 _docstring_template = \
149 _docstring_template = \
150 """Decorate the given {0} as {1} magic.
150 """Decorate the given {0} as {1} magic.
151
151
152 The decorator can be used with or without arguments, as follows.
152 The decorator can be used with or without arguments, as follows.
153
153
154 i) without arguments: it will create a {1} magic named as the {0} being
154 i) without arguments: it will create a {1} magic named as the {0} being
155 decorated::
155 decorated::
156
156
157 @deco
157 @deco
158 def foo(...)
158 def foo(...)
159
159
160 will create a {1} magic named `foo`.
160 will create a {1} magic named `foo`.
161
161
162 ii) with one string argument: which will be used as the actual name of the
162 ii) with one string argument: which will be used as the actual name of the
163 resulting magic::
163 resulting magic::
164
164
165 @deco('bar')
165 @deco('bar')
166 def foo(...)
166 def foo(...)
167
167
168 will create a {1} magic named `bar`.
168 will create a {1} magic named `bar`.
169
169
170 To register a class magic use ``Interactiveshell.register_magic(class or instance)``.
170 To register a class magic use ``Interactiveshell.register_magic(class or instance)``.
171 """
171 """
172
172
173 # These two are decorator factories. While they are conceptually very similar,
173 # These two are decorator factories. While they are conceptually very similar,
174 # there are enough differences in the details that it's simpler to have them
174 # there are enough differences in the details that it's simpler to have them
175 # written as completely standalone functions rather than trying to share code
175 # written as completely standalone functions rather than trying to share code
176 # and make a single one with convoluted logic.
176 # and make a single one with convoluted logic.
177
177
178 def _method_magic_marker(magic_kind):
178 def _method_magic_marker(magic_kind):
179 """Decorator factory for methods in Magics subclasses.
179 """Decorator factory for methods in Magics subclasses.
180 """
180 """
181
181
182 validate_type(magic_kind)
182 validate_type(magic_kind)
183
183
184 # This is a closure to capture the magic_kind. We could also use a class,
184 # This is a closure to capture the magic_kind. We could also use a class,
185 # but it's overkill for just that one bit of state.
185 # but it's overkill for just that one bit of state.
186 def magic_deco(arg):
186 def magic_deco(arg):
187 call = lambda f, *a, **k: f(*a, **k)
187 call = lambda f, *a, **k: f(*a, **k)
188
188
189 if callable(arg):
189 if callable(arg):
190 # "Naked" decorator call (just @foo, no args)
190 # "Naked" decorator call (just @foo, no args)
191 func = arg
191 func = arg
192 name = func.__name__
192 name = func.__name__
193 retval = decorator(call, func)
193 retval = decorator(call, func)
194 record_magic(magics, magic_kind, name, name)
194 record_magic(magics, magic_kind, name, name)
195 elif isinstance(arg, str):
195 elif isinstance(arg, str):
196 # Decorator called with arguments (@foo('bar'))
196 # Decorator called with arguments (@foo('bar'))
197 name = arg
197 name = arg
198 def mark(func, *a, **kw):
198 def mark(func, *a, **kw):
199 record_magic(magics, magic_kind, name, func.__name__)
199 record_magic(magics, magic_kind, name, func.__name__)
200 return decorator(call, func)
200 return decorator(call, func)
201 retval = mark
201 retval = mark
202 else:
202 else:
203 raise TypeError("Decorator can only be called with "
203 raise TypeError("Decorator can only be called with "
204 "string or function")
204 "string or function")
205 return retval
205 return retval
206
206
207 # Ensure the resulting decorator has a usable docstring
207 # Ensure the resulting decorator has a usable docstring
208 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
208 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
209 return magic_deco
209 return magic_deco
210
210
211
211
212 def _function_magic_marker(magic_kind):
212 def _function_magic_marker(magic_kind):
213 """Decorator factory for standalone functions.
213 """Decorator factory for standalone functions.
214 """
214 """
215 validate_type(magic_kind)
215 validate_type(magic_kind)
216
216
217 # This is a closure to capture the magic_kind. We could also use a class,
217 # This is a closure to capture the magic_kind. We could also use a class,
218 # but it's overkill for just that one bit of state.
218 # but it's overkill for just that one bit of state.
219 def magic_deco(arg):
219 def magic_deco(arg):
220 call = lambda f, *a, **k: f(*a, **k)
220 call = lambda f, *a, **k: f(*a, **k)
221
221
222 # Find get_ipython() in the caller's namespace
222 # Find get_ipython() in the caller's namespace
223 caller = sys._getframe(1)
223 caller = sys._getframe(1)
224 for ns in ['f_locals', 'f_globals', 'f_builtins']:
224 for ns in ['f_locals', 'f_globals', 'f_builtins']:
225 get_ipython = getattr(caller, ns).get('get_ipython')
225 get_ipython = getattr(caller, ns).get('get_ipython')
226 if get_ipython is not None:
226 if get_ipython is not None:
227 break
227 break
228 else:
228 else:
229 raise NameError('Decorator can only run in context where '
229 raise NameError('Decorator can only run in context where '
230 '`get_ipython` exists')
230 '`get_ipython` exists')
231
231
232 ip = get_ipython()
232 ip = get_ipython()
233
233
234 if callable(arg):
234 if callable(arg):
235 # "Naked" decorator call (just @foo, no args)
235 # "Naked" decorator call (just @foo, no args)
236 func = arg
236 func = arg
237 name = func.__name__
237 name = func.__name__
238 ip.register_magic_function(func, magic_kind, name)
238 ip.register_magic_function(func, magic_kind, name)
239 retval = decorator(call, func)
239 retval = decorator(call, func)
240 elif isinstance(arg, str):
240 elif isinstance(arg, str):
241 # Decorator called with arguments (@foo('bar'))
241 # Decorator called with arguments (@foo('bar'))
242 name = arg
242 name = arg
243 def mark(func, *a, **kw):
243 def mark(func, *a, **kw):
244 ip.register_magic_function(func, magic_kind, name)
244 ip.register_magic_function(func, magic_kind, name)
245 return decorator(call, func)
245 return decorator(call, func)
246 retval = mark
246 retval = mark
247 else:
247 else:
248 raise TypeError("Decorator can only be called with "
248 raise TypeError("Decorator can only be called with "
249 "string or function")
249 "string or function")
250 return retval
250 return retval
251
251
252 # Ensure the resulting decorator has a usable docstring
252 # Ensure the resulting decorator has a usable docstring
253 ds = _docstring_template.format('function', magic_kind)
253 ds = _docstring_template.format('function', magic_kind)
254
254
255 ds += dedent("""
255 ds += dedent("""
256 Note: this decorator can only be used in a context where IPython is already
256 Note: this decorator can only be used in a context where IPython is already
257 active, so that the `get_ipython()` call succeeds. You can therefore use
257 active, so that the `get_ipython()` call succeeds. You can therefore use
258 it in your startup files loaded after IPython initializes, but *not* in the
258 it in your startup files loaded after IPython initializes, but *not* in the
259 IPython configuration file itself, which is executed before IPython is
259 IPython configuration file itself, which is executed before IPython is
260 fully up and running. Any file located in the `startup` subdirectory of
260 fully up and running. Any file located in the `startup` subdirectory of
261 your configuration profile will be OK in this sense.
261 your configuration profile will be OK in this sense.
262 """)
262 """)
263
263
264 magic_deco.__doc__ = ds
264 magic_deco.__doc__ = ds
265 return magic_deco
265 return magic_deco
266
266
267
267
268 MAGIC_NO_VAR_EXPAND_ATTR = '_ipython_magic_no_var_expand'
268 MAGIC_NO_VAR_EXPAND_ATTR = '_ipython_magic_no_var_expand'
269
269
270
270
271 def no_var_expand(magic_func):
271 def no_var_expand(magic_func):
272 """Mark a magic function as not needing variable expansion
272 """Mark a magic function as not needing variable expansion
273
273
274 By default, IPython interprets `{a}` or `$a` in the line passed to magics
274 By default, IPython interprets `{a}` or `$a` in the line passed to magics
275 as variables that should be interpolated from the interactive namespace
275 as variables that should be interpolated from the interactive namespace
276 before passing the line to the magic function.
276 before passing the line to the magic function.
277 This is not always desirable, e.g. when the magic executes Python code
277 This is not always desirable, e.g. when the magic executes Python code
278 (%timeit, %time, etc.).
278 (%timeit, %time, etc.).
279 Decorate magics with `@no_var_expand` to opt-out of variable expansion.
279 Decorate magics with `@no_var_expand` to opt-out of variable expansion.
280
280
281 .. versionadded:: 7.3
281 .. versionadded:: 7.3
282 """
282 """
283 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True)
283 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True)
284 return magic_func
284 return magic_func
285
285
286
286
287 # Create the actual decorators for public use
287 # Create the actual decorators for public use
288
288
289 # These three are used to decorate methods in class definitions
289 # These three are used to decorate methods in class definitions
290 line_magic = _method_magic_marker('line')
290 line_magic = _method_magic_marker('line')
291 cell_magic = _method_magic_marker('cell')
291 cell_magic = _method_magic_marker('cell')
292 line_cell_magic = _method_magic_marker('line_cell')
292 line_cell_magic = _method_magic_marker('line_cell')
293
293
294 # These three decorate standalone functions and perform the decoration
294 # These three decorate standalone functions and perform the decoration
295 # immediately. They can only run where get_ipython() works
295 # immediately. They can only run where get_ipython() works
296 register_line_magic = _function_magic_marker('line')
296 register_line_magic = _function_magic_marker('line')
297 register_cell_magic = _function_magic_marker('cell')
297 register_cell_magic = _function_magic_marker('cell')
298 register_line_cell_magic = _function_magic_marker('line_cell')
298 register_line_cell_magic = _function_magic_marker('line_cell')
299
299
300 #-----------------------------------------------------------------------------
300 #-----------------------------------------------------------------------------
301 # Core Magic classes
301 # Core Magic classes
302 #-----------------------------------------------------------------------------
302 #-----------------------------------------------------------------------------
303
303
304 class MagicsManager(Configurable):
304 class MagicsManager(Configurable):
305 """Object that handles all magic-related functionality for IPython.
305 """Object that handles all magic-related functionality for IPython.
306 """
306 """
307 # Non-configurable class attributes
307 # Non-configurable class attributes
308
308
309 # A two-level dict, first keyed by magic type, then by magic function, and
309 # A two-level dict, first keyed by magic type, then by magic function, and
310 # holding the actual callable object as value. This is the dict used for
310 # holding the actual callable object as value. This is the dict used for
311 # magic function dispatch
311 # magic function dispatch
312 magics = Dict()
312 magics = Dict()
313
313
314 # A registry of the original objects that we've been given holding magics.
314 # A registry of the original objects that we've been given holding magics.
315 registry = Dict()
315 registry = Dict()
316
316
317 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
317 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
318
318
319 auto_magic = Bool(True, help=
319 auto_magic = Bool(True, help=
320 "Automatically call line magics without requiring explicit % prefix"
320 "Automatically call line magics without requiring explicit % prefix"
321 ).tag(config=True)
321 ).tag(config=True)
322 @observe('auto_magic')
322 @observe('auto_magic')
323 def _auto_magic_changed(self, change):
323 def _auto_magic_changed(self, change):
324 self.shell.automagic = change['new']
324 self.shell.automagic = change['new']
325
325
326 _auto_status = [
326 _auto_status = [
327 'Automagic is OFF, % prefix IS needed for line magics.',
327 'Automagic is OFF, % prefix IS needed for line magics.',
328 'Automagic is ON, % prefix IS NOT needed for line magics.']
328 'Automagic is ON, % prefix IS NOT needed for line magics.']
329
329
330 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
330 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
331
331
332 def __init__(self, shell=None, config=None, user_magics=None, **traits):
332 def __init__(self, shell=None, config=None, user_magics=None, **traits):
333
333
334 super(MagicsManager, self).__init__(shell=shell, config=config,
334 super(MagicsManager, self).__init__(shell=shell, config=config,
335 user_magics=user_magics, **traits)
335 user_magics=user_magics, **traits)
336 self.magics = dict(line={}, cell={})
336 self.magics = dict(line={}, cell={})
337 # Let's add the user_magics to the registry for uniformity, so *all*
337 # Let's add the user_magics to the registry for uniformity, so *all*
338 # registered magic containers can be found there.
338 # registered magic containers can be found there.
339 self.registry[user_magics.__class__.__name__] = user_magics
339 self.registry[user_magics.__class__.__name__] = user_magics
340
340
341 def auto_status(self):
341 def auto_status(self):
342 """Return descriptive string with automagic status."""
342 """Return descriptive string with automagic status."""
343 return self._auto_status[self.auto_magic]
343 return self._auto_status[self.auto_magic]
344
344
345 def lsmagic(self):
345 def lsmagic(self):
346 """Return a dict of currently available magic functions.
346 """Return a dict of currently available magic functions.
347
347
348 The return dict has the keys 'line' and 'cell', corresponding to the
348 The return dict has the keys 'line' and 'cell', corresponding to the
349 two types of magics we support. Each value is a list of names.
349 two types of magics we support. Each value is a list of names.
350 """
350 """
351 return self.magics
351 return self.magics
352
352
353 def lsmagic_docs(self, brief=False, missing=''):
353 def lsmagic_docs(self, brief=False, missing=''):
354 """Return dict of documentation of magic functions.
354 """Return dict of documentation of magic functions.
355
355
356 The return dict has the keys 'line' and 'cell', corresponding to the
356 The return dict has the keys 'line' and 'cell', corresponding to the
357 two types of magics we support. Each value is a dict keyed by magic
357 two types of magics we support. Each value is a dict keyed by magic
358 name whose value is the function docstring. If a docstring is
358 name whose value is the function docstring. If a docstring is
359 unavailable, the value of `missing` is used instead.
359 unavailable, the value of `missing` is used instead.
360
360
361 If brief is True, only the first line of each docstring will be returned.
361 If brief is True, only the first line of each docstring will be returned.
362 """
362 """
363 docs = {}
363 docs = {}
364 for m_type in self.magics:
364 for m_type in self.magics:
365 m_docs = {}
365 m_docs = {}
366 for m_name, m_func in self.magics[m_type].items():
366 for m_name, m_func in self.magics[m_type].items():
367 if m_func.__doc__:
367 if m_func.__doc__:
368 if brief:
368 if brief:
369 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
369 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
370 else:
370 else:
371 m_docs[m_name] = m_func.__doc__.rstrip()
371 m_docs[m_name] = m_func.__doc__.rstrip()
372 else:
372 else:
373 m_docs[m_name] = missing
373 m_docs[m_name] = missing
374 docs[m_type] = m_docs
374 docs[m_type] = m_docs
375 return docs
375 return docs
376
376
377 def register(self, *magic_objects):
377 def register(self, *magic_objects):
378 """Register one or more instances of Magics.
378 """Register one or more instances of Magics.
379
379
380 Take one or more classes or instances of classes that subclass the main
380 Take one or more classes or instances of classes that subclass the main
381 `core.Magic` class, and register them with IPython to use the magic
381 `core.Magic` class, and register them with IPython to use the magic
382 functions they provide. The registration process will then ensure that
382 functions they provide. The registration process will then ensure that
383 any methods that have decorated to provide line and/or cell magics will
383 any methods that have decorated to provide line and/or cell magics will
384 be recognized with the `%x`/`%%x` syntax as a line/cell magic
384 be recognized with the `%x`/`%%x` syntax as a line/cell magic
385 respectively.
385 respectively.
386
386
387 If classes are given, they will be instantiated with the default
387 If classes are given, they will be instantiated with the default
388 constructor. If your classes need a custom constructor, you should
388 constructor. If your classes need a custom constructor, you should
389 instanitate them first and pass the instance.
389 instanitate them first and pass the instance.
390
390
391 The provided arguments can be an arbitrary mix of classes and instances.
391 The provided arguments can be an arbitrary mix of classes and instances.
392
392
393 Parameters
393 Parameters
394 ----------
394 ----------
395 magic_objects : one or more classes or instances
395 magic_objects : one or more classes or instances
396 """
396 """
397 # Start by validating them to ensure they have all had their magic
397 # Start by validating them to ensure they have all had their magic
398 # methods registered at the instance level
398 # methods registered at the instance level
399 for m in magic_objects:
399 for m in magic_objects:
400 if not m.registered:
400 if not m.registered:
401 raise ValueError("Class of magics %r was constructed without "
401 raise ValueError("Class of magics %r was constructed without "
402 "the @register_magics class decorator")
402 "the @register_magics class decorator")
403 if isinstance(m, type):
403 if isinstance(m, type):
404 # If we're given an uninstantiated class
404 # If we're given an uninstantiated class
405 m = m(shell=self.shell)
405 m = m(shell=self.shell)
406
406
407 # Now that we have an instance, we can register it and update the
407 # Now that we have an instance, we can register it and update the
408 # table of callables
408 # table of callables
409 self.registry[m.__class__.__name__] = m
409 self.registry[m.__class__.__name__] = m
410 for mtype in magic_kinds:
410 for mtype in magic_kinds:
411 self.magics[mtype].update(m.magics[mtype])
411 self.magics[mtype].update(m.magics[mtype])
412
412
413 def register_function(self, func, magic_kind='line', magic_name=None):
413 def register_function(self, func, magic_kind='line', magic_name=None):
414 """Expose a standalone function as magic function for IPython.
414 """Expose a standalone function as magic function for IPython.
415
415
416 This will create an IPython magic (line, cell or both) from a
416 This will create an IPython magic (line, cell or both) from a
417 standalone function. The functions should have the following
417 standalone function. The functions should have the following
418 signatures:
418 signatures:
419
419
420 * For line magics: `def f(line)`
420 * For line magics: `def f(line)`
421 * For cell magics: `def f(line, cell)`
421 * For cell magics: `def f(line, cell)`
422 * For a function that does both: `def f(line, cell=None)`
422 * For a function that does both: `def f(line, cell=None)`
423
423
424 In the latter case, the function will be called with `cell==None` when
424 In the latter case, the function will be called with `cell==None` when
425 invoked as `%f`, and with cell as a string when invoked as `%%f`.
425 invoked as `%f`, and with cell as a string when invoked as `%%f`.
426
426
427 Parameters
427 Parameters
428 ----------
428 ----------
429 func : callable
429 func : callable
430 Function to be registered as a magic.
430 Function to be registered as a magic.
431
431
432 magic_kind : str
432 magic_kind : str
433 Kind of magic, one of 'line', 'cell' or 'line_cell'
433 Kind of magic, one of 'line', 'cell' or 'line_cell'
434
434
435 magic_name : optional str
435 magic_name : optional str
436 If given, the name the magic will have in the IPython namespace. By
436 If given, the name the magic will have in the IPython namespace. By
437 default, the name of the function itself is used.
437 default, the name of the function itself is used.
438 """
438 """
439
439
440 # Create the new method in the user_magics and register it in the
440 # Create the new method in the user_magics and register it in the
441 # global table
441 # global table
442 validate_type(magic_kind)
442 validate_type(magic_kind)
443 magic_name = func.__name__ if magic_name is None else magic_name
443 magic_name = func.__name__ if magic_name is None else magic_name
444 setattr(self.user_magics, magic_name, func)
444 setattr(self.user_magics, magic_name, func)
445 record_magic(self.magics, magic_kind, magic_name, func)
445 record_magic(self.magics, magic_kind, magic_name, func)
446
446
447 def register_alias(self, alias_name, magic_name, magic_kind='line', magic_params=None):
447 def register_alias(self, alias_name, magic_name, magic_kind='line', magic_params=None):
448 """Register an alias to a magic function.
448 """Register an alias to a magic function.
449
449
450 The alias is an instance of :class:`MagicAlias`, which holds the
450 The alias is an instance of :class:`MagicAlias`, which holds the
451 name and kind of the magic it should call. Binding is done at
451 name and kind of the magic it should call. Binding is done at
452 call time, so if the underlying magic function is changed the alias
452 call time, so if the underlying magic function is changed the alias
453 will call the new function.
453 will call the new function.
454
454
455 Parameters
455 Parameters
456 ----------
456 ----------
457 alias_name : str
457 alias_name : str
458 The name of the magic to be registered.
458 The name of the magic to be registered.
459
459
460 magic_name : str
460 magic_name : str
461 The name of an existing magic.
461 The name of an existing magic.
462
462
463 magic_kind : str
463 magic_kind : str
464 Kind of magic, one of 'line' or 'cell'
464 Kind of magic, one of 'line' or 'cell'
465 """
465 """
466
466
467 # `validate_type` is too permissive, as it allows 'line_cell'
467 # `validate_type` is too permissive, as it allows 'line_cell'
468 # which we do not handle.
468 # which we do not handle.
469 if magic_kind not in magic_kinds:
469 if magic_kind not in magic_kinds:
470 raise ValueError('magic_kind must be one of %s, %s given' %
470 raise ValueError('magic_kind must be one of %s, %s given' %
471 magic_kinds, magic_kind)
471 magic_kinds, magic_kind)
472
472
473 alias = MagicAlias(self.shell, magic_name, magic_kind, magic_params)
473 alias = MagicAlias(self.shell, magic_name, magic_kind, magic_params)
474 setattr(self.user_magics, alias_name, alias)
474 setattr(self.user_magics, alias_name, alias)
475 record_magic(self.magics, magic_kind, alias_name, alias)
475 record_magic(self.magics, magic_kind, alias_name, alias)
476
476
477 # Key base class that provides the central functionality for magics.
477 # Key base class that provides the central functionality for magics.
478
478
479
479
480 class Magics(Configurable):
480 class Magics(Configurable):
481 """Base class for implementing magic functions.
481 """Base class for implementing magic functions.
482
482
483 Shell functions which can be reached as %function_name. All magic
483 Shell functions which can be reached as %function_name. All magic
484 functions should accept a string, which they can parse for their own
484 functions should accept a string, which they can parse for their own
485 needs. This can make some functions easier to type, eg `%cd ../`
485 needs. This can make some functions easier to type, eg `%cd ../`
486 vs. `%cd("../")`
486 vs. `%cd("../")`
487
487
488 Classes providing magic functions need to subclass this class, and they
488 Classes providing magic functions need to subclass this class, and they
489 MUST:
489 MUST:
490
490
491 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
491 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
492 individual methods as magic functions, AND
492 individual methods as magic functions, AND
493
493
494 - Use the class decorator `@magics_class` to ensure that the magic
494 - Use the class decorator `@magics_class` to ensure that the magic
495 methods are properly registered at the instance level upon instance
495 methods are properly registered at the instance level upon instance
496 initialization.
496 initialization.
497
497
498 See :mod:`magic_functions` for examples of actual implementation classes.
498 See :mod:`magic_functions` for examples of actual implementation classes.
499 """
499 """
500 # Dict holding all command-line options for each magic.
500 # Dict holding all command-line options for each magic.
501 options_table = None
501 options_table = None
502 # Dict for the mapping of magic names to methods, set by class decorator
502 # Dict for the mapping of magic names to methods, set by class decorator
503 magics = None
503 magics = None
504 # Flag to check that the class decorator was properly applied
504 # Flag to check that the class decorator was properly applied
505 registered = False
505 registered = False
506 # Instance of IPython shell
506 # Instance of IPython shell
507 shell = None
507 shell = None
508
508
509 def __init__(self, shell=None, **kwargs):
509 def __init__(self, shell=None, **kwargs):
510 if not(self.__class__.registered):
510 if not(self.__class__.registered):
511 raise ValueError('Magics subclass without registration - '
511 raise ValueError('Magics subclass without registration - '
512 'did you forget to apply @magics_class?')
512 'did you forget to apply @magics_class?')
513 if shell is not None:
513 if shell is not None:
514 if hasattr(shell, 'configurables'):
514 if hasattr(shell, 'configurables'):
515 shell.configurables.append(self)
515 shell.configurables.append(self)
516 if hasattr(shell, 'config'):
516 if hasattr(shell, 'config'):
517 kwargs.setdefault('parent', shell)
517 kwargs.setdefault('parent', shell)
518
518
519 self.shell = shell
519 self.shell = shell
520 self.options_table = {}
520 self.options_table = {}
521 # The method decorators are run when the instance doesn't exist yet, so
521 # The method decorators are run when the instance doesn't exist yet, so
522 # they can only record the names of the methods they are supposed to
522 # they can only record the names of the methods they are supposed to
523 # grab. Only now, that the instance exists, can we create the proper
523 # grab. Only now, that the instance exists, can we create the proper
524 # mapping to bound methods. So we read the info off the original names
524 # mapping to bound methods. So we read the info off the original names
525 # table and replace each method name by the actual bound method.
525 # table and replace each method name by the actual bound method.
526 # But we mustn't clobber the *class* mapping, in case of multiple instances.
526 # But we mustn't clobber the *class* mapping, in case of multiple instances.
527 class_magics = self.magics
527 class_magics = self.magics
528 self.magics = {}
528 self.magics = {}
529 for mtype in magic_kinds:
529 for mtype in magic_kinds:
530 tab = self.magics[mtype] = {}
530 tab = self.magics[mtype] = {}
531 cls_tab = class_magics[mtype]
531 cls_tab = class_magics[mtype]
532 for magic_name, meth_name in cls_tab.items():
532 for magic_name, meth_name in cls_tab.items():
533 if isinstance(meth_name, str):
533 if isinstance(meth_name, str):
534 # it's a method name, grab it
534 # it's a method name, grab it
535 tab[magic_name] = getattr(self, meth_name)
535 tab[magic_name] = getattr(self, meth_name)
536 else:
536 else:
537 # it's the real thing
537 # it's the real thing
538 tab[magic_name] = meth_name
538 tab[magic_name] = meth_name
539 # Configurable **needs** to be initiated at the end or the config
539 # Configurable **needs** to be initiated at the end or the config
540 # magics get screwed up.
540 # magics get screwed up.
541 super(Magics, self).__init__(**kwargs)
541 super(Magics, self).__init__(**kwargs)
542
542
543 def arg_err(self,func):
543 def arg_err(self,func):
544 """Print docstring if incorrect arguments were passed"""
544 """Print docstring if incorrect arguments were passed"""
545 print('Error in arguments:')
545 print('Error in arguments:')
546 print(oinspect.getdoc(func))
546 print(oinspect.getdoc(func))
547
547
548 def format_latex(self, strng):
548 def format_latex(self, strng):
549 """Format a string for latex inclusion."""
549 """Format a string for latex inclusion."""
550
550
551 # Characters that need to be escaped for latex:
551 # Characters that need to be escaped for latex:
552 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
552 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
553 # Magic command names as headers:
553 # Magic command names as headers:
554 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
554 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
555 re.MULTILINE)
555 re.MULTILINE)
556 # Magic commands
556 # Magic commands
557 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
557 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
558 re.MULTILINE)
558 re.MULTILINE)
559 # Paragraph continue
559 # Paragraph continue
560 par_re = re.compile(r'\\$',re.MULTILINE)
560 par_re = re.compile(r'\\$',re.MULTILINE)
561
561
562 # The "\n" symbol
562 # The "\n" symbol
563 newline_re = re.compile(r'\\n')
563 newline_re = re.compile(r'\\n')
564
564
565 # Now build the string for output:
565 # Now build the string for output:
566 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
566 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
567 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
567 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
568 strng)
568 strng)
569 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
569 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
570 strng = par_re.sub(r'\\\\',strng)
570 strng = par_re.sub(r'\\\\',strng)
571 strng = escape_re.sub(r'\\\1',strng)
571 strng = escape_re.sub(r'\\\1',strng)
572 strng = newline_re.sub(r'\\textbackslash{}n',strng)
572 strng = newline_re.sub(r'\\textbackslash{}n',strng)
573 return strng
573 return strng
574
574
575 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
575 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
576 """Parse options passed to an argument string.
576 """Parse options passed to an argument string.
577
577
578 The interface is similar to that of :func:`getopt.getopt`, but it
578 The interface is similar to that of :func:`getopt.getopt`, but it
579 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
579 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
580 and the stripped argument string still as a string.
580 and the stripped argument string still as a string.
581
581
582 arg_str is quoted as a true sys.argv vector by using shlex.split.
582 arg_str is quoted as a true sys.argv vector by using shlex.split.
583 This allows us to easily expand variables, glob files, quote
583 This allows us to easily expand variables, glob files, quote
584 arguments, etc.
584 arguments, etc.
585
585
586 Parameters
586 Parameters
587 ----------
587 ----------
588
588
589 arg_str : str
589 arg_str : str
590 The arguments to parse.
590 The arguments to parse.
591
591
592 opt_str : str
592 opt_str : str
593 The options specification.
593 The options specification.
594
594
595 mode : str, default 'string'
595 mode : str, default 'string'
596 If given as 'list', the argument string is returned as a list (split
596 If given as 'list', the argument string is returned as a list (split
597 on whitespace) instead of a string.
597 on whitespace) instead of a string.
598
598
599 list_all : bool, default False
599 list_all : bool, default False
600 Put all option values in lists. Normally only options
600 Put all option values in lists. Normally only options
601 appearing more than once are put in a list.
601 appearing more than once are put in a list.
602
602
603 posix : bool, default True
603 posix : bool, default True
604 Whether to split the input line in POSIX mode or not, as per the
604 Whether to split the input line in POSIX mode or not, as per the
605 conventions outlined in the :mod:`shlex` module from the standard
605 conventions outlined in the :mod:`shlex` module from the standard
606 library.
606 library.
607 """
607 """
608
608
609 # inject default options at the beginning of the input line
609 # inject default options at the beginning of the input line
610 caller = sys._getframe(1).f_code.co_name
610 caller = sys._getframe(1).f_code.co_name
611 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
611 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
612
612
613 mode = kw.get('mode','string')
613 mode = kw.get('mode','string')
614 if mode not in ['string','list']:
614 if mode not in ['string','list']:
615 raise ValueError('incorrect mode given: %s' % mode)
615 raise ValueError('incorrect mode given: %s' % mode)
616 # Get options
616 # Get options
617 list_all = kw.get('list_all',0)
617 list_all = kw.get('list_all',0)
618 posix = kw.get('posix', os.name == 'posix')
618 posix = kw.get('posix', os.name == 'posix')
619 strict = kw.get('strict', True)
619 strict = kw.get('strict', True)
620
620
621 # Check if we have more than one argument to warrant extra processing:
621 # Check if we have more than one argument to warrant extra processing:
622 odict = {} # Dictionary with options
622 odict = {} # Dictionary with options
623 args = arg_str.split()
623 args = arg_str.split()
624 if len(args) >= 1:
624 if len(args) >= 1:
625 # If the list of inputs only has 0 or 1 thing in it, there's no
625 # If the list of inputs only has 0 or 1 thing in it, there's no
626 # need to look for options
626 # need to look for options
627 argv = arg_split(arg_str, posix, strict)
627 argv = arg_split(arg_str, posix, strict)
628 # Do regular option processing
628 # Do regular option processing
629 try:
629 try:
630 opts,args = getopt(argv, opt_str, long_opts)
630 opts,args = getopt(argv, opt_str, long_opts)
631 except GetoptError as e:
631 except GetoptError as e:
632 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
632 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
633 " ".join(long_opts)))
633 " ".join(long_opts)))
634 for o,a in opts:
634 for o,a in opts:
635 if o.startswith('--'):
635 if o.startswith('--'):
636 o = o[2:]
636 o = o[2:]
637 else:
637 else:
638 o = o[1:]
638 o = o[1:]
639 try:
639 try:
640 odict[o].append(a)
640 odict[o].append(a)
641 except AttributeError:
641 except AttributeError:
642 odict[o] = [odict[o],a]
642 odict[o] = [odict[o],a]
643 except KeyError:
643 except KeyError:
644 if list_all:
644 if list_all:
645 odict[o] = [a]
645 odict[o] = [a]
646 else:
646 else:
647 odict[o] = a
647 odict[o] = a
648
648
649 # Prepare opts,args for return
649 # Prepare opts,args for return
650 opts = Struct(odict)
650 opts = Struct(odict)
651 if mode == 'string':
651 if mode == 'string':
652 args = ' '.join(args)
652 args = ' '.join(args)
653
653
654 return opts,args
654 return opts,args
655
655
656 def default_option(self, fn, optstr):
656 def default_option(self, fn, optstr):
657 """Make an entry in the options_table for fn, with value optstr"""
657 """Make an entry in the options_table for fn, with value optstr"""
658
658
659 if fn not in self.lsmagic():
659 if fn not in self.lsmagic():
660 error("%s is not a magic function" % fn)
660 error("%s is not a magic function" % fn)
661 self.options_table[fn] = optstr
661 self.options_table[fn] = optstr
662
662
663
663
664 class MagicAlias(object):
664 class MagicAlias(object):
665 """An alias to another magic function.
665 """An alias to another magic function.
666
666
667 An alias is determined by its magic name and magic kind. Lookup
667 An alias is determined by its magic name and magic kind. Lookup
668 is done at call time, so if the underlying magic changes the alias
668 is done at call time, so if the underlying magic changes the alias
669 will call the new function.
669 will call the new function.
670
670
671 Use the :meth:`MagicsManager.register_alias` method or the
671 Use the :meth:`MagicsManager.register_alias` method or the
672 `%alias_magic` magic function to create and register a new alias.
672 `%alias_magic` magic function to create and register a new alias.
673 """
673 """
674 def __init__(self, shell, magic_name, magic_kind, magic_params=None):
674 def __init__(self, shell, magic_name, magic_kind, magic_params=None):
675 self.shell = shell
675 self.shell = shell
676 self.magic_name = magic_name
676 self.magic_name = magic_name
677 self.magic_params = magic_params
677 self.magic_params = magic_params
678 self.magic_kind = magic_kind
678 self.magic_kind = magic_kind
679
679
680 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
680 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
681 self.__doc__ = "Alias for `%s`." % self.pretty_target
681 self.__doc__ = "Alias for `%s`." % self.pretty_target
682
682
683 self._in_call = False
683 self._in_call = False
684
684
685 def __call__(self, *args, **kwargs):
685 def __call__(self, *args, **kwargs):
686 """Call the magic alias."""
686 """Call the magic alias."""
687 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
687 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
688 if fn is None:
688 if fn is None:
689 raise UsageError("Magic `%s` not found." % self.pretty_target)
689 raise UsageError("Magic `%s` not found." % self.pretty_target)
690
690
691 # Protect against infinite recursion.
691 # Protect against infinite recursion.
692 if self._in_call:
692 if self._in_call:
693 raise UsageError("Infinite recursion detected; "
693 raise UsageError("Infinite recursion detected; "
694 "magic aliases cannot call themselves.")
694 "magic aliases cannot call themselves.")
695 self._in_call = True
695 self._in_call = True
696 try:
696 try:
697 if self.magic_params:
697 if self.magic_params:
698 args_list = list(args)
698 args_list = list(args)
699 args_list[0] = self.magic_params + " " + args[0]
699 args_list[0] = self.magic_params + " " + args[0]
700 args = tuple(args_list)
700 args = tuple(args_list)
701 return fn(*args, **kwargs)
701 return fn(*args, **kwargs)
702 finally:
702 finally:
703 self._in_call = False
703 self._in_call = False
@@ -1,709 +1,709 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
8
9 # Copyright (c) IPython Development Team.
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11
11
12 from keyword import iskeyword
12 from keyword import iskeyword
13 import re
13 import re
14
14
15 from IPython.core.autocall import IPyAutocall
15 from .autocall import IPyAutocall
16 from traitlets.config.configurable import Configurable
16 from traitlets.config.configurable import Configurable
17 from IPython.core.inputtransformer2 import (
17 from .inputtransformer2 import (
18 ESC_MAGIC,
18 ESC_MAGIC,
19 ESC_QUOTE,
19 ESC_QUOTE,
20 ESC_QUOTE2,
20 ESC_QUOTE2,
21 ESC_PAREN,
21 ESC_PAREN,
22 )
22 )
23 from IPython.core.macro import Macro
23 from .macro import Macro
24 from IPython.core.splitinput import LineInfo
24 from .splitinput import LineInfo
25
25
26 from traitlets import (
26 from traitlets import (
27 List, Integer, Unicode, Bool, Instance, CRegExp
27 List, Integer, Unicode, Bool, Instance, CRegExp
28 )
28 )
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Global utilities, errors and constants
31 # Global utilities, errors and constants
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34
34
35 class PrefilterError(Exception):
35 class PrefilterError(Exception):
36 pass
36 pass
37
37
38
38
39 # RegExp to identify potential function names
39 # RegExp to identify potential function names
40 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
40 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
41
41
42 # RegExp to exclude strings with this start from autocalling. In
42 # RegExp to exclude strings with this start from autocalling. In
43 # particular, all binary operators should be excluded, so that if foo is
43 # particular, all binary operators should be excluded, so that if foo is
44 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
44 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
45 # characters '!=()' don't need to be checked for, as the checkPythonChars
45 # characters '!=()' don't need to be checked for, as the checkPythonChars
46 # routine explicitly does so, to catch direct calls and rebindings of
46 # routine explicitly does so, to catch direct calls and rebindings of
47 # existing names.
47 # existing names.
48
48
49 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
49 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
50 # it affects the rest of the group in square brackets.
50 # it affects the rest of the group in square brackets.
51 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
51 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
52 r'|^is |^not |^in |^and |^or ')
52 r'|^is |^not |^in |^and |^or ')
53
53
54 # try to catch also methods for stuff in lists/tuples/dicts: off
54 # try to catch also methods for stuff in lists/tuples/dicts: off
55 # (experimental). For this to work, the line_split regexp would need
55 # (experimental). For this to work, the line_split regexp would need
56 # to be modified so it wouldn't break things at '['. That line is
56 # to be modified so it wouldn't break things at '['. That line is
57 # nasty enough that I shouldn't change it until I can test it _well_.
57 # nasty enough that I shouldn't change it until I can test it _well_.
58 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
58 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
59
59
60
60
61 # Handler Check Utilities
61 # Handler Check Utilities
62 def is_shadowed(identifier, ip):
62 def is_shadowed(identifier, ip):
63 """Is the given identifier defined in one of the namespaces which shadow
63 """Is the given identifier defined in one of the namespaces which shadow
64 the alias and magic namespaces? Note that an identifier is different
64 the alias and magic namespaces? Note that an identifier is different
65 than ifun, because it can not contain a '.' character."""
65 than ifun, because it can not contain a '.' character."""
66 # This is much safer than calling ofind, which can change state
66 # This is much safer than calling ofind, which can change state
67 return (identifier in ip.user_ns \
67 return (identifier in ip.user_ns \
68 or identifier in ip.user_global_ns \
68 or identifier in ip.user_global_ns \
69 or identifier in ip.ns_table['builtin']\
69 or identifier in ip.ns_table['builtin']\
70 or iskeyword(identifier))
70 or iskeyword(identifier))
71
71
72
72
73 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
74 # Main Prefilter manager
74 # Main Prefilter manager
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76
76
77
77
78 class PrefilterManager(Configurable):
78 class PrefilterManager(Configurable):
79 """Main prefilter component.
79 """Main prefilter component.
80
80
81 The IPython prefilter is run on all user input before it is run. The
81 The IPython prefilter is run on all user input before it is run. The
82 prefilter consumes lines of input and produces transformed lines of
82 prefilter consumes lines of input and produces transformed lines of
83 input.
83 input.
84
84
85 The implementation consists of two phases:
85 The implementation consists of two phases:
86
86
87 1. Transformers
87 1. Transformers
88 2. Checkers and handlers
88 2. Checkers and handlers
89
89
90 Over time, we plan on deprecating the checkers and handlers and doing
90 Over time, we plan on deprecating the checkers and handlers and doing
91 everything in the transformers.
91 everything in the transformers.
92
92
93 The transformers are instances of :class:`PrefilterTransformer` and have
93 The transformers are instances of :class:`PrefilterTransformer` and have
94 a single method :meth:`transform` that takes a line and returns a
94 a single method :meth:`transform` that takes a line and returns a
95 transformed line. The transformation can be accomplished using any
95 transformed line. The transformation can be accomplished using any
96 tool, but our current ones use regular expressions for speed.
96 tool, but our current ones use regular expressions for speed.
97
97
98 After all the transformers have been run, the line is fed to the checkers,
98 After all the transformers have been run, the line is fed to the checkers,
99 which are instances of :class:`PrefilterChecker`. The line is passed to
99 which are instances of :class:`PrefilterChecker`. The line is passed to
100 the :meth:`check` method, which either returns `None` or a
100 the :meth:`check` method, which either returns `None` or a
101 :class:`PrefilterHandler` instance. If `None` is returned, the other
101 :class:`PrefilterHandler` instance. If `None` is returned, the other
102 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
102 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
103 the line is passed to the :meth:`handle` method of the returned
103 the line is passed to the :meth:`handle` method of the returned
104 handler and no further checkers are tried.
104 handler and no further checkers are tried.
105
105
106 Both transformers and checkers have a `priority` attribute, that determines
106 Both transformers and checkers have a `priority` attribute, that determines
107 the order in which they are called. Smaller priorities are tried first.
107 the order in which they are called. Smaller priorities are tried first.
108
108
109 Both transformers and checkers also have `enabled` attribute, which is
109 Both transformers and checkers also have `enabled` attribute, which is
110 a boolean that determines if the instance is used.
110 a boolean that determines if the instance is used.
111
111
112 Users or developers can change the priority or enabled attribute of
112 Users or developers can change the priority or enabled attribute of
113 transformers or checkers, but they must call the :meth:`sort_checkers`
113 transformers or checkers, but they must call the :meth:`sort_checkers`
114 or :meth:`sort_transformers` method after changing the priority.
114 or :meth:`sort_transformers` method after changing the priority.
115 """
115 """
116
116
117 multi_line_specials = Bool(True).tag(config=True)
117 multi_line_specials = Bool(True).tag(config=True)
118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
119
119
120 def __init__(self, shell=None, **kwargs):
120 def __init__(self, shell=None, **kwargs):
121 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
121 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
122 self.shell = shell
122 self.shell = shell
123 self.init_transformers()
123 self.init_transformers()
124 self.init_handlers()
124 self.init_handlers()
125 self.init_checkers()
125 self.init_checkers()
126
126
127 #-------------------------------------------------------------------------
127 #-------------------------------------------------------------------------
128 # API for managing transformers
128 # API for managing transformers
129 #-------------------------------------------------------------------------
129 #-------------------------------------------------------------------------
130
130
131 def init_transformers(self):
131 def init_transformers(self):
132 """Create the default transformers."""
132 """Create the default transformers."""
133 self._transformers = []
133 self._transformers = []
134 for transformer_cls in _default_transformers:
134 for transformer_cls in _default_transformers:
135 transformer_cls(
135 transformer_cls(
136 shell=self.shell, prefilter_manager=self, parent=self
136 shell=self.shell, prefilter_manager=self, parent=self
137 )
137 )
138
138
139 def sort_transformers(self):
139 def sort_transformers(self):
140 """Sort the transformers by priority.
140 """Sort the transformers by priority.
141
141
142 This must be called after the priority of a transformer is changed.
142 This must be called after the priority of a transformer is changed.
143 The :meth:`register_transformer` method calls this automatically.
143 The :meth:`register_transformer` method calls this automatically.
144 """
144 """
145 self._transformers.sort(key=lambda x: x.priority)
145 self._transformers.sort(key=lambda x: x.priority)
146
146
147 @property
147 @property
148 def transformers(self):
148 def transformers(self):
149 """Return a list of checkers, sorted by priority."""
149 """Return a list of checkers, sorted by priority."""
150 return self._transformers
150 return self._transformers
151
151
152 def register_transformer(self, transformer):
152 def register_transformer(self, transformer):
153 """Register a transformer instance."""
153 """Register a transformer instance."""
154 if transformer not in self._transformers:
154 if transformer not in self._transformers:
155 self._transformers.append(transformer)
155 self._transformers.append(transformer)
156 self.sort_transformers()
156 self.sort_transformers()
157
157
158 def unregister_transformer(self, transformer):
158 def unregister_transformer(self, transformer):
159 """Unregister a transformer instance."""
159 """Unregister a transformer instance."""
160 if transformer in self._transformers:
160 if transformer in self._transformers:
161 self._transformers.remove(transformer)
161 self._transformers.remove(transformer)
162
162
163 #-------------------------------------------------------------------------
163 #-------------------------------------------------------------------------
164 # API for managing checkers
164 # API for managing checkers
165 #-------------------------------------------------------------------------
165 #-------------------------------------------------------------------------
166
166
167 def init_checkers(self):
167 def init_checkers(self):
168 """Create the default checkers."""
168 """Create the default checkers."""
169 self._checkers = []
169 self._checkers = []
170 for checker in _default_checkers:
170 for checker in _default_checkers:
171 checker(
171 checker(
172 shell=self.shell, prefilter_manager=self, parent=self
172 shell=self.shell, prefilter_manager=self, parent=self
173 )
173 )
174
174
175 def sort_checkers(self):
175 def sort_checkers(self):
176 """Sort the checkers by priority.
176 """Sort the checkers by priority.
177
177
178 This must be called after the priority of a checker is changed.
178 This must be called after the priority of a checker is changed.
179 The :meth:`register_checker` method calls this automatically.
179 The :meth:`register_checker` method calls this automatically.
180 """
180 """
181 self._checkers.sort(key=lambda x: x.priority)
181 self._checkers.sort(key=lambda x: x.priority)
182
182
183 @property
183 @property
184 def checkers(self):
184 def checkers(self):
185 """Return a list of checkers, sorted by priority."""
185 """Return a list of checkers, sorted by priority."""
186 return self._checkers
186 return self._checkers
187
187
188 def register_checker(self, checker):
188 def register_checker(self, checker):
189 """Register a checker instance."""
189 """Register a checker instance."""
190 if checker not in self._checkers:
190 if checker not in self._checkers:
191 self._checkers.append(checker)
191 self._checkers.append(checker)
192 self.sort_checkers()
192 self.sort_checkers()
193
193
194 def unregister_checker(self, checker):
194 def unregister_checker(self, checker):
195 """Unregister a checker instance."""
195 """Unregister a checker instance."""
196 if checker in self._checkers:
196 if checker in self._checkers:
197 self._checkers.remove(checker)
197 self._checkers.remove(checker)
198
198
199 #-------------------------------------------------------------------------
199 #-------------------------------------------------------------------------
200 # API for managing handlers
200 # API for managing handlers
201 #-------------------------------------------------------------------------
201 #-------------------------------------------------------------------------
202
202
203 def init_handlers(self):
203 def init_handlers(self):
204 """Create the default handlers."""
204 """Create the default handlers."""
205 self._handlers = {}
205 self._handlers = {}
206 self._esc_handlers = {}
206 self._esc_handlers = {}
207 for handler in _default_handlers:
207 for handler in _default_handlers:
208 handler(
208 handler(
209 shell=self.shell, prefilter_manager=self, parent=self
209 shell=self.shell, prefilter_manager=self, parent=self
210 )
210 )
211
211
212 @property
212 @property
213 def handlers(self):
213 def handlers(self):
214 """Return a dict of all the handlers."""
214 """Return a dict of all the handlers."""
215 return self._handlers
215 return self._handlers
216
216
217 def register_handler(self, name, handler, esc_strings):
217 def register_handler(self, name, handler, esc_strings):
218 """Register a handler instance by name with esc_strings."""
218 """Register a handler instance by name with esc_strings."""
219 self._handlers[name] = handler
219 self._handlers[name] = handler
220 for esc_str in esc_strings:
220 for esc_str in esc_strings:
221 self._esc_handlers[esc_str] = handler
221 self._esc_handlers[esc_str] = handler
222
222
223 def unregister_handler(self, name, handler, esc_strings):
223 def unregister_handler(self, name, handler, esc_strings):
224 """Unregister a handler instance by name with esc_strings."""
224 """Unregister a handler instance by name with esc_strings."""
225 try:
225 try:
226 del self._handlers[name]
226 del self._handlers[name]
227 except KeyError:
227 except KeyError:
228 pass
228 pass
229 for esc_str in esc_strings:
229 for esc_str in esc_strings:
230 h = self._esc_handlers.get(esc_str)
230 h = self._esc_handlers.get(esc_str)
231 if h is handler:
231 if h is handler:
232 del self._esc_handlers[esc_str]
232 del self._esc_handlers[esc_str]
233
233
234 def get_handler_by_name(self, name):
234 def get_handler_by_name(self, name):
235 """Get a handler by its name."""
235 """Get a handler by its name."""
236 return self._handlers.get(name)
236 return self._handlers.get(name)
237
237
238 def get_handler_by_esc(self, esc_str):
238 def get_handler_by_esc(self, esc_str):
239 """Get a handler by its escape string."""
239 """Get a handler by its escape string."""
240 return self._esc_handlers.get(esc_str)
240 return self._esc_handlers.get(esc_str)
241
241
242 #-------------------------------------------------------------------------
242 #-------------------------------------------------------------------------
243 # Main prefiltering API
243 # Main prefiltering API
244 #-------------------------------------------------------------------------
244 #-------------------------------------------------------------------------
245
245
246 def prefilter_line_info(self, line_info):
246 def prefilter_line_info(self, line_info):
247 """Prefilter a line that has been converted to a LineInfo object.
247 """Prefilter a line that has been converted to a LineInfo object.
248
248
249 This implements the checker/handler part of the prefilter pipe.
249 This implements the checker/handler part of the prefilter pipe.
250 """
250 """
251 # print "prefilter_line_info: ", line_info
251 # print "prefilter_line_info: ", line_info
252 handler = self.find_handler(line_info)
252 handler = self.find_handler(line_info)
253 return handler.handle(line_info)
253 return handler.handle(line_info)
254
254
255 def find_handler(self, line_info):
255 def find_handler(self, line_info):
256 """Find a handler for the line_info by trying checkers."""
256 """Find a handler for the line_info by trying checkers."""
257 for checker in self.checkers:
257 for checker in self.checkers:
258 if checker.enabled:
258 if checker.enabled:
259 handler = checker.check(line_info)
259 handler = checker.check(line_info)
260 if handler:
260 if handler:
261 return handler
261 return handler
262 return self.get_handler_by_name('normal')
262 return self.get_handler_by_name('normal')
263
263
264 def transform_line(self, line, continue_prompt):
264 def transform_line(self, line, continue_prompt):
265 """Calls the enabled transformers in order of increasing priority."""
265 """Calls the enabled transformers in order of increasing priority."""
266 for transformer in self.transformers:
266 for transformer in self.transformers:
267 if transformer.enabled:
267 if transformer.enabled:
268 line = transformer.transform(line, continue_prompt)
268 line = transformer.transform(line, continue_prompt)
269 return line
269 return line
270
270
271 def prefilter_line(self, line, continue_prompt=False):
271 def prefilter_line(self, line, continue_prompt=False):
272 """Prefilter a single input line as text.
272 """Prefilter a single input line as text.
273
273
274 This method prefilters a single line of text by calling the
274 This method prefilters a single line of text by calling the
275 transformers and then the checkers/handlers.
275 transformers and then the checkers/handlers.
276 """
276 """
277
277
278 # print "prefilter_line: ", line, continue_prompt
278 # print "prefilter_line: ", line, continue_prompt
279 # All handlers *must* return a value, even if it's blank ('').
279 # All handlers *must* return a value, even if it's blank ('').
280
280
281 # save the line away in case we crash, so the post-mortem handler can
281 # save the line away in case we crash, so the post-mortem handler can
282 # record it
282 # record it
283 self.shell._last_input_line = line
283 self.shell._last_input_line = line
284
284
285 if not line:
285 if not line:
286 # Return immediately on purely empty lines, so that if the user
286 # Return immediately on purely empty lines, so that if the user
287 # previously typed some whitespace that started a continuation
287 # previously typed some whitespace that started a continuation
288 # prompt, he can break out of that loop with just an empty line.
288 # prompt, he can break out of that loop with just an empty line.
289 # This is how the default python prompt works.
289 # This is how the default python prompt works.
290 return ''
290 return ''
291
291
292 # At this point, we invoke our transformers.
292 # At this point, we invoke our transformers.
293 if not continue_prompt or (continue_prompt and self.multi_line_specials):
293 if not continue_prompt or (continue_prompt and self.multi_line_specials):
294 line = self.transform_line(line, continue_prompt)
294 line = self.transform_line(line, continue_prompt)
295
295
296 # Now we compute line_info for the checkers and handlers
296 # Now we compute line_info for the checkers and handlers
297 line_info = LineInfo(line, continue_prompt)
297 line_info = LineInfo(line, continue_prompt)
298
298
299 # the input history needs to track even empty lines
299 # the input history needs to track even empty lines
300 stripped = line.strip()
300 stripped = line.strip()
301
301
302 normal_handler = self.get_handler_by_name('normal')
302 normal_handler = self.get_handler_by_name('normal')
303 if not stripped:
303 if not stripped:
304 return normal_handler.handle(line_info)
304 return normal_handler.handle(line_info)
305
305
306 # special handlers are only allowed for single line statements
306 # special handlers are only allowed for single line statements
307 if continue_prompt and not self.multi_line_specials:
307 if continue_prompt and not self.multi_line_specials:
308 return normal_handler.handle(line_info)
308 return normal_handler.handle(line_info)
309
309
310 prefiltered = self.prefilter_line_info(line_info)
310 prefiltered = self.prefilter_line_info(line_info)
311 # print "prefiltered line: %r" % prefiltered
311 # print "prefiltered line: %r" % prefiltered
312 return prefiltered
312 return prefiltered
313
313
314 def prefilter_lines(self, lines, continue_prompt=False):
314 def prefilter_lines(self, lines, continue_prompt=False):
315 """Prefilter multiple input lines of text.
315 """Prefilter multiple input lines of text.
316
316
317 This is the main entry point for prefiltering multiple lines of
317 This is the main entry point for prefiltering multiple lines of
318 input. This simply calls :meth:`prefilter_line` for each line of
318 input. This simply calls :meth:`prefilter_line` for each line of
319 input.
319 input.
320
320
321 This covers cases where there are multiple lines in the user entry,
321 This covers cases where there are multiple lines in the user entry,
322 which is the case when the user goes back to a multiline history
322 which is the case when the user goes back to a multiline history
323 entry and presses enter.
323 entry and presses enter.
324 """
324 """
325 llines = lines.rstrip('\n').split('\n')
325 llines = lines.rstrip('\n').split('\n')
326 # We can get multiple lines in one shot, where multiline input 'blends'
326 # We can get multiple lines in one shot, where multiline input 'blends'
327 # into one line, in cases like recalling from the readline history
327 # into one line, in cases like recalling from the readline history
328 # buffer. We need to make sure that in such cases, we correctly
328 # buffer. We need to make sure that in such cases, we correctly
329 # communicate downstream which line is first and which are continuation
329 # communicate downstream which line is first and which are continuation
330 # ones.
330 # ones.
331 if len(llines) > 1:
331 if len(llines) > 1:
332 out = '\n'.join([self.prefilter_line(line, lnum>0)
332 out = '\n'.join([self.prefilter_line(line, lnum>0)
333 for lnum, line in enumerate(llines) ])
333 for lnum, line in enumerate(llines) ])
334 else:
334 else:
335 out = self.prefilter_line(llines[0], continue_prompt)
335 out = self.prefilter_line(llines[0], continue_prompt)
336
336
337 return out
337 return out
338
338
339 #-----------------------------------------------------------------------------
339 #-----------------------------------------------------------------------------
340 # Prefilter transformers
340 # Prefilter transformers
341 #-----------------------------------------------------------------------------
341 #-----------------------------------------------------------------------------
342
342
343
343
344 class PrefilterTransformer(Configurable):
344 class PrefilterTransformer(Configurable):
345 """Transform a line of user input."""
345 """Transform a line of user input."""
346
346
347 priority = Integer(100).tag(config=True)
347 priority = Integer(100).tag(config=True)
348 # Transformers don't currently use shell or prefilter_manager, but as we
348 # Transformers don't currently use shell or prefilter_manager, but as we
349 # move away from checkers and handlers, they will need them.
349 # move away from checkers and handlers, they will need them.
350 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
350 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
351 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
351 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
352 enabled = Bool(True).tag(config=True)
352 enabled = Bool(True).tag(config=True)
353
353
354 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
354 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
355 super(PrefilterTransformer, self).__init__(
355 super(PrefilterTransformer, self).__init__(
356 shell=shell, prefilter_manager=prefilter_manager, **kwargs
356 shell=shell, prefilter_manager=prefilter_manager, **kwargs
357 )
357 )
358 self.prefilter_manager.register_transformer(self)
358 self.prefilter_manager.register_transformer(self)
359
359
360 def transform(self, line, continue_prompt):
360 def transform(self, line, continue_prompt):
361 """Transform a line, returning the new one."""
361 """Transform a line, returning the new one."""
362 return None
362 return None
363
363
364 def __repr__(self):
364 def __repr__(self):
365 return "<%s(priority=%r, enabled=%r)>" % (
365 return "<%s(priority=%r, enabled=%r)>" % (
366 self.__class__.__name__, self.priority, self.enabled)
366 self.__class__.__name__, self.priority, self.enabled)
367
367
368
368
369 #-----------------------------------------------------------------------------
369 #-----------------------------------------------------------------------------
370 # Prefilter checkers
370 # Prefilter checkers
371 #-----------------------------------------------------------------------------
371 #-----------------------------------------------------------------------------
372
372
373
373
374 class PrefilterChecker(Configurable):
374 class PrefilterChecker(Configurable):
375 """Inspect an input line and return a handler for that line."""
375 """Inspect an input line and return a handler for that line."""
376
376
377 priority = Integer(100).tag(config=True)
377 priority = Integer(100).tag(config=True)
378 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
378 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
379 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
379 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
380 enabled = Bool(True).tag(config=True)
380 enabled = Bool(True).tag(config=True)
381
381
382 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
382 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
383 super(PrefilterChecker, self).__init__(
383 super(PrefilterChecker, self).__init__(
384 shell=shell, prefilter_manager=prefilter_manager, **kwargs
384 shell=shell, prefilter_manager=prefilter_manager, **kwargs
385 )
385 )
386 self.prefilter_manager.register_checker(self)
386 self.prefilter_manager.register_checker(self)
387
387
388 def check(self, line_info):
388 def check(self, line_info):
389 """Inspect line_info and return a handler instance or None."""
389 """Inspect line_info and return a handler instance or None."""
390 return None
390 return None
391
391
392 def __repr__(self):
392 def __repr__(self):
393 return "<%s(priority=%r, enabled=%r)>" % (
393 return "<%s(priority=%r, enabled=%r)>" % (
394 self.__class__.__name__, self.priority, self.enabled)
394 self.__class__.__name__, self.priority, self.enabled)
395
395
396
396
397 class EmacsChecker(PrefilterChecker):
397 class EmacsChecker(PrefilterChecker):
398
398
399 priority = Integer(100).tag(config=True)
399 priority = Integer(100).tag(config=True)
400 enabled = Bool(False).tag(config=True)
400 enabled = Bool(False).tag(config=True)
401
401
402 def check(self, line_info):
402 def check(self, line_info):
403 "Emacs ipython-mode tags certain input lines."
403 "Emacs ipython-mode tags certain input lines."
404 if line_info.line.endswith('# PYTHON-MODE'):
404 if line_info.line.endswith('# PYTHON-MODE'):
405 return self.prefilter_manager.get_handler_by_name('emacs')
405 return self.prefilter_manager.get_handler_by_name('emacs')
406 else:
406 else:
407 return None
407 return None
408
408
409
409
410 class MacroChecker(PrefilterChecker):
410 class MacroChecker(PrefilterChecker):
411
411
412 priority = Integer(250).tag(config=True)
412 priority = Integer(250).tag(config=True)
413
413
414 def check(self, line_info):
414 def check(self, line_info):
415 obj = self.shell.user_ns.get(line_info.ifun)
415 obj = self.shell.user_ns.get(line_info.ifun)
416 if isinstance(obj, Macro):
416 if isinstance(obj, Macro):
417 return self.prefilter_manager.get_handler_by_name('macro')
417 return self.prefilter_manager.get_handler_by_name('macro')
418 else:
418 else:
419 return None
419 return None
420
420
421
421
422 class IPyAutocallChecker(PrefilterChecker):
422 class IPyAutocallChecker(PrefilterChecker):
423
423
424 priority = Integer(300).tag(config=True)
424 priority = Integer(300).tag(config=True)
425
425
426 def check(self, line_info):
426 def check(self, line_info):
427 "Instances of IPyAutocall in user_ns get autocalled immediately"
427 "Instances of IPyAutocall in user_ns get autocalled immediately"
428 obj = self.shell.user_ns.get(line_info.ifun, None)
428 obj = self.shell.user_ns.get(line_info.ifun, None)
429 if isinstance(obj, IPyAutocall):
429 if isinstance(obj, IPyAutocall):
430 obj.set_ip(self.shell)
430 obj.set_ip(self.shell)
431 return self.prefilter_manager.get_handler_by_name('auto')
431 return self.prefilter_manager.get_handler_by_name('auto')
432 else:
432 else:
433 return None
433 return None
434
434
435
435
436 class AssignmentChecker(PrefilterChecker):
436 class AssignmentChecker(PrefilterChecker):
437
437
438 priority = Integer(600).tag(config=True)
438 priority = Integer(600).tag(config=True)
439
439
440 def check(self, line_info):
440 def check(self, line_info):
441 """Check to see if user is assigning to a var for the first time, in
441 """Check to see if user is assigning to a var for the first time, in
442 which case we want to avoid any sort of automagic / autocall games.
442 which case we want to avoid any sort of automagic / autocall games.
443
443
444 This allows users to assign to either alias or magic names true python
444 This allows users to assign to either alias or magic names true python
445 variables (the magic/alias systems always take second seat to true
445 variables (the magic/alias systems always take second seat to true
446 python code). E.g. ls='hi', or ls,that=1,2"""
446 python code). E.g. ls='hi', or ls,that=1,2"""
447 if line_info.the_rest:
447 if line_info.the_rest:
448 if line_info.the_rest[0] in '=,':
448 if line_info.the_rest[0] in '=,':
449 return self.prefilter_manager.get_handler_by_name('normal')
449 return self.prefilter_manager.get_handler_by_name('normal')
450 else:
450 else:
451 return None
451 return None
452
452
453
453
454 class AutoMagicChecker(PrefilterChecker):
454 class AutoMagicChecker(PrefilterChecker):
455
455
456 priority = Integer(700).tag(config=True)
456 priority = Integer(700).tag(config=True)
457
457
458 def check(self, line_info):
458 def check(self, line_info):
459 """If the ifun is magic, and automagic is on, run it. Note: normal,
459 """If the ifun is magic, and automagic is on, run it. Note: normal,
460 non-auto magic would already have been triggered via '%' in
460 non-auto magic would already have been triggered via '%' in
461 check_esc_chars. This just checks for automagic. Also, before
461 check_esc_chars. This just checks for automagic. Also, before
462 triggering the magic handler, make sure that there is nothing in the
462 triggering the magic handler, make sure that there is nothing in the
463 user namespace which could shadow it."""
463 user namespace which could shadow it."""
464 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
464 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
465 return None
465 return None
466
466
467 # We have a likely magic method. Make sure we should actually call it.
467 # We have a likely magic method. Make sure we should actually call it.
468 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
468 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
469 return None
469 return None
470
470
471 head = line_info.ifun.split('.',1)[0]
471 head = line_info.ifun.split('.',1)[0]
472 if is_shadowed(head, self.shell):
472 if is_shadowed(head, self.shell):
473 return None
473 return None
474
474
475 return self.prefilter_manager.get_handler_by_name('magic')
475 return self.prefilter_manager.get_handler_by_name('magic')
476
476
477
477
478 class PythonOpsChecker(PrefilterChecker):
478 class PythonOpsChecker(PrefilterChecker):
479
479
480 priority = Integer(900).tag(config=True)
480 priority = Integer(900).tag(config=True)
481
481
482 def check(self, line_info):
482 def check(self, line_info):
483 """If the 'rest' of the line begins with a function call or pretty much
483 """If the 'rest' of the line begins with a function call or pretty much
484 any python operator, we should simply execute the line (regardless of
484 any python operator, we should simply execute the line (regardless of
485 whether or not there's a possible autocall expansion). This avoids
485 whether or not there's a possible autocall expansion). This avoids
486 spurious (and very confusing) geattr() accesses."""
486 spurious (and very confusing) geattr() accesses."""
487 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
487 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
488 return self.prefilter_manager.get_handler_by_name('normal')
488 return self.prefilter_manager.get_handler_by_name('normal')
489 else:
489 else:
490 return None
490 return None
491
491
492
492
493 class AutocallChecker(PrefilterChecker):
493 class AutocallChecker(PrefilterChecker):
494
494
495 priority = Integer(1000).tag(config=True)
495 priority = Integer(1000).tag(config=True)
496
496
497 function_name_regexp = CRegExp(re_fun_name,
497 function_name_regexp = CRegExp(re_fun_name,
498 help="RegExp to identify potential function names."
498 help="RegExp to identify potential function names."
499 ).tag(config=True)
499 ).tag(config=True)
500 exclude_regexp = CRegExp(re_exclude_auto,
500 exclude_regexp = CRegExp(re_exclude_auto,
501 help="RegExp to exclude strings with this start from autocalling."
501 help="RegExp to exclude strings with this start from autocalling."
502 ).tag(config=True)
502 ).tag(config=True)
503
503
504 def check(self, line_info):
504 def check(self, line_info):
505 "Check if the initial word/function is callable and autocall is on."
505 "Check if the initial word/function is callable and autocall is on."
506 if not self.shell.autocall:
506 if not self.shell.autocall:
507 return None
507 return None
508
508
509 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
509 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
510 if not oinfo['found']:
510 if not oinfo['found']:
511 return None
511 return None
512
512
513 ignored_funs = ['b', 'f', 'r', 'u', 'br', 'rb', 'fr', 'rf']
513 ignored_funs = ['b', 'f', 'r', 'u', 'br', 'rb', 'fr', 'rf']
514 ifun = line_info.ifun
514 ifun = line_info.ifun
515 line = line_info.line
515 line = line_info.line
516 if ifun.lower() in ignored_funs and (line.startswith(ifun + "'") or line.startswith(ifun + '"')):
516 if ifun.lower() in ignored_funs and (line.startswith(ifun + "'") or line.startswith(ifun + '"')):
517 return None
517 return None
518
518
519 if callable(oinfo['obj']) \
519 if callable(oinfo['obj']) \
520 and (not self.exclude_regexp.match(line_info.the_rest)) \
520 and (not self.exclude_regexp.match(line_info.the_rest)) \
521 and self.function_name_regexp.match(line_info.ifun):
521 and self.function_name_regexp.match(line_info.ifun):
522 return self.prefilter_manager.get_handler_by_name('auto')
522 return self.prefilter_manager.get_handler_by_name('auto')
523 else:
523 else:
524 return None
524 return None
525
525
526
526
527 #-----------------------------------------------------------------------------
527 #-----------------------------------------------------------------------------
528 # Prefilter handlers
528 # Prefilter handlers
529 #-----------------------------------------------------------------------------
529 #-----------------------------------------------------------------------------
530
530
531
531
532 class PrefilterHandler(Configurable):
532 class PrefilterHandler(Configurable):
533
533
534 handler_name = Unicode('normal')
534 handler_name = Unicode('normal')
535 esc_strings = List([])
535 esc_strings = List([])
536 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
536 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
537 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
537 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
538
538
539 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
539 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
540 super(PrefilterHandler, self).__init__(
540 super(PrefilterHandler, self).__init__(
541 shell=shell, prefilter_manager=prefilter_manager, **kwargs
541 shell=shell, prefilter_manager=prefilter_manager, **kwargs
542 )
542 )
543 self.prefilter_manager.register_handler(
543 self.prefilter_manager.register_handler(
544 self.handler_name,
544 self.handler_name,
545 self,
545 self,
546 self.esc_strings
546 self.esc_strings
547 )
547 )
548
548
549 def handle(self, line_info):
549 def handle(self, line_info):
550 # print "normal: ", line_info
550 # print "normal: ", line_info
551 """Handle normal input lines. Use as a template for handlers."""
551 """Handle normal input lines. Use as a template for handlers."""
552
552
553 # With autoindent on, we need some way to exit the input loop, and I
553 # With autoindent on, we need some way to exit the input loop, and I
554 # don't want to force the user to have to backspace all the way to
554 # don't want to force the user to have to backspace all the way to
555 # clear the line. The rule will be in this case, that either two
555 # clear the line. The rule will be in this case, that either two
556 # lines of pure whitespace in a row, or a line of pure whitespace but
556 # lines of pure whitespace in a row, or a line of pure whitespace but
557 # of a size different to the indent level, will exit the input loop.
557 # of a size different to the indent level, will exit the input loop.
558 line = line_info.line
558 line = line_info.line
559 continue_prompt = line_info.continue_prompt
559 continue_prompt = line_info.continue_prompt
560
560
561 if (continue_prompt and
561 if (continue_prompt and
562 self.shell.autoindent and
562 self.shell.autoindent and
563 line.isspace() and
563 line.isspace() and
564 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
564 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
565 line = ''
565 line = ''
566
566
567 return line
567 return line
568
568
569 def __str__(self):
569 def __str__(self):
570 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
570 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
571
571
572
572
573 class MacroHandler(PrefilterHandler):
573 class MacroHandler(PrefilterHandler):
574 handler_name = Unicode("macro")
574 handler_name = Unicode("macro")
575
575
576 def handle(self, line_info):
576 def handle(self, line_info):
577 obj = self.shell.user_ns.get(line_info.ifun)
577 obj = self.shell.user_ns.get(line_info.ifun)
578 pre_space = line_info.pre_whitespace
578 pre_space = line_info.pre_whitespace
579 line_sep = "\n" + pre_space
579 line_sep = "\n" + pre_space
580 return pre_space + line_sep.join(obj.value.splitlines())
580 return pre_space + line_sep.join(obj.value.splitlines())
581
581
582
582
583 class MagicHandler(PrefilterHandler):
583 class MagicHandler(PrefilterHandler):
584
584
585 handler_name = Unicode('magic')
585 handler_name = Unicode('magic')
586 esc_strings = List([ESC_MAGIC])
586 esc_strings = List([ESC_MAGIC])
587
587
588 def handle(self, line_info):
588 def handle(self, line_info):
589 """Execute magic functions."""
589 """Execute magic functions."""
590 ifun = line_info.ifun
590 ifun = line_info.ifun
591 the_rest = line_info.the_rest
591 the_rest = line_info.the_rest
592 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
592 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
593 t_arg_s = ifun + " " + the_rest
593 t_arg_s = ifun + " " + the_rest
594 t_magic_name, _, t_magic_arg_s = t_arg_s.partition(' ')
594 t_magic_name, _, t_magic_arg_s = t_arg_s.partition(' ')
595 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
595 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
596 cmd = '%sget_ipython().run_line_magic(%r, %r)' % (line_info.pre_whitespace, t_magic_name, t_magic_arg_s)
596 cmd = '%sget_ipython().run_line_magic(%r, %r)' % (line_info.pre_whitespace, t_magic_name, t_magic_arg_s)
597 return cmd
597 return cmd
598
598
599
599
600 class AutoHandler(PrefilterHandler):
600 class AutoHandler(PrefilterHandler):
601
601
602 handler_name = Unicode('auto')
602 handler_name = Unicode('auto')
603 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
603 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
604
604
605 def handle(self, line_info):
605 def handle(self, line_info):
606 """Handle lines which can be auto-executed, quoting if requested."""
606 """Handle lines which can be auto-executed, quoting if requested."""
607 line = line_info.line
607 line = line_info.line
608 ifun = line_info.ifun
608 ifun = line_info.ifun
609 the_rest = line_info.the_rest
609 the_rest = line_info.the_rest
610 esc = line_info.esc
610 esc = line_info.esc
611 continue_prompt = line_info.continue_prompt
611 continue_prompt = line_info.continue_prompt
612 obj = line_info.ofind(self.shell)['obj']
612 obj = line_info.ofind(self.shell)['obj']
613
613
614 # This should only be active for single-line input!
614 # This should only be active for single-line input!
615 if continue_prompt:
615 if continue_prompt:
616 return line
616 return line
617
617
618 force_auto = isinstance(obj, IPyAutocall)
618 force_auto = isinstance(obj, IPyAutocall)
619
619
620 # User objects sometimes raise exceptions on attribute access other
620 # User objects sometimes raise exceptions on attribute access other
621 # than AttributeError (we've seen it in the past), so it's safest to be
621 # than AttributeError (we've seen it in the past), so it's safest to be
622 # ultra-conservative here and catch all.
622 # ultra-conservative here and catch all.
623 try:
623 try:
624 auto_rewrite = obj.rewrite
624 auto_rewrite = obj.rewrite
625 except Exception:
625 except Exception:
626 auto_rewrite = True
626 auto_rewrite = True
627
627
628 if esc == ESC_QUOTE:
628 if esc == ESC_QUOTE:
629 # Auto-quote splitting on whitespace
629 # Auto-quote splitting on whitespace
630 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
630 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
631 elif esc == ESC_QUOTE2:
631 elif esc == ESC_QUOTE2:
632 # Auto-quote whole string
632 # Auto-quote whole string
633 newcmd = '%s("%s")' % (ifun,the_rest)
633 newcmd = '%s("%s")' % (ifun,the_rest)
634 elif esc == ESC_PAREN:
634 elif esc == ESC_PAREN:
635 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
635 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
636 else:
636 else:
637 # Auto-paren.
637 # Auto-paren.
638 if force_auto:
638 if force_auto:
639 # Don't rewrite if it is already a call.
639 # Don't rewrite if it is already a call.
640 do_rewrite = not the_rest.startswith('(')
640 do_rewrite = not the_rest.startswith('(')
641 else:
641 else:
642 if not the_rest:
642 if not the_rest:
643 # We only apply it to argument-less calls if the autocall
643 # We only apply it to argument-less calls if the autocall
644 # parameter is set to 2.
644 # parameter is set to 2.
645 do_rewrite = (self.shell.autocall >= 2)
645 do_rewrite = (self.shell.autocall >= 2)
646 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
646 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
647 # Don't autocall in this case: item access for an object
647 # Don't autocall in this case: item access for an object
648 # which is BOTH callable and implements __getitem__.
648 # which is BOTH callable and implements __getitem__.
649 do_rewrite = False
649 do_rewrite = False
650 else:
650 else:
651 do_rewrite = True
651 do_rewrite = True
652
652
653 # Figure out the rewritten command
653 # Figure out the rewritten command
654 if do_rewrite:
654 if do_rewrite:
655 if the_rest.endswith(';'):
655 if the_rest.endswith(';'):
656 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
656 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
657 else:
657 else:
658 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
658 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
659 else:
659 else:
660 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
660 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
661 return normal_handler.handle(line_info)
661 return normal_handler.handle(line_info)
662
662
663 # Display the rewritten call
663 # Display the rewritten call
664 if auto_rewrite:
664 if auto_rewrite:
665 self.shell.auto_rewrite_input(newcmd)
665 self.shell.auto_rewrite_input(newcmd)
666
666
667 return newcmd
667 return newcmd
668
668
669
669
670 class EmacsHandler(PrefilterHandler):
670 class EmacsHandler(PrefilterHandler):
671
671
672 handler_name = Unicode('emacs')
672 handler_name = Unicode('emacs')
673 esc_strings = List([])
673 esc_strings = List([])
674
674
675 def handle(self, line_info):
675 def handle(self, line_info):
676 """Handle input lines marked by python-mode."""
676 """Handle input lines marked by python-mode."""
677
677
678 # Currently, nothing is done. Later more functionality can be added
678 # Currently, nothing is done. Later more functionality can be added
679 # here if needed.
679 # here if needed.
680
680
681 # The input cache shouldn't be updated
681 # The input cache shouldn't be updated
682 return line_info.line
682 return line_info.line
683
683
684
684
685 #-----------------------------------------------------------------------------
685 #-----------------------------------------------------------------------------
686 # Defaults
686 # Defaults
687 #-----------------------------------------------------------------------------
687 #-----------------------------------------------------------------------------
688
688
689
689
690 _default_transformers = [
690 _default_transformers = [
691 ]
691 ]
692
692
693 _default_checkers = [
693 _default_checkers = [
694 EmacsChecker,
694 EmacsChecker,
695 MacroChecker,
695 MacroChecker,
696 IPyAutocallChecker,
696 IPyAutocallChecker,
697 AssignmentChecker,
697 AssignmentChecker,
698 AutoMagicChecker,
698 AutoMagicChecker,
699 PythonOpsChecker,
699 PythonOpsChecker,
700 AutocallChecker
700 AutocallChecker
701 ]
701 ]
702
702
703 _default_handlers = [
703 _default_handlers = [
704 PrefilterHandler,
704 PrefilterHandler,
705 MacroHandler,
705 MacroHandler,
706 MagicHandler,
706 MagicHandler,
707 AutoHandler,
707 AutoHandler,
708 EmacsHandler
708 EmacsHandler
709 ]
709 ]
@@ -1,223 +1,223 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 traitlets.config.configurable import LoggingConfigurable
11 from traitlets.config.configurable import LoggingConfigurable
12 from IPython.paths import get_ipython_package_dir
12 from ..paths import get_ipython_package_dir
13 from IPython.utils.path import expand_path, ensure_dir_exists
13 from ..utils.path import expand_path, ensure_dir_exists
14 from traitlets import Unicode, Bool, observe
14 from traitlets import Unicode, Bool, observe
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Module errors
17 # Module errors
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 class ProfileDirError(Exception):
20 class ProfileDirError(Exception):
21 pass
21 pass
22
22
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Class for managing profile directories
25 # Class for managing profile directories
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class ProfileDir(LoggingConfigurable):
28 class ProfileDir(LoggingConfigurable):
29 """An object to manage the profile directory and its resources.
29 """An object to manage the profile directory and its resources.
30
30
31 The profile directory is used by all IPython applications, to manage
31 The profile directory is used by all IPython applications, to manage
32 configuration, logging and security.
32 configuration, logging and security.
33
33
34 This object knows how to find, create and manage these directories. This
34 This object knows how to find, create and manage these directories. This
35 should be used by any code that wants to handle profiles.
35 should be used by any code that wants to handle profiles.
36 """
36 """
37
37
38 security_dir_name = Unicode('security')
38 security_dir_name = Unicode('security')
39 log_dir_name = Unicode('log')
39 log_dir_name = Unicode('log')
40 startup_dir_name = Unicode('startup')
40 startup_dir_name = Unicode('startup')
41 pid_dir_name = Unicode('pid')
41 pid_dir_name = Unicode('pid')
42 static_dir_name = Unicode('static')
42 static_dir_name = Unicode('static')
43 security_dir = Unicode(u'')
43 security_dir = Unicode(u'')
44 log_dir = Unicode(u'')
44 log_dir = Unicode(u'')
45 startup_dir = Unicode(u'')
45 startup_dir = Unicode(u'')
46 pid_dir = Unicode(u'')
46 pid_dir = Unicode(u'')
47 static_dir = Unicode(u'')
47 static_dir = Unicode(u'')
48
48
49 location = Unicode(u'',
49 location = Unicode(u'',
50 help="""Set the profile location directly. This overrides the logic used by the
50 help="""Set the profile location directly. This overrides the logic used by the
51 `profile` option.""",
51 `profile` option.""",
52 ).tag(config=True)
52 ).tag(config=True)
53
53
54 _location_isset = Bool(False) # flag for detecting multiply set location
54 _location_isset = Bool(False) # flag for detecting multiply set location
55 @observe('location')
55 @observe('location')
56 def _location_changed(self, change):
56 def _location_changed(self, change):
57 if self._location_isset:
57 if self._location_isset:
58 raise RuntimeError("Cannot set profile location more than once.")
58 raise RuntimeError("Cannot set profile location more than once.")
59 self._location_isset = True
59 self._location_isset = True
60 new = change['new']
60 new = change['new']
61 ensure_dir_exists(new)
61 ensure_dir_exists(new)
62
62
63 # ensure config files exist:
63 # ensure config files exist:
64 self.security_dir = os.path.join(new, self.security_dir_name)
64 self.security_dir = os.path.join(new, self.security_dir_name)
65 self.log_dir = os.path.join(new, self.log_dir_name)
65 self.log_dir = os.path.join(new, self.log_dir_name)
66 self.startup_dir = os.path.join(new, self.startup_dir_name)
66 self.startup_dir = os.path.join(new, self.startup_dir_name)
67 self.pid_dir = os.path.join(new, self.pid_dir_name)
67 self.pid_dir = os.path.join(new, self.pid_dir_name)
68 self.static_dir = os.path.join(new, self.static_dir_name)
68 self.static_dir = os.path.join(new, self.static_dir_name)
69 self.check_dirs()
69 self.check_dirs()
70
70
71 def _mkdir(self, path, mode=None):
71 def _mkdir(self, path, mode=None):
72 """ensure a directory exists at a given path
72 """ensure a directory exists at a given path
73
73
74 This is a version of os.mkdir, with the following differences:
74 This is a version of os.mkdir, with the following differences:
75
75
76 - returns True if it created the directory, False otherwise
76 - returns True if it created the directory, False otherwise
77 - ignores EEXIST, protecting against race conditions where
77 - ignores EEXIST, protecting against race conditions where
78 the dir may have been created in between the check and
78 the dir may have been created in between the check and
79 the creation
79 the creation
80 - sets permissions if requested and the dir already exists
80 - sets permissions if requested and the dir already exists
81 """
81 """
82 if os.path.exists(path):
82 if os.path.exists(path):
83 if mode and os.stat(path).st_mode != mode:
83 if mode and os.stat(path).st_mode != mode:
84 try:
84 try:
85 os.chmod(path, mode)
85 os.chmod(path, mode)
86 except OSError:
86 except OSError:
87 self.log.warning(
87 self.log.warning(
88 "Could not set permissions on %s",
88 "Could not set permissions on %s",
89 path
89 path
90 )
90 )
91 return False
91 return False
92 try:
92 try:
93 if mode:
93 if mode:
94 os.mkdir(path, mode)
94 os.mkdir(path, mode)
95 else:
95 else:
96 os.mkdir(path)
96 os.mkdir(path)
97 except OSError as e:
97 except OSError as e:
98 if e.errno == errno.EEXIST:
98 if e.errno == errno.EEXIST:
99 return False
99 return False
100 else:
100 else:
101 raise
101 raise
102
102
103 return True
103 return True
104
104
105 @observe('log_dir')
105 @observe('log_dir')
106 def check_log_dir(self, change=None):
106 def check_log_dir(self, change=None):
107 self._mkdir(self.log_dir)
107 self._mkdir(self.log_dir)
108
108
109 @observe('startup_dir')
109 @observe('startup_dir')
110 def check_startup_dir(self, change=None):
110 def check_startup_dir(self, change=None):
111 self._mkdir(self.startup_dir)
111 self._mkdir(self.startup_dir)
112
112
113 readme = os.path.join(self.startup_dir, 'README')
113 readme = os.path.join(self.startup_dir, 'README')
114 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
114 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
115
115
116 if not os.path.exists(src):
116 if not os.path.exists(src):
117 self.log.warning("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
117 self.log.warning("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
118
118
119 if os.path.exists(src) and not os.path.exists(readme):
119 if os.path.exists(src) and not os.path.exists(readme):
120 shutil.copy(src, readme)
120 shutil.copy(src, readme)
121
121
122 @observe('security_dir')
122 @observe('security_dir')
123 def check_security_dir(self, change=None):
123 def check_security_dir(self, change=None):
124 self._mkdir(self.security_dir, 0o40700)
124 self._mkdir(self.security_dir, 0o40700)
125
125
126 @observe('pid_dir')
126 @observe('pid_dir')
127 def check_pid_dir(self, change=None):
127 def check_pid_dir(self, change=None):
128 self._mkdir(self.pid_dir, 0o40700)
128 self._mkdir(self.pid_dir, 0o40700)
129
129
130 def check_dirs(self):
130 def check_dirs(self):
131 self.check_security_dir()
131 self.check_security_dir()
132 self.check_log_dir()
132 self.check_log_dir()
133 self.check_pid_dir()
133 self.check_pid_dir()
134 self.check_startup_dir()
134 self.check_startup_dir()
135
135
136 def copy_config_file(self, config_file, path=None, overwrite=False):
136 def copy_config_file(self, config_file, path=None, overwrite=False):
137 """Copy a default config file into the active profile directory.
137 """Copy a default config file into the active profile directory.
138
138
139 Default configuration files are kept in :mod:`IPython.core.profile`.
139 Default configuration files are kept in :mod:`IPython.core.profile`.
140 This function moves these from that location to the working profile
140 This function moves these from that location to the working profile
141 directory.
141 directory.
142 """
142 """
143 dst = os.path.join(self.location, config_file)
143 dst = os.path.join(self.location, config_file)
144 if os.path.isfile(dst) and not overwrite:
144 if os.path.isfile(dst) and not overwrite:
145 return False
145 return False
146 if path is None:
146 if path is None:
147 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
147 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
148 src = os.path.join(path, config_file)
148 src = os.path.join(path, config_file)
149 shutil.copy(src, dst)
149 shutil.copy(src, dst)
150 return True
150 return True
151
151
152 @classmethod
152 @classmethod
153 def create_profile_dir(cls, profile_dir, config=None):
153 def create_profile_dir(cls, profile_dir, config=None):
154 """Create a new profile directory given a full path.
154 """Create a new profile directory given a full path.
155
155
156 Parameters
156 Parameters
157 ----------
157 ----------
158 profile_dir : str
158 profile_dir : str
159 The full path to the profile directory. If it does exist, it will
159 The full path to the profile directory. If it does exist, it will
160 be used. If not, it will be created.
160 be used. If not, it will be created.
161 """
161 """
162 return cls(location=profile_dir, config=config)
162 return cls(location=profile_dir, config=config)
163
163
164 @classmethod
164 @classmethod
165 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
165 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
166 """Create a profile dir by profile name and path.
166 """Create a profile dir by profile name and path.
167
167
168 Parameters
168 Parameters
169 ----------
169 ----------
170 path : unicode
170 path : unicode
171 The path (directory) to put the profile directory in.
171 The path (directory) to put the profile directory in.
172 name : unicode
172 name : unicode
173 The name of the profile. The name of the profile directory will
173 The name of the profile. The name of the profile directory will
174 be "profile_<profile>".
174 be "profile_<profile>".
175 """
175 """
176 if not os.path.isdir(path):
176 if not os.path.isdir(path):
177 raise ProfileDirError('Directory not found: %s' % path)
177 raise ProfileDirError('Directory not found: %s' % path)
178 profile_dir = os.path.join(path, u'profile_' + name)
178 profile_dir = os.path.join(path, u'profile_' + name)
179 return cls(location=profile_dir, config=config)
179 return cls(location=profile_dir, config=config)
180
180
181 @classmethod
181 @classmethod
182 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
182 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
183 """Find an existing profile dir by profile name, return its ProfileDir.
183 """Find an existing profile dir by profile name, return its ProfileDir.
184
184
185 This searches through a sequence of paths for a profile dir. If it
185 This searches through a sequence of paths for a profile dir. If it
186 is not found, a :class:`ProfileDirError` exception will be raised.
186 is not found, a :class:`ProfileDirError` exception will be raised.
187
187
188 The search path algorithm is:
188 The search path algorithm is:
189 1. ``os.getcwd()``
189 1. ``os.getcwd()``
190 2. ``ipython_dir``
190 2. ``ipython_dir``
191
191
192 Parameters
192 Parameters
193 ----------
193 ----------
194 ipython_dir : unicode or str
194 ipython_dir : unicode or str
195 The IPython directory to use.
195 The IPython directory to use.
196 name : unicode or str
196 name : unicode or str
197 The name of the profile. The name of the profile directory
197 The name of the profile. The name of the profile directory
198 will be "profile_<profile>".
198 will be "profile_<profile>".
199 """
199 """
200 dirname = u'profile_' + name
200 dirname = u'profile_' + name
201 paths = [os.getcwd(), ipython_dir]
201 paths = [os.getcwd(), ipython_dir]
202 for p in paths:
202 for p in paths:
203 profile_dir = os.path.join(p, dirname)
203 profile_dir = os.path.join(p, dirname)
204 if os.path.isdir(profile_dir):
204 if os.path.isdir(profile_dir):
205 return cls(location=profile_dir, config=config)
205 return cls(location=profile_dir, config=config)
206 else:
206 else:
207 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
207 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
208
208
209 @classmethod
209 @classmethod
210 def find_profile_dir(cls, profile_dir, config=None):
210 def find_profile_dir(cls, profile_dir, config=None):
211 """Find/create a profile dir and return its ProfileDir.
211 """Find/create a profile dir and return its ProfileDir.
212
212
213 This will create the profile directory if it doesn't exist.
213 This will create the profile directory if it doesn't exist.
214
214
215 Parameters
215 Parameters
216 ----------
216 ----------
217 profile_dir : unicode or str
217 profile_dir : unicode or str
218 The path of the profile directory.
218 The path of the profile directory.
219 """
219 """
220 profile_dir = expand_path(profile_dir)
220 profile_dir = expand_path(profile_dir)
221 if not os.path.isdir(profile_dir):
221 if not os.path.isdir(profile_dir):
222 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
222 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
223 return cls(location=profile_dir, config=config)
223 return cls(location=profile_dir, config=config)
General Comments 0
You need to be logged in to leave comments. Login now